summaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-rp-2.6.26/htcuni.patch
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-kernel/linux/linux-rp-2.6.26/htcuni.patch
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadpoky-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-kernel/linux/linux-rp-2.6.26/htcuni.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-rp-2.6.26/htcuni.patch7899
1 files changed, 7899 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-rp-2.6.26/htcuni.patch b/meta/recipes-kernel/linux/linux-rp-2.6.26/htcuni.patch
new file mode 100644
index 0000000000..783f55b064
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-rp-2.6.26/htcuni.patch
@@ -0,0 +1,7899 @@
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/generic.c | 13
6 arch/arm/mach-pxa/htcuniversal/Makefile | 19
7 arch/arm/mach-pxa/htcuniversal/htcuniversal.c | 468 +++++
8 arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.c | 917 +++++++++++
9 arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.h | 65
10 arch/arm/mach-pxa/htcuniversal/htcuniversal_asic3_leds.c | 143 +
11 arch/arm/mach-pxa/htcuniversal/htcuniversal_bl.c | 61
12 arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.c | 135 +
13 arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.h | 17
14 arch/arm/mach-pxa/htcuniversal/htcuniversal_buttons.c | 87 +
15 arch/arm/mach-pxa/htcuniversal/htcuniversal_core.c | 226 ++
16 arch/arm/mach-pxa/htcuniversal/htcuniversal_lcd.c | 212 ++
17 arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.c | 167 ++
18 arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.h | 16
19 arch/arm/mach-pxa/htcuniversal/htcuniversal_pm.c | 69
20 arch/arm/mach-pxa/htcuniversal/htcuniversal_power2.c | 97 +
21 arch/arm/mach-pxa/htcuniversal/htcuniversal_ts2.c | 490 ++++++
22 arch/arm/mach-pxa/htcuniversal/htcuniversal_udc.c | 71
23 arch/arm/mach-pxa/htcuniversal/tsc2046_ts.h | 20
24 drivers/input/keyboard/Kconfig | 7
25 drivers/input/keyboard/Makefile | 1
26 drivers/input/keyboard/asic3_keys.c | 131 +
27 drivers/leds/Kconfig | 7
28 drivers/leds/Makefile | 1
29 drivers/leds/leds-asic3.c | 189 ++
30 drivers/mfd/Kconfig | 10
31 drivers/mfd/Makefile | 2
32 drivers/mfd/asic3_base.c | 1208 +++++++++++++++
33 drivers/mfd/soc-core.c | 106 +
34 drivers/mfd/soc-core.h | 30
35 drivers/mmc/host/Kconfig | 6
36 drivers/mmc/host/Makefile | 1
37 drivers/mmc/host/asic3_mmc.c | 900 +++++++++++
38 drivers/mmc/host/asic3_mmc.h | 25
39 drivers/serial/pxa.c | 22
40 include/asm-arm/arch-pxa/clock.h | 27
41 include/asm-arm/arch-pxa/htcuniversal-asic.h | 213 ++
42 include/asm-arm/arch-pxa/htcuniversal-gpio.h | 220 ++
43 include/asm-arm/arch-pxa/htcuniversal-init.h | 14
44 include/asm-arm/arch-pxa/htcuniversal.h | 3
45 include/asm-arm/arch-pxa/irqs.h | 2
46 include/asm-arm/arch-pxa/pxa-pm_ll.h | 6
47 include/asm-arm/arch-pxa/pxa-regs.h | 2
48 include/asm-arm/arch-pxa/serial.h | 78
49 include/asm-arm/hardware/asic3_keys.h | 18
50 include/asm-arm/hardware/asic3_leds.h | 34
51 include/asm-arm/hardware/ipaq-asic3.h | 602 +++++++
52 include/linux/backlight.h | 7
53 include/linux/gpiodev.h | 44
54 include/linux/input_pda.h | 47
55 include/linux/ioport.h | 1
56 include/linux/soc/asic3_base.h | 104 +
57 include/linux/soc/tmio_mmc.h | 17
58 56 files changed, 7469 insertions(+), 1 deletion(-)
59
60Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/Makefile
61===================================================================
62--- /dev/null 1970-01-01 00:00:00.000000000 +0000
63+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/Makefile 2008-06-01 18:49:45.000000000 +0100
64@@ -0,0 +1,19 @@
65+#
66+# Makefile for HTC Universal
67+#
68+
69+snd-htcuniversal-ak4641-objs := htcuniversal_ak4641.o
70+
71+obj-$(CONFIG_MACH_HTCUNIVERSAL) += htcuniversal.o
72+obj-$(CONFIG_HTCUNIVERSAL_CORE) += htcuniversal_core.o
73+obj-$(CONFIG_HTCUNIVERSAL_POWER) += htcuniversal_power2.o
74+obj-$(CONFIG_HTCUNIVERSAL_LCD) += htcuniversal_lcd.o
75+obj-$(CONFIG_HTCUNIVERSAL_BACKLIGHT) += htcuniversal_bl.o
76+obj-$(CONFIG_HTCUNIVERSAL_TS2) += htcuniversal_ts2.o
77+obj-$(CONFIG_HTCUNIVERSAL_BUTTONS) += htcuniversal_buttons.o
78+obj-$(CONFIG_HTCUNIVERSAL_BLUETOOTH) += htcuniversal_bt.o
79+obj-$(CONFIG_HTCUNIVERSAL_PHONE) += htcuniversal_phone.o
80+obj-$(CONFIG_HTCUNIVERSAL_ASIC3_LEDS) += htcuniversal_asic3_leds.o
81+obj-$(CONFIG_HTCUNIVERSAL_UDC) += htcuniversal_udc.o
82+
83+obj-$(CONFIG_HTCUNIVERSAL_AK4641) += htcuniversal_ak4641.o
84Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal.c
85===================================================================
86--- /dev/null 1970-01-01 00:00:00.000000000 +0000
87+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal.c 2008-06-01 18:49:45.000000000 +0100
88@@ -0,0 +1,468 @@
89+/*
90+ * Hardware definitions for HTC Universal
91+ *
92+ * Copyright (c) 2006 Oleg Gusev
93+ *
94+ * Use consistent with the GNU GPL is permitted,
95+ * provided that this copyright notice is
96+ * preserved in its entirety in all copies and derived works.
97+ *
98+ */
99+
100+#include <linux/kernel.h>
101+#include <linux/init.h>
102+#include <linux/platform_device.h>
103+#include <linux/irq.h>
104+#include <linux/input.h>
105+#include <linux/gpio_keys.h>
106+#include <linux/soc/asic3_base.h>
107+
108+#include <asm/mach-types.h>
109+#include <asm/hardware.h>
110+#include <asm/setup.h>
111+
112+#include <asm/mach/irq.h>
113+#include <asm/mach/arch.h>
114+
115+#include <asm/arch/bitfield.h>
116+#include <asm/arch/pxa-regs.h>
117+#include <asm/arch/serial.h>
118+#include <asm/arch/pxa27x_keyboard.h>
119+#include <asm/arch/pxafb.h>
120+#include <asm/arch/irda.h>
121+#include <asm/arch/ohci.h>
122+
123+#include <asm/arch/htcuniversal.h>
124+#include <asm/arch/htcuniversal-gpio.h>
125+#include <asm/arch/htcuniversal-init.h>
126+#include <asm/arch/htcuniversal-asic.h>
127+
128+#include <asm/hardware/ipaq-asic3.h>
129+
130+#include "../generic.h"
131+
132+#include "htcuniversal_bt.h"
133+#include "htcuniversal_phone.h"
134+#include "tsc2046_ts.h"
135+
136+/*
137+ * IRDA
138+ */
139+
140+static void htcuniversal_irda_transceiver_mode(struct device *dev, int mode)
141+{
142+ /* */
143+}
144+
145+static struct pxaficp_platform_data htcuniversal_ficp_platform_data = {
146+ .transceiver_cap = IR_SIRMODE | IR_FIRMODE,
147+ .transceiver_mode = htcuniversal_irda_transceiver_mode,
148+};
149+
150+/*
151+ * Bluetooth - Relies on other loadable modules, like ASIC3 and Core,
152+ * so make the calls indirectly through pointers. Requires that the
153+ * htcuniversal_bt module be loaded before any attempt to use
154+ * bluetooth (obviously).
155+ */
156+
157+static struct htcuniversal_bt_funcs bt_funcs;
158+
159+static void
160+htcuniversal_bt_configure( int state )
161+{
162+ if (bt_funcs.configure != NULL)
163+ bt_funcs.configure( state );
164+}
165+
166+static struct htcuniversal_phone_funcs phone_funcs;
167+
168+static void
169+htcuniversal_phone_configure( int state )
170+{
171+ if (phone_funcs.configure != NULL)
172+ phone_funcs.configure( state );
173+}
174+
175+//void htcuniversal_ll_pm_init(void);
176+
177+extern struct platform_device htcuniversal_bl;
178+static struct platform_device htcuniversal_lcd = { .name = "htcuniversal_lcd", };
179+//static struct platform_device htcuniversal_kbd = { .name = "htcuniversal_kbd", };
180+static struct platform_device htcuniversal_buttons = { .name = "htcuniversal_buttons", };
181+//static struct platform_device htcuniversal_ts = { .name = "htcuniversal_ts", };
182+//static struct platform_device htcuniversal_bt = { .name = "htcuniversal_bt", };
183+//static struct platform_device htcuniversal_phone = { .name = "htcuniversal_phone", };
184+static struct platform_device htcuniversal_power = { .name = "htcuniversal_power", };
185+static struct platform_device htcuniversal_udc = { .name = "htcuniversal_udc", };
186+
187+static struct tsc2046_mach_info htcuniversal_ts_platform_data = {
188+ .port = 1,
189+ .clock = CKEN_SSP1,
190+ .pwrbit_X = 1,
191+ .pwrbit_Y = 1,
192+ .irq = 0 /* asic3 irq */
193+};
194+
195+static struct platform_device htcuniversal_ts = {
196+ .name = "htcuniversal_ts",
197+ .dev = {
198+ .platform_data = &htcuniversal_ts_platform_data,
199+ },
200+};
201+
202+
203+/* Bluetooth */
204+
205+static struct platform_device htcuniversal_bt = {
206+ .name = "htcuniversal_bt",
207+ .id = -1,
208+ .dev = {
209+ .platform_data = &bt_funcs,
210+ },
211+};
212+
213+static struct platform_device htcuniversal_phone = {
214+ .name = "htcuniversal_phone",
215+ .id = -1,
216+ .dev = {
217+ .platform_data = &phone_funcs,
218+ },
219+};
220+
221+/* PXA2xx Keys */
222+
223+static struct gpio_keys_button htcuniversal_button_table[] = {
224+ { KEY_POWER, GPIO_NR_HTCUNIVERSAL_KEY_ON_N, 1 },
225+};
226+
227+static struct gpio_keys_platform_data htcuniversal_pxa_keys_data = {
228+ .buttons = htcuniversal_button_table,
229+ .nbuttons = ARRAY_SIZE(htcuniversal_button_table),
230+};
231+
232+static struct platform_device htcuniversal_pxa_keys = {
233+ .name = "gpio-keys",
234+ .dev = {
235+ .platform_data = &htcuniversal_pxa_keys_data,
236+ },
237+ .id = -1,
238+};
239+
240+/****************************************************************
241+ * Keyboard
242+ ****************************************************************/
243+
244+static struct pxa27x_keyboard_platform_data htcuniversal_kbd = {
245+ .nr_rows = 8,
246+ .nr_cols = 8,
247+ .keycodes = {
248+ {
249+ /* row 0 */
250+ KEY_ENTER,
251+ KEY_MINUS,
252+ KEY_ESC,
253+ KEY_1,
254+ KEY_TAB,
255+ KEY_CAPSLOCK,
256+ KEY_LEFTSHIFT,
257+ KEY_RIGHTALT, /* Fn */
258+ }, { /* row 1 */
259+ KEY_COMMA,
260+ KEY_EQUAL,
261+ KEY_F1,
262+ KEY_2,
263+ KEY_Q,
264+ KEY_A,
265+ KEY_Z,
266+ KEY_LEFTCTRL,
267+ }, { /* row 2 */
268+ KEY_UP,
269+ KEY_I,
270+ KEY_F2,
271+ KEY_3,
272+ KEY_W,
273+ KEY_S,
274+ KEY_X,
275+ KEY_F6,
276+ }, { /* row 3 */
277+ KEY_DOT,
278+ KEY_O,
279+ KEY_F3,
280+ KEY_4,
281+ KEY_E,
282+ KEY_D,
283+ KEY_C,
284+ KEY_LEFTALT,
285+ }, { /* row 4 */
286+ KEY_F9,
287+ KEY_P,
288+ KEY_F4,
289+ KEY_5,
290+ KEY_R,
291+ KEY_F,
292+ KEY_V,
293+ KEY_SPACE,
294+ }, { /* row 5 */
295+ KEY_RIGHT,
296+ KEY_BACKSPACE,
297+ KEY_F5,
298+ KEY_6,
299+ KEY_T,
300+ KEY_G,
301+ KEY_B,
302+ KEY_F7,
303+ }, { /* row 6 */
304+ KEY_F9,
305+ KEY_K,
306+ KEY_9,
307+ KEY_7,
308+ KEY_Y,
309+ KEY_H,
310+ KEY_N,
311+ KEY_LEFT,
312+ }, { /* row 7 */
313+ KEY_F10,
314+ KEY_L,
315+ KEY_0,
316+ KEY_8,
317+ KEY_U,
318+ KEY_J,
319+ KEY_M,
320+ KEY_DOWN,
321+ },
322+ },
323+ .gpio_modes = {
324+ GPIO_NR_HTCUNIVERSAL_KP_MKIN0_MD,
325+ GPIO_NR_HTCUNIVERSAL_KP_MKIN1_MD,
326+ GPIO_NR_HTCUNIVERSAL_KP_MKIN2_MD,
327+ GPIO_NR_HTCUNIVERSAL_KP_MKIN3_MD,
328+ GPIO_NR_HTCUNIVERSAL_KP_MKIN4_MD,
329+ GPIO_NR_HTCUNIVERSAL_KP_MKIN5_MD,
330+ GPIO_NR_HTCUNIVERSAL_KP_MKIN6_MD,
331+ GPIO_NR_HTCUNIVERSAL_KP_MKIN7_MD,
332+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT0_MD,
333+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT1_MD,
334+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT2_MD,
335+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT3_MD,
336+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT4_MD,
337+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT5_MD,
338+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT6_MD,
339+ GPIO_NR_HTCUNIVERSAL_KP_MKOUT7_MD,
340+ },
341+};
342+
343+static struct platform_device htcuniversal_pxa_keyboard = {
344+ .name = "pxa27x-keyboard",
345+ .id = -1,
346+ .dev = {
347+ .platform_data = &htcuniversal_kbd,
348+ },
349+};
350+/* Core Hardware Functions */
351+
352+struct platform_device htcuniversal_core = {
353+ .name = "htcuniversal_core",
354+ .id = 0,
355+ .dev = {
356+ .platform_data = NULL,
357+ },
358+};
359+
360+static struct platform_device *devices[] __initdata = {
361+ &htcuniversal_core,
362+// &htcuniversal_flash,
363+ &htcuniversal_pxa_keyboard,
364+ &htcuniversal_pxa_keys,
365+};
366+
367+static struct platform_device *htcuniversal_asic3_devices[] __initdata = {
368+ &htcuniversal_lcd,
369+#ifdef CONFIG_HTCUNIVERSAL_BACKLIGHT
370+ &htcuniversal_bl,
371+#endif
372+ &htcuniversal_buttons,
373+ &htcuniversal_ts,
374+ &htcuniversal_bt,
375+ &htcuniversal_phone,
376+ &htcuniversal_power,
377+ &htcuniversal_udc,
378+};
379+
380+static struct asic3_platform_data htcuniversal_asic3_platform_data = {
381+
382+ /* Setting ASIC3 GPIO registers to the below initialization states
383+ * HTC Universal asic3 information:
384+ * http://wiki.xda-developers.com/index.php?pagename=UniversalASIC3
385+ * http://wiki.xda-developers.com/index.php?pagename=ASIC3
386+ *
387+ * dir: Direction of the GPIO pin. 0: input, 1: output.
388+ * If unknown, set as output to avoid power consuming floating input nodes
389+ * init: Initial state of the GPIO bits
390+ *
391+ * These registers are configured as they are on Wince.
392+ */
393+ .gpio_a = {
394+ .dir = (1<<GPIOA_LCD_PWR5_ON) |
395+ (1<<GPIOA_FLASHLIGHT) |
396+ (1<<GPIOA_UNKNOWN9) |
397+ (1<<GPIOA_SPK_PWR2_ON) |
398+ (1<<GPIOA_UNKNOWN4) |
399+ (1<<GPIOA_EARPHONE_PWR_ON)|
400+ (1<<GPIOA_AUDIO_PWR_ON) |
401+ (1<<GPIOA_SPK_PWR1_ON) |
402+ (1<<GPIOA_I2C_EN),
403+ .init = (1<<GPIOA_LCD_PWR5_ON) |
404+ (1<<GPIOA_I2C_EN),
405+ .sleep_out = 0x0000,
406+ .batt_fault_out = 0x0000,
407+ .alt_function = 0x0000,
408+ .sleep_conf = 0x000c,
409+ },
410+ .gpio_b = {
411+ .dir = 0xc142,
412+ .init = 0x8842, // TODO: 0x0900
413+ .sleep_out = 0x0000,
414+ .batt_fault_out = 0x0000,
415+ .alt_function = 0x0000,
416+ .sleep_conf = 0x000c,
417+ },
418+ .gpio_c = {
419+ .dir = 0xc7e7,
420+ .init = 0xc6e0, // TODO: 0x8000
421+ .sleep_out = 0x0000,
422+ .batt_fault_out = 0x0000,
423+ .alt_function = 0x0007, // GPIOC_LED_RED | GPIOC_LED_GREEN | GPIOC_LED_BLUE
424+ .sleep_conf = 0x000c,
425+ },
426+ .gpio_d = {
427+ .dir = 0xffc0,
428+ .init = 0x7840, // TODO: 0x0000
429+ .sleep_out = 0x0000,
430+ .batt_fault_out = 0x0000,
431+ .alt_function = 0x0000,
432+ .sleep_conf = 0x0008,
433+ },
434+ .bus_shift = 1,
435+ .irq_base = HTCUNIVERSAL_ASIC3_IRQ_BASE,
436+
437+ .child_platform_devs = htcuniversal_asic3_devices,
438+ .num_child_platform_devs = ARRAY_SIZE(htcuniversal_asic3_devices),
439+};
440+
441+static struct resource htcuniversal_asic3_resources[] = {
442+ [0] = {
443+ .start = HTCUNIVERSAL_ASIC3_GPIO_PHYS,
444+ .end = HTCUNIVERSAL_ASIC3_GPIO_PHYS + IPAQ_ASIC3_MAP_SIZE,
445+ .flags = IORESOURCE_MEM,
446+ },
447+ [1] = {
448+ .start = HTCUNIVERSAL_IRQ(ASIC3_EXT_INT),
449+ .end = HTCUNIVERSAL_IRQ(ASIC3_EXT_INT),
450+ .flags = IORESOURCE_IRQ,
451+ },
452+ [2] = {
453+ .start = HTCUNIVERSAL_ASIC3_MMC_PHYS,
454+ .end = HTCUNIVERSAL_ASIC3_MMC_PHYS + IPAQ_ASIC3_MAP_SIZE,
455+ .flags = IORESOURCE_MEM,
456+ },
457+ [3] = {
458+ .start = HTCUNIVERSAL_IRQ(ASIC3_SDIO_INT_N),
459+ .flags = IORESOURCE_IRQ,
460+ },
461+};
462+
463+struct platform_device htcuniversal_asic3 = {
464+ .name = "asic3",
465+ .id = 0,
466+ .num_resources = ARRAY_SIZE(htcuniversal_asic3_resources),
467+ .resource = htcuniversal_asic3_resources,
468+ .dev = { .platform_data = &htcuniversal_asic3_platform_data, },
469+};
470+EXPORT_SYMBOL(htcuniversal_asic3);
471+
472+static struct pxafb_mode_info htcuniversal_lcd_modes[] = {
473+{
474+ .pixclock = 96153,
475+ .xres = 480,
476+ .yres = 640,
477+ .bpp = 16,
478+ .hsync_len = 4,
479+ .vsync_len = 1,
480+ .left_margin = 20,
481+ .right_margin = 8,
482+ .upper_margin = 7,
483+ .lower_margin = 8,
484+
485+// .sync = FB_SYNC_HOR_LOW_ACT|FB_SYNC_VERT_LOW_ACT,
486+
487+},
488+};
489+
490+static struct pxafb_mach_info sony_acx526akm = {
491+ .modes = htcuniversal_lcd_modes,
492+ .num_modes = ARRAY_SIZE(htcuniversal_lcd_modes),
493+
494+ /* fixme: use constants defined in pxafb.h */
495+ .lccr0 = 0x00000080,
496+ .lccr3 = 0x00400000,
497+// .lccr4 = 0x80000000,
498+};
499+
500+static void __init htcuniversal_init_irq(void)
501+{
502+ pxa27x_init_irq();
503+}
504+
505+static struct platform_pxa_serial_funcs htcuniversal_pxa_bt_funcs = {
506+ .configure = htcuniversal_bt_configure,
507+};
508+static struct platform_pxa_serial_funcs htcuniversal_pxa_phone_funcs = {
509+ .configure = htcuniversal_phone_configure,
510+};
511+
512+/* USB OHCI */
513+
514+static int htcuniversal_ohci_init(struct device *dev)
515+{
516+ /* missing GPIO setup here */
517+
518+ /* got the value from wince */
519+ UHCHR=UHCHR_CGR;
520+
521+ return 0;
522+}
523+
524+static struct pxaohci_platform_data htcuniversal_ohci_platform_data = {
525+ .port_mode = PMM_PERPORT_MODE,
526+ .init = htcuniversal_ohci_init,
527+};
528+
529+static void __init htcuniversal_map_io(void)
530+{
531+ pxa_map_io();
532+
533+ pxa_set_btuart_info(&htcuniversal_pxa_bt_funcs);
534+ pxa_set_ffuart_info(&htcuniversal_pxa_phone_funcs);
535+}
536+
537+static void __init htcuniversal_init(void)
538+{
539+ set_pxa_fb_info(&sony_acx526akm);
540+
541+ platform_device_register(&htcuniversal_asic3);
542+ platform_add_devices(devices, ARRAY_SIZE(devices) );
543+ pxa_set_ficp_info(&htcuniversal_ficp_platform_data);
544+ pxa_set_ohci_info(&htcuniversal_ohci_platform_data);
545+}
546+
547+MACHINE_START(HTCUNIVERSAL, "HTC Universal")
548+ /* Maintainer xanadux.org */
549+ .phys_io = 0x40000000,
550+ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
551+ .boot_params = 0xa0000100,
552+ .map_io = htcuniversal_map_io,
553+ .init_irq = htcuniversal_init_irq,
554+ .init_machine = htcuniversal_init,
555+ .timer = &pxa_timer,
556+MACHINE_END
557Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.c
558===================================================================
559--- /dev/null 1970-01-01 00:00:00.000000000 +0000
560+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.c 2008-06-01 18:49:45.000000000 +0100
561@@ -0,0 +1,917 @@
562+/*
563+ * Audio support for codec Asahi Kasei AK4641
564+ *
565+ * This program is free software; you can redistribute it and/or modify
566+ * it under the terms of the GNU General Public License version 2 as
567+ * published by the Free Software Foundation.
568+ *
569+ * Copyright (c) 2006 Giorgio Padrin <giorgio@mandarinlogiq.org>
570+ *
571+ * History:
572+ *
573+ * 2006-03 Written -- Giorgio Padrin
574+ * 2006-09 Test and debug on machine (HP hx4700) -- Elshin Roman <roxmail@list.ru>
575+ *
576+ * AK4641 codec device driver
577+ *
578+ * Copyright (c) 2005 SDG Systems, LLC
579+ *
580+ * Based on code:
581+ * Copyright (c) 2002 Hewlett-Packard Company
582+ * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
583+ * Copyright (c) 2000 Lernout & Hauspie Speech Products, N.V.
584+ *
585+ * This program is free software; you can redistribute it and/or
586+ * modify it under the terms of the GNU General Public License.
587+ */
588+
589+#include <sound/driver.h>
590+
591+#include <linux/module.h>
592+#include <linux/init.h>
593+#include <linux/types.h>
594+#include <linux/string.h>
595+#include <linux/slab.h>
596+#include <linux/errno.h>
597+#include <linux/ioctl.h>
598+#include <linux/delay.h>
599+#include <linux/i2c.h>
600+
601+#include <sound/core.h>
602+#include <sound/control.h>
603+#include <sound/initval.h>
604+#include <sound/info.h>
605+
606+#include "htcuniversal_ak4641.h"
607+
608+/* Registers */
609+#define R_PM1 0x00
610+#define R_PM2 0x01
611+#define R_SEL1 0x02
612+#define R_SEL2 0x03
613+#define R_MODE1 0x04
614+#define R_MODE2 0x05
615+#define R_DAC 0x06
616+#define R_MIC 0x07
617+#define REG_TIMER 0x08
618+#define REG_ALC1 0x09
619+#define REG_ALC2 0x0a
620+#define R_PGA 0x0b
621+#define R_ATTL 0x0c
622+#define R_ATTR 0x0d
623+#define REG_VOL 0x0e
624+#define R_STATUS 0x0f
625+#define REG_EQLO 0x10
626+#define REG_EQMID 0x11
627+#define REG_EQHI 0x12
628+#define REG_BTIF 0x13
629+
630+/* Register flags */
631+/* REG_PWR1 */
632+#define R_PM1_PMADC 0x01
633+#define R_PM1_PMMIC 0x02
634+#define REG_PWR1_PMAUX 0x04
635+#define REG_PWR1_PMMO 0x08
636+#define R_PM1_PMLO 0x10
637+/* unused 0x20 */
638+/* unused 0x40 */
639+#define R_PM1_PMVCM 0x80
640+
641+/* REG_PWR2 */
642+#define R_PM2_PMDAC 0x01
643+/* unused 0x02 */
644+/* unused 0x04 */
645+#define R_PM2_PMMO2 0x08
646+#define REG_PWR2_MCKAC 0x10
647+/* unused 0x20 */
648+/* unused 0x40 */
649+#define R_PM2_MCKPD 0x80
650+
651+/* REG_SEL1 */
652+#define R_SEL1_PSMO2 0x01
653+/* unused 0x02 */
654+/* unused 0x04 */
655+/* unused 0x08 */
656+#define REG_SEL1_MICM 0x10
657+#define REG_SEL1_DACM 0x20
658+#define REG_SEL1_PSMO 0x40
659+#define REG_SEL1_MOGN 0x80
660+
661+/* REG_SEL2 */
662+#define R_SEL2_PSLOR 0x01
663+#define R_SEL2_PSLOL 0x02
664+#define REG_SEL2_AUXSI 0x04
665+/* unused 0x08 */
666+#define REG_SEL2_MICL 0x10
667+#define REG_SEL2_AUXL 0x20
668+/* unused 0x40 */
669+#define R_SEL2_DACL 0x80
670+
671+/* REG_MODE1 */
672+#define REG_MODE1_DIF0 0x01
673+#define REG_MODE1_DIF1 0x02
674+/* unused 0x04 */
675+/* unused 0x08 */
676+/* unused 0x10 */
677+/* unused 0x20 */
678+/* unused 0x40 */
679+/* unused 0x80 */
680+
681+/* REG_MODE2 */
682+/* unused 0x01 */
683+#define REG_MODE2_LOOP 0x02
684+#define REG_MODE2_HPM 0x04
685+/* unused 0x08 */
686+/* unused 0x10 */
687+#define REG_MODE2_MCK0 0x20
688+#define REG_MODE2_MCK1 0x40
689+/* unused 0x80 */
690+
691+/* REG_DAC */
692+#define REG_DAC_DEM0 0x01
693+#define REG_DAC_DEM1 0x02
694+#define REG_DAC_EQ 0x04
695+/* unused 0x08 */
696+#define R_DAC_DATTC 0x10
697+#define R_DAC_SMUTE 0x20
698+#define REG_DAC_TM 0x40
699+/* unused 0x80 */
700+
701+/* REG_MIC */
702+#define R_MIC_MGAIN 0x01
703+#define R_MIC_MSEL 0x02
704+#define R_MIC_MICAD 0x04
705+#define R_MIC_MPWRI 0x08
706+#define R_MIC_MPWRE 0x10
707+#define REG_MIC_AUXAD 0x20
708+/* unused 0x40 */
709+/* unused 0x80 */
710+
711+/* REG_TIMER */
712+
713+#define REG_TIMER_LTM0 0x01
714+#define REG_TIMER_LTM1 0x02
715+#define REG_TIMER_WTM0 0x04
716+#define REG_TIMER_WTM1 0x08
717+#define REG_TIMER_ZTM0 0x10
718+#define REG_TIMER_ZTM1 0x20
719+/* unused 0x40 */
720+/* unused 0x80 */
721+
722+#define REG_ALC1_LMTH 0x01
723+#define REG_ALC1_RATT 0x02
724+#define REG_ALC1_LMAT0 0x04
725+#define REG_ALC1_LMAT1 0x08
726+#define REG_ALC1_ZELM 0x10
727+#define REG_ALC1_ALC1 0x20
728+/* unused 0x40 */
729+/* unused 0x80 */
730+
731+/* REG_ALC2 */
732+
733+/* REG_PGA */
734+
735+/* REG_ATTL */
736+
737+/* REG_ATTR */
738+
739+/* REG_VOL */
740+#define REG_VOL_ATTM 0x80
741+
742+/* REG_STATUS */
743+#define R_STATUS_DTMIC 0x01
744+
745+/* REG_EQ controls use 4 bits for each of 5 EQ levels */
746+
747+/* Bluetooth not yet implemented */
748+#define REG_BTIF_PMAD2 0x01
749+#define REG_BTIF_PMDA2 0x02
750+#define REG_BTIF_PMBIF 0x04
751+#define REG_BTIF_ADC2 0x08
752+#define REG_BTIF_DAC2 0x10
753+#define REG_BTIF_BTFMT0 0x20
754+#define REG_BTIF_BTFMT1 0x40
755+/* unused 0x80 */
756+
757+/* begin {{ I2C }} */
758+
759+static struct i2c_driver snd_ak4641_i2c_driver = {
760+ .driver = {
761+ .name = "ak4641-i2c"
762+ },
763+};
764+
765+static int snd_ak4641_i2c_init(void)
766+{
767+ return i2c_add_driver(&snd_ak4641_i2c_driver);
768+}
769+
770+static void snd_ak4641_i2c_free(void)
771+{
772+ i2c_del_driver(&snd_ak4641_i2c_driver);
773+}
774+
775+static inline int snd_ak4641_i2c_probe(struct snd_ak4641 *ak)
776+{
777+ if (ak->i2c_client.adapter == NULL) return -EINVAL;
778+ ak->i2c_client.addr = 0x12;
779+ if (i2c_smbus_xfer(ak->i2c_client.adapter, ak->i2c_client.addr,
780+ 0, 0, 0, I2C_SMBUS_QUICK, NULL) < 0)
781+ return -ENODEV;
782+ else return 0;
783+}
784+
785+static int snd_ak4641_i2c_attach(struct snd_ak4641 *ak)
786+{
787+ int ret = 0;
788+ if ((ret = snd_ak4641_i2c_probe(ak)) < 0) return ret;
789+ snprintf(ak->i2c_client.name, sizeof(ak->i2c_client.name),
790+ "ak4641-i2c at %d-%04x",
791+ i2c_adapter_id(ak->i2c_client.adapter), ak->i2c_client.addr);
792+ return i2c_attach_client(&ak->i2c_client);
793+}
794+
795+static void snd_ak4641_i2c_detach(struct snd_ak4641 *ak)
796+{
797+ i2c_detach_client(&ak->i2c_client);
798+}
799+
800+/* end {{ I2C }} */
801+
802+
803+/* begin {{ Registers & Cache Ops }} */
804+
805+static int snd_ak4641_hwsync(struct snd_ak4641 *ak, int read, u8 reg)
806+{
807+ struct i2c_msg msgs[2];
808+ u8 buf[2];
809+ int ret;
810+
811+ snd_assert(reg < ARRAY_SIZE(ak->regs), return -EINVAL);
812+
813+ /* setup i2c msgs */
814+ msgs[0].addr = ak->i2c_client.addr;
815+ msgs[0].flags = 0;
816+ msgs[0].buf = buf;
817+ if (!read)
818+ msgs[0].len = 2;
819+ else {
820+ msgs[1].flags = I2C_M_RD;
821+ msgs[1].addr = msgs[0].addr;
822+ msgs[1].buf = msgs[0].buf + 1;
823+ msgs[0].len = 1;
824+ msgs[1].len = 1;
825+ }
826+
827+ buf[0] = reg;
828+
829+ /* regs[reg] -> buffer, on write */
830+ if (!read) buf[1] = ak->regs[reg];
831+
832+ /* i2c transfer */
833+ ret = i2c_transfer(ak->i2c_client.adapter, msgs, read ? 2 : 1);
834+ if (ret != (read ? 2 : 1)) return ret; /* transfer error */ //@@ error ret < 0, or not ?
835+
836+ /* regs[reg] <- buffer, on read */
837+ if (read) ak->regs[reg] = buf[1];
838+
839+ return 0;
840+}
841+
842+static inline int snd_ak4641_hwsync_read(struct snd_ak4641 *ak, u8 reg)
843+{
844+ return snd_ak4641_hwsync(ak, 1, reg);
845+}
846+
847+static inline int snd_ak4641_hwsync_write(struct snd_ak4641 *ak, u8 reg)
848+{
849+ return snd_ak4641_hwsync(ak, 0, reg);
850+}
851+
852+static int snd_ak4641_hwsync_read_all(struct snd_ak4641 *ak)
853+{
854+ u8 reg;
855+ for (reg = 0; reg < ARRAY_SIZE(ak->regs); reg++)
856+ if (snd_ak4641_hwsync_read(ak, reg) < 0) return -1;
857+ return 0;
858+}
859+
860+static int snd_ak4641_hwsync_write_all(struct snd_ak4641 *ak)
861+{
862+ u8 reg;
863+ for (reg = 0; reg < ARRAY_SIZE(ak->regs); reg++)
864+ if (snd_ak4641_hwsync_write(ak, reg) < 0) return -1;
865+ return 0;
866+}
867+
868+static int snd_ak4641_reg_changed(struct snd_ak4641 *ak, u8 reg)
869+{
870+ if ((reg != R_PGA && ak->powered_on) ||
871+ (reg == R_PGA && (ak->regs[R_PM1] & R_PM1_PMMIC)))
872+ return snd_ak4641_hwsync_write(ak, reg);
873+ return 0;
874+}
875+
876+/* end {{ Registers & Cache Ops }}*/
877+
878+
879+static inline void snd_ak4641_lock(struct snd_ak4641 *ak)
880+{
881+ down(&ak->sem);
882+}
883+
884+static inline void snd_ak4641_unlock(struct snd_ak4641 *ak)
885+{
886+ up(&ak->sem);
887+}
888+
889+#define WRITE_MASK(i, val, mask) (((i) & ~(mask)) | ((val) & (mask)))
890+
891+
892+/* begin {{ Controls }} */
893+
894+#define INV_RANGE(val, mask) \
895+ (~(val) & (mask))
896+
897+/*-begin----------------------------------------------------------*/
898+static int snd_ak4641_actl_playback_volume_info(struct snd_kcontrol *kcontrol,
899+ struct snd_ctl_elem_info *uinfo)
900+{
901+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
902+ uinfo->count = 2;
903+ uinfo->value.integer.min = 0;
904+ uinfo->value.integer.max = 0xff;
905+ return 0;
906+}
907+
908+static int snd_ak4641_actl_playback_volume_get(struct snd_kcontrol *kcontrol,
909+ struct snd_ctl_elem_value *ucontrol)
910+{
911+ struct snd_ak4641 *ak = (struct snd_ak4641 *) kcontrol->private_data;
912+
913+ snd_ak4641_lock(ak);
914+ ucontrol->value.integer.value[0] = INV_RANGE(ak->regs[R_ATTL], 0xff);
915+ ucontrol->value.integer.value[1] = INV_RANGE(ak->regs[R_ATTR], 0xff);
916+ snd_ak4641_unlock(ak);
917+ return 0;
918+}
919+
920+static int snd_ak4641_actl_playback_volume_put(struct snd_kcontrol *kcontrol,
921+ struct snd_ctl_elem_value *ucontrol)
922+{
923+ struct snd_ak4641 *ak = (struct snd_ak4641 *) kcontrol->private_data;
924+
925+ snd_ak4641_lock(ak);
926+ ak->regs[R_ATTL] = INV_RANGE(ucontrol->value.integer.value[0], 0xff);
927+ ak->regs[R_ATTR] = INV_RANGE(ucontrol->value.integer.value[1], 0xff);
928+ snd_ak4641_reg_changed(ak, R_ATTL);
929+ snd_ak4641_reg_changed(ak, R_ATTR);
930+ snd_ak4641_unlock(ak);
931+ return 0;
932+}
933+/*-end------------------------------------------------------------*/
934+
935+/*-begin----------------------------------------------------------*/
936+static int snd_ak4641_actl_mic_gain_info(struct snd_kcontrol *kcontrol,
937+ struct snd_ctl_elem_info *uinfo)
938+{
939+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
940+ uinfo->count = 1;
941+ uinfo->value.integer.min = 0;
942+ uinfo->value.integer.max = 0x7f;
943+ return 0;
944+}
945+
946+static int snd_ak4641_actl_mic_gain_get(struct snd_kcontrol *kcontrol,
947+ struct snd_ctl_elem_value *ucontrol)
948+{
949+ struct snd_ak4641 *ak = (struct snd_ak4641 *) kcontrol->private_data;
950+
951+ ucontrol->value.integer.value[0] = ak->regs[R_PGA];
952+ return 0;
953+}
954+
955+static int snd_ak4641_actl_mic_gain_put(struct snd_kcontrol *kcontrol,
956+ struct snd_ctl_elem_value *ucontrol)
957+{
958+ struct snd_ak4641 *ak = (struct snd_ak4641 *) kcontrol->private_data;
959+
960+ snd_ak4641_lock(ak);
961+ ak->regs[R_PGA] = ucontrol->value.integer.value[0];
962+ snd_ak4641_reg_changed(ak, R_PGA);
963+ snd_ak4641_unlock(ak);
964+ return 0;
965+}
966+/*-end------------------------------------------------------------*/
967+
968+#define ACTL(ctl_name, _name) \
969+static struct snd_kcontrol_new snd_ak4641_actl_ ## ctl_name = \
970+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = _name, \
971+ .info = snd_ak4641_actl_ ## ctl_name ## _info, \
972+ .get = snd_ak4641_actl_ ## ctl_name ## _get, .put = snd_ak4641_actl_ ## ctl_name ## _put };
973+
974+ACTL(playback_volume, "Master Playback Volume")
975+ACTL(mic_gain, "Mic Capture Gain")
976+
977+struct snd_ak4641_uctl_bool {
978+ int (*get) (struct snd_ak4641 *uda);
979+ int (*set) (struct snd_ak4641 *uda, int on);
980+};
981+
982+static int snd_ak4641_actl_bool_info(struct snd_kcontrol *kcontrol,
983+ struct snd_ctl_elem_info *uinfo)
984+{
985+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
986+ uinfo->count = 1;
987+ return 0;
988+}
989+
990+static int snd_ak4641_actl_bool_get(struct snd_kcontrol *kcontrol,
991+ struct snd_ctl_elem_value *ucontrol)
992+{
993+ struct snd_ak4641 *ak = (struct snd_ak4641 *) kcontrol->private_data;
994+ struct snd_ak4641_uctl_bool *uctl =
995+ (struct snd_ak4641_uctl_bool *) kcontrol->private_value;
996+
997+ ucontrol->value.integer.value[0] = uctl->get(ak);
998+ return 0;
999+}
1000+
1001+static int snd_ak4641_actl_bool_put(struct snd_kcontrol *kcontrol,
1002+ struct snd_ctl_elem_value *ucontrol)
1003+{
1004+ struct snd_ak4641 *ak = (struct snd_ak4641 *) kcontrol->private_data;
1005+ struct snd_ak4641_uctl_bool *uctl =
1006+ (struct snd_ak4641_uctl_bool *) kcontrol->private_value;
1007+
1008+ return uctl->set(ak, ucontrol->value.integer.value[0]);
1009+}
1010+
1011+/*-begin----------------------------------------------------------*/
1012+static int snd_ak4641_uctl_playback_switch_get(struct snd_ak4641 *ak)
1013+{
1014+ return (ak->regs[R_DAC] & R_DAC_SMUTE) == 0x00;
1015+}
1016+
1017+static int snd_ak4641_uctl_playback_switch_set(struct snd_ak4641 *ak, int on)
1018+{
1019+ snd_ak4641_lock(ak);
1020+ ak->regs[R_DAC] = WRITE_MASK(ak->regs[R_DAC],
1021+ on ? 0x00 : R_DAC_SMUTE, R_DAC_SMUTE);
1022+ snd_ak4641_reg_changed(ak, R_DAC);
1023+ snd_ak4641_unlock(ak);
1024+ return 0;
1025+}
1026+/*-end------------------------------------------------------------*/
1027+
1028+/*-begin----------------------------------------------------------*/
1029+static int snd_ak4641_uctl_mic_boost_get(struct snd_ak4641 *ak)
1030+{
1031+ return (ak->regs[R_MIC] & R_MIC_MGAIN) == R_MIC_MGAIN;
1032+}
1033+
1034+static int snd_ak4641_uctl_mic_boost_set(struct snd_ak4641 *ak, int on)
1035+{
1036+ snd_ak4641_lock(ak);
1037+ ak->regs[R_MIC] = WRITE_MASK(ak->regs[R_MIC],
1038+ on ? R_MIC_MGAIN : 0x00, R_MIC_MGAIN);
1039+ snd_ak4641_reg_changed(ak, R_MIC);
1040+ snd_ak4641_unlock(ak);
1041+ return 0;
1042+}
1043+/*-end------------------------------------------------------------*/
1044+
1045+/*-begin----------------------------------------------------------*/
1046+static int snd_ak4641_uctl_mono_out_get(struct snd_ak4641 *ak)
1047+{
1048+ printk("mono_out status 0x%8.8x -> 0x%8.8x\n",ak->regs[R_SEL1], ak->regs[R_SEL1] & REG_SEL1_PSMO);
1049+ return (ak->regs[R_SEL1] & REG_SEL1_PSMO) == REG_SEL1_PSMO;
1050+}
1051+
1052+static int snd_ak4641_uctl_mono_out_set(struct snd_ak4641 *ak, int on)
1053+{
1054+ printk("phone mic enable called. on=%d\n",on);
1055+ snd_ak4641_lock(ak);
1056+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], on ? R_PM1_PMMIC : 0x00, R_PM1_PMMIC);
1057+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], on ? REG_PWR1_PMMO : 0x00, REG_PWR1_PMMO);
1058+ snd_ak4641_reg_changed(ak, R_PM1);
1059+
1060+ snd_ak4641_hwsync_write(ak, R_PGA); /* mic PGA gain is reset when PMMIC = 0 */
1061+
1062+ /* internal mic */
1063+ ak->regs[R_MIC] = WRITE_MASK(ak->regs[R_MIC], on ? R_MIC_MPWRI : 0x0, R_MIC_MPWRI);
1064+ ak->regs[R_MIC] = WRITE_MASK(ak->regs[R_MIC], 0x0, R_MIC_MSEL);
1065+ snd_ak4641_hwsync_write(ak, R_MIC);
1066+
1067+// ak->regs[REG_BTIF] = WRITE_MASK(ak->regs[REG_BTIF], 0x0, REG_BTIF_DAC2);
1068+// snd_ak4641_hwsync_write(ak, REG_BTIF);
1069+ /* */
1070+// ak->regs[REG_VOL] = WRITE_MASK(ak->regs[REG_VOL], on ? REG_VOL_ATTM : 0x00, REG_VOL_ATTM);
1071+// ak->regs[R_SEL1] = WRITE_MASK(ak->regs[R_SEL1], on ? REG_SEL1_MOGN : 0x00, REG_SEL1_MOGN);
1072+ ak->regs[R_SEL1] = WRITE_MASK(ak->regs[R_SEL1], on ? REG_SEL1_MICM : 0x00, REG_SEL1_MICM);
1073+ ak->regs[R_SEL1] = WRITE_MASK(ak->regs[R_SEL1], on ? REG_SEL1_PSMO : 0x00, REG_SEL1_PSMO);
1074+ snd_ak4641_reg_changed(ak, R_SEL1);
1075+ snd_ak4641_unlock(ak);
1076+ return 0;
1077+}
1078+/*-end------------------------------------------------------------*/
1079+
1080+#define ACTL_BOOL(ctl_name, _name) \
1081+static struct snd_ak4641_uctl_bool snd_ak4641_actl_ ## ctl_name ## _pvalue = \
1082+{ .get = snd_ak4641_uctl_ ## ctl_name ## _get, \
1083+ .set = snd_ak4641_uctl_ ## ctl_name ## _set }; \
1084+static struct snd_kcontrol_new snd_ak4641_actl_ ## ctl_name = \
1085+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = _name, .info = snd_ak4641_actl_bool_info, \
1086+ .get = snd_ak4641_actl_bool_get, .put = snd_ak4641_actl_bool_put, \
1087+ .private_value = (unsigned long) &snd_ak4641_actl_ ## ctl_name ## _pvalue };
1088+
1089+ACTL_BOOL(playback_switch, "Master Playback Switch")
1090+ACTL_BOOL(mic_boost, "Mic Boost (+20dB)")
1091+ACTL_BOOL(mono_out, "Phone mic enable")
1092+
1093+static void snd_ak4641_headphone_on(struct snd_ak4641 *ak, int on);
1094+static void snd_ak4641_speaker_on(struct snd_ak4641 *ak, int on);
1095+static void snd_ak4641_select_mic(struct snd_ak4641 *ak);
1096+
1097+void snd_ak4641_hp_connected(struct snd_ak4641 *ak, int connected)
1098+{
1099+ snd_ak4641_lock(ak);
1100+ if (connected != ak->hp_connected) {
1101+ ak->hp_connected = connected;
1102+
1103+ /* headphone or speaker, on playback */
1104+ if (ak->playback_on) {
1105+ if (connected) {
1106+ snd_ak4641_headphone_on(ak, 1);
1107+ snd_ak4641_speaker_on(ak, 0);
1108+ } else {
1109+ snd_ak4641_speaker_on(ak, 1);
1110+ snd_ak4641_headphone_on(ak, 0);
1111+ }
1112+ }
1113+
1114+ /* headset or internal mic, on capture */
1115+ if (ak->capture_on)
1116+ snd_ak4641_select_mic(ak);
1117+ }
1118+ snd_ak4641_unlock(ak);
1119+}
1120+
1121+/* end {{ Controls }} */
1122+
1123+
1124+/* begin {{ Headphone Detected Notification }} */
1125+
1126+static void snd_ak4641_hp_detected_w_fn(void *p)
1127+{
1128+ struct snd_ak4641 *ak = (struct snd_ak4641 *)p;
1129+
1130+ snd_ak4641_hp_connected(ak, ak->hp_detected.detected);
1131+}
1132+
1133+void snd_ak4641_hp_detected(struct snd_ak4641 *ak, int detected)
1134+{
1135+ if (detected != ak->hp_detected.detected) {
1136+ ak->hp_detected.detected = detected;
1137+ queue_work(ak->hp_detected.wq, &ak->hp_detected.w);
1138+ }
1139+}
1140+
1141+static int snd_ak4641_hp_detected_init(struct snd_ak4641 *ak)
1142+{
1143+ INIT_WORK(&ak->hp_detected.w, snd_ak4641_hp_detected_w_fn);
1144+ ak->hp_detected.detected = ak->hp_connected;
1145+ ak->hp_detected.wq = create_singlethread_workqueue("ak4641");
1146+ if (ak->hp_detected.wq) return 0;
1147+ else return -1;
1148+}
1149+
1150+static void snd_ak4641_hp_detected_free(struct snd_ak4641 *ak)
1151+{
1152+ destroy_workqueue(ak->hp_detected.wq);
1153+}
1154+
1155+/* end {{ Headphone Detected Notification }} */
1156+
1157+
1158+/* begin {{ Codec Control }} */
1159+
1160+static void snd_ak4641_headphone_on(struct snd_ak4641 *ak, int on)
1161+{
1162+ if (on) {
1163+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], R_PM1_PMLO, R_PM1_PMLO);
1164+ snd_ak4641_hwsync_write(ak, R_PM1);
1165+ ak->headphone_out_on(1);
1166+ ak->regs[R_SEL2] = WRITE_MASK(ak->regs[R_SEL2],
1167+ R_SEL2_PSLOL | R_SEL2_PSLOR,
1168+ R_SEL2_PSLOL | R_SEL2_PSLOR);
1169+ snd_ak4641_hwsync_write(ak, R_SEL2);
1170+ } else {
1171+ ak->regs[R_SEL2] = WRITE_MASK(ak->regs[R_SEL2],
1172+ 0x00, R_SEL2_PSLOL | R_SEL2_PSLOR);
1173+ snd_ak4641_hwsync_write(ak, R_SEL2);
1174+ ak->headphone_out_on(0);
1175+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], 0x00, R_PM1_PMLO);
1176+ snd_ak4641_hwsync_write(ak, R_PM1);
1177+ }
1178+}
1179+
1180+static void snd_ak4641_speaker_on(struct snd_ak4641 *ak, int on)
1181+{
1182+ if (on) {
1183+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], R_PM1_PMLO, R_PM1_PMLO);
1184+ snd_ak4641_hwsync_write(ak, R_PM1);
1185+ ak->speaker_out_on(1);
1186+ ak->regs[R_SEL2] = WRITE_MASK(ak->regs[R_SEL2],
1187+ R_SEL2_PSLOL | R_SEL2_PSLOR,
1188+ R_SEL2_PSLOL | R_SEL2_PSLOR);
1189+ snd_ak4641_hwsync_write(ak, R_SEL2);
1190+ } else {
1191+ ak->regs[R_SEL2] = WRITE_MASK(ak->regs[R_SEL2],
1192+ 0x00, R_SEL2_PSLOL | R_SEL2_PSLOR);
1193+ snd_ak4641_hwsync_write(ak, R_SEL2);
1194+ ak->speaker_out_on(0);
1195+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], 0x00, R_PM1_PMLO);
1196+ snd_ak4641_hwsync_write(ak, R_PM1);
1197+ }
1198+}
1199+
1200+static inline int snd_ak4641_power_on(struct snd_ak4641 *ak)
1201+{
1202+ ak->reset_pin(1);
1203+ ak->power_on_chip(1);
1204+ msleep(1);
1205+ ak->reset_pin(0);
1206+ ak->powered_on = 1;
1207+ return 0;
1208+}
1209+
1210+static inline int snd_ak4641_power_off(struct snd_ak4641 *ak)
1211+{
1212+ ak->powered_on = 0;
1213+ ak->power_on_chip(0);
1214+ return 0;
1215+}
1216+
1217+static inline void snd_ak4641_headphone_out_on(struct snd_ak4641 *ak, int on)
1218+{
1219+ if (ak->headphone_out_on) ak->headphone_out_on(on);
1220+}
1221+
1222+static inline void snd_ak4641_speaker_out_on(struct snd_ak4641 *ak, int on)
1223+{
1224+ if (ak->speaker_out_on) ak->speaker_out_on(on);
1225+}
1226+
1227+static int snd_ak4641_playback_on(struct snd_ak4641 *ak)
1228+{
1229+ if (ak->playback_on) return 0;
1230+
1231+ ak->regs[R_PM2] = WRITE_MASK(ak->regs[R_PM2],
1232+ R_PM2_PMDAC, R_PM2_MCKPD | R_PM2_PMDAC);
1233+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], R_PM1_PMLO, R_PM1_PMLO);
1234+ snd_ak4641_hwsync_write(ak, R_PM2);
1235+ snd_ak4641_hwsync_write(ak, R_PM1);
1236+ if (ak->hp_connected) snd_ak4641_headphone_on(ak, 1);
1237+ else snd_ak4641_speaker_on(ak, 1);
1238+
1239+ ak->playback_on = 1;
1240+
1241+ return 0;
1242+}
1243+
1244+static int snd_ak4641_playback_off(struct snd_ak4641 *ak)
1245+{
1246+ if (!ak->playback_on) return 0;
1247+
1248+ ak->playback_on = 0;
1249+
1250+ if (ak->hp_connected) snd_ak4641_headphone_on(ak, 0);
1251+ else snd_ak4641_speaker_on(ak, 0);
1252+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], 0x00, R_PM1_PMLO);
1253+ ak->regs[R_PM2] = WRITE_MASK(ak->regs[R_PM2],
1254+ (!ak->capture_on ? R_PM2_MCKPD : 0x00) | R_PM2_PMDAC,
1255+ R_PM2_MCKPD | R_PM2_PMDAC);
1256+ snd_ak4641_hwsync_write(ak, R_PM1);
1257+ snd_ak4641_hwsync_write(ak, R_PM2);
1258+
1259+ return 0;
1260+}
1261+
1262+static void snd_ak4641_select_mic(struct snd_ak4641 *ak)
1263+{
1264+ int mic = 0;
1265+ u8 r_mic;
1266+
1267+ if (ak->hp_connected) {
1268+ /* check headset mic */
1269+ ak->regs[R_MIC] = WRITE_MASK(ak->regs[R_MIC], R_MIC_MPWRE, R_MIC_MPWRE);
1270+ snd_ak4641_hwsync_write(ak, R_MIC);
1271+ snd_ak4641_hwsync_read(ak, R_STATUS);
1272+ mic = (ak->regs[R_STATUS] & R_STATUS_DTMIC) == R_STATUS_DTMIC;
1273+
1274+ printk("htcuniversal_ak4641_select_mic: mic=%d\n",mic);
1275+
1276+ r_mic = WRITE_MASK(ak->regs[R_MIC],
1277+ R_MIC_MSEL | (ak->capture_on ? R_MIC_MPWRE : 0x00),
1278+ R_MIC_MSEL | R_MIC_MPWRI | R_MIC_MPWRE);
1279+ }
1280+ else
1281+ r_mic = WRITE_MASK(ak->regs[R_MIC],
1282+ 0x00 | (ak->capture_on ? R_MIC_MPWRI : 0x00),
1283+ R_MIC_MSEL | R_MIC_MPWRI | R_MIC_MPWRE);
1284+
1285+ if (r_mic != ak->regs[R_MIC]) {
1286+ ak->regs[R_MIC] = r_mic;
1287+ snd_ak4641_hwsync_write(ak, R_MIC);
1288+ }
1289+}
1290+
1291+static int snd_ak4641_capture_on(struct snd_ak4641 *ak)
1292+{
1293+ if (ak->capture_on) return 0;
1294+
1295+ if (!ak->playback_on) {
1296+ ak->regs[R_PM2] = WRITE_MASK(ak->regs[R_PM2], 0x00, R_PM2_MCKPD);
1297+ snd_ak4641_hwsync_write(ak, R_PM2);
1298+ }
1299+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], R_PM1_PMMIC | R_PM1_PMADC,
1300+ R_PM1_PMMIC | R_PM1_PMADC);
1301+ snd_ak4641_hwsync_write(ak, R_PM1);
1302+ snd_ak4641_hwsync_write(ak, R_PGA); /* mic PGA gain is reset when PMMIC = 0 */
1303+
1304+ ak->capture_on = 1;
1305+
1306+ snd_ak4641_select_mic(ak);
1307+
1308+ msleep(47); /* accounts for ADC init cycle, time enough for fs >= 44.1 kHz */
1309+
1310+ return 0;
1311+}
1312+
1313+static int snd_ak4641_capture_off(struct snd_ak4641 *ak)
1314+{
1315+ if (!ak->capture_on) return 0;
1316+
1317+ ak->regs[R_MIC] = WRITE_MASK(ak->regs[R_MIC],
1318+ 0x00, R_MIC_MPWRI | R_MIC_MPWRE | R_MIC_MSEL);
1319+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], 0x00, R_PM1_PMMIC | R_PM1_PMADC);
1320+ snd_ak4641_hwsync_write(ak, R_MIC);
1321+ snd_ak4641_hwsync_write(ak, R_PM1);
1322+ if (!ak->playback_on) {
1323+ ak->regs[R_PM2] = WRITE_MASK(ak->regs[R_PM2], R_PM2_MCKPD, R_PM2_MCKPD);
1324+ snd_ak4641_hwsync_write(ak, R_PM2);
1325+ }
1326+
1327+ ak->capture_on = 0;
1328+
1329+ return 0;
1330+}
1331+
1332+int snd_ak4641_open_stream(struct snd_ak4641 *ak, int stream)
1333+{
1334+ snd_ak4641_lock(ak);
1335+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1336+ ak->playback_stream_opened = 1;
1337+ snd_ak4641_playback_on(ak);
1338+ } else {
1339+ ak->capture_stream_opened = 1;
1340+ snd_ak4641_capture_on(ak);
1341+ }
1342+ snd_ak4641_unlock(ak);
1343+ return 0;
1344+}
1345+
1346+int snd_ak4641_close_stream(struct snd_ak4641 *ak, int stream)
1347+{
1348+ snd_ak4641_lock(ak);
1349+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
1350+ ak->playback_stream_opened = 0;
1351+ snd_ak4641_playback_off(ak);
1352+ } else {
1353+ ak->capture_stream_opened = 0;
1354+ snd_ak4641_capture_off(ak);
1355+ }
1356+ snd_ak4641_unlock(ak);
1357+ return 0;
1358+}
1359+
1360+static int snd_ak4641_init_regs(struct snd_ak4641 *ak)
1361+{
1362+ snd_ak4641_hwsync_read_all(ak);
1363+
1364+ //@@ MEMO: add some configs
1365+
1366+ ak->regs[R_PM1] = WRITE_MASK(ak->regs[R_PM1], R_PM1_PMVCM, R_PM1_PMVCM);
1367+ ak->regs[R_DAC] = WRITE_MASK(ak->regs[R_DAC], 0x00, R_DAC_DATTC);
1368+ snd_ak4641_hwsync_write(ak, R_PM1);
1369+ snd_ak4641_hwsync_write(ak, R_DAC);
1370+
1371+ return 0;
1372+}
1373+
1374+int snd_ak4641_suspend(struct snd_ak4641 *ak, pm_message_t state)
1375+{
1376+ snd_ak4641_lock(ak);
1377+ if (ak->playback_on) snd_ak4641_playback_off(ak);
1378+ if (ak->capture_on) snd_ak4641_capture_off(ak);
1379+ snd_ak4641_power_off(ak);
1380+ snd_ak4641_unlock(ak);
1381+ return 0;
1382+}
1383+
1384+int snd_ak4641_resume(struct snd_ak4641 *ak)
1385+{
1386+ snd_ak4641_lock(ak);
1387+ snd_ak4641_power_on(ak);
1388+ snd_ak4641_hwsync_write_all(ak);
1389+ if (ak->playback_stream_opened) snd_ak4641_playback_on(ak);
1390+ if (ak->capture_stream_opened) snd_ak4641_capture_on(ak);
1391+ snd_ak4641_unlock(ak);
1392+ return 0;
1393+}
1394+
1395+static void snd_ak4641_init_ak(struct snd_ak4641 *ak)
1396+{
1397+ init_MUTEX(&ak->sem);
1398+ ak->i2c_client.driver = &snd_ak4641_i2c_driver;
1399+}
1400+
1401+int snd_ak4641_activate(struct snd_ak4641 *ak)
1402+{
1403+ int ret = 0;
1404+
1405+ snd_ak4641_init_ak(ak);
1406+ snd_ak4641_lock(ak);
1407+ snd_ak4641_power_on(ak);
1408+ if ((ret = snd_ak4641_i2c_attach(ak)) < 0)
1409+ goto failed_i2c_attach;
1410+ snd_ak4641_init_regs(ak);
1411+ if ((ret = snd_ak4641_hp_detected_init(ak)) < 0)
1412+ goto failed_hp_detected_init;
1413+ snd_ak4641_unlock(ak);
1414+ return 0;
1415+
1416+ failed_hp_detected_init:
1417+ snd_ak4641_i2c_detach(ak);
1418+ failed_i2c_attach:
1419+ snd_ak4641_power_off(ak);
1420+ snd_ak4641_unlock(ak);
1421+ return ret;
1422+}
1423+
1424+void snd_ak4641_deactivate(struct snd_ak4641 *ak)
1425+{
1426+ snd_ak4641_lock(ak);
1427+ snd_ak4641_hp_detected_free(ak);
1428+ snd_ak4641_i2c_detach(ak);
1429+ snd_ak4641_power_off(ak);
1430+ snd_ak4641_unlock(ak);
1431+}
1432+
1433+int snd_ak4641_add_mixer_controls(struct snd_ak4641 *ak, struct snd_card *card)
1434+{
1435+ snd_ak4641_lock(ak);
1436+ snd_ctl_add(card, snd_ctl_new1(&snd_ak4641_actl_playback_volume, ak));
1437+ snd_ctl_add(card, snd_ctl_new1(&snd_ak4641_actl_playback_switch, ak));
1438+ snd_ctl_add(card, snd_ctl_new1(&snd_ak4641_actl_mic_gain, ak));
1439+ snd_ctl_add(card, snd_ctl_new1(&snd_ak4641_actl_mic_boost, ak));
1440+ snd_ctl_add(card, snd_ctl_new1(&snd_ak4641_actl_mono_out, ak));
1441+ snd_ak4641_unlock(ak);
1442+ return 0;
1443+}
1444+
1445+/* end {{ Codec Control }} */
1446+
1447+
1448+/* begin {{ Module }} */
1449+
1450+static int __init snd_ak4641_module_on_load(void)
1451+{
1452+ snd_ak4641_i2c_init();
1453+ return 0;
1454+}
1455+
1456+static void __exit snd_ak4641_module_on_unload(void)
1457+{
1458+ snd_ak4641_i2c_free();
1459+}
1460+
1461+module_init(snd_ak4641_module_on_load);
1462+module_exit(snd_ak4641_module_on_unload);
1463+
1464+EXPORT_SYMBOL(snd_ak4641_activate);
1465+EXPORT_SYMBOL(snd_ak4641_deactivate);
1466+EXPORT_SYMBOL(snd_ak4641_add_mixer_controls);
1467+EXPORT_SYMBOL(snd_ak4641_open_stream);
1468+EXPORT_SYMBOL(snd_ak4641_close_stream);
1469+EXPORT_SYMBOL(snd_ak4641_suspend);
1470+EXPORT_SYMBOL(snd_ak4641_resume);
1471+EXPORT_SYMBOL(snd_ak4641_hp_connected);
1472+EXPORT_SYMBOL(snd_ak4641_hp_detected);
1473+
1474+MODULE_AUTHOR("Giorgio Padrin");
1475+MODULE_DESCRIPTION("Audio support for codec Asahi Kasei AK4641");
1476+MODULE_LICENSE("GPL");
1477+
1478+/* end {{ Module }} */
1479Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.h
1480===================================================================
1481--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1482+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_ak4641.h 2008-06-01 18:49:45.000000000 +0100
1483@@ -0,0 +1,65 @@
1484+/*
1485+ * Audio support for codec Asahi Kasei AK4641
1486+ *
1487+ * This program is free software; you can redistribute it and/or modify
1488+ * it under the terms of the GNU General Public License version 2 as
1489+ * published by the Free Software Foundation.
1490+ *
1491+ * Copyright (c) 2006 Giorgio Padrin <giorgio@mandarinlogiq.org>
1492+ */
1493+
1494+#ifndef __SOUND_AK4641_H
1495+#define __SOUND_AK4641_H
1496+
1497+#include <linux/i2c.h>
1498+
1499+struct snd_ak4641 {
1500+ struct semaphore sem;
1501+
1502+ u8 regs[0x14]; /* registers cache */
1503+
1504+ unsigned int
1505+ powered_on:1,
1506+ playback_on:1,
1507+ playback_stream_opened:1,
1508+ capture_on:1,
1509+ capture_stream_opened:1;
1510+
1511+ unsigned int
1512+ hp_connected:1;
1513+
1514+ /* -- configuration (to fill before activation) -- */
1515+ void (*power_on_chip)(int on);
1516+ void (*reset_pin)(int on);
1517+ void (*headphone_out_on)(int on);
1518+ void (*speaker_out_on)(int on);
1519+
1520+ struct i2c_client i2c_client; /* to fill .adapter */
1521+ /* ----------------------------------------------- */
1522+
1523+ struct {
1524+ int detected;
1525+ struct workqueue_struct *wq;
1526+ struct work_struct w;
1527+ } hp_detected;
1528+};
1529+
1530+
1531+/* Note: opening, closing, suspending and resuming a stream
1532+ * require the clocks (MCLK and I2S ones) running
1533+ */
1534+
1535+/* don't forget to specify I2C adapter in i2c_client field */
1536+int snd_ak4641_activate(struct snd_ak4641 *ak);
1537+
1538+void snd_ak4641_deactivate(struct snd_ak4641 *ak);
1539+int snd_ak4641_add_mixer_controls(struct snd_ak4641 *ak, struct snd_card *card);
1540+int snd_ak4641_open_stream(struct snd_ak4641 *ak, int stream);
1541+int snd_ak4641_close_stream(struct snd_ak4641 *ak, int stream);
1542+int snd_ak4641_suspend(struct snd_ak4641 *ak, pm_message_t state);
1543+int snd_ak4641_resume(struct snd_ak4641 *ak);
1544+
1545+void snd_ak4641_hp_connected(struct snd_ak4641 *ak, int connected); /* non atomic context */
1546+void snd_ak4641_hp_detected(struct snd_ak4641 *ak, int detected); /* atomic context */
1547+
1548+#endif /* __SOUND_AK4641_H */
1549Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_asic3_leds.c
1550===================================================================
1551--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1552+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_asic3_leds.c 2008-06-01 18:49:45.000000000 +0100
1553@@ -0,0 +1,143 @@
1554+/*
1555+ * LEDs support for the HP iPaq hx4700
1556+ *
1557+ * Copyright (c) 2006 Anton Vorontsov <cbou@mail.ru>
1558+ *
1559+ * This file is subject to the terms and conditions of the GNU General Public
1560+ * License. See the file COPYING in the main directory of this archive for
1561+ * more details.
1562+ *
1563+ */
1564+
1565+#include <linux/kernel.h>
1566+#include <linux/init.h>
1567+#include <linux/platform_device.h>
1568+#include <linux/leds.h>
1569+#include <linux/soc/asic3_base.h>
1570+
1571+#include <asm/hardware/ipaq-asic3.h>
1572+#include <asm/mach-types.h>
1573+#include <asm/hardware/asic3_leds.h>
1574+#include <asm/arch/htcuniversal-asic.h>
1575+
1576+//FIXME
1577+//DEFINE_LED_TRIGGER_SHARED_GLOBAL(htcuniversal_radio_trig);
1578+//EXPORT_LED_TRIGGER_SHARED(htcuniversal_radio_trig);
1579+
1580+static struct asic3_led htcuniversal_leds[] = {
1581+ {
1582+ .led_cdev = {
1583+ .name = "htcuniversal:red",
1584+ .default_trigger = "htcuniversal-charging",
1585+ },
1586+ .hw_num = 2,
1587+
1588+ },
1589+ {
1590+ .led_cdev = {
1591+ .name = "htcuniversal:green",
1592+ .default_trigger = "htcuniversal-chargefull",
1593+ },
1594+ .hw_num = 1,
1595+ },
1596+ {
1597+ .led_cdev = {
1598+ .name = "htcuniversal:wifi-bt",
1599+ .default_trigger = "htcuniversal-radio",
1600+ },
1601+ .hw_num = 0,
1602+ },
1603+ {
1604+ .led_cdev = {
1605+ .name = "htcuniversal:phonebuttons",
1606+ .default_trigger = "htcuniversal-phonebuttons",
1607+ },
1608+ .hw_num = -1,
1609+ .gpio_num = ('D'-'A')*16+GPIOD_BL_KEYP_PWR_ON,
1610+ },
1611+ {
1612+ .led_cdev = {
1613+ .name = "htcuniversal:vibra",
1614+ .default_trigger = "htcuniversal-vibra",
1615+ },
1616+ .hw_num = -1,
1617+ .gpio_num = ('D'-'A')*16+GPIOD_VIBRA_PWR_ON,
1618+ },
1619+ {
1620+ .led_cdev = {
1621+ .name = "htcuniversal:flashlight1",
1622+ .default_trigger = "htcuniversal-flashlight1",
1623+ },
1624+ .hw_num = -1,
1625+ .gpio_num = ('A'-'A')*16+GPIOA_FLASHLIGHT,
1626+ },
1627+ {
1628+ .led_cdev = {
1629+ .name = "htcuniversal:kbdbacklight",
1630+ .default_trigger = "htcuniversal-kbdbacklight",
1631+ },
1632+ .hw_num = -1,
1633+ .gpio_num = ('D'-'A')*16+GPIOD_BL_KEYB_PWR_ON,
1634+ },
1635+};
1636+
1637+void htcuniversal_leds_release(struct device *dev)
1638+{
1639+ return;
1640+}
1641+
1642+static
1643+struct asic3_leds_machinfo htcuniversal_leds_machinfo = {
1644+ .num_leds = ARRAY_SIZE(htcuniversal_leds),
1645+ .leds = htcuniversal_leds,
1646+ .asic3_pdev = &htcuniversal_asic3,
1647+};
1648+
1649+static
1650+struct platform_device htcuniversal_leds_pdev = {
1651+ .name = "asic3-leds",
1652+ .dev = {
1653+ .platform_data = &htcuniversal_leds_machinfo,
1654+ .release = htcuniversal_leds_release,
1655+ },
1656+};
1657+
1658+static
1659+int __init htcuniversal_leds_init(void)
1660+{
1661+ int ret;
1662+ printk("htcuniversal LEDs Driver\n");
1663+// led_trigger_register_shared("htcuniversal-radio", &htcuniversal_radio_trig);
1664+
1665+ ret = asic3_leds_register();
1666+ if (ret) goto asic3_leds_failed;
1667+
1668+ ret = platform_device_register(&htcuniversal_leds_pdev);
1669+ if (ret) goto platform_device_failed;
1670+
1671+ goto success;
1672+
1673+platform_device_failed:
1674+ asic3_leds_unregister();
1675+asic3_leds_failed:
1676+// led_trigger_unregister_shared(htcuniversal_radio_trig);
1677+ printk("htcuniversal LEDs Driver failed to init");
1678+success:
1679+ return ret;
1680+}
1681+
1682+static
1683+void __exit htcuniversal_leds_exit(void)
1684+{
1685+// led_trigger_unregister_shared(htcuniversal_radio_trig);
1686+ platform_device_unregister(&htcuniversal_leds_pdev);
1687+ asic3_leds_unregister();
1688+ return;
1689+}
1690+
1691+module_init(htcuniversal_leds_init);
1692+module_exit(htcuniversal_leds_exit);
1693+
1694+MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
1695+MODULE_DESCRIPTION("htcuniversal LEDs driver");
1696+MODULE_LICENSE("GPL");
1697Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_bl.c
1698===================================================================
1699--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1700+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_bl.c 2008-06-01 18:49:45.000000000 +0100
1701@@ -0,0 +1,61 @@
1702+/*
1703+ * Use consistent with the GNU GPL is permitted,
1704+ * provided that this copyright notice is
1705+ * preserved in its entirety in all copies and derived works.
1706+ *
1707+ * Copyright (C) 2006 Paul Sokolosvky
1708+ * Based on code from older versions of htcuniversal_lcd.c
1709+ *
1710+ */
1711+
1712+#include <linux/types.h>
1713+#include <linux/platform_device.h>
1714+#include <asm/arch/hardware.h> /* for pxa-regs.h (__REG) */
1715+#include <asm/arch/pxa-regs.h>
1716+#include <asm/mach-types.h> /* machine_is_htcuniversal */
1717+//#include <linux/corgi_bl.h>
1718+#include <linux/backlight.h>
1719+#include <linux/err.h>
1720+
1721+#include <asm/arch/htcuniversal-gpio.h>
1722+#include <asm/arch/htcuniversal-asic.h>
1723+#include <asm/hardware/ipaq-asic3.h>
1724+#include <linux/soc/asic3_base.h>
1725+
1726+#define HTCUNIVERSAL_MAX_INTENSITY 0xc7
1727+
1728+static void htcuniversal_set_bl_intensity(int intensity)
1729+{
1730+ PWM_CTRL1 = 1; /* pre-scaler */
1731+ PWM_PWDUTY1 = intensity; /* duty cycle */
1732+ PWM_PERVAL1 = HTCUNIVERSAL_MAX_INTENSITY+1; /* period */
1733+
1734+ if (intensity > 0) {
1735+ pxa_set_cken(CKEN_PWM1, 1);
1736+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev,
1737+ (1<<GPIOD_FL_PWR_ON), (1<<GPIOD_FL_PWR_ON));
1738+ } else {
1739+ pxa_set_cken(CKEN_PWM1, 0);
1740+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev,
1741+ (1<<GPIOD_FL_PWR_ON), 0);
1742+ }
1743+}
1744+
1745+
1746+static struct generic_bl_info htcuniversal_bl_machinfo = {
1747+ .default_intensity = HTCUNIVERSAL_MAX_INTENSITY / 4,
1748+ .limit_mask = 0xff,
1749+ .max_intensity = HTCUNIVERSAL_MAX_INTENSITY,
1750+ .set_bl_intensity = htcuniversal_set_bl_intensity,
1751+};
1752+
1753+struct platform_device htcuniversal_bl = {
1754+ .name = "corgi-bl",
1755+ .dev = {
1756+ .platform_data = &htcuniversal_bl_machinfo,
1757+ },
1758+};
1759+
1760+MODULE_AUTHOR("Paul Sokolovsky <pmiscml@gmail.com>");
1761+MODULE_DESCRIPTION("Backlight driver for HTC Universal");
1762+MODULE_LICENSE("GPL");
1763Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.c
1764===================================================================
1765--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1766+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.c 2008-06-01 18:49:45.000000000 +0100
1767@@ -0,0 +1,135 @@
1768+/* Bluetooth interface driver for TI BRF6150 on HX4700
1769+ *
1770+ * Copyright (c) 2005 SDG Systems, LLC
1771+ *
1772+ * 2005-04-21 Todd Blumer Created.
1773+ */
1774+
1775+#include <linux/module.h>
1776+#include <linux/kernel.h>
1777+#include <linux/delay.h>
1778+#include <linux/platform_device.h>
1779+#include <linux/soc/asic3_base.h>
1780+
1781+#include <asm/hardware.h>
1782+#include <asm/arch/serial.h>
1783+#include <asm/hardware/ipaq-asic3.h>
1784+#include <asm/arch/htcuniversal-gpio.h>
1785+#include <asm/arch/htcuniversal-asic.h>
1786+
1787+#include "htcuniversal_bt.h"
1788+
1789+static uint use_led=1;
1790+
1791+static void
1792+htcuniversal_bt_configure( int state )
1793+{
1794+ int tries;
1795+
1796+ printk( KERN_NOTICE "htcuniversal configure bluetooth: %d\n", state );
1797+ switch (state) {
1798+
1799+ case PXA_UART_CFG_PRE_STARTUP:
1800+ break;
1801+
1802+ case PXA_UART_CFG_POST_STARTUP:
1803+ /* pre-serial-up hardware configuration */
1804+ htcuniversal_egpio_enable(1<<EGPIO5_BT_3V3_ON);
1805+ mdelay(50);
1806+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_BT_PWR_ON, 1<<GPIOC_BT_PWR_ON);
1807+ mdelay(10);
1808+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_BT_RESET, 0);
1809+ mdelay(10);
1810+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_BT_RESET, 1<<GPIOC_BT_RESET);
1811+ mdelay(10);
1812+
1813+ /*
1814+ * BRF6150's RTS goes low when firmware is ready
1815+ * so check for CTS=1 (nCTS=0 -> CTS=1). Typical 150ms
1816+ */
1817+ tries = 0;
1818+ do {
1819+ mdelay(10);
1820+ } while ((BTMSR & MSR_CTS) == 0 && tries++ < 50);
1821+ if (use_led) {
1822+// htcuniversal_set_led(2, 16, 16);
1823+ }
1824+ break;
1825+
1826+ case PXA_UART_CFG_PRE_SHUTDOWN:
1827+ htcuniversal_egpio_disable(1<<EGPIO5_BT_3V3_ON );
1828+ mdelay(50);
1829+// htcuniversal_clear_led(2);
1830+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_BT_PWR_ON, 0);
1831+ break;
1832+
1833+ default:
1834+ break;
1835+ }
1836+}
1837+
1838+
1839+static int
1840+htcuniversal_bt_probe( struct platform_device *dev )
1841+{
1842+ struct htcuniversal_bt_funcs *funcs = dev->dev.platform_data;
1843+
1844+ /* configure bluetooth UART */
1845+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_BT_RXD_MD );
1846+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_BT_TXD_MD );
1847+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_BT_UART_CTS_MD );
1848+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_BT_UART_RTS_MD );
1849+
1850+ funcs->configure = htcuniversal_bt_configure;
1851+
1852+ /* Make sure the LED is off */
1853+// htcuniversal_clear_led(2);
1854+
1855+ return 0;
1856+}
1857+
1858+static int
1859+htcuniversal_bt_remove( struct platform_device *dev )
1860+{
1861+ struct htcuniversal_bt_funcs *funcs = dev->dev.platform_data;
1862+
1863+ funcs->configure = NULL;
1864+
1865+ /* Make sure the LED is off */
1866+// htcuniversal_clear_led(2);
1867+
1868+ return 0;
1869+}
1870+
1871+static struct platform_driver bt_driver = {
1872+ .driver = {
1873+ .name = "htcuniversal_bt",
1874+ },
1875+ .probe = htcuniversal_bt_probe,
1876+ .remove = htcuniversal_bt_remove,
1877+};
1878+
1879+module_param(use_led, uint, 0);
1880+
1881+static int __init
1882+htcuniversal_bt_init( void )
1883+{
1884+ printk(KERN_NOTICE "htcuniversal Bluetooth Driver\n");
1885+ return platform_driver_register( &bt_driver );
1886+}
1887+
1888+static void __exit
1889+htcuniversal_bt_exit( void )
1890+{
1891+ platform_driver_unregister( &bt_driver );
1892+}
1893+
1894+module_init( htcuniversal_bt_init );
1895+module_exit( htcuniversal_bt_exit );
1896+
1897+MODULE_AUTHOR("Todd Blumer, SDG Systems, LLC");
1898+MODULE_DESCRIPTION("HTC Universal Bluetooth Support Driver");
1899+MODULE_LICENSE("GPL");
1900+
1901+/* vim600: set noexpandtab sw=8 ts=8 :*/
1902+
1903Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.h
1904===================================================================
1905--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1906+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_bt.h 2008-06-01 18:49:45.000000000 +0100
1907@@ -0,0 +1,17 @@
1908+/*
1909+ * Bluetooth support file for calling bluetooth configuration functions
1910+ *
1911+ * Copyright (c) 2005 SDG Systems, LLC
1912+ *
1913+ * 2005-06 Todd Blumer Initial Revision
1914+ */
1915+
1916+#ifndef _HTCUNIVERSAL_BT_H
1917+#define _HTCUNIVERSAL_BT_H
1918+
1919+struct htcuniversal_bt_funcs {
1920+ void (*configure) ( int state );
1921+};
1922+
1923+
1924+#endif
1925Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_buttons.c
1926===================================================================
1927--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1928+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_buttons.c 2008-06-01 18:49:45.000000000 +0100
1929@@ -0,0 +1,87 @@
1930+/*
1931+ * Buttons driver for HTC Universal
1932+ *
1933+ * This file is subject to the terms and conditions of the GNU General Public
1934+ * License.
1935+ *
1936+ * Copyright (C) 2005 Pawel Kolodziejski
1937+ * Copyright (C) 2003 Joshua Wise
1938+ *
1939+ */
1940+
1941+#include <linux/input.h>
1942+#include <linux/input_pda.h>
1943+#include <linux/module.h>
1944+#include <linux/init.h>
1945+#include <linux/interrupt.h>
1946+#include <linux/irq.h>
1947+#include <linux/platform_device.h>
1948+#include <linux/gpio_keys.h>
1949+#include <linux/soc/asic3_base.h>
1950+#include <asm/mach-types.h>
1951+#include <asm/hardware/asic3_keys.h>
1952+#include <asm/arch/htcuniversal-gpio.h>
1953+#include <asm/arch/htcuniversal-asic.h>
1954+
1955+static struct asic3_keys_button asic3_buttons[] = {
1956+//{KEY_SCREEN, ASIC3_GPIOA_IRQ_BASE+GPIOA_COVER_ROTATE_N, 1, "screen_cover", EV_SW},
1957+//{KEY_SWITCHVIDEOMODE, ASIC3_GPIOB_IRQ_BASE+GPIOB_CLAMSHELL_N, 1, "clamshell_rotate", EV_SW},
1958+//{KEY_KBDILLUMTOGGLE, ASIC3_GPIOB_IRQ_BASE+GPIOB_NIGHT_SENSOR, 1, "night_sensor", EV_SW},
1959+{SW_LID, ASIC3_GPIOA_IRQ_BASE+GPIOA_COVER_ROTATE_N, 1, "screen_cover", EV_SW},
1960+{SW_TABLET_MODE, ASIC3_GPIOB_IRQ_BASE+GPIOB_CLAMSHELL_N, 1, "clamshell_rotate", EV_SW},
1961+//{SW_NIGHT_SENSOR, ASIC3_GPIOB_IRQ_BASE+GPIOB_NIGHT_SENSOR, 1, "night_sensor", EV_SW},
1962+{KEY_F10, ASIC3_GPIOA_IRQ_BASE+GPIOA_BUTTON_BACKLIGHT_N, 1, "backlight_button"},
1963+{KEY_RECORD, ASIC3_GPIOA_IRQ_BASE+GPIOA_BUTTON_RECORD_N, 1, "record_button"},
1964+{KEY_CAMERA, ASIC3_GPIOA_IRQ_BASE+GPIOA_BUTTON_CAMERA_N, 1, "camera_button"},
1965+{KEY_VOLUMEDOWN, ASIC3_GPIOA_IRQ_BASE+GPIOA_VOL_UP_N, 1, "volume_slider_down"},
1966+{KEY_VOLUMEUP, ASIC3_GPIOA_IRQ_BASE+GPIOA_VOL_DOWN_N, 1, "volume_slider_up"},
1967+{KEY_KPENTER, ASIC3_GPIOD_IRQ_BASE+GPIOD_KEY_OK_N, 1, "select"},
1968+{KEY_RIGHT, ASIC3_GPIOD_IRQ_BASE+GPIOD_KEY_RIGHT_N, 1, "right"},
1969+{KEY_LEFT, ASIC3_GPIOD_IRQ_BASE+GPIOD_KEY_LEFT_N, 1, "left"},
1970+{KEY_DOWN, ASIC3_GPIOD_IRQ_BASE+GPIOD_KEY_DOWN_N, 1, "down"},
1971+{KEY_UP, ASIC3_GPIOD_IRQ_BASE+GPIOD_KEY_UP_N, 1, "up"},
1972+};
1973+
1974+static struct asic3_keys_platform_data asic3_keys_data = {
1975+ .buttons = asic3_buttons,
1976+ .nbuttons = ARRAY_SIZE(asic3_buttons),
1977+ .asic3_dev = &htcuniversal_asic3.dev,
1978+};
1979+
1980+static struct platform_device htcuniversal_keys_asic3 = {
1981+ .name = "asic3-keys",
1982+ .dev = { .platform_data = &asic3_keys_data, }
1983+};
1984+
1985+static int __init htcuniversal_buttons_probe(struct platform_device *dev)
1986+{
1987+ platform_device_register(&htcuniversal_keys_asic3);
1988+ return 0;
1989+}
1990+
1991+static struct platform_driver htcuniversal_buttons_driver = {
1992+ .driver = {
1993+ .name = "htcuniversal_buttons",
1994+ },
1995+ .probe = htcuniversal_buttons_probe,
1996+};
1997+
1998+static int __init htcuniversal_buttons_init(void)
1999+{
2000+ if (!machine_is_htcuniversal())
2001+ return -ENODEV;
2002+
2003+ return platform_driver_register(&htcuniversal_buttons_driver);
2004+}
2005+
2006+static void __exit htcuniversal_buttons_exit(void)
2007+{
2008+ platform_driver_unregister(&htcuniversal_buttons_driver);
2009+}
2010+
2011+module_init(htcuniversal_buttons_init);
2012+module_exit(htcuniversal_buttons_exit);
2013+
2014+MODULE_AUTHOR ("Joshua Wise, Pawel Kolodziejski, Paul Sokolosvky");
2015+MODULE_DESCRIPTION ("Buttons support for HTC Universal");
2016+MODULE_LICENSE ("GPL");
2017Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_core.c
2018===================================================================
2019--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2020+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_core.c 2008-06-01 18:49:45.000000000 +0100
2021@@ -0,0 +1,226 @@
2022+/* Core Hardware driver for Hx4700 (Serial, ASIC3, EGPIOs)
2023+ *
2024+ * Copyright (c) 2005 SDG Systems, LLC
2025+ *
2026+ * 2005-03-29 Todd Blumer Converted basic structure to support hx4700
2027+ * 2005-04-30 Todd Blumer Add IRDA code from H2200
2028+ */
2029+
2030+#include <linux/module.h>
2031+#include <linux/version.h>
2032+#include <linux/interrupt.h>
2033+#include <linux/platform_device.h>
2034+#include <linux/delay.h>
2035+#include <linux/pm.h>
2036+#include <linux/irq.h>
2037+
2038+#include <asm/io.h>
2039+#include <asm/mach/irq.h>
2040+#include <asm/arch/pxa-regs.h>
2041+#include <asm/arch/pxa-pm_ll.h>
2042+#include <asm/arch/htcuniversal-gpio.h>
2043+#include <asm/arch/htcuniversal-asic.h>
2044+
2045+#include <linux/soc/asic3_base.h>
2046+#include <asm/hardware/ipaq-asic3.h>
2047+
2048+volatile u_int16_t *egpios;
2049+u_int16_t egpio_reg;
2050+
2051+static int htc_bootloader = 0; /* Is the stock HTC bootloader installed? */
2052+
2053+/*
2054+ * may make sense to put egpios elsewhere, but they're here now
2055+ * since they share some of the same address space with the TI WLAN
2056+ *
2057+ * EGPIO register is write-only
2058+ */
2059+
2060+void
2061+htcuniversal_egpio_enable( u_int16_t bits )
2062+{
2063+ unsigned long flags;
2064+
2065+ local_irq_save(flags);
2066+
2067+ egpio_reg |= bits;
2068+ *egpios = egpio_reg;
2069+
2070+ local_irq_restore(flags);
2071+}
2072+EXPORT_SYMBOL_GPL(htcuniversal_egpio_enable);
2073+
2074+void
2075+htcuniversal_egpio_disable( u_int16_t bits )
2076+{
2077+ unsigned long flags;
2078+
2079+ local_irq_save(flags);
2080+
2081+ egpio_reg &= ~bits;
2082+ *egpios = egpio_reg;
2083+
2084+ local_irq_restore(flags);
2085+}
2086+EXPORT_SYMBOL_GPL(htcuniversal_egpio_disable);
2087+
2088+#ifdef CONFIG_PM
2089+
2090+//void htcuniversal_ll_pm_init(void);
2091+
2092+static int htcuniversal_suspend(struct platform_device *dev, pm_message_t state)
2093+{
2094+ /* Turn off external clocks here, because htcuniversal_power and asic3_mmc
2095+ * scared to do so to not hurt each other. (-5 mA) */
2096+
2097+
2098+ /* 0x20c2 is HTC clock value
2099+ * CLOCK_CDEX_SOURCE 2
2100+ * CLOCK_CDEX_SPI 0
2101+ * CLOCK_CDEX_OWM 0
2102+ *
2103+ * CLOCK_CDEX_PWM0 0
2104+ * CLOCK_CDEX_PWM1 0
2105+ * CLOCK_CDEX_LED0 1
2106+ * CLOCK_CDEX_LED1 1
2107+ *
2108+ * CLOCK_CDEX_LED2 0
2109+ * CLOCK_CDEX_SD_HOST 0
2110+ * CLOCK_CDEX_SD_BUS 0
2111+ * CLOCK_CDEX_SMBUS 0
2112+ *
2113+ * CLOCK_CDEX_CONTROL_CX 0
2114+ * CLOCK_CDEX_EX0 1
2115+ * CLOCK_CDEX_EX1 0
2116+ * */
2117+ asic3_set_clock_cdex(&htcuniversal_asic3.dev, 0xffff, CLOCK_CDEX_SOURCE1
2118+ |CLOCK_CDEX_LED0
2119+ |CLOCK_CDEX_LED1
2120+ |CLOCK_CDEX_LED2
2121+ |CLOCK_CDEX_EX0
2122+ |CLOCK_CDEX_EX1);
2123+
2124+ *egpios = 0; /* turn off all egpio power */
2125+
2126+ /* Wake up enable. */
2127+ PWER = PWER_GPIO0
2128+ | PWER_GPIO1 /* reset */
2129+ | PWER_GPIO9 /* USB */
2130+ | PWER_GPIO10 /* AC on USB */
2131+ | PWER_GPIO14 /* ASIC3 mux */
2132+ | PWER_RTC;
2133+ /* Wake up on falling edge. */
2134+ PFER = PWER_GPIO0
2135+ | PWER_GPIO1
2136+ | PWER_GPIO9
2137+ | PWER_GPIO10
2138+ | PWER_GPIO14;
2139+
2140+ /* Wake up on rising edge. */
2141+ PRER = PWER_GPIO0
2142+ | PWER_GPIO1
2143+ | PWER_GPIO9
2144+ | PWER_GPIO10;
2145+ /* 3.6864 MHz oscillator power-down enable */
2146+ PCFR = PCFR_OPDE | PCFR_PI2CEN | PCFR_GPROD | PCFR_GPR_EN;
2147+
2148+ PGSR0 = 0x09088004;
2149+ PGSR1 = 0x00020002;
2150+ PGSR2 = 0x8001c000;
2151+ PGSR3 = 0x00106284;
2152+
2153+ PSLR = 0xcc000000;
2154+
2155+#if 0
2156+ /*
2157+ * If we're using bootldr and not the stock HTC bootloader,
2158+ * we want to wake up periodically to see if the charge is full while
2159+ * it is suspended. We do this with the OS timer 4 in the pxa270.
2160+ */
2161+ if (!htc_bootloader) {
2162+ OMCR4 = 0x4b; /* Periodic, self-resetting, 1-second timer */
2163+ OSMR4 = 5; /* Wake up bootldr after x seconds so it can
2164+ figure out what to do with the LEDs. */
2165+ OIER |= 0x10; /* Enable interrupt source for Timer 4 */
2166+ OSCR4 = 0; /* This starts the timer */
2167+ }
2168+#endif
2169+
2170+ asic3_set_extcf_select(&htcuniversal_asic3.dev, ASIC3_EXTCF_OWM_EN, 0);
2171+
2172+ return 0;
2173+}
2174+
2175+static int htcuniversal_resume(struct platform_device *dev)
2176+{
2177+ htcuniversal_egpio_enable(0);
2178+
2179+ return 0;
2180+}
2181+#else
2182+# define htcuniversal_suspend NULL
2183+# define htcuniversal_resume NULL
2184+#endif
2185+
2186+static int
2187+htcuniversal_core_probe( struct platform_device *dev )
2188+{
2189+
2190+ printk( KERN_NOTICE "HTC Universal Core Hardware Driver\n" );
2191+
2192+ egpios = (volatile u_int16_t *)ioremap_nocache(HTCUNIVERSAL_EGPIO_BASE, sizeof *egpios );
2193+ if (!egpios)
2194+ return -ENODEV;
2195+ else
2196+ printk( KERN_NOTICE "HTC Universal Core: egpio at phy=0x%8.8x is at virt=0x%p\n",
2197+ HTCUNIVERSAL_EGPIO_BASE, egpios );
2198+
2199+ printk("Using stock HTC first stage bootloader\n");
2200+ htc_bootloader = 1;
2201+
2202+// htcuniversal_ll_pm_init();
2203+
2204+ return 0;
2205+}
2206+
2207+static int
2208+htcuniversal_core_remove( struct platform_device *dev )
2209+{
2210+
2211+ if (egpios != NULL)
2212+ iounmap( (void *)egpios );
2213+
2214+ return 0;
2215+}
2216+
2217+static struct platform_driver htcuniversal_core_driver = {
2218+ .driver = {
2219+ .name = "htcuniversal_core",
2220+ },
2221+ .probe = htcuniversal_core_probe,
2222+ .remove = htcuniversal_core_remove,
2223+ .suspend = htcuniversal_suspend,
2224+ .resume = htcuniversal_resume,
2225+};
2226+
2227+static int __init
2228+htcuniversal_core_init( void )
2229+{
2230+ return platform_driver_register( &htcuniversal_core_driver );
2231+}
2232+
2233+
2234+static void __exit
2235+htcuniversal_core_exit( void )
2236+{
2237+ platform_driver_unregister( &htcuniversal_core_driver );
2238+}
2239+
2240+module_init( htcuniversal_core_init );
2241+module_exit( htcuniversal_core_exit );
2242+
2243+MODULE_AUTHOR("Todd Blumer, SDG Systems, LLC");
2244+MODULE_DESCRIPTION("HTC Universal Core Hardware Driver");
2245+MODULE_LICENSE("GPL");
2246+
2247+/* vim600: set noexpandtab sw=8 ts=8 :*/
2248Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_lcd.c
2249===================================================================
2250--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2251+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_lcd.c 2008-06-01 18:49:45.000000000 +0100
2252@@ -0,0 +1,212 @@
2253+/*
2254+ * Use consistent with the GNU GPL is permitted,
2255+ * provided that this copyright notice is
2256+ * preserved in its entirety in all copies and derived works.
2257+ *
2258+ * History:
2259+ *
2260+ * 2004-03-01 Eddi De Pieri Adapted for htcuniversal using h3900_lcd.c
2261+ * 2004 Shawn Anderson Lcd hacking on htcuniversal
2262+ * see h3900_lcd.c for more history.
2263+ *
2264+ */
2265+
2266+#include <linux/types.h>
2267+#include <asm/arch/hardware.h> /* for pxa-regs.h (__REG) */
2268+#include <linux/platform_device.h>
2269+#include <asm/arch/pxa-regs.h> /* LCCR[0,1,2,3]* */
2270+#include <asm/arch/bitfield.h> /* for pxa-regs.h (Fld, etc) */
2271+#include <asm/arch/pxafb.h> /* pxafb_mach_info, set_pxa_fb_info */
2272+#include <asm/mach-types.h> /* machine_is_htcuniversal */
2273+#include <linux/lcd.h> /* lcd_device */
2274+#include <linux/err.h>
2275+#include <linux/delay.h>
2276+
2277+#include <asm/arch/htcuniversal-gpio.h>
2278+#include <asm/arch/htcuniversal-asic.h>
2279+#include <asm/hardware/ipaq-asic3.h>
2280+#include <linux/soc/asic3_base.h>
2281+
2282+static int saved_lcdpower=-1;
2283+
2284+static int powerup_lcd(void)
2285+{
2286+ printk( KERN_INFO "htcuniversal powerup_lcd: called\n");
2287+
2288+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR1_ON, 0);
2289+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR2_ON, 0);
2290+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_LCD_PWR3_ON, 0);
2291+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_LCD_PWR4_ON, 0);
2292+ asic3_set_gpio_out_a(&htcuniversal_asic3.dev, 1<<GPIOA_LCD_PWR5_ON, 0);
2293+#if 1
2294+ LCCR4|=LCCR4_PCDDIV;
2295+#endif
2296+ pxa_set_cken(CKEN_LCD, 0);
2297+
2298+ mdelay(100);
2299+ asic3_set_gpio_out_a(&htcuniversal_asic3.dev, 1<<GPIOA_LCD_PWR5_ON, 1<<GPIOA_LCD_PWR5_ON);
2300+ mdelay(5);
2301+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_LCD_PWR3_ON, 1<<GPIOB_LCD_PWR3_ON);
2302+ mdelay(2);
2303+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR1_ON, 1<<GPIOC_LCD_PWR1_ON);
2304+ mdelay(2);
2305+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR2_ON, 1<<GPIOC_LCD_PWR2_ON);
2306+ mdelay(20);
2307+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_LCD_PWR4_ON, 1<<GPIOD_LCD_PWR4_ON);
2308+ mdelay(1);
2309+ pxa_set_cken(CKEN_LCD, 1);
2310+
2311+ SET_HTCUNIVERSAL_GPIO(LCD1,1);
2312+ SET_HTCUNIVERSAL_GPIO(LCD2,1);
2313+ return 0;
2314+}
2315+
2316+static int powerdown_lcd(void)
2317+{
2318+ printk( KERN_INFO "htcuniversal powerdown_lcd: called\n");
2319+
2320+#if 1
2321+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR2_ON, 0);
2322+ mdelay(100);
2323+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_LCD_PWR4_ON, 0);
2324+ mdelay(10);
2325+ asic3_set_gpio_out_a(&htcuniversal_asic3.dev, 1<<GPIOA_LCD_PWR5_ON, 0);
2326+ mdelay(1);
2327+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_LCD_PWR3_ON, 0);
2328+ mdelay(1);
2329+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR1_ON, 0);
2330+ pxa_set_cken(CKEN_LCD, 0);
2331+
2332+ SET_HTCUNIVERSAL_GPIO(LCD1,0);
2333+ SET_HTCUNIVERSAL_GPIO(LCD2,0);
2334+#else
2335+ pxa_set_cken(CKEN_LCD, 0);
2336+
2337+ SET_HTCUNIVERSAL_GPIO(LCD1,0);
2338+ SET_HTCUNIVERSAL_GPIO(LCD2,0);
2339+
2340+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR2_ON, 0);
2341+ mdelay(100);
2342+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_LCD_PWR4_ON, 0);
2343+ mdelay(10);
2344+ asic3_set_gpio_out_a(&htcuniversal_asic3.dev, 1<<GPIOA_LCD_PWR5_ON, 0);
2345+ mdelay(1);
2346+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_LCD_PWR3_ON, 0);
2347+ mdelay(1);
2348+ asic3_set_gpio_out_c(&htcuniversal_asic3.dev, 1<<GPIOC_LCD_PWR1_ON, 0);
2349+#endif
2350+ return 0;
2351+}
2352+
2353+static int htcuniversal_lcd_set_power(struct lcd_device *lm, int power)
2354+{
2355+ /* Enable or disable power to the LCD (0: on; 4: off) */
2356+
2357+ if ( power < 1 ) {
2358+
2359+ powerup_lcd();
2360+
2361+ } else {
2362+
2363+ powerdown_lcd();
2364+
2365+ }
2366+
2367+ saved_lcdpower=power;
2368+
2369+ return 0;
2370+}
2371+
2372+static int htcuniversal_lcd_get_power(struct lcd_device *lm)
2373+{
2374+ /* Get the LCD panel power status (0: full on, 1..3: controller
2375+ * power on, flat panel power off, 4: full off) */
2376+
2377+ if (saved_lcdpower == -1)
2378+ {
2379+ htcuniversal_lcd_set_power(lm, 4);
2380+ saved_lcdpower=4;
2381+ }
2382+
2383+ return saved_lcdpower;
2384+}
2385+
2386+static struct lcd_ops htcuniversal_lcd_properties =
2387+{
2388+ .get_power = htcuniversal_lcd_get_power,
2389+ .set_power = htcuniversal_lcd_set_power,
2390+};
2391+
2392+static struct lcd_device *htcuniversal_lcd_dev;
2393+
2394+static int htcuniversal_lcd_probe(struct platform_device * dev)
2395+{
2396+ htcuniversal_lcd_dev = lcd_device_register("pxa2xx-fb", &dev->dev, NULL,
2397+ &htcuniversal_lcd_properties);
2398+ if (IS_ERR(htcuniversal_lcd_dev)) {
2399+ printk("htcuniversal_lcd_probe: error registering devices\n");
2400+ return -1;
2401+ }
2402+
2403+ return 0;
2404+}
2405+
2406+static int htcuniversal_lcd_remove(struct platform_device * dev)
2407+{
2408+ htcuniversal_lcd_set_power(htcuniversal_lcd_dev, 4);
2409+ lcd_device_unregister(htcuniversal_lcd_dev);
2410+
2411+ return 0;
2412+}
2413+
2414+static int htcuniversal_lcd_suspend(struct platform_device * dev, pm_message_t state)
2415+{
2416+// printk("htcuniversal_lcd_suspend: called.\n");
2417+ htcuniversal_lcd_set_power(htcuniversal_lcd_dev, 4);
2418+ return 0;
2419+}
2420+
2421+static int htcuniversal_lcd_resume(struct platform_device * dev)
2422+{
2423+// printk("htcuniversal_lcd_resume: called.\n");
2424+
2425+ /* */
2426+#if 1
2427+ LCCR4|=LCCR4_PCDDIV;
2428+#endif
2429+
2430+ htcuniversal_lcd_set_power(htcuniversal_lcd_dev, 0);
2431+ return 0;
2432+}
2433+
2434+static struct platform_driver htcuniversal_lcd_driver = {
2435+ .driver = {
2436+ .name = "htcuniversal_lcd",
2437+ },
2438+ .probe = htcuniversal_lcd_probe,
2439+ .remove = htcuniversal_lcd_remove,
2440+ .suspend = htcuniversal_lcd_suspend,
2441+ .resume = htcuniversal_lcd_resume,
2442+};
2443+
2444+static int htcuniversal_lcd_init(void)
2445+{
2446+ if (!machine_is_htcuniversal())
2447+ return -ENODEV;
2448+
2449+ return platform_driver_register(&htcuniversal_lcd_driver);
2450+}
2451+
2452+static void htcuniversal_lcd_exit(void)
2453+{
2454+ lcd_device_unregister(htcuniversal_lcd_dev);
2455+ platform_driver_unregister(&htcuniversal_lcd_driver);
2456+}
2457+
2458+module_init(htcuniversal_lcd_init);
2459+module_exit(htcuniversal_lcd_exit);
2460+
2461+MODULE_AUTHOR("xanadux.org");
2462+MODULE_DESCRIPTION("Framebuffer driver for HTC Universal");
2463+MODULE_LICENSE("GPL");
2464+
2465Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.c
2466===================================================================
2467--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2468+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.c 2008-06-01 18:49:45.000000000 +0100
2469@@ -0,0 +1,167 @@
2470+
2471+/* Phone interface driver for Qualcomm MSM6250 on HTC Universal
2472+ *
2473+ * Copyright (c) 2005 SDG Systems, LLC
2474+ *
2475+ * 2005-04-21 Todd Blumer Created.
2476+ */
2477+
2478+#include <linux/module.h>
2479+#include <linux/kernel.h>
2480+#include <linux/delay.h>
2481+#include <linux/platform_device.h>
2482+#include <linux/soc/asic3_base.h>
2483+
2484+#include <asm/hardware.h>
2485+#include <asm/arch/serial.h>
2486+#include <asm/hardware/ipaq-asic3.h>
2487+#include <asm/arch/htcuniversal-gpio.h>
2488+#include <asm/arch/htcuniversal-asic.h>
2489+
2490+#include "htcuniversal_phone.h"
2491+
2492+static void phone_reset(void)
2493+{
2494+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_BB_RESET2, 0);
2495+
2496+ SET_HTCUNIVERSAL_GPIO(PHONE_RESET,0);
2497+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BB_RESET1, 0);
2498+ mdelay(1);
2499+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BB_RESET1, 1<<GPIOD_BB_RESET1);
2500+ mdelay(20);
2501+ SET_HTCUNIVERSAL_GPIO(PHONE_RESET,1);
2502+ mdelay(200);
2503+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BB_RESET1, 0);
2504+}
2505+
2506+static void phone_off(void)
2507+{
2508+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BB_RESET1, 1<<GPIOD_BB_RESET1);
2509+ mdelay(2000);
2510+ asic3_set_gpio_out_d(&htcuniversal_asic3.dev, 1<<GPIOD_BB_RESET1, 0);
2511+
2512+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_BB_RESET2, 1<<GPIOB_BB_RESET2);
2513+ SET_HTCUNIVERSAL_GPIO(PHONE_OFF,0);
2514+}
2515+
2516+static void
2517+htcuniversal_phone_configure( int state )
2518+{
2519+ int tries;
2520+ unsigned short statusb;
2521+
2522+ printk( KERN_NOTICE "htcuniversal configure phone: %d\n", state );
2523+ switch (state) {
2524+
2525+ case PXA_UART_CFG_PRE_STARTUP:
2526+ break;
2527+
2528+ case PXA_UART_CFG_POST_STARTUP:
2529+ /* pre-serial-up hardware configuration */
2530+
2531+ SET_HTCUNIVERSAL_GPIO(PHONE_START,0); /* "bootloader" */
2532+ SET_HTCUNIVERSAL_GPIO(PHONE_UNKNOWN,0); /* not used */
2533+ SET_HTCUNIVERSAL_GPIO(PHONE_OFF,0); /* PHONE_OFF */
2534+
2535+ phone_reset();
2536+
2537+ SET_HTCUNIVERSAL_GPIO(PHONE_START,1); /* phone */
2538+
2539+ phone_reset();
2540+
2541+ asic3_set_gpio_dir_b(&htcuniversal_asic3.dev, 1<<GPIOB_BB_READY, 0);
2542+ asic3_set_gpio_dir_b(&htcuniversal_asic3.dev, 1<<GPIOB_BB_UNKNOWN3, 0);
2543+
2544+ /*
2545+ */
2546+ tries = 0;
2547+ do {
2548+ mdelay(10);
2549+ statusb = asic3_get_gpio_status_b( &htcuniversal_asic3.dev );
2550+ } while ( (statusb & (1<<GPIOB_UMTS_DCD)) == 0 && tries++ < 200);
2551+
2552+ printk("UMTS_DCD tries=%d of 200\n",tries);
2553+
2554+ tries = 0;
2555+ do {
2556+ SET_HTCUNIVERSAL_GPIO(PHONE_OFF,1);
2557+ mdelay(10);
2558+ SET_HTCUNIVERSAL_GPIO(PHONE_OFF,0);
2559+ mdelay(20);
2560+ statusb = asic3_get_gpio_status_b( &htcuniversal_asic3.dev );
2561+ } while ( (statusb & (1<<GPIOB_BB_READY)) == 0 && tries++ < 200);
2562+
2563+ printk("BB_READY tries=%d of 200\n",tries);
2564+
2565+ break;
2566+
2567+ case PXA_UART_CFG_PRE_SHUTDOWN:
2568+
2569+ phone_off();
2570+
2571+ break;
2572+
2573+ default:
2574+ break;
2575+ }
2576+}
2577+
2578+
2579+static int
2580+htcuniversal_phone_probe( struct platform_device *dev )
2581+{
2582+ struct htcuniversal_phone_funcs *funcs = dev->dev.platform_data;
2583+
2584+ /* configure phone UART */
2585+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_PHONE_RXD_MD );
2586+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_PHONE_TXD_MD );
2587+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_PHONE_UART_CTS_MD );
2588+ pxa_gpio_mode( GPIO_NR_HTCUNIVERSAL_PHONE_UART_RTS_MD );
2589+
2590+ funcs->configure = htcuniversal_phone_configure;
2591+
2592+ return 0;
2593+}
2594+
2595+static int
2596+htcuniversal_phone_remove( struct platform_device *dev )
2597+{
2598+ struct htcuniversal_phone_funcs *funcs = dev->dev.platform_data;
2599+
2600+ funcs->configure = NULL;
2601+
2602+ asic3_set_gpio_dir_b(&htcuniversal_asic3.dev, 1<<GPIOB_BB_READY, 1<<GPIOB_BB_READY);
2603+ asic3_set_gpio_dir_b(&htcuniversal_asic3.dev, 1<<GPIOB_BB_UNKNOWN3, 1<<GPIOB_BB_UNKNOWN3);
2604+
2605+ return 0;
2606+}
2607+
2608+static struct platform_driver phone_driver = {
2609+ .driver = {
2610+ .name = "htcuniversal_phone",
2611+ },
2612+ .probe = htcuniversal_phone_probe,
2613+ .remove = htcuniversal_phone_remove,
2614+};
2615+
2616+static int __init
2617+htcuniversal_phone_init( void )
2618+{
2619+ printk(KERN_NOTICE "htcuniversal Phone Driver\n");
2620+ return platform_driver_register( &phone_driver );
2621+}
2622+
2623+static void __exit
2624+htcuniversal_phone_exit( void )
2625+{
2626+ platform_driver_unregister( &phone_driver );
2627+}
2628+
2629+module_init( htcuniversal_phone_init );
2630+module_exit( htcuniversal_phone_exit );
2631+
2632+MODULE_AUTHOR("Todd Blumer, SDG Systems, LLC");
2633+MODULE_DESCRIPTION("HTC Universal Phone Support Driver");
2634+MODULE_LICENSE("GPL");
2635+
2636+/* vim600: set noexpandtab sw=8 ts=8 :*/
2637Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.h
2638===================================================================
2639--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2640+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_phone.h 2008-06-01 18:49:45.000000000 +0100
2641@@ -0,0 +1,16 @@
2642+/*
2643+ * Bluetooth support file for calling bluetooth configuration functions
2644+ *
2645+ * Copyright (c) 2005 SDG Systems, LLC
2646+ *
2647+ * 2005-06 Todd Blumer Initial Revision
2648+ */
2649+
2650+#ifndef _HTCUNIVERSAL_PHONE_H
2651+#define _HTCUNIVERSAL_PHONE_H
2652+
2653+struct htcuniversal_phone_funcs {
2654+ void (*configure) ( int state );
2655+};
2656+
2657+#endif
2658Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_pm.c
2659===================================================================
2660--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2661+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_pm.c 2008-06-01 18:49:45.000000000 +0100
2662@@ -0,0 +1,69 @@
2663+/*
2664+ * MyPal 716 power management support for the original HTC IPL in DoC G3
2665+ *
2666+ * Use consistent with the GNU GPL is permitted, provided that this
2667+ * copyright notice is preserved in its entirety in all copies and
2668+ * derived works.
2669+ *
2670+ * Copyright (C) 2005 Pawel Kolodziejski
2671+ *
2672+ */
2673+
2674+#include <linux/kernel.h>
2675+#include <linux/module.h>
2676+#include <linux/device.h>
2677+#include <linux/pm.h>
2678+
2679+#include <asm/mach-types.h>
2680+#include <asm/hardware.h>
2681+#include <asm/arch/pxa-regs.h>
2682+#include <asm/arch/pxa-pm_ll.h>
2683+
2684+#ifdef CONFIG_PM
2685+
2686+static u32 *addr_a0040000;
2687+static u32 *addr_a0040004;
2688+static u32 *addr_a0040008;
2689+static u32 *addr_a004000c;
2690+
2691+static u32 save_a0040000;
2692+static u32 save_a0040004;
2693+static u32 save_a0040008;
2694+static u32 save_a004000c;
2695+
2696+static void htcuniversal_pxa_ll_pm_suspend(unsigned long resume_addr)
2697+{
2698+ save_a0040000 = *addr_a0040000;
2699+ save_a0040004 = *addr_a0040004;
2700+ save_a0040008 = *addr_a0040008;
2701+ save_a004000c = *addr_a004000c;
2702+
2703+ /* jump to PSPR */
2704+ *addr_a0040000 = 0xe3a00101; // mov r0, #0x40000000
2705+ *addr_a0040004 = 0xe380060f; // orr r0, r0, #0x0f000000
2706+ *addr_a0040008 = 0xe3800008; // orr r0, r0, #8
2707+ *addr_a004000c = 0xe590f000; // ldr pc, [r0]
2708+}
2709+
2710+static void htcuniversal_pxa_ll_pm_resume(void)
2711+{
2712+ *addr_a0040000 = save_a0040000;
2713+ *addr_a0040004 = save_a0040004;
2714+ *addr_a0040008 = save_a0040008;
2715+ *addr_a004000c = save_a004000c;
2716+}
2717+
2718+static struct pxa_ll_pm_ops htcuniversal_ll_pm_ops = {
2719+ .suspend = htcuniversal_pxa_ll_pm_suspend,
2720+ .resume = htcuniversal_pxa_ll_pm_resume,
2721+};
2722+
2723+void htcuniversal_ll_pm_init(void) {
2724+ addr_a0040000 = phys_to_virt(0xa0040000);
2725+ addr_a0040004 = phys_to_virt(0xa0040004);
2726+ addr_a0040008 = phys_to_virt(0xa0040008);
2727+ addr_a004000c = phys_to_virt(0xa004000c);
2728+
2729+ pxa_pm_set_ll_ops(&htcuniversal_ll_pm_ops);
2730+}
2731+#endif /* CONFIG_PM */
2732Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_power2.c
2733===================================================================
2734--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2735+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_power2.c 2008-06-01 18:49:45.000000000 +0100
2736@@ -0,0 +1,97 @@
2737+/*
2738+ * pda_power driver for HTC Universal
2739+ *
2740+ * This program is free software; you can redistribute it and/or modify
2741+ * it under the terms of the GNU General Public License as published by
2742+ * the Free Software Foundation; either version 2 of the License, or (at
2743+ * your option) any later version.
2744+ *
2745+ */
2746+
2747+#include <linux/platform_device.h>
2748+#include <linux/module.h>
2749+#include <linux/pda_power.h>
2750+#include <linux/soc/asic3_base.h>
2751+
2752+#include <asm/mach-types.h>
2753+#include <asm/hardware.h>
2754+#include <asm/arch/htcuniversal-gpio.h>
2755+#include <asm/arch/htcuniversal-asic.h>
2756+
2757+static void charge_on(int flags)
2758+{
2759+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev, 1<<GPIOB_CHARGE_EN, 0);
2760+}
2761+
2762+static int ac_on(void)
2763+{
2764+ return (GET_HTCUNIVERSAL_GPIO(POWER_DET) == 0);
2765+}
2766+
2767+static int usb_on(void)
2768+{
2769+ return (GET_HTCUNIVERSAL_GPIO(USB_DET) == 0);
2770+}
2771+
2772+static char *supplicants[] = {
2773+ "ds2760-battery.0", "backup-battery"
2774+};
2775+
2776+static struct pda_power_pdata power_pdata = {
2777+ .is_ac_online = ac_on,
2778+ .is_usb_online = usb_on,
2779+ .set_charge = charge_on,
2780+ .supplied_to = supplicants,
2781+ .num_supplicants = ARRAY_SIZE(supplicants),
2782+};
2783+
2784+static struct resource power_resources[] = {
2785+ [0] = {
2786+ .name = "ac",
2787+ .start = HTCUNIVERSAL_IRQ(POWER_DET),
2788+ .end = HTCUNIVERSAL_IRQ(POWER_DET),
2789+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
2790+ },
2791+ [1] = {
2792+ .name = "usb",
2793+ .start = HTCUNIVERSAL_IRQ(USB_DET),
2794+ .end = HTCUNIVERSAL_IRQ(USB_DET),
2795+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
2796+ },
2797+};
2798+
2799+static void dev_release(struct device *dev)
2800+{
2801+ return;
2802+}
2803+
2804+static struct platform_device power_dev =
2805+{
2806+ .name = "pda-power",
2807+ .id = -1,
2808+ .resource = power_resources,
2809+ .num_resources = ARRAY_SIZE(power_resources),
2810+ .dev =
2811+ {
2812+ .platform_data = &power_pdata,
2813+ .release = dev_release,
2814+ },
2815+};
2816+
2817+static int htcuniversal_power_init(void)
2818+{
2819+ return platform_device_register(&power_dev);
2820+}
2821+
2822+static void htcuniversal_power_exit(void)
2823+{
2824+ platform_device_unregister(&power_dev);
2825+
2826+ return;
2827+}
2828+
2829+module_init(htcuniversal_power_init);
2830+module_exit(htcuniversal_power_exit);
2831+
2832+MODULE_DESCRIPTION("Power driver for HTC Universal");
2833+MODULE_LICENSE("GPL");
2834Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_ts2.c
2835===================================================================
2836--- /dev/null 1970-01-01 00:00:00.000000000 +0000
2837+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_ts2.c 2008-06-01 18:49:45.000000000 +0100
2838@@ -0,0 +1,490 @@
2839+/* Touch screen driver for the TI something-or-other
2840+ *
2841+ * Copyright © 2005 SDG Systems, LLC
2842+ *
2843+ * Based on code that was based on the SAMCOP driver.
2844+ * Copyright © 2003, 2004 Compaq Computer Corporation.
2845+ *
2846+ * Use consistent with the GNU GPL is permitted,
2847+ * provided that this copyright notice is
2848+ * preserved in its entirety in all copies and derived works.
2849+ *
2850+ * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
2851+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
2852+ * FITNESS FOR ANY PARTICULAR PURPOSE.
2853+ *
2854+ * Author: Keith Packard <keith.packard@hp.com>
2855+ * May 2003
2856+ *
2857+ * Updates:
2858+ *
2859+ * 2004-02-11 Michael Opdenacker Renamed names from samcop to shamcop,
2860+ * Goal:support HAMCOP and SAMCOP.
2861+ * 2004-02-14 Michael Opdenacker Temporary fix for device id handling
2862+ *
2863+ * 2005-02-18 Aric Blumer Converted basic structure to support hx4700
2864+ *
2865+ * 2005-06-07 Aric Blumer Added tssim device handling so we can
2866+ * hook in the fbvncserver.
2867+ */
2868+
2869+#include <linux/module.h>
2870+#include <linux/version.h>
2871+
2872+#include <linux/init.h>
2873+#include <linux/fs.h>
2874+#include <linux/cdev.h>
2875+#include <linux/interrupt.h>
2876+#include <linux/sched.h>
2877+#include <linux/pm.h>
2878+#include <linux/delay.h>
2879+#include <linux/input.h>
2880+#include <linux/platform_device.h>
2881+#include <linux/irq.h>
2882+
2883+#include <asm/arch/hardware.h>
2884+#include <asm/mach/irq.h>
2885+#include <asm/io.h>
2886+
2887+/* remove me */
2888+#include <asm/arch/pxa-regs.h>
2889+#include <asm/arch/htcuniversal-gpio.h>
2890+#include <asm/arch/htcuniversal-asic.h>
2891+#include <asm/mach-types.h>
2892+
2893+#include <asm/hardware/ipaq-asic3.h>
2894+#include <linux/soc/asic3_base.h>
2895+
2896+
2897+#include "tsc2046_ts.h"
2898+
2899+enum touchscreen_state {
2900+ STATE_WAIT_FOR_TOUCH, /* Waiting for a PEN interrupt */
2901+ STATE_SAMPLING /* Actively sampling ADC */
2902+};
2903+
2904+struct touchscreen_data {
2905+ enum touchscreen_state state;
2906+ struct timer_list timer;
2907+ int irq;
2908+ struct input_dev *input;
2909+ /* */
2910+ int port;
2911+ int clock;
2912+ int pwrbit_X;
2913+ int pwrbit_Y;
2914+ int (*pen_down)(void);
2915+};
2916+
2917+static unsigned long poll_sample_time = 10; /* Sample every 10 milliseconds */
2918+
2919+static struct touchscreen_data *ts_data;
2920+
2921+static int irqblock;
2922+
2923+module_param(poll_sample_time, ulong, 0644);
2924+MODULE_PARM_DESC(poll_sample_time, "Poll sample time");
2925+
2926+static inline void
2927+report_touchpanel(struct touchscreen_data *ts, int pressure, int x, int y)
2928+{
2929+ input_report_abs(ts->input, ABS_PRESSURE, pressure);
2930+ input_report_abs(ts->input, ABS_X, x);
2931+ input_report_abs(ts->input, ABS_Y, y);
2932+ input_sync(ts->input);
2933+}
2934+
2935+static void start_read(struct touchscreen_data *touch);
2936+
2937+static irqreturn_t
2938+pen_isr(int irq, void *irq_desc)
2939+{
2940+ struct touchscreen_data *ts = ts_data;
2941+
2942+ if(irq == ts->irq /* && !irqblock */) {
2943+ irqblock = 1;
2944+
2945+ /*
2946+ * Disable the pen interrupt. It's reenabled when the user lifts the
2947+ * pen.
2948+ */
2949+ disable_irq(ts->irq);
2950+
2951+ if (ts->state == STATE_WAIT_FOR_TOUCH) {
2952+ ts->state = STATE_SAMPLING;
2953+ start_read(ts);
2954+ } else {
2955+ /* Shouldn't happen */
2956+ printk(KERN_ERR "Unexpected ts interrupt\n");
2957+ }
2958+
2959+ }
2960+ return IRQ_HANDLED;
2961+}
2962+
2963+static void
2964+ssp_init(int port, int clock)
2965+{
2966+
2967+ pxa_set_cken(clock, 0);
2968+
2969+ pxa_gpio_mode(GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_CLK_MD);
2970+ pxa_gpio_mode(GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_FRM_MD);
2971+ pxa_gpio_mode(GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_DO_MD);
2972+ pxa_gpio_mode(GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_DI_MD);
2973+
2974+ SET_HTCUNIVERSAL_GPIO(SPI_FRM,1);
2975+
2976+ /* *** Set up the SPI Registers *** */
2977+ SSCR0_P(port) =
2978+ SSCR0_EDSS /* Extended Data Size Select */
2979+ | SSCR0_SerClkDiv(7) /* Serial Clock Rate */
2980+ /* Synchronous Serial Enable (Disable for now) */
2981+ | SSCR0_Motorola /* Motorola SPI Interface */
2982+ | SSCR0_DataSize(8) /* Data Size Select (24-bit) */
2983+ ;
2984+ SSCR1_P(port) = 0;
2985+ SSPSP_P(port) = 0;
2986+
2987+ /* Clear the Status */
2988+ SSSR_P(port) = SSSR_P(port) & 0x00fcfffc;
2989+
2990+ /* Now enable it */
2991+ SSCR0_P(port) =
2992+ SSCR0_EDSS /* Extended Data Size Select */
2993+ | SSCR0_SerClkDiv(7) /* Serial Clock Rate */
2994+ | SSCR0_SSE /* Synchronous Serial Enable */
2995+ | SSCR0_Motorola /* Motorola SPI Interface */
2996+ | SSCR0_DataSize(8) /* Data Size Select (24-bit) */
2997+ ;
2998+
2999+ pxa_set_cken(clock, 1);
3000+}
3001+
3002+static void
3003+start_read(struct touchscreen_data *touch)
3004+{
3005+ unsigned long inc = (poll_sample_time * HZ) / 1000;
3006+ int i;
3007+
3008+ /* Write here to the serial port. We request X and Y only for now.
3009+ * Then we have to wait for poll_sample_time before we read out the serial
3010+ * port. Then, when we read it out, we check to see if the pen is still
3011+ * down. If so, then we issue another request here.
3012+ */
3013+#define TS_SAMPLES 7
3014+
3015+ /*
3016+ * We do four samples for each, and throw out the highest and lowest, then
3017+ * average the other two.
3018+ */
3019+
3020+ for(i = 0; i < TS_SAMPLES; i++) {
3021+ while(!(SSSR_P(touch->port) & SSSR_TNF))
3022+ ;
3023+ /* It's not full. Write the command for X */
3024+ SSDR_P(touch->port) = (TSC2046_SAMPLE_X|(touch->pwrbit_X))<<16;
3025+ }
3026+
3027+ for(i = 0; i < TS_SAMPLES; i++) {
3028+ while(!(SSSR_P(touch->port) & SSSR_TNF))
3029+ ;
3030+ /* It's not full. Write the command for Y */
3031+ SSDR_P(touch->port) = (TSC2046_SAMPLE_Y|(touch->pwrbit_Y))<<16;
3032+ }
3033+
3034+ /*
3035+ * Enable the timer. We should get an interrupt, but we want keep a timer
3036+ * to ensure that we can detect missing data
3037+ */
3038+ mod_timer(&touch->timer, jiffies + inc);
3039+}
3040+
3041+static void
3042+ts_timer_callback(unsigned long data)
3043+{
3044+ struct touchscreen_data *ts = (struct touchscreen_data *)data;
3045+ int x, a[TS_SAMPLES], y;
3046+ static int oldx, oldy;
3047+ int ssrval;
3048+
3049+ /*
3050+ * Check here to see if there is anything in the SPI FIFO. If so,
3051+ * return it if there has been a change. If not, then we have a
3052+ * timeout. Generate an erro somehow.
3053+ */
3054+ ssrval = SSSR_P(ts->port);
3055+
3056+ if(ssrval & SSSR_RNE) { /* Look at Rx Not Empty bit */
3057+ int number_of_entries_in_fifo;
3058+
3059+ /* The FIFO is not emtpy. Good! Now make sure there are at least two
3060+ * entries. (Should be two exactly.) */
3061+
3062+ number_of_entries_in_fifo = ((ssrval >> 12) & 0xf) + 1;
3063+
3064+ if(number_of_entries_in_fifo < TS_SAMPLES * 2) {
3065+ /* Not ready yet. Come back later. */
3066+ unsigned long inc = (poll_sample_time * HZ) / 1000;
3067+ mod_timer(&ts->timer, jiffies + inc);
3068+ return;
3069+ }
3070+
3071+ if(number_of_entries_in_fifo == TS_SAMPLES * 2) {
3072+ int i, j;
3073+
3074+ for(i = 0; i < TS_SAMPLES; i++) {
3075+ a[i] = SSDR_P(ts->port);
3076+ }
3077+ /* Sort them (bubble) */
3078+ for(j = TS_SAMPLES - 1; j > 0; j--) {
3079+ for(i = 0; i < j; i++) {
3080+ if(a[i] > a[i + 1]) {
3081+ int tmp;
3082+ tmp = a[i+1];
3083+ a[i+1] = a[i];
3084+ a[i] = tmp;
3085+ }
3086+ }
3087+ }
3088+
3089+ /* Take the average of the middle two */
3090+ /* x = (a[TS_SAMPLES/2 - 1] + a[TS_SAMPLES/2] + a[TS_SAMPLES/2+1] + a[TS_SAMPLES/2+2]) >> 2; */
3091+ x = a[TS_SAMPLES/2];
3092+
3093+ for(i = 0; i < TS_SAMPLES; i++) {
3094+ a[i] = SSDR_P(ts->port);
3095+ }
3096+ /* Sort them (bubble) */
3097+ for(j = TS_SAMPLES - 1; j > 0; j--) {
3098+ for(i = 0; i < j; i++) {
3099+ if(a[i] > a[i + 1]) {
3100+ int tmp;
3101+ tmp = a[i+1];
3102+ a[i+1] = a[i];
3103+ a[i] = tmp;
3104+ }
3105+ }
3106+ }
3107+
3108+
3109+ /* Take the average of the middle two */
3110+ /* y = (a[TS_SAMPLES/2 - 1] + a[TS_SAMPLES/2] + a[TS_SAMPLES/2+1] + a[TS_SAMPLES/2+2]) >> 2; */
3111+ y = a[TS_SAMPLES/2];
3112+ } else {
3113+ /* We have an error! Too many entries. */
3114+ printk(KERN_ERR "TS: Expected %d entries. Got %d\n", TS_SAMPLES*2, number_of_entries_in_fifo);
3115+ /* Try to clear the FIFO */
3116+ while(number_of_entries_in_fifo--) {
3117+ (void)SSDR_P(ts->port);
3118+ }
3119+
3120+ if (ts->pen_down())
3121+ start_read(ts);
3122+
3123+ return;
3124+ }
3125+ } else {
3126+ /* Not ready yet. Come back later. */
3127+ unsigned long inc = (poll_sample_time * HZ) / 1000;
3128+ mod_timer(&ts->timer, jiffies + inc);
3129+ return;
3130+ }
3131+
3132+ /*
3133+ * Now we check to see if the pen is still down. If it is, then call
3134+ * start_read().
3135+ */
3136+ if (ts->pen_down())
3137+ {
3138+ /* Still down */
3139+ if(oldx != x || oldy != y) {
3140+ oldx = x;
3141+ oldy = y;
3142+ report_touchpanel(ts, 1, x, y);
3143+ }
3144+ start_read(ts);
3145+ } else {
3146+ /* Up */
3147+ report_touchpanel(ts, 0, 0, 0);
3148+ irqblock = 0;
3149+ ts->state = STATE_WAIT_FOR_TOUCH;
3150+ /* Re-enable pen down interrupt */
3151+ enable_irq(ts->irq);
3152+ }
3153+}
3154+
3155+static int pen_down(void)
3156+{
3157+ return ( asic3_get_gpio_status_a( &htcuniversal_asic3.dev ) & (1<<GPIOA_TOUCHSCREEN_N)) == 0 ;
3158+}
3159+
3160+static int
3161+ts_probe (struct platform_device *dev)
3162+{
3163+ int retval;
3164+ struct touchscreen_data *ts;
3165+ struct tsc2046_mach_info *mach = dev->dev.platform_data;
3166+
3167+ printk("htcuniversal: ts_probe\n");
3168+
3169+ ts = ts_data = kmalloc (sizeof (*ts), GFP_KERNEL);
3170+ if (ts == NULL) {
3171+ printk( KERN_NOTICE "htcuniversal_ts: unable to allocate memory\n" );
3172+ return -ENOMEM;
3173+ }
3174+ memset (ts, 0, sizeof (*ts));
3175+
3176+ ts->input = input_allocate_device();
3177+ if (ts->input == NULL) {
3178+ printk( KERN_NOTICE "htcuniversal_ts: unable to allocation touchscreen input\n" );
3179+ kfree(ts);
3180+ return -ENOMEM;
3181+ }
3182+ ts->input->evbit[0] = BIT(EV_ABS);
3183+ ts->input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
3184+ ts->input->absmin[ABS_X] = 0;
3185+ ts->input->absmax[ABS_X] = 32767;
3186+ ts->input->absmin[ABS_Y] = 0;
3187+ ts->input->absmax[ABS_Y] = 32767;
3188+ ts->input->absmin[ABS_PRESSURE] = 0;
3189+ ts->input->absmax[ABS_PRESSURE] = 1;
3190+
3191+ ts->input->name = "htcuniversal_ts";
3192+ ts->input->phys = "touchscreen/htcuniversal_ts";
3193+ ts->input->private = ts;
3194+
3195+ input_register_device(ts->input);
3196+
3197+ ts->timer.function = ts_timer_callback;
3198+ ts->timer.data = (unsigned long)ts;
3199+ ts->state = STATE_WAIT_FOR_TOUCH;
3200+ init_timer (&ts->timer);
3201+
3202+ platform_set_drvdata(dev, ts);
3203+
3204+ ts->port=-1;
3205+
3206+ if (mach) {
3207+ ts->port = mach->port;
3208+ ts->clock = mach->clock;
3209+ ts->pwrbit_X = mach->pwrbit_X;
3210+ ts->pwrbit_Y = mach->pwrbit_Y;
3211+
3212+ /* static irq */
3213+ if (mach->irq)
3214+ ts->irq = mach->irq;
3215+
3216+ if (mach->pen_down)
3217+ ts->pen_down=mach->pen_down;
3218+ }
3219+
3220+ if (ts->port == -1)
3221+ {
3222+ printk("tsc2046: your device is not supported by this driver\n");
3223+ return -ENODEV;
3224+ }
3225+
3226+ /* *** Initialize the SSP interface *** */
3227+ ssp_init(ts->port, ts->clock);
3228+
3229+ while(!(SSSR_P(ts->port) & SSSR_TNF))
3230+ ;
3231+ SSDR_P(ts->port) = (TSC2046_SAMPLE_X|(ts->pwrbit_X))<<16;
3232+
3233+ for(retval = 0; retval < 100; retval++) {
3234+ if(SSSR_P(ts->port) & SSSR_RNE) {
3235+ while(SSSR_P(ts->port) & SSSR_RNE) {
3236+ (void)SSDR_P(ts->port);
3237+ }
3238+ break;
3239+ }
3240+ mdelay(1);
3241+ }
3242+
3243+ if (machine_is_htcuniversal() )
3244+ {
3245+ ts->irq = asic3_irq_base( &htcuniversal_asic3.dev ) + ASIC3_GPIOA_IRQ_BASE + GPIOA_TOUCHSCREEN_N;
3246+ ts->pen_down=pen_down;
3247+ }
3248+
3249+ retval = request_irq(ts->irq, pen_isr, IRQF_DISABLED, "tsc2046_ts", ts);
3250+ if(retval) {
3251+ printk("Unable to get interrupt\n");
3252+ input_unregister_device (ts->input);
3253+ return -ENODEV;
3254+ }
3255+ set_irq_type(ts->irq, IRQ_TYPE_EDGE_FALLING);
3256+
3257+ return 0;
3258+}
3259+
3260+static int
3261+ts_remove (struct platform_device *dev)
3262+{
3263+ struct touchscreen_data *ts = platform_get_drvdata(dev);
3264+
3265+ input_unregister_device (ts->input);
3266+ del_timer_sync (&ts->timer);
3267+ free_irq (ts->irq, ts);
3268+ pxa_set_cken(ts->clock, 0);
3269+
3270+ kfree(ts);
3271+ return 0;
3272+}
3273+
3274+static int
3275+ts_suspend (struct platform_device *dev, pm_message_t state)
3276+{
3277+ struct touchscreen_data *ts = platform_get_drvdata(dev);
3278+
3279+ disable_irq(ts->irq);
3280+
3281+ printk("htcuniversal_ts2_suspend: called.\n");
3282+ return 0;
3283+}
3284+
3285+static int
3286+ts_resume (struct platform_device *dev)
3287+{
3288+ struct touchscreen_data *ts = platform_get_drvdata(dev);
3289+
3290+ ts->state = STATE_WAIT_FOR_TOUCH;
3291+ ssp_init(ts->port, ts->clock);
3292+ enable_irq(ts->irq);
3293+
3294+ printk("htcuniversal_ts2_resume: called.\n");
3295+ return 0;
3296+}
3297+
3298+static struct platform_driver ts_driver = {
3299+ .probe = ts_probe,
3300+ .remove = ts_remove,
3301+ .suspend = ts_suspend,
3302+ .resume = ts_resume,
3303+ .driver = {
3304+ .name = "htcuniversal_ts",
3305+ },
3306+};
3307+
3308+
3309+static int
3310+ts_module_init (void)
3311+{
3312+ printk(KERN_NOTICE "HTC Universal Touch Screen Driver\n");
3313+
3314+ return platform_driver_register(&ts_driver);
3315+}
3316+
3317+static void
3318+ts_module_cleanup (void)
3319+{
3320+ platform_driver_unregister (&ts_driver);
3321+}
3322+
3323+module_init(ts_module_init);
3324+module_exit(ts_module_cleanup);
3325+
3326+MODULE_LICENSE("GPL");
3327+MODULE_AUTHOR("Aric Blumer, SDG Systems, LLC");
3328+MODULE_DESCRIPTION("HTC Universal Touch Screen Driver");
3329Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_udc.c
3330===================================================================
3331--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3332+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/htcuniversal_udc.c 2008-06-01 18:49:45.000000000 +0100
3333@@ -0,0 +1,71 @@
3334+
3335+/*
3336+ *
3337+ * htcuniversal_udc.c:
3338+ * htcuniversal specific code for the pxa27x usb device controller.
3339+ *
3340+ * Use consistent with the GNU GPL is permitted.
3341+ *
3342+ */
3343+
3344+#include <linux/module.h>
3345+#include <linux/init.h>
3346+#include <linux/platform_device.h>
3347+#include <asm/arch/hardware.h>
3348+#include <asm/arch/pxa-regs.h>
3349+#include <asm/arch/udc.h>
3350+#include <linux/soc/asic3_base.h>
3351+#include <asm/arch/htcuniversal-gpio.h>
3352+#include <asm/arch/htcuniversal-asic.h>
3353+
3354+static void htcuniversal_udc_command(int cmd)
3355+{
3356+ switch (cmd) {
3357+ case PXA2XX_UDC_CMD_DISCONNECT:
3358+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev,
3359+ 1<<GPIOB_USB_PUEN, 0);
3360+// SET_HTCUNIVERSAL_GPIO(USB_PUEN,0);
3361+ break;
3362+ case PXA2XX_UDC_CMD_CONNECT:
3363+ asic3_set_gpio_out_b(&htcuniversal_asic3.dev,
3364+ 1<<GPIOB_USB_PUEN, 1<<GPIOB_USB_PUEN);
3365+// SET_HTCUNIVERSAL_GPIO(USB_PUEN,1);
3366+ break;
3367+ default:
3368+ printk("_udc_control: unknown command!\n");
3369+ break;
3370+ }
3371+}
3372+
3373+static int htcuniversal_udc_is_connected(void)
3374+{
3375+ return (GET_HTCUNIVERSAL_GPIO(USB_DET) != 0);
3376+}
3377+
3378+static struct pxa2xx_udc_mach_info htcuniversal_udc_info __initdata = {
3379+ .udc_is_connected = htcuniversal_udc_is_connected,
3380+ .udc_command = htcuniversal_udc_command,
3381+};
3382+
3383+static int htcuniversal_udc_probe(struct platform_device * dev)
3384+{
3385+ asic3_set_gpio_dir_b(&htcuniversal_asic3.dev, 1<<GPIOB_USB_PUEN, 1<<GPIOB_USB_PUEN);
3386+
3387+ pxa_set_udc_info(&htcuniversal_udc_info);
3388+ return 0;
3389+}
3390+
3391+static struct platform_driver htcuniversal_udc_driver = {
3392+ .driver = {
3393+ .name = "htcuniversal_udc",
3394+ },
3395+ .probe = htcuniversal_udc_probe,
3396+};
3397+
3398+static int __init htcuniversal_udc_init(void)
3399+{
3400+ return platform_driver_register(&htcuniversal_udc_driver);
3401+}
3402+
3403+module_init(htcuniversal_udc_init);
3404+MODULE_LICENSE("GPL");
3405Index: linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/tsc2046_ts.h
3406===================================================================
3407--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3408+++ linux-2.6.26-rc4/arch/arm/mach-pxa/htcuniversal/tsc2046_ts.h 2008-06-01 18:49:45.000000000 +0100
3409@@ -0,0 +1,20 @@
3410+/*
3411+ * temporary TSC2046 touchscreen hack
3412+ */
3413+
3414+#ifndef _TSC2046_TS_H
3415+#define _TSC2046_TS_H
3416+
3417+struct tsc2046_mach_info {
3418+ int port;
3419+ int clock;
3420+ int pwrbit_X;
3421+ int pwrbit_Y;
3422+ int irq;
3423+ int (*pen_down)(void);
3424+};
3425+
3426+#define TSC2046_SAMPLE_X 0xd0
3427+#define TSC2046_SAMPLE_Y 0x90
3428+
3429+#endif
3430Index: linux-2.6.26-rc4/arch/arm/mach-pxa/Kconfig
3431===================================================================
3432--- linux-2.6.26-rc4.orig/arch/arm/mach-pxa/Kconfig 2008-06-01 18:49:43.000000000 +0100
3433+++ linux-2.6.26-rc4/arch/arm/mach-pxa/Kconfig 2008-06-01 18:49:45.000000000 +0100
3434@@ -147,6 +147,14 @@
3435 select PXA27x
3436 select IWMMXT
3437
3438+config MACH_HTCUNIVERSAL
3439+ bool "HTC Universal"
3440+ select PXA27x
3441+ help
3442+ Say Y here if you intend to run this kernel on a
3443+ HTC Universal. Currently there is only basic support
3444+ for this PDA.
3445+
3446 endchoice
3447
3448 choice
3449@@ -204,6 +212,86 @@
3450
3451 endif
3452
3453+if MACH_HTCUNIVERSAL
3454+
3455+menu "HTC Universal support"
3456+
3457+config HTCUNIVERSAL_CORE
3458+ tristate "HTC Universal core"
3459+ depends on MACH_HTCUNIVERSAL
3460+ help
3461+ This selection enables HTC Universal core support.
3462+
3463+config HTCUNIVERSAL_UDC
3464+ bool "USB Device Controller support"
3465+ depends on MACH_HTCUNIVERSAL && HTC_ASIC3 && USB_PXA27X
3466+ help
3467+ Enables HTC Universal specific USB detection
3468+
3469+config HTCUNIVERSAL_POWER
3470+ tristate "HTC Universal power"
3471+ depends on MACH_HTCUNIVERSAL && HTC_ASIC3
3472+ help
3473+ This selection enables HTC Universal power monitoring
3474+ hardware support (through ASIC3).
3475+
3476+config HTCUNIVERSAL_BACKLIGHT
3477+ bool "HTC Universal Backlight"
3478+ depends on MACH_HTCUNIVERSAL && HTC_ASIC3 && BACKLIGHT_CLASS_DEVICE
3479+ help
3480+ This driver provides support for changing power and brightness
3481+ on HTC Universal LCD backlight.
3482+
3483+config HTCUNIVERSAL_LCD
3484+ tristate "HTC Universal LCD"
3485+ depends on MACH_HTCUNIVERSAL && HTC_ASIC3 && LCD_CLASS_DEVICE
3486+ help
3487+ This driver provides support for changing power and brightness
3488+ on HTC Universal LCD display.
3489+
3490+config HTCUNIVERSAL_TS2
3491+ tristate "HTC Universal Touchscreen (old)"
3492+ depends on MACH_HTCUNIVERSAL && HTC_ASIC3
3493+ help
3494+ Enable support for the HTC Universal Touchscreen Panel.
3495+
3496+config HTCUNIVERSAL_BUTTONS
3497+ tristate "HTC Universal buttons support"
3498+ depends on MACH_HTCUNIVERSAL && HTC_ASIC3
3499+
3500+config HTCUNIVERSAL_BLUETOOTH
3501+ tristate "HTC Universal Bluetooth"
3502+ depends on MACH_HTCUNIVERSAL && HTCUNIVERSAL_CORE && HTC_ASIC3
3503+ help
3504+ Enables support for the TI BRF6150 Bluetooth Module
3505+ in the HTC Universal.
3506+
3507+config HTCUNIVERSAL_ASIC3_LEDS
3508+ tristate "HTC Universal ASIC3 LED support"
3509+ select LEDS_ASIC3
3510+ depends on MACH_HTCUNIVERSAL && HTCUNIVERSAL_CORE && HTC_ASIC3
3511+ ---help---
3512+ Support for right (colors red+green+(amber)) and left (green+blue) led
3513+ Off/on hook keys LED backlight
3514+ Keyboard backlight
3515+ Vibra
3516+ Flashlight
3517+
3518+config HTCUNIVERSAL_PHONE
3519+ tristate "HTC Universal Phone"
3520+ depends on MACH_HTCUNIVERSAL && HTCUNIVERSAL_CORE && HTC_ASIC3
3521+ help
3522+ Enables support for the Qualcomm MSM6520 Phone Module
3523+ in the HTC Universal.
3524+
3525+config HTCUNIVERSAL_AK4641
3526+ depends on SND && I2C
3527+ tristate "AK4641 chipset support"
3528+
3529+endmenu
3530+
3531+endif
3532+
3533 endmenu
3534
3535 config MACH_POODLE
3536@@ -289,4 +377,3 @@
3537 depends on (PXA25x || PXA27x) && INPUT
3538
3539 endif
3540-
3541Index: linux-2.6.26-rc4/arch/arm/mach-pxa/Makefile
3542===================================================================
3543--- linux-2.6.26-rc4.orig/arch/arm/mach-pxa/Makefile 2008-06-01 18:49:43.000000000 +0100
3544+++ linux-2.6.26-rc4/arch/arm/mach-pxa/Makefile 2008-06-01 18:50:46.000000000 +0100
3545@@ -36,6 +36,7 @@
3546 obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o
3547 obj-$(CONFIG_MACH_TOSA) += tosa.o
3548 obj-$(CONFIG_MACH_EM_X270) += em-x270.o
3549+obj-$(CONFIG_MACH_HTCUNIVERSAL) += htcuniversal/
3550 obj-$(CONFIG_MACH_MAGICIAN) += magician.o
3551 obj-$(CONFIG_ARCH_PXA_ESERIES) += eseries.o
3552
3553Index: linux-2.6.26-rc4/drivers/leds/Kconfig
3554===================================================================
3555--- linux-2.6.26-rc4.orig/drivers/leds/Kconfig 2008-05-26 19:08:11.000000000 +0100
3556+++ linux-2.6.26-rc4/drivers/leds/Kconfig 2008-06-01 18:49:45.000000000 +0100
3557@@ -147,6 +147,13 @@
3558 To compile this driver as a module, choose M here: the
3559 module will be called leds-clevo-mail.
3560
3561+config LEDS_ASIC3
3562+ tristate "LED Support for the HTC ASIC3 chip"
3563+ depends on LEDS_CLASS && HTC_ASIC3
3564+ help
3565+ This option enables support for the LEDs connected to the
3566+ HTC ASIC3 chip.
3567+
3568 comment "LED Triggers"
3569
3570 config LEDS_TRIGGERS
3571Index: linux-2.6.26-rc4/drivers/leds/leds-asic3.c
3572===================================================================
3573--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3574+++ linux-2.6.26-rc4/drivers/leds/leds-asic3.c 2008-06-01 18:49:45.000000000 +0100
3575@@ -0,0 +1,189 @@
3576+/*
3577+ * LEDs support for HTC ASIC3 devices.
3578+ *
3579+ * Copyright (c) 2006 Anton Vorontsov <cbou@mail.ru>
3580+ *
3581+ * This file is subject to the terms and conditions of the GNU General Public
3582+ * License. See the file COPYING in the main directory of this archive for
3583+ * more details.
3584+ *
3585+ */
3586+
3587+#include <linux/kernel.h>
3588+#include <linux/init.h>
3589+#include <linux/platform_device.h>
3590+#include <linux/leds.h>
3591+#include "leds.h"
3592+
3593+#include <asm/hardware/ipaq-asic3.h>
3594+#include <linux/soc/asic3_base.h>
3595+#include <asm/mach-types.h>
3596+#include <asm/hardware/asic3_leds.h>
3597+
3598+#ifdef DEBUG
3599+#define dbg(msg, ...) printk(msg, __VA_ARGS__)
3600+#else
3601+#define dbg(msg, ...)
3602+#endif
3603+
3604+static
3605+void asic3_leds_set(struct led_classdev *led_cdev, enum led_brightness b)
3606+{
3607+ struct asic3_led *led = container_of(led_cdev, struct asic3_led,
3608+ led_cdev);
3609+ struct asic3_leds_machinfo *machinfo = led->machinfo;
3610+ struct device *asic3_dev = &machinfo->asic3_pdev->dev;
3611+
3612+ dbg("%s:%s %d(%d)-%s %d\n", __FILE__, __FUNCTION__, led->hw_num,
3613+ led->gpio_num, led->led_cdev.name, b);
3614+
3615+ if (led->hw_num == -1) {
3616+ asic3_gpio_set_value(asic3_dev, led->gpio_num, b);
3617+ return;
3618+ }
3619+
3620+ if (b == LED_OFF) {
3621+ asic3_set_led(asic3_dev, led->hw_num, 0, 16, 6);
3622+ asic3_set_gpio_out_c(asic3_dev, led->hw_num, 0);
3623+ }
3624+ else {
3625+ asic3_set_gpio_out_c(asic3_dev, led->hw_num, led->hw_num);
3626+ #ifdef CONFIG_LEDS_TRIGGER_HWTIMER
3627+ if (led_cdev->trigger && led_cdev->trigger->is_led_supported &&
3628+ (led_cdev->trigger->is_led_supported(led_cdev) &
3629+ LED_SUPPORTS_HWTIMER)) {
3630+ struct hwtimer_data *td = led_cdev->trigger_data;
3631+ if (!td) return;
3632+ asic3_set_led(asic3_dev, led->hw_num, td->delay_on/8,
3633+ (td->delay_on + td->delay_off)/8, 6);
3634+ }
3635+ else
3636+ #endif
3637+ asic3_set_led(asic3_dev, led->hw_num, 16, 16, 6);
3638+ }
3639+
3640+ return;
3641+}
3642+
3643+static
3644+int asic3_leds_probe(struct platform_device *pdev)
3645+{
3646+ struct asic3_leds_machinfo *machinfo = pdev->dev.platform_data;
3647+ struct asic3_led *leds = machinfo->leds;
3648+ int ret, i = 0;
3649+
3650+ dbg("%s:%s\n", __FILE__, __FUNCTION__);
3651+
3652+ // Turn on clocks early, for the case if trigger would enable
3653+ // led immediately after led_classdev_register().
3654+ asic3_set_clock_cdex(&machinfo->asic3_pdev->dev,
3655+ CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2,
3656+ CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2);
3657+
3658+ for (i = 0; i < machinfo->num_leds; i++) {
3659+ leds[i].machinfo = machinfo;
3660+ leds[i].led_cdev.brightness_set = asic3_leds_set;
3661+ ret = led_classdev_register(&pdev->dev, &leds[i].led_cdev);
3662+ if (ret) {
3663+ printk(KERN_ERR "Error: can't register %s led\n",
3664+ leds[i].led_cdev.name);
3665+ goto out_err;
3666+ }
3667+ }
3668+
3669+ return 0;
3670+
3671+out_err:
3672+ while (--i >= 0) led_classdev_unregister(&leds[i].led_cdev);
3673+
3674+ asic3_set_clock_cdex(&machinfo->asic3_pdev->dev,
3675+ CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2,
3676+ 0 | 0 | 0);
3677+
3678+ return ret;
3679+}
3680+
3681+static
3682+int asic3_leds_remove(struct platform_device *pdev)
3683+{
3684+ struct asic3_leds_machinfo *machinfo = pdev->dev.platform_data;
3685+ struct asic3_led *leds = machinfo->leds;
3686+ int i = 0;
3687+
3688+ dbg("%s:%s\n", __FILE__, __FUNCTION__);
3689+
3690+ for (i = 0; i < machinfo->num_leds; i++)
3691+ led_classdev_unregister(&leds[i].led_cdev);
3692+
3693+ asic3_set_clock_cdex(&machinfo->asic3_pdev->dev,
3694+ CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2,
3695+ 0 | 0 | 0);
3696+
3697+ return 0;
3698+}
3699+
3700+#ifdef CONFIG_PM
3701+
3702+static
3703+int asic3_leds_suspend(struct platform_device *pdev, pm_message_t state)
3704+{
3705+ struct asic3_leds_machinfo *machinfo = pdev->dev.platform_data;
3706+ struct asic3_led *leds = machinfo->leds;
3707+ int i = 0;
3708+
3709+ dbg("%s:%s\n", __FILE__, __FUNCTION__);
3710+
3711+ for (i = 0; i < machinfo->num_leds; i++)
3712+ led_classdev_suspend(&leds[i].led_cdev);
3713+
3714+ return 0;
3715+}
3716+
3717+static
3718+int asic3_leds_resume(struct platform_device *pdev)
3719+{
3720+ struct asic3_leds_machinfo *machinfo = pdev->dev.platform_data;
3721+ struct asic3_led *leds = machinfo->leds;
3722+ int i = 0;
3723+
3724+ dbg("%s:%s\n", __FILE__, __FUNCTION__);
3725+
3726+ for (i = 0; i < machinfo->num_leds; i++)
3727+ led_classdev_resume(&leds[i].led_cdev);
3728+
3729+ return 0;
3730+}
3731+
3732+#endif
3733+
3734+static
3735+struct platform_driver asic3_leds_driver = {
3736+ .probe = asic3_leds_probe,
3737+ .remove = asic3_leds_remove,
3738+#ifdef CONFIG_PM
3739+ .suspend = asic3_leds_suspend,
3740+ .resume = asic3_leds_resume,
3741+#endif
3742+ .driver = {
3743+ .name = "asic3-leds",
3744+ },
3745+};
3746+
3747+int asic3_leds_register(void)
3748+{
3749+ dbg("%s:%s\n", __FILE__, __FUNCTION__);
3750+ return platform_driver_register(&asic3_leds_driver);
3751+}
3752+
3753+void asic3_leds_unregister(void)
3754+{
3755+ platform_driver_unregister(&asic3_leds_driver);
3756+ return;
3757+}
3758+
3759+EXPORT_SYMBOL_GPL(asic3_leds_register);
3760+EXPORT_SYMBOL_GPL(asic3_leds_unregister);
3761+
3762+MODULE_AUTHOR("Anton Vorontsov <cbou@mail.ru>");
3763+MODULE_DESCRIPTION("HTC ASIC3 LEDs driver");
3764+MODULE_LICENSE("GPL");
3765Index: linux-2.6.26-rc4/drivers/mfd/Kconfig
3766===================================================================
3767--- linux-2.6.26-rc4.orig/drivers/mfd/Kconfig 2008-06-01 18:49:43.000000000 +0100
3768+++ linux-2.6.26-rc4/drivers/mfd/Kconfig 2008-06-01 18:49:45.000000000 +0100
3769@@ -44,6 +44,16 @@
3770 help
3771 Support for TI TSC2101 Touchscreen and Audio Codec
3772
3773+config HTC_ASIC3
3774+ tristate "HTC ASIC3 (iPAQ h1900/h3900/h4000/hx4700/rx3000) support"
3775+
3776+config HTC_ASIC3_DS1WM
3777+ bool "Support HTC ASIC3 builtin DS1WM block"
3778+ help
3779+ Choose Y here if you want to include support for ASIC3's builtin
3780+ W1 controller. Some devices do not use it, and yet other have
3781+ separate DS1WM controller. For them, choose N.
3782+
3783 endmenu
3784
3785 menu "Multimedia Capabilities Port drivers"
3786Index: linux-2.6.26-rc4/drivers/mfd/Makefile
3787===================================================================
3788--- linux-2.6.26-rc4.orig/drivers/mfd/Makefile 2008-06-01 18:49:43.000000000 +0100
3789+++ linux-2.6.26-rc4/drivers/mfd/Makefile 2008-06-01 18:49:45.000000000 +0100
3790@@ -2,6 +2,8 @@
3791 # Makefile for multifunction miscellaneous devices
3792 #
3793
3794+obj-$(CONFIG_HTC_ASIC3) += asic3_base.o soc-core.o
3795+
3796 obj-$(CONFIG_MFD_SM501) += sm501.o
3797 obj-$(CONFIG_MFD_ASIC3) += asic3.o
3798
3799Index: linux-2.6.26-rc4/drivers/mfd/asic3_base.c
3800===================================================================
3801--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3802+++ linux-2.6.26-rc4/drivers/mfd/asic3_base.c 2008-06-01 18:49:45.000000000 +0100
3803@@ -0,0 +1,1208 @@
3804+/*
3805+ * Driver interface to HTC "ASIC3"
3806+ *
3807+ * Copyright 2001 Compaq Computer Corporation.
3808+ * Copyright 2004-2005 Phil Blundell
3809+ *
3810+ * This program is free software; you can redistribute it and/or modify
3811+ * it under the terms of the GNU General Public License as published by
3812+ * the Free Software Foundation; either version 2 of the License, or
3813+ * (at your option) any later version.
3814+ *
3815+ * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
3816+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
3817+ * FITNESS FOR ANY PARTICULAR PURPOSE.
3818+ *
3819+ * Author: Andrew Christian
3820+ * <Andrew.Christian@compaq.com>
3821+ * October 2001
3822+ */
3823+
3824+#include <linux/module.h>
3825+#include <linux/version.h>
3826+#include <linux/platform_device.h>
3827+#include <linux/delay.h>
3828+#include <linux/init.h>
3829+#include <linux/irq.h>
3830+#include <linux/clk.h>
3831+#include <linux/ds1wm.h>
3832+#include <asm/arch/clock.h>
3833+
3834+#include <asm/hardware.h>
3835+#include <asm/irq.h>
3836+#include <asm/io.h>
3837+
3838+#include <asm/hardware/ipaq-asic3.h>
3839+#include <linux/soc/asic3_base.h>
3840+#include <linux/soc/tmio_mmc.h>
3841+#include "soc-core.h"
3842+
3843+
3844+struct asic3_data {
3845+ void *mapping;
3846+ unsigned int bus_shift;
3847+ int irq_base;
3848+ int irq_nr;
3849+
3850+ u16 irq_bothedge[4];
3851+ struct device *dev;
3852+
3853+ struct platform_device *mmc_dev;
3854+};
3855+
3856+static DEFINE_SPINLOCK(asic3_gpio_lock);
3857+
3858+static int asic3_remove(struct platform_device *dev);
3859+
3860+static inline unsigned long asic3_address(struct device *dev,
3861+ unsigned int reg)
3862+{
3863+ struct asic3_data *adata;
3864+
3865+ adata = (struct asic3_data *)dev->driver_data;
3866+
3867+ return (unsigned long)adata->mapping + (reg >> (2 - adata->bus_shift));
3868+}
3869+
3870+void asic3_write_register(struct device *dev, unsigned int reg, u32 value)
3871+{
3872+ __raw_writew(value, asic3_address(dev, reg));
3873+}
3874+EXPORT_SYMBOL(asic3_write_register);
3875+
3876+u32 asic3_read_register(struct device *dev, unsigned int reg)
3877+{
3878+ return __raw_readw(asic3_address(dev, reg));
3879+}
3880+EXPORT_SYMBOL(asic3_read_register);
3881+
3882+static inline void __asic3_write_register(struct asic3_data *asic,
3883+ unsigned int reg, u32 value)
3884+{
3885+ __raw_writew(value, (unsigned long)asic->mapping
3886+ + (reg >> (2 - asic->bus_shift)));
3887+}
3888+
3889+static inline u32 __asic3_read_register(struct asic3_data *asic,
3890+ unsigned int reg)
3891+{
3892+ return __raw_readw((unsigned long)asic->mapping
3893+ + (reg >> (2 - asic->bus_shift)));
3894+}
3895+
3896+#define ASIC3_GPIO_FN(get_fn_name, set_fn_name, REG) \
3897+u32 get_fn_name(struct device *dev) \
3898+{ \
3899+ return asic3_read_register(dev, REG); \
3900+} \
3901+EXPORT_SYMBOL(get_fn_name); \
3902+ \
3903+void set_fn_name(struct device *dev, u32 bits, u32 val) \
3904+{ \
3905+ unsigned long flags; \
3906+ \
3907+ spin_lock_irqsave(&asic3_gpio_lock, flags); \
3908+ val |= (asic3_read_register(dev, REG) & ~bits); \
3909+ asic3_write_register(dev, REG, val); \
3910+ spin_unlock_irqrestore(&asic3_gpio_lock, flags); \
3911+} \
3912+EXPORT_SYMBOL(set_fn_name);
3913+
3914+#define ASIC3_GPIO_REGISTER(ACTION, action, fn, FN) \
3915+ ASIC3_GPIO_FN(asic3_get_gpio_ ## action ## _ ## fn , \
3916+ asic3_set_gpio_ ## action ## _ ## fn , \
3917+ _IPAQ_ASIC3_GPIO_ ## FN ## _Base \
3918+ + _IPAQ_ASIC3_GPIO_ ## ACTION )
3919+
3920+#define ASIC3_GPIO_FUNCTIONS(fn, FN) \
3921+ ASIC3_GPIO_REGISTER(Direction, dir, fn, FN) \
3922+ ASIC3_GPIO_REGISTER(Out, out, fn, FN) \
3923+ ASIC3_GPIO_REGISTER(SleepMask, sleepmask, fn, FN) \
3924+ ASIC3_GPIO_REGISTER(SleepOut, sleepout, fn, FN) \
3925+ ASIC3_GPIO_REGISTER(BattFaultOut, battfaultout, fn, FN) \
3926+ ASIC3_GPIO_REGISTER(AltFunction, alt_fn, fn, FN) \
3927+ ASIC3_GPIO_REGISTER(SleepConf, sleepconf, fn, FN) \
3928+ ASIC3_GPIO_REGISTER(Status, status, fn, FN)
3929+
3930+#if 0
3931+ ASIC3_GPIO_REGISTER(Mask, mask, fn, FN)
3932+ ASIC3_GPIO_REGISTER(TriggerType, trigtype, fn, FN)
3933+ ASIC3_GPIO_REGISTER(EdgeTrigger, rising, fn, FN)
3934+ ASIC3_GPIO_REGISTER(LevelTrigger, triglevel, fn, FN)
3935+ ASIC3_GPIO_REGISTER(IntStatus, intstatus, fn, FN)
3936+#endif
3937+
3938+ASIC3_GPIO_FUNCTIONS(a, A)
3939+ASIC3_GPIO_FUNCTIONS(b, B)
3940+ASIC3_GPIO_FUNCTIONS(c, C)
3941+ASIC3_GPIO_FUNCTIONS(d, D)
3942+
3943+int asic3_gpio_get_value(struct device *dev, unsigned gpio)
3944+{
3945+ u32 mask = ASIC3_GPIO_bit(gpio);
3946+ printk("%s(%d)\n", __FUNCTION__, gpio);
3947+ switch (gpio >> 4) {
3948+ case _IPAQ_ASIC3_GPIO_BANK_A:
3949+ return asic3_get_gpio_status_a(dev) & mask;
3950+ case _IPAQ_ASIC3_GPIO_BANK_B:
3951+ return asic3_get_gpio_status_b(dev) & mask;
3952+ case _IPAQ_ASIC3_GPIO_BANK_C:
3953+ return asic3_get_gpio_status_c(dev) & mask;
3954+ case _IPAQ_ASIC3_GPIO_BANK_D:
3955+ return asic3_get_gpio_status_d(dev) & mask;
3956+ }
3957+
3958+ printk(KERN_ERR "%s: invalid GPIO value 0x%x", __FUNCTION__, gpio);
3959+ return 0;
3960+}
3961+EXPORT_SYMBOL(asic3_gpio_get_value);
3962+
3963+void asic3_gpio_set_value(struct device *dev, unsigned gpio, int val)
3964+{
3965+ u32 mask = ASIC3_GPIO_bit(gpio);
3966+ u32 bitval = 0;
3967+ if (val) bitval = mask;
3968+ printk("%s(%d, %d)\n", __FUNCTION__, gpio, val);
3969+
3970+ switch (gpio >> 4) {
3971+ case _IPAQ_ASIC3_GPIO_BANK_A:
3972+ asic3_set_gpio_out_a(dev, mask, bitval);
3973+ return;
3974+ case _IPAQ_ASIC3_GPIO_BANK_B:
3975+ asic3_set_gpio_out_b(dev, mask, bitval);
3976+ return;
3977+ case _IPAQ_ASIC3_GPIO_BANK_C:
3978+ asic3_set_gpio_out_c(dev, mask, bitval);
3979+ return;
3980+ case _IPAQ_ASIC3_GPIO_BANK_D:
3981+ asic3_set_gpio_out_d(dev, mask, bitval);
3982+ return;
3983+ }
3984+
3985+ printk(KERN_ERR "%s: invalid GPIO value 0x%x", __FUNCTION__, gpio);
3986+}
3987+EXPORT_SYMBOL(asic3_gpio_set_value);
3988+
3989+int asic3_irq_base(struct device *dev)
3990+{
3991+ struct asic3_data *asic = dev->driver_data;
3992+
3993+ return asic->irq_base;
3994+}
3995+EXPORT_SYMBOL(asic3_irq_base);
3996+
3997+static int asic3_gpio_to_irq(struct device *dev, unsigned gpio)
3998+{
3999+ struct asic3_data *asic = dev->driver_data;
4000+ printk("%s(%d)\n", __FUNCTION__, gpio);
4001+
4002+ return asic->irq_base + gpio;
4003+}
4004+
4005+void asic3_set_led(struct device *dev, int led_num, int duty_time,
4006+ int cycle_time, int timebase)
4007+{
4008+ struct asic3_data *asic = dev->driver_data;
4009+ unsigned int led_base;
4010+
4011+ /* it's a macro thing: see #define _IPAQ_ASIC_LED_0_Base for why you
4012+ * can't substitute led_num in the macros below...
4013+ */
4014+
4015+ switch (led_num) {
4016+ case 0:
4017+ led_base = _IPAQ_ASIC3_LED_0_Base;
4018+ break;
4019+ case 1:
4020+ led_base = _IPAQ_ASIC3_LED_1_Base;
4021+ break;
4022+ case 2:
4023+ led_base = _IPAQ_ASIC3_LED_2_Base;
4024+ break;
4025+ default:
4026+ printk(KERN_ERR "%s: invalid led number %d", __FUNCTION__,
4027+ led_num);
4028+ return;
4029+ }
4030+
4031+ __asic3_write_register(asic, led_base + _IPAQ_ASIC3_LED_TimeBase,
4032+ timebase | LED_EN);
4033+ __asic3_write_register(asic, led_base + _IPAQ_ASIC3_LED_PeriodTime,
4034+ cycle_time);
4035+ __asic3_write_register(asic, led_base + _IPAQ_ASIC3_LED_DutyTime,
4036+ 0);
4037+ udelay(20); /* asic voodoo - possibly need a whole duty cycle? */
4038+ __asic3_write_register(asic, led_base + _IPAQ_ASIC3_LED_DutyTime,
4039+ duty_time);
4040+}
4041+EXPORT_SYMBOL(asic3_set_led);
4042+
4043+void asic3_set_clock_sel(struct device *dev, u32 bits, u32 val)
4044+{
4045+ struct asic3_data *asic = dev->driver_data;
4046+ unsigned long flags;
4047+ u32 v;
4048+
4049+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4050+ v = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, SEL));
4051+ v = (v & ~bits) | val;
4052+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, SEL), v);
4053+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4054+}
4055+EXPORT_SYMBOL(asic3_set_clock_sel);
4056+
4057+void asic3_set_clock_cdex(struct device *dev, u32 bits, u32 val)
4058+{
4059+ struct asic3_data *asic = dev->driver_data;
4060+ unsigned long flags;
4061+ u32 v;
4062+
4063+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4064+ v = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX));
4065+ v = (v & ~bits) | val;
4066+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX), v);
4067+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4068+}
4069+EXPORT_SYMBOL(asic3_set_clock_cdex);
4070+
4071+static void asic3_clock_cdex_enable(struct clk *clk)
4072+{
4073+ struct asic3_data *asic = (struct asic3_data *)clk->parent->ctrlbit;
4074+ unsigned long flags, val;
4075+
4076+ local_irq_save(flags);
4077+
4078+ val = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX));
4079+ val |= clk->ctrlbit;
4080+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX), val);
4081+
4082+ local_irq_restore(flags);
4083+}
4084+
4085+static void asic3_clock_cdex_disable(struct clk *clk)
4086+{
4087+ struct asic3_data *asic = (struct asic3_data *)clk->parent->ctrlbit;
4088+ unsigned long flags, val;
4089+
4090+ local_irq_save(flags);
4091+
4092+ val = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX));
4093+ val &= ~clk->ctrlbit;
4094+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX), val);
4095+
4096+ local_irq_restore(flags);
4097+}
4098+
4099+/* base clocks */
4100+
4101+static struct clk clk_g = {
4102+ .name = "gclk",
4103+ .rate = 0,
4104+ .parent = NULL,
4105+};
4106+
4107+/* clock definitions */
4108+
4109+static struct clk asic3_clocks[] = {
4110+ {
4111+ .name = "spi",
4112+ .id = -1,
4113+ .parent = &clk_g,
4114+ .enable = asic3_clock_cdex_enable,
4115+ .disable = asic3_clock_cdex_disable,
4116+ .ctrlbit = CLOCK_CDEX_SPI,
4117+ },
4118+#ifdef CONFIG_HTC_ASIC3_DS1WM
4119+ {
4120+ .name = "ds1wm",
4121+ .id = -1,
4122+ .rate = 5000000,
4123+ .parent = &clk_g,
4124+ .enable = asic3_clock_cdex_enable,
4125+ .disable = asic3_clock_cdex_disable,
4126+ .ctrlbit = CLOCK_CDEX_OWM,
4127+ },
4128+#endif
4129+ {
4130+ .name = "pwm0",
4131+ .id = -1,
4132+ .parent = &clk_g,
4133+ .enable = asic3_clock_cdex_enable,
4134+ .disable = asic3_clock_cdex_disable,
4135+ .ctrlbit = CLOCK_CDEX_PWM0,
4136+ },
4137+ {
4138+ .name = "pwm1",
4139+ .id = -1,
4140+ .parent = &clk_g,
4141+ .enable = asic3_clock_cdex_enable,
4142+ .disable = asic3_clock_cdex_disable,
4143+ .ctrlbit = CLOCK_CDEX_PWM1,
4144+ },
4145+ {
4146+ .name = "led0",
4147+ .id = -1,
4148+ .parent = &clk_g,
4149+ .enable = asic3_clock_cdex_enable,
4150+ .disable = asic3_clock_cdex_disable,
4151+ .ctrlbit = CLOCK_CDEX_LED0,
4152+ },
4153+ {
4154+ .name = "led1",
4155+ .id = -1,
4156+ .parent = &clk_g,
4157+ .enable = asic3_clock_cdex_enable,
4158+ .disable = asic3_clock_cdex_disable,
4159+ .ctrlbit = CLOCK_CDEX_LED1,
4160+ },
4161+ {
4162+ .name = "led2",
4163+ .id = -1,
4164+ .parent = &clk_g,
4165+ .enable = asic3_clock_cdex_enable,
4166+ .disable = asic3_clock_cdex_disable,
4167+ .ctrlbit = CLOCK_CDEX_LED2,
4168+ },
4169+ {
4170+ .name = "smbus",
4171+ .id = -1,
4172+ .parent = &clk_g,
4173+ .enable = asic3_clock_cdex_enable,
4174+ .disable = asic3_clock_cdex_disable,
4175+ .ctrlbit = CLOCK_CDEX_SMBUS,
4176+ },
4177+ {
4178+ .name = "ex0",
4179+ .id = -1,
4180+ .parent = &clk_g,
4181+ .enable = asic3_clock_cdex_enable,
4182+ .disable = asic3_clock_cdex_disable,
4183+ .ctrlbit = CLOCK_CDEX_EX0,
4184+ },
4185+ {
4186+ .name = "ex1",
4187+ .id = -1,
4188+ .parent = &clk_g,
4189+ .enable = asic3_clock_cdex_enable,
4190+ .disable = asic3_clock_cdex_disable,
4191+ .ctrlbit = CLOCK_CDEX_EX1,
4192+ },
4193+};
4194+
4195+void asic3_set_extcf_select(struct device *dev, u32 bits, u32 val)
4196+{
4197+ struct asic3_data *asic = dev->driver_data;
4198+ unsigned long flags;
4199+ u32 v;
4200+
4201+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4202+ v = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(EXTCF, Select));
4203+ v = (v & ~bits) | val;
4204+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(EXTCF, Select), v);
4205+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4206+}
4207+EXPORT_SYMBOL(asic3_set_extcf_select);
4208+
4209+void asic3_set_extcf_reset(struct device *dev, u32 bits, u32 val)
4210+{
4211+ struct asic3_data *asic = dev->driver_data;
4212+ unsigned long flags;
4213+ u32 v;
4214+
4215+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4216+ v = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(EXTCF, Reset));
4217+ v = (v & ~bits) | val;
4218+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(EXTCF, Reset), v);
4219+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4220+}
4221+EXPORT_SYMBOL(asic3_set_extcf_reset);
4222+
4223+void asic3_set_sdhwctrl(struct device *dev, u32 bits, u32 val)
4224+{
4225+ struct asic3_data *asic = dev->driver_data;
4226+ unsigned long flags;
4227+ u32 v;
4228+
4229+ spin_lock_irqsave (&asic3_gpio_lock, flags);
4230+ v = __asic3_read_register(asic, IPAQ_ASIC3_OFFSET(SDHWCTRL, SDConf));
4231+ v = (v & ~bits) | val;
4232+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(SDHWCTRL, SDConf), v);
4233+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4234+}
4235+EXPORT_SYMBOL(asic3_set_sdhwctrl);
4236+
4237+
4238+#define MAX_ASIC_ISR_LOOPS 20
4239+#define _IPAQ_ASIC3_GPIO_Base_INCR \
4240+ (_IPAQ_ASIC3_GPIO_B_Base - _IPAQ_ASIC3_GPIO_A_Base)
4241+
4242+static inline void asic3_irq_flip_edge(struct asic3_data *asic,
4243+ u32 base, int bit)
4244+{
4245+ u16 edge = __asic3_read_register(asic,
4246+ base + _IPAQ_ASIC3_GPIO_EdgeTrigger);
4247+ edge ^= bit;
4248+ __asic3_write_register(asic,
4249+ base + _IPAQ_ASIC3_GPIO_EdgeTrigger, edge);
4250+}
4251+
4252+static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc)
4253+{
4254+ int iter;
4255+ struct asic3_data *asic;
4256+
4257+ /* Acknowledge the parrent (i.e. CPU's) IRQ */
4258+ desc->chip->ack(irq);
4259+
4260+ asic = desc->handler_data;
4261+
4262+ /* printk( KERN_NOTICE "asic3_irq_demux: irq=%d\n", irq ); */
4263+ for (iter = 0 ; iter < MAX_ASIC_ISR_LOOPS; iter++) {
4264+ u32 status;
4265+ int bank;
4266+
4267+ status = __asic3_read_register(asic,
4268+ IPAQ_ASIC3_OFFSET(INTR, PIntStat));
4269+ /* Check all ten register bits */
4270+ if ((status & 0x3ff) == 0)
4271+ break;
4272+
4273+ /* Handle GPIO IRQs */
4274+ for (bank = 0; bank < 4; bank++) {
4275+ if (status & (1 << bank)) {
4276+ unsigned long base, i, istat;
4277+
4278+ base = _IPAQ_ASIC3_GPIO_A_Base
4279+ + bank * _IPAQ_ASIC3_GPIO_Base_INCR;
4280+ istat = __asic3_read_register(asic,
4281+ base + _IPAQ_ASIC3_GPIO_IntStatus);
4282+ /* IntStatus is write 0 to clear */
4283+ /* XXX could miss interrupts! */
4284+ __asic3_write_register(asic,
4285+ base + _IPAQ_ASIC3_GPIO_IntStatus, 0);
4286+
4287+ for (i = 0; i < 16; i++) {
4288+ int bit = (1 << i);
4289+ unsigned int irqnr;
4290+ if (!(istat & bit))
4291+ continue;
4292+
4293+ irqnr = asic->irq_base
4294+ + (16 * bank) + i;
4295+ desc = irq_desc + irqnr;
4296+ desc->handle_irq(irqnr, desc);
4297+ if (asic->irq_bothedge[bank] & bit) {
4298+ asic3_irq_flip_edge(asic, base,
4299+ bit);
4300+ }
4301+ }
4302+ }
4303+ }
4304+
4305+ /* Handle remaining IRQs in the status register */
4306+ {
4307+ int i;
4308+
4309+ for (i = ASIC3_LED0_IRQ; i <= ASIC3_OWM_IRQ; i++) {
4310+ /* They start at bit 4 and go up */
4311+ if (status & (1 << (i - ASIC3_LED0_IRQ + 4))) {
4312+ desc = irq_desc + asic->irq_base + i;
4313+ desc->handle_irq(asic->irq_base + i,
4314+ desc);
4315+ }
4316+ }
4317+ }
4318+
4319+ }
4320+
4321+ if (iter >= MAX_ASIC_ISR_LOOPS)
4322+ printk(KERN_ERR "%s: interrupt processing overrun\n",
4323+ __FUNCTION__);
4324+}
4325+
4326+static inline int asic3_irq_to_bank(struct asic3_data *asic, int irq)
4327+{
4328+ int n;
4329+
4330+ n = (irq - asic->irq_base) >> 4;
4331+
4332+ return (n * (_IPAQ_ASIC3_GPIO_B_Base - _IPAQ_ASIC3_GPIO_A_Base));
4333+}
4334+
4335+static inline int asic3_irq_to_index(struct asic3_data *asic, int irq)
4336+{
4337+ return (irq - asic->irq_base) & 15;
4338+}
4339+
4340+static void asic3_mask_gpio_irq(unsigned int irq)
4341+{
4342+ struct asic3_data *asic = get_irq_chip_data(irq);
4343+ u32 val, bank, index;
4344+ unsigned long flags;
4345+
4346+ bank = asic3_irq_to_bank(asic, irq);
4347+ index = asic3_irq_to_index(asic, irq);
4348+
4349+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4350+ val = __asic3_read_register(asic, bank + _IPAQ_ASIC3_GPIO_Mask);
4351+ val |= 1 << index;
4352+ __asic3_write_register(asic, bank + _IPAQ_ASIC3_GPIO_Mask, val);
4353+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4354+}
4355+
4356+static void asic3_mask_irq(unsigned int irq)
4357+{
4358+ struct asic3_data *asic = get_irq_chip_data(irq);
4359+ int regval;
4360+
4361+ if (irq < ASIC3_NR_GPIO_IRQS) {
4362+ printk(KERN_ERR "asic3_base: gpio mask attempt, irq %d\n",
4363+ irq);
4364+ return;
4365+ }
4366+
4367+ regval = __asic3_read_register(asic,
4368+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask);
4369+
4370+ switch (irq - asic->irq_base) {
4371+ case ASIC3_LED0_IRQ:
4372+ __asic3_write_register(asic,
4373+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4374+ regval & ~ASIC3_INTMASK_MASK0);
4375+ break;
4376+ case ASIC3_LED1_IRQ:
4377+ __asic3_write_register(asic,
4378+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4379+ regval & ~ASIC3_INTMASK_MASK1);
4380+ break;
4381+ case ASIC3_LED2_IRQ:
4382+ __asic3_write_register(asic,
4383+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4384+ regval & ~ASIC3_INTMASK_MASK2);
4385+ break;
4386+ case ASIC3_SPI_IRQ:
4387+ __asic3_write_register(asic,
4388+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4389+ regval & ~ASIC3_INTMASK_MASK3);
4390+ break;
4391+ case ASIC3_SMBUS_IRQ:
4392+ __asic3_write_register(asic,
4393+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4394+ regval & ~ASIC3_INTMASK_MASK4);
4395+ break;
4396+ case ASIC3_OWM_IRQ:
4397+ __asic3_write_register(asic,
4398+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4399+ regval & ~ASIC3_INTMASK_MASK5);
4400+ break;
4401+ default:
4402+ printk(KERN_ERR "asic3_base: bad non-gpio irq %d\n", irq);
4403+ break;
4404+ }
4405+}
4406+
4407+static void asic3_unmask_gpio_irq(unsigned int irq)
4408+{
4409+ struct asic3_data *asic = get_irq_chip_data(irq);
4410+ u32 val, bank, index;
4411+ unsigned long flags;
4412+
4413+ bank = asic3_irq_to_bank(asic, irq);
4414+ index = asic3_irq_to_index(asic, irq);
4415+
4416+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4417+ val = __asic3_read_register(asic, bank + _IPAQ_ASIC3_GPIO_Mask);
4418+ val &= ~(1 << index);
4419+ __asic3_write_register(asic, bank + _IPAQ_ASIC3_GPIO_Mask, val);
4420+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4421+}
4422+
4423+static void asic3_unmask_irq(unsigned int irq)
4424+{
4425+ struct asic3_data *asic = get_irq_chip_data(irq);
4426+ int regval;
4427+
4428+ if (irq < ASIC3_NR_GPIO_IRQS) {
4429+ printk(KERN_ERR "asic3_base: gpio unmask attempt, irq %d\n",
4430+ irq);
4431+ return;
4432+ }
4433+
4434+ regval = __asic3_read_register(asic,
4435+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask);
4436+
4437+ switch (irq - asic->irq_base) {
4438+ case ASIC3_LED0_IRQ:
4439+ __asic3_write_register(asic,
4440+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4441+ regval | ASIC3_INTMASK_MASK0);
4442+ break;
4443+ case ASIC3_LED1_IRQ:
4444+ __asic3_write_register(asic,
4445+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4446+ regval | ASIC3_INTMASK_MASK1);
4447+ break;
4448+ case ASIC3_LED2_IRQ:
4449+ __asic3_write_register(asic,
4450+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4451+ regval | ASIC3_INTMASK_MASK2);
4452+ break;
4453+ case ASIC3_SPI_IRQ:
4454+ __asic3_write_register(asic,
4455+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4456+ regval | ASIC3_INTMASK_MASK3);
4457+ break;
4458+ case ASIC3_SMBUS_IRQ:
4459+ __asic3_write_register(asic,
4460+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4461+ regval | ASIC3_INTMASK_MASK4);
4462+ break;
4463+ case ASIC3_OWM_IRQ:
4464+ __asic3_write_register(asic,
4465+ _IPAQ_ASIC3_INTR_Base + _IPAQ_ASIC3_INTR_IntMask,
4466+ regval | ASIC3_INTMASK_MASK5);
4467+ break;
4468+ default:
4469+ printk(KERN_ERR "asic3_base: bad non-gpio irq %d\n", irq);
4470+ break;
4471+ }
4472+}
4473+
4474+static int asic3_gpio_irq_type(unsigned int irq, unsigned int type)
4475+{
4476+ struct asic3_data *asic = get_irq_chip_data(irq);
4477+ u32 bank, index;
4478+ unsigned long flags;
4479+ u16 trigger, level, edge, bit;
4480+
4481+ bank = asic3_irq_to_bank(asic, irq);
4482+ index = asic3_irq_to_index(asic, irq);
4483+ bit = 1<<index;
4484+
4485+ spin_lock_irqsave(&asic3_gpio_lock, flags);
4486+ level = __asic3_read_register(asic,
4487+ bank + _IPAQ_ASIC3_GPIO_LevelTrigger);
4488+ edge = __asic3_read_register(asic,
4489+ bank + _IPAQ_ASIC3_GPIO_EdgeTrigger);
4490+ trigger = __asic3_read_register(asic,
4491+ bank + _IPAQ_ASIC3_GPIO_TriggerType);
4492+ asic->irq_bothedge[(irq - asic->irq_base) >> 4] &= ~bit;
4493+
4494+ if (type == IRQT_RISING) {
4495+ trigger |= bit;
4496+ edge |= bit;
4497+ } else if (type == IRQT_FALLING) {
4498+ trigger |= bit;
4499+ edge &= ~bit;
4500+ } else if (type == IRQT_BOTHEDGE) {
4501+ trigger |= bit;
4502+ if (asic3_gpio_get_value(asic->dev, irq - asic->irq_base))
4503+ edge &= ~bit;
4504+ else
4505+ edge |= bit;
4506+ asic->irq_bothedge[(irq - asic->irq_base) >> 4] |= bit;
4507+ } else if (type == IRQT_LOW) {
4508+ trigger &= ~bit;
4509+ level &= ~bit;
4510+ } else if (type == IRQT_HIGH) {
4511+ trigger &= ~bit;
4512+ level |= bit;
4513+ } else {
4514+ /*
4515+ * if type == IRQT_NOEDGE, we should mask interrupts, but
4516+ * be careful to not unmask them if mask was also called.
4517+ * Probably need internal state for mask.
4518+ */
4519+ printk(KERN_NOTICE "asic3: irq type not changed.\n");
4520+ }
4521+ __asic3_write_register(asic, bank + _IPAQ_ASIC3_GPIO_LevelTrigger,
4522+ level);
4523+ __asic3_write_register(asic, bank + _IPAQ_ASIC3_GPIO_EdgeTrigger,
4524+ edge);
4525+ __asic3_write_register(asic, bank + _IPAQ_ASIC3_GPIO_TriggerType,
4526+ trigger);
4527+ spin_unlock_irqrestore(&asic3_gpio_lock, flags);
4528+ return 0;
4529+}
4530+
4531+static struct irq_chip asic3_gpio_irq_chip = {
4532+ .name = "ASIC3-GPIO",
4533+ .ack = asic3_mask_gpio_irq,
4534+ .mask = asic3_mask_gpio_irq,
4535+ .unmask = asic3_unmask_gpio_irq,
4536+ .set_type = asic3_gpio_irq_type,
4537+};
4538+
4539+static struct irq_chip asic3_irq_chip = {
4540+ .name = "ASIC3",
4541+ .ack = asic3_mask_irq,
4542+ .mask = asic3_mask_irq,
4543+ .unmask = asic3_unmask_irq,
4544+};
4545+
4546+static void asic3_release(struct device *dev)
4547+{
4548+ struct platform_device *sdev = to_platform_device(dev);
4549+
4550+ kfree(sdev->resource);
4551+ kfree(sdev);
4552+}
4553+
4554+int asic3_register_mmc(struct device *dev)
4555+{
4556+ struct platform_device *sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
4557+ struct tmio_mmc_hwconfig *mmc_config = kmalloc(sizeof(*mmc_config),
4558+ GFP_KERNEL);
4559+ struct platform_device *pdev = to_platform_device(dev);
4560+ struct asic3_data *asic = dev->driver_data;
4561+ struct asic3_platform_data *asic3_pdata = dev->platform_data;
4562+ struct resource *res;
4563+ int rc;
4564+
4565+ if (sdev == NULL || mmc_config == NULL)
4566+ return -ENOMEM;
4567+
4568+ if (asic3_pdata->tmio_mmc_hwconfig) {
4569+ memcpy(mmc_config, asic3_pdata->tmio_mmc_hwconfig,
4570+ sizeof(*mmc_config));
4571+ } else {
4572+ memset(mmc_config, 0, sizeof(*mmc_config));
4573+ }
4574+ mmc_config->address_shift = asic->bus_shift;
4575+
4576+ sdev->id = -1;
4577+ sdev->name = "asic3_mmc";
4578+ sdev->dev.parent = dev;
4579+ sdev->num_resources = 2;
4580+ sdev->dev.platform_data = mmc_config;
4581+ sdev->dev.release = asic3_release;
4582+
4583+ res = kzalloc(sdev->num_resources * sizeof(struct resource),
4584+ GFP_KERNEL);
4585+ if (res == NULL) {
4586+ kfree(sdev);
4587+ kfree(mmc_config);
4588+ return -ENOMEM;
4589+ }
4590+ sdev->resource = res;
4591+
4592+ res[0].start = pdev->resource[2].start;
4593+ res[0].end = pdev->resource[2].end;
4594+ res[0].flags = IORESOURCE_MEM;
4595+ res[1].start = res[1].end = pdev->resource[3].start;
4596+ res[1].flags = IORESOURCE_IRQ;
4597+
4598+ rc = platform_device_register(sdev);
4599+ if (rc) {
4600+ printk(KERN_ERR "asic3_base: "
4601+ "Could not register asic3_mmc device\n");
4602+ kfree(res);
4603+ kfree(sdev);
4604+ return rc;
4605+ }
4606+
4607+ asic->mmc_dev = sdev;
4608+
4609+ return 0;
4610+}
4611+EXPORT_SYMBOL(asic3_register_mmc);
4612+
4613+int asic3_unregister_mmc(struct device *dev)
4614+{
4615+ struct asic3_data *asic = dev->driver_data;
4616+ platform_device_unregister(asic->mmc_dev);
4617+ asic->mmc_dev = 0;
4618+
4619+ return 0;
4620+}
4621+EXPORT_SYMBOL(asic3_unregister_mmc);
4622+
4623+#ifdef CONFIG_HTC_ASIC3_DS1WM
4624+/*
4625+ * DS1WM subdevice
4626+ */
4627+
4628+static void asic3_ds1wm_enable(struct platform_device *ds1wm_dev)
4629+{
4630+ struct device *dev = ds1wm_dev->dev.parent;
4631+
4632+ /* Turn on external clocks and the OWM clock */
4633+ asic3_set_clock_cdex(dev,
4634+ CLOCK_CDEX_EX0 | CLOCK_CDEX_EX1 | CLOCK_CDEX_OWM,
4635+ CLOCK_CDEX_EX0 | CLOCK_CDEX_EX1 | CLOCK_CDEX_OWM);
4636+
4637+ mdelay(1);
4638+
4639+ asic3_set_extcf_reset(dev, ASIC3_EXTCF_OWM_RESET,
4640+ ASIC3_EXTCF_OWM_RESET);
4641+ mdelay(1);
4642+ asic3_set_extcf_reset(dev, ASIC3_EXTCF_OWM_RESET, 0);
4643+ mdelay(1);
4644+
4645+ /* Clear OWM_SMB, set OWM_EN */
4646+ asic3_set_extcf_select(dev,
4647+ ASIC3_EXTCF_OWM_SMB | ASIC3_EXTCF_OWM_EN,
4648+ 0 | ASIC3_EXTCF_OWM_EN);
4649+
4650+ mdelay(1);
4651+}
4652+
4653+static void asic3_ds1wm_disable(struct platform_device *ds1wm_dev)
4654+{
4655+ struct device *dev = ds1wm_dev->dev.parent;
4656+
4657+ asic3_set_extcf_select(dev,
4658+ ASIC3_EXTCF_OWM_SMB | ASIC3_EXTCF_OWM_EN,
4659+ 0 | 0);
4660+
4661+ asic3_set_clock_cdex(dev,
4662+ CLOCK_CDEX_EX0 | CLOCK_CDEX_EX1 | CLOCK_CDEX_OWM,
4663+ CLOCK_CDEX_EX0 | CLOCK_CDEX_EX1 | 0);
4664+}
4665+
4666+
4667+static struct resource asic3_ds1wm_resources[] = {
4668+ {
4669+ .start = _IPAQ_ASIC3_OWM_Base,
4670+ .end = _IPAQ_ASIC3_OWM_Base + 0x14 - 1,
4671+ .flags = IORESOURCE_MEM,
4672+ },
4673+ {
4674+ .start = ASIC3_OWM_IRQ,
4675+ .end = ASIC3_OWM_IRQ,
4676+ .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
4677+ IORESOURCE_IRQ_SOC_SUBDEVICE,
4678+ },
4679+};
4680+
4681+static struct ds1wm_platform_data ds1wm_pd = {
4682+ .enable = asic3_ds1wm_enable,
4683+ .disable = asic3_ds1wm_disable,
4684+};
4685+#endif
4686+
4687+static struct soc_device_data asic3_blocks[] = {
4688+#ifdef CONFIG_HTC_ASIC3_DS1WM
4689+ {
4690+ .name = "ds1wm",
4691+ .res = asic3_ds1wm_resources,
4692+ .num_resources = ARRAY_SIZE(asic3_ds1wm_resources),
4693+ .hwconfig = &ds1wm_pd,
4694+ },
4695+#endif
4696+};
4697+
4698+static int asic3_probe(struct platform_device *pdev)
4699+{
4700+ struct asic3_platform_data *pdata = pdev->dev.platform_data;
4701+ struct asic3_data *asic;
4702+ struct device *dev = &pdev->dev;
4703+ unsigned long clksel;
4704+ int i, rc;
4705+
4706+ asic = kzalloc(sizeof(struct asic3_data), GFP_KERNEL);
4707+ if (!asic)
4708+ return -ENOMEM;
4709+
4710+ platform_set_drvdata(pdev, asic);
4711+ asic->dev = &pdev->dev;
4712+
4713+ asic->mapping = ioremap(pdev->resource[0].start, IPAQ_ASIC3_MAP_SIZE);
4714+ if (!asic->mapping) {
4715+ printk(KERN_ERR "asic3: couldn't ioremap ASIC3\n");
4716+ kfree (asic);
4717+ return -ENOMEM;
4718+ }
4719+
4720+ if (pdata && pdata->bus_shift)
4721+ asic->bus_shift = pdata->bus_shift;
4722+ else
4723+ asic->bus_shift = 2;
4724+
4725+ /* XXX: should get correct SD clock values from pdata struct */
4726+ clksel = 0;
4727+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, SEL), clksel);
4728+
4729+ /* Register ASIC3's clocks. */
4730+ clk_g.ctrlbit = (int)asic;
4731+
4732+ if (clk_register(&clk_g) < 0)
4733+ printk(KERN_ERR "asic3: failed to register ASIC3 gclk\n");
4734+
4735+ for (i = 0; i < ARRAY_SIZE(asic3_clocks); i++) {
4736+ rc = clk_register(&asic3_clocks[i]);
4737+ if (rc < 0)
4738+ printk(KERN_ERR "asic3: "
4739+ "failed to register clock %s (%d)\n",
4740+ asic3_clocks[i].name, rc);
4741+ }
4742+
4743+ __asic3_write_register(asic, IPAQ_ASIC3_GPIO_OFFSET(A, Mask), 0xffff);
4744+ __asic3_write_register(asic, IPAQ_ASIC3_GPIO_OFFSET(B, Mask), 0xffff);
4745+ __asic3_write_register(asic, IPAQ_ASIC3_GPIO_OFFSET(C, Mask), 0xffff);
4746+ __asic3_write_register(asic, IPAQ_ASIC3_GPIO_OFFSET(D, Mask), 0xffff);
4747+
4748+ asic3_set_gpio_sleepmask_a(dev, 0xffff, 0xffff);
4749+ asic3_set_gpio_sleepmask_b(dev, 0xffff, 0xffff);
4750+ asic3_set_gpio_sleepmask_c(dev, 0xffff, 0xffff);
4751+ asic3_set_gpio_sleepmask_d(dev, 0xffff, 0xffff);
4752+
4753+ if (pdata) {
4754+ asic3_set_gpio_out_a(dev, 0xffff, pdata->gpio_a.init);
4755+ asic3_set_gpio_out_b(dev, 0xffff, pdata->gpio_b.init);
4756+ asic3_set_gpio_out_c(dev, 0xffff, pdata->gpio_c.init);
4757+ asic3_set_gpio_out_d(dev, 0xffff, pdata->gpio_d.init);
4758+
4759+ asic3_set_gpio_dir_a(dev, 0xffff, pdata->gpio_a.dir);
4760+ asic3_set_gpio_dir_b(dev, 0xffff, pdata->gpio_b.dir);
4761+ asic3_set_gpio_dir_c(dev, 0xffff, pdata->gpio_c.dir);
4762+ asic3_set_gpio_dir_d(dev, 0xffff, pdata->gpio_d.dir);
4763+
4764+ asic3_set_gpio_sleepmask_a(dev, 0xffff,
4765+ pdata->gpio_a.sleep_mask);
4766+ asic3_set_gpio_sleepmask_b(dev, 0xffff,
4767+ pdata->gpio_b.sleep_mask);
4768+ asic3_set_gpio_sleepmask_c(dev, 0xffff,
4769+ pdata->gpio_c.sleep_mask);
4770+ asic3_set_gpio_sleepmask_d(dev, 0xffff,
4771+ pdata->gpio_d.sleep_mask);
4772+
4773+ asic3_set_gpio_sleepout_a(dev, 0xffff,
4774+ pdata->gpio_a.sleep_out);
4775+ asic3_set_gpio_sleepout_b(dev, 0xffff,
4776+ pdata->gpio_b.sleep_out);
4777+ asic3_set_gpio_sleepout_c(dev, 0xffff,
4778+ pdata->gpio_c.sleep_out);
4779+ asic3_set_gpio_sleepout_d(dev, 0xffff,
4780+ pdata->gpio_d.sleep_out);
4781+
4782+ asic3_set_gpio_battfaultout_a(dev, 0xffff,
4783+ pdata->gpio_a.batt_fault_out);
4784+ asic3_set_gpio_battfaultout_b(dev, 0xffff,
4785+ pdata->gpio_b.batt_fault_out);
4786+ asic3_set_gpio_battfaultout_c(dev, 0xffff,
4787+ pdata->gpio_c.batt_fault_out);
4788+ asic3_set_gpio_battfaultout_d(dev, 0xffff,
4789+ pdata->gpio_d.batt_fault_out);
4790+
4791+ asic3_set_gpio_sleepconf_a(dev, 0xffff,
4792+ pdata->gpio_a.sleep_conf);
4793+ asic3_set_gpio_sleepconf_b(dev, 0xffff,
4794+ pdata->gpio_b.sleep_conf);
4795+ asic3_set_gpio_sleepconf_c(dev, 0xffff,
4796+ pdata->gpio_c.sleep_conf);
4797+ asic3_set_gpio_sleepconf_d(dev, 0xffff,
4798+ pdata->gpio_d.sleep_conf);
4799+
4800+ asic3_set_gpio_alt_fn_a(dev, 0xffff,
4801+ pdata->gpio_a.alt_function);
4802+ asic3_set_gpio_alt_fn_b(dev, 0xffff,
4803+ pdata->gpio_b.alt_function);
4804+ asic3_set_gpio_alt_fn_c(dev, 0xffff,
4805+ pdata->gpio_c.alt_function);
4806+ asic3_set_gpio_alt_fn_d(dev, 0xffff,
4807+ pdata->gpio_d.alt_function);
4808+ }
4809+
4810+ asic->irq_nr = -1;
4811+ asic->irq_base = -1;
4812+
4813+ if (pdev->num_resources > 1)
4814+ asic->irq_nr = pdev->resource[1].start;
4815+
4816+ if (asic->irq_nr != -1) {
4817+ unsigned int i;
4818+
4819+ if (!pdata->irq_base) {
4820+ printk(KERN_ERR "asic3: IRQ base not specified\n");
4821+ asic3_remove(pdev);
4822+ return -EINVAL;
4823+ }
4824+
4825+ asic->irq_base = pdata->irq_base;
4826+
4827+ /* turn on clock to IRQ controller */
4828+ clksel |= CLOCK_SEL_CX;
4829+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, SEL),
4830+ clksel);
4831+
4832+ printk(KERN_INFO "asic3: using irq %d-%d on irq %d\n",
4833+ asic->irq_base, asic->irq_base + ASIC3_NR_IRQS - 1,
4834+ asic->irq_nr);
4835+
4836+ for (i = 0 ; i < ASIC3_NR_IRQS ; i++) {
4837+ int irq = i + asic->irq_base;
4838+ if (i < ASIC3_NR_GPIO_IRQS) {
4839+ set_irq_chip(irq, &asic3_gpio_irq_chip);
4840+ set_irq_chip_data(irq, asic);
4841+ set_irq_handler(irq, handle_level_irq);
4842+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
4843+ } else {
4844+ /* The remaining IRQs are not GPIO */
4845+ set_irq_chip(irq, &asic3_irq_chip);
4846+ set_irq_chip_data(irq, asic);
4847+ set_irq_handler(irq, handle_level_irq);
4848+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
4849+ }
4850+ }
4851+
4852+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(INTR, IntMask),
4853+ ASIC3_INTMASK_GINTMASK);
4854+
4855+ set_irq_chained_handler(asic->irq_nr, asic3_irq_demux);
4856+ set_irq_type(asic->irq_nr, IRQT_RISING);
4857+ set_irq_data(asic->irq_nr, asic);
4858+ }
4859+
4860+#ifdef CONFIG_HTC_ASIC3_DS1WM
4861+ ds1wm_pd.bus_shift = asic->bus_shift;
4862+#endif
4863+
4864+ pdata->gpiodev_ops.get = asic3_gpio_get_value;
4865+ pdata->gpiodev_ops.set = asic3_gpio_set_value;
4866+ pdata->gpiodev_ops.to_irq = asic3_gpio_to_irq;
4867+
4868+ soc_add_devices(pdev, asic3_blocks, ARRAY_SIZE(asic3_blocks),
4869+ &pdev->resource[0],
4870+ asic->bus_shift - ASIC3_DEFAULT_ADDR_SHIFT,
4871+ asic->irq_base);
4872+
4873+ if (pdev->num_resources > 2) {
4874+ int rc;
4875+ rc = asic3_register_mmc(dev);
4876+ if (rc) {
4877+ asic3_remove(pdev);
4878+ return rc;
4879+ }
4880+ }
4881+
4882+ if (pdata && pdata->num_child_platform_devs != 0)
4883+ platform_add_devices(pdata->child_platform_devs,
4884+ pdata->num_child_platform_devs);
4885+
4886+ return 0;
4887+}
4888+
4889+static int asic3_remove(struct platform_device *pdev)
4890+{
4891+ struct asic3_platform_data *pdata = pdev->dev.platform_data;
4892+ struct asic3_data *asic = platform_get_drvdata(pdev);
4893+ int i;
4894+
4895+ if (pdata && pdata->num_child_platform_devs != 0) {
4896+ for (i = 0; i < pdata->num_child_platform_devs; i++) {
4897+ platform_device_unregister(
4898+ pdata->child_platform_devs[i]);
4899+ }
4900+ }
4901+
4902+ if (asic->irq_nr != -1) {
4903+ unsigned int i;
4904+
4905+ for (i = 0 ; i < ASIC3_NR_IRQS ; i++) {
4906+ int irq = i + asic->irq_base;
4907+ set_irq_flags(irq, 0);
4908+ set_irq_handler (irq, NULL);
4909+ set_irq_chip (irq, NULL);
4910+ set_irq_chip_data(irq, NULL);
4911+ }
4912+
4913+ set_irq_chained_handler(asic->irq_nr, NULL);
4914+ }
4915+
4916+ if (asic->mmc_dev)
4917+ asic3_unregister_mmc(&pdev->dev);
4918+
4919+ for (i = 0; i < ARRAY_SIZE(asic3_clocks); i++)
4920+ clk_unregister(&asic3_clocks[i]);
4921+ clk_unregister(&clk_g);
4922+
4923+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, SEL), 0);
4924+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(INTR, IntMask), 0);
4925+
4926+ iounmap(asic->mapping);
4927+
4928+ kfree(asic);
4929+
4930+ return 0;
4931+}
4932+
4933+static void asic3_shutdown(struct platform_device *pdev)
4934+{
4935+}
4936+
4937+#define ASIC3_SUSPEND_CDEX_MASK \
4938+ (CLOCK_CDEX_LED0 | CLOCK_CDEX_LED1 | CLOCK_CDEX_LED2)
4939+static unsigned short suspend_cdex;
4940+
4941+static int asic3_suspend(struct platform_device *pdev, pm_message_t state)
4942+{
4943+ struct asic3_data *asic = platform_get_drvdata(pdev);
4944+ suspend_cdex = __asic3_read_register(asic,
4945+ _IPAQ_ASIC3_CLOCK_Base + _IPAQ_ASIC3_CLOCK_CDEX);
4946+ /* The LEDs are still active during suspend */
4947+ __asic3_write_register(asic,
4948+ _IPAQ_ASIC3_CLOCK_Base + _IPAQ_ASIC3_CLOCK_CDEX,
4949+ suspend_cdex & ASIC3_SUSPEND_CDEX_MASK);
4950+ return 0;
4951+}
4952+
4953+static int asic3_resume(struct platform_device *pdev)
4954+{
4955+ struct asic3_data *asic = platform_get_drvdata(pdev);
4956+ unsigned short intmask;
4957+
4958+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(CLOCK, CDEX),
4959+ suspend_cdex);
4960+
4961+ if (asic->irq_nr != -1) {
4962+ /* Toggle the interrupt mask to try to get ASIC3 to show
4963+ * the CPU an interrupt edge. For more details see the
4964+ * kernel-discuss thread around 13 June 2005 with the
4965+ * subject "asic3 suspend / resume". */
4966+ intmask = __asic3_read_register(asic,
4967+ IPAQ_ASIC3_OFFSET(INTR, IntMask));
4968+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(INTR, IntMask),
4969+ intmask & ~ASIC3_INTMASK_GINTMASK);
4970+ mdelay(1);
4971+ __asic3_write_register(asic, IPAQ_ASIC3_OFFSET(INTR, IntMask),
4972+ intmask | ASIC3_INTMASK_GINTMASK);
4973+ }
4974+
4975+ return 0;
4976+}
4977+
4978+static struct platform_driver asic3_device_driver = {
4979+ .driver = {
4980+ .name = "asic3",
4981+ },
4982+ .probe = asic3_probe,
4983+ .remove = asic3_remove,
4984+ .suspend = asic3_suspend,
4985+ .resume = asic3_resume,
4986+ .shutdown = asic3_shutdown,
4987+};
4988+
4989+static int __init asic3_base_init(void)
4990+{
4991+ int retval = 0;
4992+ retval = platform_driver_register(&asic3_device_driver);
4993+ return retval;
4994+}
4995+
4996+static void __exit asic3_base_exit(void)
4997+{
4998+ platform_driver_unregister(&asic3_device_driver);
4999+}
5000+
5001+#ifdef MODULE
5002+module_init(asic3_base_init);
5003+#else /* start early for dependencies */
5004+subsys_initcall(asic3_base_init);
5005+#endif
5006+module_exit(asic3_base_exit);
5007+
5008+MODULE_LICENSE("GPL");
5009+MODULE_AUTHOR("Phil Blundell <pb@handhelds.org>");
5010+MODULE_DESCRIPTION("Core driver for HTC ASIC3");
5011+MODULE_SUPPORTED_DEVICE("asic3");
5012Index: linux-2.6.26-rc4/drivers/mfd/soc-core.c
5013===================================================================
5014--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5015+++ linux-2.6.26-rc4/drivers/mfd/soc-core.c 2008-06-01 18:49:45.000000000 +0100
5016@@ -0,0 +1,106 @@
5017+/*
5018+ * drivers/soc/soc-core.c
5019+ *
5020+ * core SoC support
5021+ * Copyright (c) 2006 Ian Molton
5022+ *
5023+ * This program is free software; you can redistribute it and/or modify
5024+ * it under the terms of the GNU General Public License version 2 as
5025+ * published by the Free Software Foundation.
5026+ *
5027+ * This file contains functionality used by many SoC type devices.
5028+ *
5029+ * Created: 2006-11-28
5030+ *
5031+ */
5032+
5033+#include <linux/ioport.h>
5034+#include <linux/slab.h>
5035+#include <linux/kernel.h>
5036+#include <linux/platform_device.h>
5037+#include "soc-core.h"
5038+
5039+void soc_free_devices(struct platform_device *devices, int nr_devs)
5040+{
5041+ struct platform_device *dev = devices;
5042+ int i;
5043+
5044+ for (i = 0; i < nr_devs; i++) {
5045+ struct resource *res = dev->resource;
5046+ platform_device_unregister(dev++);
5047+ kfree(res);
5048+ }
5049+ kfree(devices);
5050+}
5051+EXPORT_SYMBOL_GPL(soc_free_devices);
5052+
5053+#define SIGNED_SHIFT(val, shift) ((shift) >= 0 ? ((val) << (shift)) : ((val) >> -(shift)))
5054+
5055+struct platform_device *soc_add_devices(struct platform_device *dev,
5056+ struct soc_device_data *soc, int nr_devs,
5057+ struct resource *mem,
5058+ int relative_addr_shift, int irq_base)
5059+{
5060+ struct platform_device *devices;
5061+ int i, r, base;
5062+
5063+ devices = kzalloc(nr_devs * sizeof(struct platform_device), GFP_KERNEL);
5064+ if (!devices)
5065+ return NULL;
5066+
5067+ for (i = 0; i < nr_devs; i++) {
5068+ struct platform_device *sdev = &devices[i];
5069+ struct soc_device_data *blk = &soc[i];
5070+ struct resource *res;
5071+
5072+ sdev->id = -1;
5073+ sdev->name = blk->name;
5074+
5075+ sdev->dev.parent = &dev->dev;
5076+ sdev->dev.platform_data = (void *)blk->hwconfig;
5077+ sdev->num_resources = blk->num_resources;
5078+
5079+ /* Allocate space for the subdevice resources */
5080+ res = kzalloc (blk->num_resources * sizeof (struct resource), GFP_KERNEL);
5081+ if (!res)
5082+ goto fail;
5083+
5084+ for (r = 0 ; r < blk->num_resources ; r++) {
5085+ res[r].name = blk->res[r].name; // Fixme - should copy
5086+
5087+ /* Find out base to use */
5088+ base = 0;
5089+ if (blk->res[r].flags & IORESOURCE_MEM) {
5090+ base = mem->start;
5091+ } else if ((blk->res[r].flags & IORESOURCE_IRQ) &&
5092+ (blk->res[r].flags & IORESOURCE_IRQ_SOC_SUBDEVICE)) {
5093+ base = irq_base;
5094+ }
5095+
5096+ /* Adjust resource */
5097+ if (blk->res[r].flags & IORESOURCE_MEM) {
5098+ res[r].parent = mem;
5099+ res[r].start = base + SIGNED_SHIFT(blk->res[r].start, relative_addr_shift);
5100+ res[r].end = base + SIGNED_SHIFT(blk->res[r].end, relative_addr_shift);
5101+ } else {
5102+ res[r].start = base + blk->res[r].start;
5103+ res[r].end = base + blk->res[r].end;
5104+ }
5105+ res[r].flags = blk->res[r].flags;
5106+ }
5107+
5108+ sdev->resource = res;
5109+ if (platform_device_register(sdev)) {
5110+ kfree(res);
5111+ goto fail;
5112+ }
5113+
5114+ printk(KERN_INFO "SoC: registering %s\n", blk->name);
5115+ }
5116+ return devices;
5117+
5118+fail:
5119+ soc_free_devices(devices, i + 1);
5120+ return NULL;
5121+}
5122+EXPORT_SYMBOL_GPL(soc_add_devices);
5123Index: linux-2.6.26-rc4/drivers/mfd/soc-core.h
5124===================================================================
5125--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5126+++ linux-2.6.26-rc4/drivers/mfd/soc-core.h 2008-06-01 18:49:45.000000000 +0100
5127@@ -0,0 +1,30 @@
5128+/*
5129+ * drivers/soc/soc-core.h
5130+ *
5131+ * core SoC support
5132+ * Copyright (c) 2006 Ian Molton
5133+ *
5134+ * This program is free software; you can redistribute it and/or modify
5135+ * it under the terms of the GNU General Public License version 2 as
5136+ * published by the Free Software Foundation.
5137+ *
5138+ * This file contains prototypes for the functions in soc-core.c
5139+ *
5140+ * Created: 2006-11-28
5141+ *
5142+ */
5143+
5144+struct soc_device_data {
5145+ char *name;
5146+ struct resource *res;
5147+ int num_resources;
5148+ void *hwconfig; /* platform_data to pass to the subdevice */
5149+};
5150+
5151+struct platform_device *soc_add_devices(struct platform_device *dev,
5152+ struct soc_device_data *soc, int n_devs,
5153+ struct resource *mem,
5154+ int relative_addr_shift, int irq_base);
5155+
5156+void soc_free_devices(struct platform_device *devices, int nr_devs);
5157+
5158Index: linux-2.6.26-rc4/include/asm-arm/arch-pxa/clock.h
5159===================================================================
5160--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5161+++ linux-2.6.26-rc4/include/asm-arm/arch-pxa/clock.h 2008-06-01 18:49:45.000000000 +0100
5162@@ -0,0 +1,27 @@
5163+/*
5164+ * linux/include/asm-arm/arch-pxa/clock.h
5165+ *
5166+ * Copyright (C) 2006 Erik Hovland
5167+ *
5168+ * This program is free software; you can redistribute it and/or modify
5169+ * it under the terms of the GNU General Public License version 2 as
5170+ * published by the Free Software Foundation.
5171+ */
5172+
5173+struct clk {
5174+ struct list_head node;
5175+ struct module *owner;
5176+ struct clk *parent;
5177+ const char *name;
5178+ int id;
5179+ unsigned int enabled;
5180+ unsigned long rate;
5181+ unsigned long ctrlbit;
5182+
5183+ void (*enable)(struct clk *);
5184+ void (*disable)(struct clk *);
5185+};
5186+
5187+
5188+extern int clk_register(struct clk *clk);
5189+extern void clk_unregister(struct clk *clk);
5190Index: linux-2.6.26-rc4/include/asm-arm/arch-pxa/htcuniversal-asic.h
5191===================================================================
5192--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5193+++ linux-2.6.26-rc4/include/asm-arm/arch-pxa/htcuniversal-asic.h 2008-06-01 18:49:45.000000000 +0100
5194@@ -0,0 +1,213 @@
5195+/*
5196+ * include/asm/arm/arch-pxa/htcuniversal-asic.h
5197+ *
5198+ * Authors: Giuseppe Zompatori <giuseppe_zompatori@yahoo.it>
5199+ *
5200+ * based on previews work, see below:
5201+ *
5202+ * include/asm/arm/arch-pxa/hx4700-asic.h
5203+ * Copyright (c) 2004 SDG Systems, LLC
5204+ *
5205+ */
5206+
5207+#ifndef _HTCUNIVERSAL_ASIC_H_
5208+#define _HTCUNIVERSAL_ASIC_H_
5209+
5210+#include <asm/hardware/ipaq-asic3.h>
5211+
5212+/* ASIC3 */
5213+
5214+#define HTCUNIVERSAL_ASIC3_GPIO_PHYS PXA_CS4_PHYS
5215+#define HTCUNIVERSAL_ASIC3_MMC_PHYS PXA_CS3_PHYS
5216+
5217+/* TODO: some information is missing here */
5218+
5219+/* ASIC3 GPIO A bank */
5220+
5221+#define GPIOA_I2C_EN 0 /* Output */
5222+#define GPIOA_SPK_PWR1_ON 1 /* Output */
5223+#define GPIOA_AUDIO_PWR_ON 2 /* Output */
5224+#define GPIOA_EARPHONE_PWR_ON 3 /* Output */
5225+
5226+#define GPIOA_UNKNOWN4 4 /* Output */
5227+#define GPIOA_BUTTON_BACKLIGHT_N 5 /* Input */
5228+#define GPIOA_SPK_PWR2_ON 6 /* Output */
5229+#define GPIOA_BUTTON_RECORD_N 7 /* Input */
5230+
5231+#define GPIOA_BUTTON_CAMERA_N 8 /* Input */
5232+#define GPIOA_UNKNOWN9 9 /* Output */
5233+#define GPIOA_FLASHLIGHT 10 /* Output */
5234+#define GPIOA_COVER_ROTATE_N 11 /* Input */
5235+
5236+#define GPIOA_TOUCHSCREEN_N 12 /* Input */
5237+#define GPIOA_VOL_UP_N 13 /* Input */
5238+#define GPIOA_VOL_DOWN_N 14 /* Input */
5239+#define GPIOA_LCD_PWR5_ON 15 /* Output */
5240+
5241+/* ASIC3 GPIO B bank */
5242+
5243+#define GPIOB_BB_READY 0 /* Input */
5244+#define GPIOB_CODEC_PDN 1 /* Output */
5245+#define GPIOB_UNKNOWN2 2 /* Input */
5246+#define GPIOB_BB_UNKNOWN3 3 /* Input */
5247+
5248+#define GPIOB_BT_IRQ 4 /* Input */
5249+#define GPIOB_CLAMSHELL_N 5 /* Input */
5250+#define GPIOB_LCD_PWR3_ON 6 /* Output */
5251+#define GPIOB_BB_ALERT 7 /* Input */
5252+
5253+#define GPIOB_BB_RESET2 8 /* Output */
5254+#define GPIOB_EARPHONE_N 9 /* Input */
5255+#define GPIOB_MICRECORD_N 10 /* Input */
5256+#define GPIOB_NIGHT_SENSOR 11 /* Input */
5257+
5258+#define GPIOB_UMTS_DCD 12 /* Input */
5259+#define GPIOB_UNKNOWN13 13 /* Input */
5260+#define GPIOB_CHARGE_EN 14 /* Output */
5261+#define GPIOB_USB_PUEN 15 /* Output */
5262+
5263+/* ASIC3 GPIO C bank */
5264+
5265+#define GPIOC_LED_BTWIFI 0 /* Output */
5266+#define GPIOC_LED_RED 1 /* Output */
5267+#define GPIOC_LED_GREEN 2 /* Output */
5268+#define GPIOC_BOARDID3 3 /* Input */
5269+
5270+#define GPIOC_WIFI_IRQ_N 4 /* Input */
5271+#define GPIOC_WIFI_RESET 5 /* Output */
5272+#define GPIOC_WIFI_PWR1_ON 6 /* Output */
5273+#define GPIOC_BT_RESET 7 /* Output */
5274+
5275+#define GPIOC_UNKNOWN8 8 /* Output */
5276+#define GPIOC_LCD_PWR1_ON 9 /* Output */
5277+#define GPIOC_LCD_PWR2_ON 10 /* Output */
5278+#define GPIOC_BOARDID2 11 /* Input */
5279+
5280+#define GPIOC_BOARDID1 12 /* Input */
5281+#define GPIOC_BOARDID0 13 /* Input */
5282+#define GPIOC_BT_PWR_ON 14 /* Output */
5283+#define GPIOC_CHARGE_ON 15 /* Output */
5284+
5285+/* ASIC3 GPIO D bank */
5286+
5287+#define GPIOD_KEY_OK_N 0 /* Input */
5288+#define GPIOD_KEY_RIGHT_N 1 /* Input */
5289+#define GPIOD_KEY_LEFT_N 2 /* Input */
5290+#define GPIOD_KEY_DOWN_N 3 /* Input */
5291+
5292+#define GPIOD_KEY_UP_N 4 /* Input */
5293+#define GPIOD_SDIO_DET 5 /* Input */
5294+#define GPIOD_WIFI_PWR2_ON 6 /* Output */
5295+#define GPIOD_HW_REBOOT 7 /* Output */
5296+
5297+#define GPIOD_BB_RESET1 8 /* Output */
5298+#define GPIOD_UNKNOWN9 9 /* Output */
5299+#define GPIOD_VIBRA_PWR_ON 10 /* Output */
5300+#define GPIOD_WIFI_PWR3_ON 11 /* Output */
5301+
5302+#define GPIOD_FL_PWR_ON 12 /* Output */
5303+#define GPIOD_LCD_PWR4_ON 13 /* Output */
5304+#define GPIOD_BL_KEYP_PWR_ON 14 /* Output */
5305+#define GPIOD_BL_KEYB_PWR_ON 15 /* Output */
5306+
5307+extern struct platform_device htcuniversal_asic3;
5308+
5309+/* ASIC3 GPIO A bank */
5310+
5311+#define GPIO_I2C_EN 0*16+GPIOA_I2C_EN
5312+#define GPIO_SPK_PWR1_ON 0*16+GPIOA_SPK_PWR1_ON
5313+#define GPIO_AUDIO_PWR_ON 0*16+GPIOA_AUDIO_PWR_ON
5314+#define GPIO_EARPHONE_PWR_ON 0*16+GPIOA_EARPHONE_PWR_ON
5315+
5316+#define GPIO_UNKNOWNA4 0*16+GPIOA_UNKNOWN4
5317+#define GPIO_BUTTON_BACKLIGHT_N 0*16+GPIOA_BUTTON_BACKLIGHT_N
5318+#define GPIO_SPK_PWR2_ON 0*16+GPIOA_SPK_PWR2_ON
5319+#define GPIO_BUTTON_RECORD_N 0*16+GPIOA_BUTTON_RECORD_N
5320+
5321+#define GPIO_BUTTON_CAMERA_N 0*16+GPIOA_BUTTON_CAMERA_N
5322+#define GPIO_UNKNOWNA9 0*16+GPIOA_UNKNOWN9
5323+#define GPIO_FLASHLIGHT 0*16+GPIOA_FLASHLIGHT
5324+#define GPIO_COVER_ROTATE_N 0*16+GPIOA_COVER_ROTATE_N
5325+
5326+#define GPIO_TOUCHSCREEN_N 0*16+GPIOA_TOUCHSCREEN_N
5327+#define GPIO_VOL_UP_N 0*16+GPIOA_VOL_UP_N
5328+#define GPIO_VOL_DOWN_N 0*16+GPIOA_VOL_DOWN_N
5329+#define GPIO_LCD_PWR5_ON 0*16+GPIOA_LCD_PWR5_ON
5330+
5331+/* ASIC3 GPIO B bank */
5332+
5333+#define GPIO_BB_READY 1*16+GPIOB_BB_READY
5334+#define GPIO_CODEC_PDN 1*16+GPIOB_CODEC_PDN
5335+#define GPIO_UNKNOWNB2 1*16+GPIOB_UNKNOWN2
5336+#define GPIO_BB_UNKNOWN3 1*16+GPIOB_BB_UNKNOWN3
5337+
5338+#define GPIO_BT_IRQ 1*16+GPIOB_BT_IRQ
5339+#define GPIO_CLAMSHELL_N 1*16+GPIOB_CLAMSHELL_N
5340+#define GPIO_LCD_PWR3_ON 1*16+GPIOB_LCD_PWR3_ON
5341+#define GPIO_BB_ALERT 1*16+GPIOB_BB_ALERT
5342+
5343+#define GPIO_BB_RESET2 1*16+GPIOB_BB_RESET2
5344+#define GPIO_EARPHONE_N 1*16+GPIOB_EARPHONE_N
5345+#define GPIO_MICRECORD_N 1*16+GPIOB_MICRECORD_N
5346+#define GPIO_NIGHT_SENSOR 1*16+GPIOB_NIGHT_SENSOR
5347+
5348+#define GPIO_UMTS_DCD 1*16+GPIOB_UMTS_DCD
5349+#define GPIO_UNKNOWNB13 1*16+GPIOB_UNKNOWN13
5350+#define GPIO_CHARGE_EN 1*16+GPIOB_CHARGE_EN
5351+#define GPIO_USB_PUEN 1*16+GPIOB_USB_PUEN
5352+
5353+/* ASIC3 GPIO C bank */
5354+
5355+#define GPIO_LED_BTWIFI 2*16+GPIOC_LED_BTWIFI
5356+#define GPIO_LED_RED 2*16+GPIOC_LED_RED
5357+#define GPIO_LED_GREEN 2*16+GPIOC_LED_GREEN
5358+#define GPIO_BOARDID3 2*16+GPIOC_BOARDID3
5359+
5360+#define GPIO_WIFI_IRQ_N 2*16+GPIOC_WIFI_IRQ_N
5361+#define GPIO_WIFI_RESET 2*16+GPIOC_WIFI_RESET
5362+#define GPIO_WIFI_PWR1_ON 2*16+GPIOC_WIFI_PWR1_ON
5363+#define GPIO_BT_RESET 2*16+GPIOC_BT_RESET
5364+
5365+#define GPIO_UNKNOWNC8 2*16+GPIOC_UNKNOWN8
5366+#define GPIO_LCD_PWR1_ON 2*16+GPIOC_LCD_PWR1_ON
5367+#define GPIO_LCD_PWR2_ON 2*16+GPIOC_LCD_PWR2_ON
5368+#define GPIO_BOARDID2 2*16+GPIOC_BOARDID2
5369+
5370+#define GPIO_BOARDID1 2*16+GPIOC_BOARDID1
5371+#define GPIO_BOARDID0 2*16+GPIOC_BOARDID0
5372+#define GPIO_BT_PWR_ON 2*16+GPIOC_BT_PWR_ON
5373+#define GPIO_CHARGE_ON 2*16+GPIOC_CHARGE_ON
5374+
5375+/* ASIC3 GPIO D bank */
5376+
5377+#define GPIO_KEY_OK_N 3*16+GPIOD_KEY_OK_N
5378+#define GPIO_KEY_RIGHT_N 3*16+GPIOD_KEY_RIGHT_N
5379+#define GPIO_KEY_LEFT_N 3*16+GPIOD_KEY_LEFT_N
5380+#define GPIO_KEY_DOWN_N 3*16+GPIOD_KEY_DOWN_N
5381+
5382+#define GPIO_KEY_UP_N 3*16+GPIOD_KEY_UP_N
5383+#define GPIO_SDIO_DET 3*16+GPIOD_SDIO_DET
5384+#define GPIO_WIFI_PWR2_ON 3*16+GPIOD_WIFI_PWR2_ON
5385+#define GPIO_HW_REBOOT 3*16+GPIOD_HW_REBOOT
5386+
5387+#define GPIO_BB_RESET1 3*16+GPIOD_BB_RESET1
5388+#define GPIO_UNKNOWND9 3*16+GPIOD_UNKNOWN9
5389+#define GPIO_VIBRA_PWR_ON 3*16+GPIOD_VIBRA_PWR_ON
5390+#define GPIO_WIFI_PWR3_ON 3*16+GPIOD_WIFI_PWR3_ON
5391+
5392+#define GPIO_FL_PWR_ON 3*16+GPIOD_FL_PWR_ON
5393+#define GPIO_LCD_PWR4_ON 3*16+GPIOD_LCD_PWR4_ON
5394+#define GPIO_BL_KEYP_PWR_ON 3*16+GPIOD_BL_KEYP_PWR_ON
5395+#define GPIO_BL_KEYB_PWR_ON 3*16+GPIOD_BL_KEYB_PWR_ON
5396+
5397+#define HTCUNIVERSAL_EGPIO_BASE PXA_CS2_PHYS+0x02000000
5398+
5399+#define EGPIO4_ON 4 /* something */
5400+#define EGPIO5_BT_3V3_ON 5 /* Bluetooth related */
5401+#define EGPIO6_WIFI_ON 6 /* WLAN related*/
5402+
5403+extern void htcuniversal_egpio_enable( u_int16_t bits );
5404+extern void htcuniversal_egpio_disable( u_int16_t bits );
5405+
5406+#endif /* _HTCUNIVERSAL_ASIC_H_ */
5407+
5408Index: linux-2.6.26-rc4/include/asm-arm/arch-pxa/htcuniversal-gpio.h
5409===================================================================
5410--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5411+++ linux-2.6.26-rc4/include/asm-arm/arch-pxa/htcuniversal-gpio.h 2008-06-01 18:49:45.000000000 +0100
5412@@ -0,0 +1,220 @@
5413+/*
5414+ * include/asm-arm/arch-pxa/htcuniversal-gpio.h
5415+ * History:
5416+ *
5417+ * 2004-12-10 Michael Opdenacker. Wrote down GPIO settings as identified by Jamey Hicks.
5418+ * Reused the h2200-gpio.h file as a template.
5419+ */
5420+
5421+#ifndef _HTCUNIVERSAL_GPIO_H_
5422+#define _HTCUNIVERSAL_GPIO_H_
5423+
5424+#include <asm/arch/pxa-regs.h>
5425+
5426+#define GET_HTCUNIVERSAL_GPIO(gpio) \
5427+ (GPLR(GPIO_NR_HTCUNIVERSAL_ ## gpio) & GPIO_bit(GPIO_NR_HTCUNIVERSAL_ ## gpio))
5428+
5429+#define SET_HTCUNIVERSAL_GPIO(gpio, setp) \
5430+do { \
5431+if (setp) \
5432+ GPSR(GPIO_NR_HTCUNIVERSAL_ ## gpio) = GPIO_bit(GPIO_NR_HTCUNIVERSAL_ ## gpio); \
5433+else \
5434+ GPCR(GPIO_NR_HTCUNIVERSAL_ ## gpio) = GPIO_bit(GPIO_NR_HTCUNIVERSAL_ ## gpio); \
5435+} while (0)
5436+
5437+#define SET_HTCUNIVERSAL_GPIO_N(gpio, setp) \
5438+do { \
5439+if (setp) \
5440+ GPCR(GPIO_NR_HTCUNIVERSAL_ ## gpio ## _N) = GPIO_bit(GPIO_NR_HTCUNIVERSAL_ ## gpio ## _N); \
5441+else \
5442+ GPSR(GPIO_NR_HTCUNIVERSAL_ ## gpio ## _N) = GPIO_bit(GPIO_NR_HTCUNIVERSAL_ ## gpio ## _N); \
5443+} while (0)
5444+
5445+#define HTCUNIVERSAL_IRQ(gpio) \
5446+ IRQ_GPIO(GPIO_NR_HTCUNIVERSAL_ ## gpio)
5447+
5448+#define GPIO_NR_HTCUNIVERSAL_KEY_ON_N 0
5449+#define GPIO_NR_HTCUNIVERSAL_GP_RST_N 1
5450+
5451+#define GPIO_NR_HTCUNIVERSAL_USB_DET 9
5452+#define GPIO_NR_HTCUNIVERSAL_POWER_DET 10
5453+
5454+#define GPIO_NR_HTCUNIVERSAL_CIF_DD7 12
5455+#define GPIO_NR_HTCUNIVERSAL_ASIC3_SDIO_INT_N 13
5456+#define GPIO_NR_HTCUNIVERSAL_ASIC3_EXT_INT 14
5457+#define GPIO_NR_HTCUNIVERSAL_CS1_N 15
5458+
5459+#define GPIO_NR_HTCUNIVERSAL_CIF_DD6 17
5460+#define GPIO_NR_HTCUNIVERSAL_RDY 18
5461+
5462+#define GPIO_NR_HTCUNIVERSAL_PHONE_START 19
5463+
5464+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT7 22
5465+#define GPIO_NR_HTCUNIVERSAL_SPI_CLK 23
5466+#define GPIO_NR_HTCUNIVERSAL_SPI_FRM 24
5467+#define GPIO_NR_HTCUNIVERSAL_SPI_DO 25
5468+#define GPIO_NR_HTCUNIVERSAL_SPI_DI 26
5469+
5470+#define GPIO_NR_HTCUNIVERSAL_CODEC_ON 27
5471+#define GPIO_NR_HTCUNIVERSAL_I2S_BCK 28
5472+#define GPIO_NR_HTCUNIVERSAL_I2S_DIN 29
5473+#define GPIO_NR_HTCUNIVERSAL_I2S_DOUT 30
5474+#define GPIO_NR_HTCUNIVERSAL_I2S_SYNC 31
5475+
5476+#define GPIO_NR_HTCUNIVERSAL_RS232_ON 32
5477+#define GPIO_NR_HTCUNIVERSAL_CS5_N 33
5478+
5479+#define GPIO_NR_HTCUNIVERSAL_PHONE_RXD 34
5480+#define GPIO_NR_HTCUNIVERSAL_PHONE_UART_CTS 35
5481+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN7 36
5482+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN3 37
5483+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN4 38
5484+#define GPIO_NR_HTCUNIVERSAL_PHONE_TXD 39
5485+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT6 40
5486+#define GPIO_NR_HTCUNIVERSAL_PHONE_UART_RTS 41
5487+#define GPIO_NR_HTCUNIVERSAL_BT_RXD 42
5488+#define GPIO_NR_HTCUNIVERSAL_BT_TXD 43
5489+#define GPIO_NR_HTCUNIVERSAL_BT_UART_CTS 44
5490+#define GPIO_NR_HTCUNIVERSAL_BT_UART_RTS 45
5491+
5492+#define GPIO_NR_HTCUNIVERSAL_SIR_RXD 42
5493+#define GPIO_NR_HTCUNIVERSAL_SIR_TXD 43
5494+
5495+#define GPIO_NR_HTCUNIVERSAL_POE_N 48
5496+#define GPIO_NR_HTCUNIVERSAL_PWE_N 49
5497+#define GPIO_NR_HTCUNIVERSAL_CIF_DD3 50
5498+#define GPIO_NR_HTCUNIVERSAL_CIF_DD2 51
5499+#define GPIO_NR_HTCUNIVERSAL_CIF_DD4 52
5500+
5501+#define GPIO_NR_HTCUNIVERSAL_CIF_MCLK 53
5502+#define GPIO_NR_HTCUNIVERSAL_CIF_PCLK 54
5503+#define GPIO_NR_HTCUNIVERSAL_CIF_DD1 55
5504+
5505+#define GPIO_NR_HTCUNIVERSAL_LDD0 58
5506+#define GPIO_NR_HTCUNIVERSAL_LDD1 59
5507+#define GPIO_NR_HTCUNIVERSAL_LDD2 60
5508+#define GPIO_NR_HTCUNIVERSAL_LDD3 61
5509+#define GPIO_NR_HTCUNIVERSAL_LDD4 62
5510+#define GPIO_NR_HTCUNIVERSAL_LDD5 63
5511+#define GPIO_NR_HTCUNIVERSAL_LDD6 64
5512+#define GPIO_NR_HTCUNIVERSAL_LDD7 65
5513+#define GPIO_NR_HTCUNIVERSAL_LDD8 66
5514+#define GPIO_NR_HTCUNIVERSAL_LDD9 67
5515+#define GPIO_NR_HTCUNIVERSAL_LDD10 68
5516+#define GPIO_NR_HTCUNIVERSAL_LDD11 69
5517+#define GPIO_NR_HTCUNIVERSAL_LDD12 70
5518+#define GPIO_NR_HTCUNIVERSAL_LDD13 71
5519+#define GPIO_NR_HTCUNIVERSAL_LDD14 72
5520+#define GPIO_NR_HTCUNIVERSAL_LDD15 73
5521+
5522+#define GPIO_NR_HTCUNIVERSAL_LFCLK_RD 74
5523+#define GPIO_NR_HTCUNIVERSAL_LFCLK_A0 75
5524+#define GPIO_NR_HTCUNIVERSAL_LFCLK_WR 76
5525+#define GPIO_NR_HTCUNIVERSAL_LBIAS 77
5526+
5527+#define GPIO_NR_HTCUNIVERSAL_CS2_N 78
5528+#define GPIO_NR_HTCUNIVERSAL_CS3_N 79
5529+#define GPIO_NR_HTCUNIVERSAL_CS4_N 80
5530+#define GPIO_NR_HTCUNIVERSAL_CIF_DD0 81
5531+#define GPIO_NR_HTCUNIVERSAL_CIF_DD5 82
5532+
5533+#define GPIO_NR_HTCUNIVERSAL_CIF_LV 84
5534+#define GPIO_NR_HTCUNIVERSAL_CIF_FV 85
5535+
5536+#define GPIO_NR_HTCUNIVERSAL_LCD1 86
5537+#define GPIO_NR_HTCUNIVERSAL_LCD2 87
5538+
5539+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN5 90
5540+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN6 91
5541+
5542+#define GPIO_NR_HTCUNIVERSAL_DREQ1 97
5543+
5544+#define GPIO_NR_HTCUNIVERSAL_PHONE_RESET 98
5545+
5546+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN0 100
5547+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN1 101
5548+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN2 102
5549+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT0 103
5550+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT1 104
5551+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT2 105
5552+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT3 106
5553+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT4 107
5554+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT5 108
5555+
5556+#define GPIO_NR_HTCUNIVERSAL_PHONE_UNKNOWN 109
5557+#define GPIO_NR_HTCUNIVERSAL_PHONE_OFF 110
5558+
5559+#define GPIO_NR_HTCUNIVERSAL_USB_PUEN 112
5560+#define GPIO_NR_HTCUNIVERSAL_I2S_SYSCLK 113
5561+
5562+#define GPIO_NR_HTCUNIVERSAL_PWM_OUT1 115
5563+
5564+#define GPIO_NR_HTCUNIVERSAL_I2C_SCL 117
5565+#define GPIO_NR_HTCUNIVERSAL_I2C_SDA 118
5566+
5567+#if 0
5568+#define GPIO_NR_HTCUNIVERSAL_CPU_BATT_FAULT_N
5569+#define GPIO_NR_HTCUNIVERSAL_ASIC3_RESET_N
5570+#define GPIO_NR_HTCUNIVERSAL_CHARGE_EN_N
5571+#define GPIO_NR_HTCUNIVERSAL_FLASH_VPEN
5572+#define GPIO_NR_HTCUNIVERSAL_BATT_OFF
5573+#define GPIO_NR_HTCUNIVERSAL_USB_CHARGE_RATE
5574+#define GPIO_NR_HTCUNIVERSAL_BL_DETECT_N
5575+#define GPIO_NR_HTCUNIVERSAL_CPU_HW_RESET_N
5576+#endif
5577+
5578+
5579+#define GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_CLK_MD (23 | GPIO_ALT_FN_2_OUT)
5580+#define GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_FRM_MD (24 | GPIO_ALT_FN_2_OUT)
5581+#define GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_DO_MD (25 | GPIO_ALT_FN_2_OUT)
5582+#define GPIO_NR_HTCUNIVERSAL_TOUCHSCREEN_SPI_DI_MD (26 | GPIO_ALT_FN_1_IN)
5583+
5584+#define GPIO_NR_HTCUNIVERSAL_I2S_BCK_MD (28 | GPIO_ALT_FN_1_OUT)
5585+#define GPIO_NR_HTCUNIVERSAL_I2S_DIN_MD (29 | GPIO_ALT_FN_2_IN)
5586+#define GPIO_NR_HTCUNIVERSAL_I2S_DOUT_MD (30 | GPIO_ALT_FN_1_OUT)
5587+#define GPIO_NR_HTCUNIVERSAL_I2S_SYNC_MD (31 | GPIO_ALT_FN_1_OUT)
5588+
5589+#define GPIO_NR_HTCUNIVERSAL_PHONE_RXD_MD (34 | GPIO_ALT_FN_1_IN)
5590+#define GPIO_NR_HTCUNIVERSAL_PHONE_UART_CTS_MD (35 | GPIO_ALT_FN_1_IN)
5591+
5592+#define GPIO_NR_HTCUNIVERSAL_PHONE_TXD_MD (39 | GPIO_ALT_FN_2_OUT)
5593+#define GPIO_NR_HTCUNIVERSAL_PHONE_UART_RTS_MD (41 | GPIO_ALT_FN_2_OUT)
5594+
5595+#define GPIO_NR_HTCUNIVERSAL_BT_RXD_MD (42 | GPIO_ALT_FN_1_IN)
5596+#define GPIO_NR_HTCUNIVERSAL_BT_TXD_MD (43 | GPIO_ALT_FN_2_OUT)
5597+#define GPIO_NR_HTCUNIVERSAL_BT_UART_CTS_MD (44 | GPIO_ALT_FN_1_IN)
5598+#define GPIO_NR_HTCUNIVERSAL_BT_UART_RTS_MD (45 | GPIO_ALT_FN_2_OUT)
5599+
5600+#define GPIO_NR_HTCUNIVERSAL_SIR_RXD_MD (46 | GPIO_ALT_FN_2_IN)
5601+#define GPIO_NR_HTCUNIVERSAL_SIR_TXD_MD (47 | GPIO_ALT_FN_1_OUT)
5602+
5603+#define GPIO_NR_HTCUNIVERSAL_POE_N_MD (48 | GPIO_ALT_FN_2_OUT | GPIO_DFLT_HIGH)
5604+#define GPIO_NR_HTCUNIVERSAL_PWE_N_MD (49 | GPIO_ALT_FN_2_OUT | GPIO_DFLT_HIGH)
5605+
5606+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN0_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN0 | GPIO_ALT_FN_1_IN)
5607+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN1_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN1 | GPIO_ALT_FN_1_IN)
5608+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN2_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN2 | GPIO_ALT_FN_1_IN)
5609+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN3_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN3 | GPIO_ALT_FN_3_IN)
5610+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN4_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN4 | GPIO_ALT_FN_2_IN)
5611+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN5_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN5 | GPIO_ALT_FN_1_IN)
5612+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN6_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN6 | GPIO_ALT_FN_1_IN)
5613+#define GPIO_NR_HTCUNIVERSAL_KP_MKIN7_MD (GPIO_NR_HTCUNIVERSAL_KP_MKIN7 | GPIO_ALT_FN_3_IN)
5614+
5615+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT0_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT0 | GPIO_ALT_FN_2_OUT)
5616+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT1_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT1 | GPIO_ALT_FN_2_OUT)
5617+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT2_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT2 | GPIO_ALT_FN_2_OUT)
5618+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT3_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT3 | GPIO_ALT_FN_2_OUT)
5619+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT4_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT4 | GPIO_ALT_FN_2_OUT)
5620+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT5_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT5 | GPIO_ALT_FN_2_OUT)
5621+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT6_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT6 | GPIO_ALT_FN_1_OUT)
5622+#define GPIO_NR_HTCUNIVERSAL_KP_MKOUT7_MD (GPIO_NR_HTCUNIVERSAL_KP_MKOUT7 | GPIO_ALT_FN_1_OUT)
5623+
5624+
5625+#define GPIO_NR_HTCUNIVERSAL_I2S_SYSCLK_MD (113 | GPIO_ALT_FN_1_OUT)
5626+
5627+#define GPIO_NR_HTCUNIVERSAL_PWM1OUT_MD (115 | GPIO_ALT_FN_3_OUT)
5628+
5629+#define GPIO_NR_HTCUNIVERSAL_I2C_SCL_MD (117 | GPIO_ALT_FN_1_OUT)
5630+#define GPIO_NR_HTCUNIVERSAL_I2C_SDA_MD (118 | GPIO_ALT_FN_1_OUT)
5631+
5632+#endif /* _HTCUNIVERSAL_GPIO_H */
5633Index: linux-2.6.26-rc4/include/asm-arm/arch-pxa/htcuniversal-init.h
5634===================================================================
5635--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5636+++ linux-2.6.26-rc4/include/asm-arm/arch-pxa/htcuniversal-init.h 2008-06-01 18:49:45.000000000 +0100
5637@@ -0,0 +1,14 @@
5638+/*
5639+ * include/asm/arm/arch-pxa/htcuniversal-init.h
5640+ * Copyright (c) 2004 SDG Systems, LLC
5641+ */
5642+
5643+#ifndef _HTCUNIVERSAL_INIT_H_
5644+#define _HTCUNIVERSAL_INIT_H_
5645+
5646+/* htcuniversal initialization data should be found here
5647+ * See -init.h files from other devices for details
5648+ */
5649+
5650+#endif /* _HTCUNIVERSAL_INIT_H_ */
5651+
5652Index: linux-2.6.26-rc4/include/asm-arm/arch-pxa/htcuniversal.h
5653===================================================================
5654--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5655+++ linux-2.6.26-rc4/include/asm-arm/arch-pxa/htcuniversal.h 2008-06-01 18:49:45.000000000 +0100
5656@@ -0,0 +1,3 @@
5657+#include <asm/arch/irqs.h>
5658+
5659+#define HTCUNIVERSAL_ASIC3_IRQ_BASE IRQ_BOARD_START
5660Index: linux-2.6.26-rc4/include/asm-arm/arch-pxa/pxa-pm_ll.h
5661===================================================================
5662--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5663+++ linux-2.6.26-rc4/include/asm-arm/arch-pxa/pxa-pm_ll.h 2008-06-01 18:49:45.000000000 +0100
5664@@ -0,0 +1,6 @@
5665+struct pxa_ll_pm_ops {
5666+ void (*suspend)(unsigned long);
5667+ void (*resume)(void);
5668+};
5669+
5670+extern struct pxa_ll_pm_ops *pxa_pm_set_ll_ops(struct pxa_ll_pm_ops *new_ops);
5671Index: linux-2.6.26-rc4/include/asm-arm/hardware/asic3_keys.h
5672===================================================================
5673--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5674+++ linux-2.6.26-rc4/include/asm-arm/hardware/asic3_keys.h 2008-06-01 18:49:45.000000000 +0100
5675@@ -0,0 +1,18 @@
5676+#include <linux/input.h>
5677+
5678+struct asic3_keys_button {
5679+ /* Configuration parameters */
5680+ int keycode;
5681+ int gpio;
5682+ int active_low;
5683+ char *desc;
5684+ int type;
5685+ /* Internal state vars - add below */
5686+};
5687+
5688+struct asic3_keys_platform_data {
5689+ struct asic3_keys_button *buttons;
5690+ int nbuttons;
5691+ struct input_dev *input;
5692+ struct device *asic3_dev;
5693+};
5694Index: linux-2.6.26-rc4/include/asm-arm/hardware/asic3_leds.h
5695===================================================================
5696--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5697+++ linux-2.6.26-rc4/include/asm-arm/hardware/asic3_leds.h 2008-06-01 18:49:45.000000000 +0100
5698@@ -0,0 +1,34 @@
5699+/*
5700+ * LEDs support for HTC ASIC3 devices.
5701+ *
5702+ * Copyright (c) 2006 Anton Vorontsov <cbou@mail.ru>
5703+ *
5704+ * This file is subject to the terms and conditions of the GNU General Public
5705+ * License. See the file COPYING in the main directory of this archive for
5706+ * more details.
5707+ *
5708+ */
5709+
5710+#include <linux/kernel.h>
5711+#include <linux/init.h>
5712+#include <linux/platform_device.h>
5713+#include <linux/leds.h>
5714+
5715+struct asic3_leds_machinfo;
5716+
5717+struct asic3_led {
5718+ struct led_classdev led_cdev;
5719+ int hw_num; /* Number of "hardware-accelerated" led */
5720+ int gpio_num; /* Number of GPIO if hw_num == -1 */
5721+ struct asic3_leds_machinfo *machinfo;
5722+};
5723+
5724+struct asic3_leds_machinfo {
5725+ int num_leds;
5726+ struct asic3_led *leds;
5727+ struct platform_device *asic3_pdev;
5728+};
5729+
5730+extern int asic3_leds_register(void);
5731+extern void asic3_leds_unregister(void);
5732+
5733Index: linux-2.6.26-rc4/include/asm-arm/hardware/ipaq-asic3.h
5734===================================================================
5735--- /dev/null 1970-01-01 00:00:00.000000000 +0000
5736+++ linux-2.6.26-rc4/include/asm-arm/hardware/ipaq-asic3.h 2008-06-01 18:49:45.000000000 +0100
5737@@ -0,0 +1,602 @@
5738+/*
5739+ *
5740+ * Definitions for the HTC ASIC3 chip found in several handheld devices
5741+ *
5742+ * Copyright 2001 Compaq Computer Corporation.
5743+ *
5744+ * This program is free software; you can redistribute it and/or modify
5745+ * it under the terms of the GNU General Public License as published by
5746+ * the Free Software Foundation; either version 2 of the License, or
5747+ * (at your option) any later version.
5748+ *
5749+ * COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
5750+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
5751+ * FITNESS FOR ANY PARTICULAR PURPOSE.
5752+ *
5753+ * Author: Andrew Christian
5754+ *
5755+ */
5756+
5757+#ifndef IPAQ_ASIC3_H
5758+#define IPAQ_ASIC3_H
5759+
5760+/****************************************************/
5761+/* IPAQ, ASIC #3, replaces ASIC #1 */
5762+
5763+#define IPAQ_ASIC3_OFFSET(x,y) (_IPAQ_ASIC3_ ## x ## _Base + _IPAQ_ASIC3_ ## x ## _ ## y)
5764+#define IPAQ_ASIC3_GPIO_OFFSET(x,y) (_IPAQ_ASIC3_GPIO_ ## x ## _Base + _IPAQ_ASIC3_GPIO_ ## y)
5765+
5766+
5767+/* All offsets below are specified with the following address bus shift */
5768+#define ASIC3_DEFAULT_ADDR_SHIFT 2
5769+
5770+#define _IPAQ_ASIC3_GPIO_A_Base 0x0000
5771+#define _IPAQ_ASIC3_GPIO_B_Base 0x0100
5772+#define _IPAQ_ASIC3_GPIO_C_Base 0x0200
5773+#define _IPAQ_ASIC3_GPIO_D_Base 0x0300
5774+
5775+#define _IPAQ_ASIC3_GPIO_Mask 0x00 /* R/W 0:don't mask, 1:mask interrupt */
5776+#define _IPAQ_ASIC3_GPIO_Direction 0x04 /* R/W 0:input, 1:output */
5777+#define _IPAQ_ASIC3_GPIO_Out 0x08 /* R/W 0:output low, 1:output high */
5778+#define _IPAQ_ASIC3_GPIO_TriggerType 0x0c /* R/W 0:level, 1:edge */
5779+#define _IPAQ_ASIC3_GPIO_EdgeTrigger 0x10 /* R/W 0:falling, 1:rising */
5780+#define _IPAQ_ASIC3_GPIO_LevelTrigger 0x14 /* R/W 0:low, 1:high level detect */
5781+#define _IPAQ_ASIC3_GPIO_SleepMask 0x18 /* R/W 0:don't mask, 1:mask trigger in sleep mode */
5782+#define _IPAQ_ASIC3_GPIO_SleepOut 0x1c /* R/W level 0:low, 1:high in sleep mode */
5783+#define _IPAQ_ASIC3_GPIO_BattFaultOut 0x20 /* R/W level 0:low, 1:high in batt_fault */
5784+#define _IPAQ_ASIC3_GPIO_IntStatus 0x24 /* R/W 0:none, 1:detect */
5785+#define _IPAQ_ASIC3_GPIO_AltFunction 0x28 /* R/W 0:normal control 1:LED register control */
5786+#define _IPAQ_ASIC3_GPIO_SleepConf 0x2c /* R/W bit 1: autosleep 0: disable gposlpout in normal mode, enable gposlpout in sleep mode */
5787+#define _IPAQ_ASIC3_GPIO_Status 0x30 /* R Pin status */
5788+
5789+#define IPAQ_ASIC3_GPIO_A_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, A, Mask )
5790+#define IPAQ_ASIC3_GPIO_A_DIR(_b) IPAQ_ASIC3_GPIO( _b, u16, A, Direction )
5791+#define IPAQ_ASIC3_GPIO_A_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, A, Out )
5792+#define IPAQ_ASIC3_GPIO_A_LEVELTRI(_b) IPAQ_ASIC3_GPIO( _b, u16, A, TriggerType )
5793+#define IPAQ_ASIC3_GPIO_A_RISING(_b) IPAQ_ASIC3_GPIO( _b, u16, A, EdgeTrigger )
5794+#define IPAQ_ASIC3_GPIO_A_LEVEL(_b) IPAQ_ASIC3_GPIO( _b, u16, A, LevelTrigger )
5795+#define IPAQ_ASIC3_GPIO_A_SLEEP_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, A, SleepMask )
5796+#define IPAQ_ASIC3_GPIO_A_SLEEP_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, A, SleepOut )
5797+#define IPAQ_ASIC3_GPIO_A_BATT_FAULT_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, A, BattFaultOut )
5798+#define IPAQ_ASIC3_GPIO_A_INT_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, A, IntStatus )
5799+#define IPAQ_ASIC3_GPIO_A_ALT_FUNCTION(_b) IPAQ_ASIC3_GPIO( _b, u16, A, AltFunction )
5800+#define IPAQ_ASIC3_GPIO_A_SLEEP_CONF(_b) IPAQ_ASIC3_GPIO( _b, u16, A, SleepConf )
5801+#define IPAQ_ASIC3_GPIO_A_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, A, Status )
5802+
5803+#define IPAQ_ASIC3_GPIO_B_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, B, Mask )
5804+#define IPAQ_ASIC3_GPIO_B_DIR(_b) IPAQ_ASIC3_GPIO( _b, u16, B, Direction )
5805+#define IPAQ_ASIC3_GPIO_B_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, B, Out )
5806+#define IPAQ_ASIC3_GPIO_B_LEVELTRI(_b) IPAQ_ASIC3_GPIO( _b, u16, B, TriggerType )
5807+#define IPAQ_ASIC3_GPIO_B_RISING(_b) IPAQ_ASIC3_GPIO( _b, u16, B, EdgeTrigger )
5808+#define IPAQ_ASIC3_GPIO_B_LEVEL(_b) IPAQ_ASIC3_GPIO( _b, u16, B, LevelTrigger )
5809+#define IPAQ_ASIC3_GPIO_B_SLEEP_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, B, SleepMask )
5810+#define IPAQ_ASIC3_GPIO_B_SLEEP_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, B, SleepOut )
5811+#define IPAQ_ASIC3_GPIO_B_BATT_FAULT_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, B, BattFaultOut )
5812+#define IPAQ_ASIC3_GPIO_B_INT_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, B, IntStatus )
5813+#define IPAQ_ASIC3_GPIO_B_ALT_FUNCTION(_b) IPAQ_ASIC3_GPIO( _b, u16, B, AltFunction )
5814+#define IPAQ_ASIC3_GPIO_B_SLEEP_CONF(_b) IPAQ_ASIC3_GPIO( _b, u16, B, SleepConf )
5815+#define IPAQ_ASIC3_GPIO_B_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, B, Status )
5816+
5817+#define IPAQ_ASIC3_GPIO_C_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, C, Mask )
5818+#define IPAQ_ASIC3_GPIO_C_DIR(_b) IPAQ_ASIC3_GPIO( _b, u16, C, Direction )
5819+#define IPAQ_ASIC3_GPIO_C_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, C, Out )
5820+#define IPAQ_ASIC3_GPIO_C_LEVELTRI(_b) IPAQ_ASIC3_GPIO( _b, u16, C, TriggerType )
5821+#define IPAQ_ASIC3_GPIO_C_RISING(_b) IPAQ_ASIC3_GPIO( _b, u16, C, EdgeTrigger )
5822+#define IPAQ_ASIC3_GPIO_C_LEVEL(_b) IPAQ_ASIC3_GPIO( _b, u16, C, LevelTrigger )
5823+#define IPAQ_ASIC3_GPIO_C_SLEEP_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, C, SleepMask )
5824+#define IPAQ_ASIC3_GPIO_C_SLEEP_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, C, SleepOut )
5825+#define IPAQ_ASIC3_GPIO_C_BATT_FAULT_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, C, BattFaultOut )
5826+#define IPAQ_ASIC3_GPIO_C_INT_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, C, IntStatus )
5827+#define IPAQ_ASIC3_GPIO_C_ALT_FUNCTION(_b) IPAQ_ASIC3_GPIO( _b, u16, C, AltFunction )
5828+#define IPAQ_ASIC3_GPIO_C_SLEEP_CONF(_b) IPAQ_ASIC3_GPIO( _b, u16, C, SleepConf )
5829+#define IPAQ_ASIC3_GPIO_C_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, C, Status )
5830+
5831+#define IPAQ_ASIC3_GPIO_D_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, D, Mask )
5832+#define IPAQ_ASIC3_GPIO_D_DIR(_b) IPAQ_ASIC3_GPIO( _b, u16, D, Direction )
5833+#define IPAQ_ASIC3_GPIO_D_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, D, Out )
5834+#define IPAQ_ASIC3_GPIO_D_LEVELTRI(_b) IPAQ_ASIC3_GPIO( _b, u16, D, TriggerType )
5835+#define IPAQ_ASIC3_GPIO_D_RISING(_b) IPAQ_ASIC3_GPIO( _b, u16, D, EdgeTrigger )
5836+#define IPAQ_ASIC3_GPIO_D_LEVEL(_b) IPAQ_ASIC3_GPIO( _b, u16, D, LevelTrigger )
5837+#define IPAQ_ASIC3_GPIO_D_SLEEP_MASK(_b) IPAQ_ASIC3_GPIO( _b, u16, D, SleepMask )
5838+#define IPAQ_ASIC3_GPIO_D_SLEEP_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, D, SleepOut )
5839+#define IPAQ_ASIC3_GPIO_D_BATT_FAULT_OUT(_b) IPAQ_ASIC3_GPIO( _b, u16, D, BattFaultOut )
5840+#define IPAQ_ASIC3_GPIO_D_INT_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, D, IntStatus )
5841+#define IPAQ_ASIC3_GPIO_D_ALT_FUNCTION(_b) IPAQ_ASIC3_GPIO( _b, u16, D, AltFunction )
5842+#define IPAQ_ASIC3_GPIO_D_SLEEP_CONF(_b) IPAQ_ASIC3_GPIO( _b, u16, D, SleepConf )
5843+#define IPAQ_ASIC3_GPIO_D_STATUS(_b) IPAQ_ASIC3_GPIO( _b, u16, D, Status )
5844+
5845+#define _IPAQ_ASIC3_SPI_Base 0x0400
5846+#define _IPAQ_ASIC3_SPI_Control 0x0000
5847+#define _IPAQ_ASIC3_SPI_TxData 0x0004
5848+#define _IPAQ_ASIC3_SPI_RxData 0x0008
5849+#define _IPAQ_ASIC3_SPI_Int 0x000c
5850+#define _IPAQ_ASIC3_SPI_Status 0x0010
5851+
5852+#define IPAQ_ASIC3_SPI_Control(_b) IPAQ_ASIC3( _b, u16, SPI, Control )
5853+#define IPAQ_ASIC3_SPI_TxData(_b) IPAQ_ASIC3( _b, u16, SPI, TxData )
5854+#define IPAQ_ASIC3_SPI_RxData(_b) IPAQ_ASIC3( _b, u16, SPI, RxData )
5855+#define IPAQ_ASIC3_SPI_Int(_b) IPAQ_ASIC3( _b, u16, SPI, Int )
5856+#define IPAQ_ASIC3_SPI_Status(_b) IPAQ_ASIC3( _b, u16, SPI, Status )
5857+
5858+#define SPI_CONTROL_SPR(clk) ((clk) & 0x0f) /* Clock rate */
5859+
5860+#define _IPAQ_ASIC3_PWM_0_Base 0x0500
5861+#define _IPAQ_ASIC3_PWM_1_Base 0x0600
5862+#define _IPAQ_ASIC3_PWM_TimeBase 0x0000
5863+#define _IPAQ_ASIC3_PWM_PeriodTime 0x0004
5864+#define _IPAQ_ASIC3_PWM_DutyTime 0x0008
5865+
5866+#define IPAQ_ASIC3_PWM_TimeBase(_b, x) IPAQ_ASIC3_N( _b, u16, PWM, x, TimeBase )
5867+#define IPAQ_ASIC3_PWM_PeriodTime(_b, x) IPAQ_ASIC3_N( _b, u16, PWM, x, PeriodTime )
5868+#define IPAQ_ASIC3_PWM_DutyTime(_b, x) IPAQ_ASIC3_N( _b, u16, PWM, x, DutyTime )
5869+
5870+#define PWM_TIMEBASE_VALUE(x) ((x)&0xf) /* Low 4 bits sets time base */
5871+#define PWM_TIMEBASE_ENABLE (1 << 4) /* Enable clock */
5872+
5873+#define _IPAQ_ASIC3_LED_0_Base 0x0700
5874+#define _IPAQ_ASIC3_LED_1_Base 0x0800
5875+#define _IPAQ_ASIC3_LED_2_Base 0x0900
5876+#define _IPAQ_ASIC3_LED_TimeBase 0x0000 /* R/W 7 bits */
5877+#define _IPAQ_ASIC3_LED_PeriodTime 0x0004 /* R/W 12 bits */
5878+#define _IPAQ_ASIC3_LED_DutyTime 0x0008 /* R/W 12 bits */
5879+#define _IPAQ_ASIC3_LED_AutoStopCount 0x000c /* R/W 16 bits */
5880+
5881+#define IPAQ_ASIC3_LED_TimeBase(_b, x) IPAQ_ASIC3_N( _b, u8, LED, x, TimeBase )
5882+#define IPAQ_ASIC3_LED_PeriodTime(_b, x) IPAQ_ASIC3_N( _b, u16, LED, x, PeriodTime )
5883+#define IPAQ_ASIC3_LED_DutyTime(_b, x) IPAQ_ASIC3_N( _b, u16, LED, x, DutyTime )
5884+#define IPAQ_ASIC3_LED_AutoStopCount(_b, x) IPAQ_ASIC3_N( _b, u16, LED, x, AutoStopCount )
5885+
5886+/* LED TimeBase bits - match ASIC2 */
5887+#define LED_TBS 0x0f /* Low 4 bits sets time base, max = 13 */
5888+ /* Note: max = 5 on hx4700 */
5889+ /* 0: maximum time base */
5890+ /* 1: maximum time base / 2 */
5891+ /* n: maximum time base / 2^n */
5892+
5893+#define LED_EN (1 << 4) /* LED ON/OFF 0:off, 1:on */
5894+#define LED_AUTOSTOP (1 << 5) /* LED ON/OFF auto stop set 0:disable, 1:enable */
5895+#define LED_ALWAYS (1 << 6) /* LED Interrupt Mask 0:No mask, 1:mask */
5896+
5897+#define _IPAQ_ASIC3_CLOCK_Base 0x0A00
5898+#define _IPAQ_ASIC3_CLOCK_CDEX 0x00
5899+#define _IPAQ_ASIC3_CLOCK_SEL 0x04
5900+
5901+#define IPAQ_ASIC3_CLOCK_CDEX(_b) IPAQ_ASIC3( _b, u16, CLOCK, CDEX )
5902+#define IPAQ_ASIC3_CLOCK_SEL(_b) IPAQ_ASIC3( _b, u16, CLOCK, SEL )
5903+
5904+#define CLOCK_CDEX_SOURCE (1 << 0) /* 2 bits */
5905+#define CLOCK_CDEX_SOURCE0 (1 << 0)
5906+#define CLOCK_CDEX_SOURCE1 (1 << 1)
5907+#define CLOCK_CDEX_SPI (1 << 2)
5908+#define CLOCK_CDEX_OWM (1 << 3)
5909+#define CLOCK_CDEX_PWM0 (1 << 4)
5910+#define CLOCK_CDEX_PWM1 (1 << 5)
5911+#define CLOCK_CDEX_LED0 (1 << 6)
5912+#define CLOCK_CDEX_LED1 (1 << 7)
5913+#define CLOCK_CDEX_LED2 (1 << 8)
5914+
5915+#define CLOCK_CDEX_SD_HOST (1 << 9) /* R/W: SD host clock source 24.576M/12.288M */
5916+#define CLOCK_CDEX_SD_BUS (1 << 10) /* R/W: SD bus clock source control 24.576M/12.288M */
5917+#define CLOCK_CDEX_SMBUS (1 << 11)
5918+#define CLOCK_CDEX_CONTROL_CX (1 << 12)
5919+
5920+#define CLOCK_CDEX_EX0 (1 << 13) /* R/W: 32.768 kHz crystal */
5921+#define CLOCK_CDEX_EX1 (1 << 14) /* R/W: 24.576 MHz crystal */
5922+
5923+#define CLOCK_SEL_SD_HCLK_SEL (1 << 0) /* R/W: SDIO host clock select - 1: 24.576 Mhz, 0: 12.288 MHz */
5924+#define CLOCK_SEL_SD_BCLK_SEL (1 << 1) /* R/W: SDIO bus clock select - 1: 24.576 MHz, 0: 12.288 MHz */
5925+#define CLOCK_SEL_CX (1 << 2) /* R/W: INT clock source control (32.768 kHz) */
5926+
5927+
5928+#define _IPAQ_ASIC3_INTR_Base 0x0B00
5929+
5930+#define _IPAQ_ASIC3_INTR_IntMask 0x00 /* Interrupt mask control */
5931+#define _IPAQ_ASIC3_INTR_PIntStat 0x04 /* Peripheral interrupt status */
5932+#define _IPAQ_ASIC3_INTR_IntCPS 0x08 /* Interrupt timer clock pre-scale */
5933+#define _IPAQ_ASIC3_INTR_IntTBS 0x0c /* Interrupt timer set */
5934+
5935+#define IPAQ_ASIC3_INTR_IntMask(_b) IPAQ_ASIC3( _b, u8, INTR, IntMask )
5936+#define IPAQ_ASIC3_INTR_PIntStat(_b) IPAQ_ASIC3( _b, u8, INTR, PIntStat )
5937+#define IPAQ_ASIC3_INTR_IntCPS(_b) IPAQ_ASIC3( _b, u8, INTR, IntCPS )
5938+#define IPAQ_ASIC3_INTR_IntTBS(_b) IPAQ_ASIC3( _b, u16, INTR, IntTBS )
5939+
5940+#define ASIC3_INTMASK_GINTMASK (1 << 0) /* Global interrupt mask 1:enable */
5941+#define ASIC3_INTMASK_GINTEL (1 << 1) /* 1: rising edge, 0: hi level */
5942+#define ASIC3_INTMASK_MASK0 (1 << 2)
5943+#define ASIC3_INTMASK_MASK1 (1 << 3)
5944+#define ASIC3_INTMASK_MASK2 (1 << 4)
5945+#define ASIC3_INTMASK_MASK3 (1 << 5)
5946+#define ASIC3_INTMASK_MASK4 (1 << 6)
5947+#define ASIC3_INTMASK_MASK5 (1 << 7)
5948+
5949+#define ASIC3_INTR_PERIPHERAL_A (1 << 0)
5950+#define ASIC3_INTR_PERIPHERAL_B (1 << 1)
5951+#define ASIC3_INTR_PERIPHERAL_C (1 << 2)
5952+#define ASIC3_INTR_PERIPHERAL_D (1 << 3)
5953+#define ASIC3_INTR_LED0 (1 << 4)
5954+#define ASIC3_INTR_LED1 (1 << 5)
5955+#define ASIC3_INTR_LED2 (1 << 6)
5956+#define ASIC3_INTR_SPI (1 << 7)
5957+#define ASIC3_INTR_SMBUS (1 << 8)
5958+#define ASIC3_INTR_OWM (1 << 9)
5959+
5960+#define ASIC3_INTR_CPS(x) ((x)&0x0f) /* 4 bits, max 14 */
5961+#define ASIC3_INTR_CPS_SET ( 1 << 4 ) /* Time base enable */
5962+
5963+
5964+/* Basic control of the SD ASIC */
5965+#define _IPAQ_ASIC3_SDHWCTRL_Base 0x0E00
5966+
5967+#define _IPAQ_ASIC3_SDHWCTRL_SDConf 0x00
5968+#define IPAQ_ASIC3_SDHWCTRL_SDConf(_b) IPAQ_ASIC3( _b, u8, SDHWCTRL, SDConf )
5969+
5970+#define ASIC3_SDHWCTRL_SUSPEND (1 << 0) /* 1=suspend all SD operations */
5971+#define ASIC3_SDHWCTRL_CLKSEL (1 << 1) /* 1=SDICK, 0=HCLK */
5972+#define ASIC3_SDHWCTRL_PCLR (1 << 2) /* All registers of SDIO cleared */
5973+#define ASIC3_SDHWCTRL_LEVCD (1 << 3) /* Level of SD card detection: 1:high, 0:low */
5974+#define ASIC3_SDHWCTRL_LEVWP (1 << 4) /* Level of SD card write protection: 1=low, 0=high */
5975+#define ASIC3_SDHWCTRL_SDLED (1 << 5) /* SD card LED signal 1=enable, 0=disable */
5976+#define ASIC3_SDHWCTRL_SDPWR (1 << 6) /* SD card power supply control 1=enable */
5977+
5978+
5979+/* This is a pointer to an array of 12 u32 values - but only the lower 2 bytes matter */
5980+/* Use it as "IPAQ_ASIC3_HWPROTECT_ARRAY[x]" */
5981+
5982+#define _IPAQ_ASIC3_HWPROTECT_Base 0x1000
5983+#define IPAQ_ASIC3_HWPROTECT_ARRAY ((volatile u32*)(_IPAQ_ASIC3_Base + _IPAQ_ASIC3_HWPROTECT_Base))
5984+#define HWPROTECT_ARRAY_LEN 12
5985+#define HWPROTECT_ARRAY_VALUES {0x4854,0x432d,0x5344,0x494f,0x2050,0x2f4e,0x3a33,0x3048,0x3830,0x3032,0x382d,0x3030}
5986+
5987+
5988+#define _IPAQ_ASIC3_EXTCF_Base 0x1100
5989+
5990+#define _IPAQ_ASIC3_EXTCF_Select 0x00
5991+#define _IPAQ_ASIC3_EXTCF_Reset 0x04
5992+
5993+#define IPAQ_ASIC3_EXTCF_Select(_b) IPAQ_ASIC3( _b, u16, EXTCF, Select )
5994+#define IPAQ_ASIC3_EXTCF_Reset(_b) IPAQ_ASIC3( _b, u16, EXTCF, Reset )
5995+
5996+#define ASIC3_EXTCF_SMOD0 (1 << 0) /* slot number of mode 0 */
5997+#define ASIC3_EXTCF_SMOD1 (1 << 1) /* slot number of mode 1 */
5998+#define ASIC3_EXTCF_SMOD2 (1 << 2) /* slot number of mode 2 */
5999+#define ASIC3_EXTCF_OWM_EN (1 << 4) /* enable onewire module */
6000+#define ASIC3_EXTCF_OWM_SMB (1 << 5) /* OWM bus selection */
6001+#define ASIC3_EXTCF_OWM_RESET (1 << 6) /* undocumented, used by OWM and CF */
6002+#define ASIC3_EXTCF_CF0_SLEEP_MODE (1 << 7) /* CF0 sleep state control */
6003+#define ASIC3_EXTCF_CF1_SLEEP_MODE (1 << 8) /* CF1 sleep state control */
6004+#define ASIC3_EXTCF_CF0_PWAIT_EN (1 << 10) /* CF0 PWAIT_n control */
6005+#define ASIC3_EXTCF_CF1_PWAIT_EN (1 << 11) /* CF1 PWAIT_n control */
6006+#define ASIC3_EXTCF_CF0_BUF_EN (1 << 12) /* CF0 buffer control */
6007+#define ASIC3_EXTCF_CF1_BUF_EN (1 << 13) /* CF1 buffer control */
6008+#define ASIC3_EXTCF_SD_MEM_ENABLE (1 << 14)
6009+#define ASIC3_EXTCF_CF_SLEEP (1 << 15) /* CF sleep mode control */
6010+
6011+/*****************************************************************************
6012+ * The Onewire interface registers
6013+ *
6014+ * OWM_CMD
6015+ * OWM_DAT
6016+ * OWM_INTR
6017+ * OWM_INTEN
6018+ * OWM_CLKDIV
6019+ *
6020+ *****************************************************************************/
6021+
6022+#define _IPAQ_ASIC3_OWM_Base 0xC00
6023+
6024+#define _IPAQ_ASIC3_OWM_CMD 0x00
6025+#define _IPAQ_ASIC3_OWM_DAT 0x04
6026+#define _IPAQ_ASIC3_OWM_INTR 0x08
6027+#define _IPAQ_ASIC3_OWM_INTEN 0x0C
6028+#define _IPAQ_ASIC3_OWM_CLKDIV 0x10
6029+
6030+#define ASIC3_OWM_CMD_ONEWR (1 << 0)
6031+#define ASIC3_OWM_CMD_SRA (1 << 1)
6032+#define ASIC3_OWM_CMD_DQO (1 << 2)
6033+#define ASIC3_OWM_CMD_DQI (1 << 3)
6034+
6035+#define ASIC3_OWM_INTR_PD (1 << 0)
6036+#define ASIC3_OWM_INTR_PDR (1 << 1)
6037+#define ASIC3_OWM_INTR_TBE (1 << 2)
6038+#define ASIC3_OWM_INTR_TEMP (1 << 3)
6039+#define ASIC3_OWM_INTR_RBF (1 << 4)
6040+
6041+#define ASIC3_OWM_INTEN_EPD (1 << 0)
6042+#define ASIC3_OWM_INTEN_IAS (1 << 1)
6043+#define ASIC3_OWM_INTEN_ETBE (1 << 2)
6044+#define ASIC3_OWM_INTEN_ETMT (1 << 3)
6045+#define ASIC3_OWM_INTEN_ERBF (1 << 4)
6046+
6047+#define ASIC3_OWM_CLKDIV_PRE (3 << 0) /* two bits wide at bit position 0 */
6048+#define ASIC3_OWM_CLKDIV_DIV (7 << 2) /* 3 bits wide at bit position 2 */
6049+
6050+
6051+/*****************************************************************************
6052+ * The SD configuration registers are at a completely different location
6053+ * in memory. They are divided into three sets of registers:
6054+ *
6055+ * SD_CONFIG Core configuration register
6056+ * SD_CTRL Control registers for SD operations
6057+ * SDIO_CTRL Control registers for SDIO operations
6058+ *
6059+ *****************************************************************************/
6060+
6061+#define IPAQ_ASIC3_SD_CONFIG(_b, s,x) \
6062+ (*((volatile s *) ((_b) + _IPAQ_ASIC3_SD_CONFIG_Base + (_IPAQ_ASIC3_SD_CONFIG_ ## x))))
6063+
6064+#define _IPAQ_ASIC3_SD_CONFIG_Base 0x0400 // Assumes 32 bit addressing
6065+
6066+#define _IPAQ_ASIC3_SD_CONFIG_Command 0x08 /* R/W: Command */
6067+#define _IPAQ_ASIC3_SD_CONFIG_Addr0 0x20 /* [9:31] SD Control Register Base Address */
6068+#define _IPAQ_ASIC3_SD_CONFIG_Addr1 0x24 /* [9:31] SD Control Register Base Address */
6069+#define _IPAQ_ASIC3_SD_CONFIG_IntPin 0x78 /* R/O: interrupt assigned to pin */
6070+#define _IPAQ_ASIC3_SD_CONFIG_ClkStop 0x80 /* Set to 0x1f to clock SD controller, 0 otherwise. */
6071+ /* at 0x82 - Gated Clock Control */
6072+#define _IPAQ_ASIC3_SD_CONFIG_ClockMode 0x84 /* Control clock of SD controller */
6073+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_PinStatus 0x88 /* R/0: read status of SD pins */
6074+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_Power1 0x90 /* Power1 - manual power control */
6075+ /* Power2 is at 0x92 - auto power up after card inserted */
6076+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_Power3 0x94 /* auto power down when card removed */
6077+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_CardDetect 0x98 /* */
6078+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_Slot 0xA0 /* R/O: define support slot number */
6079+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_ExtGateClk1 0x1E0 /* Could be used for gated clock (don't use) */
6080+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_ExtGateClk2 0x1E2 /* Could be used for gated clock (don't use) */
6081+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_GPIO_OutAndEnable 0x1E8 /* GPIO Output Reg. , at 0x1EA - GPIO Output Enable Reg. */
6082+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_GPIO_Status 0x1EC /* GPIO Status Reg. */
6083+#define _IPAQ_ASIC3_SD_CONFIG_SDHC_ExtGateClk3 0x1F0 /* Bit 1: double buffer/single buffer */
6084+
6085+#define IPAQ_ASIC3_SD_CONFIG_Command(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, Command )
6086+#define IPAQ_ASIC3_SD_CONFIG_Addr0(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, Addr0 )
6087+#define IPAQ_ASIC3_SD_CONFIG_Addr1(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, Addr1 )
6088+#define IPAQ_ASIC3_SD_CONFIG_IntPin(_b) IPAQ_ASIC3_SD_CONFIG(_b, u8, IntPin )
6089+#define IPAQ_ASIC3_SD_CONFIG_ClkStop(_b) IPAQ_ASIC3_SD_CONFIG(_b, u8, ClkStop )
6090+#define IPAQ_ASIC3_SD_CONFIG_ClockMode(_b) IPAQ_ASIC3_SD_CONFIG(_b, u8, ClockMode )
6091+#define IPAQ_ASIC3_SD_CONFIG_SDHC_PinStatus(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_PinStatus )
6092+#define IPAQ_ASIC3_SD_CONFIG_SDHC_Power1(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_Power1 )
6093+#define IPAQ_ASIC3_SD_CONFIG_SDHC_Power3(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_Power3 )
6094+#define IPAQ_ASIC3_SD_CONFIG_SDHC_CardDetect(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_CardDetect )
6095+#define IPAQ_ASIC3_SD_CONFIG_SDHC_Slot(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_Slot )
6096+#define IPAQ_ASIC3_SD_CONFIG_SDHC_ExtGateClk1(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_ExtGateClk1 )
6097+#define IPAQ_ASIC3_SD_CONFIG_SDHC_ExtGateClk3(_b) IPAQ_ASIC3_SD_CONFIG(_b, u16, SDHC_ExtGateClk3 )
6098+
6099+#define SD_CONFIG_
6100+
6101+#define SD_CONFIG_COMMAND_MAE (1<<1) /* Memory access enable (set to 1 to access SD Controller) */
6102+
6103+#define SD_CONFIG_CLK_ENABLE_ALL 0x1f
6104+
6105+#define SD_CONFIG_POWER1_PC_33V 0x0200 /* Set for 3.3 volts */
6106+#define SD_CONFIG_POWER1_PC_OFF 0x0000 /* Turn off power */
6107+
6108+#define SD_CONFIG_CARDDETECTMODE_CLK ((x)&0x3) /* two bits - number of cycles for card detection */
6109+
6110+
6111+#define _IPAQ_ASIC3_SD_CTRL_Base 0x1000
6112+
6113+#define IPAQ_ASIC3_SD(_b, s,x) \
6114+ (*((volatile s *) ((_b) + _IPAQ_ASIC3_SD_CTRL_Base + (_IPAQ_ASIC3_SD_CTRL_ ## x))))
6115+
6116+#define _IPAQ_ASIC3_SD_CTRL_Cmd 0x00
6117+#define _IPAQ_ASIC3_SD_CTRL_Arg0 0x08
6118+#define _IPAQ_ASIC3_SD_CTRL_Arg1 0x0C
6119+#define _IPAQ_ASIC3_SD_CTRL_StopInternal 0x10
6120+#define _IPAQ_ASIC3_SD_CTRL_TransferSectorCount 0x14
6121+#define _IPAQ_ASIC3_SD_CTRL_Response0 0x18
6122+#define _IPAQ_ASIC3_SD_CTRL_Response1 0x1C
6123+#define _IPAQ_ASIC3_SD_CTRL_Response2 0x20
6124+#define _IPAQ_ASIC3_SD_CTRL_Response3 0x24
6125+#define _IPAQ_ASIC3_SD_CTRL_Response4 0x28
6126+#define _IPAQ_ASIC3_SD_CTRL_Response5 0x2C
6127+#define _IPAQ_ASIC3_SD_CTRL_Response6 0x30
6128+#define _IPAQ_ASIC3_SD_CTRL_Response7 0x34
6129+#define _IPAQ_ASIC3_SD_CTRL_CardStatus 0x38
6130+#define _IPAQ_ASIC3_SD_CTRL_BufferCtrl 0x3C
6131+#define _IPAQ_ASIC3_SD_CTRL_IntMaskCard 0x40
6132+#define _IPAQ_ASIC3_SD_CTRL_IntMaskBuffer 0x44
6133+#define _IPAQ_ASIC3_SD_CTRL_CardClockCtrl 0x48
6134+#define _IPAQ_ASIC3_SD_CTRL_MemCardXferDataLen 0x4C
6135+#define _IPAQ_ASIC3_SD_CTRL_MemCardOptionSetup 0x50
6136+#define _IPAQ_ASIC3_SD_CTRL_ErrorStatus0 0x58
6137+#define _IPAQ_ASIC3_SD_CTRL_ErrorStatus1 0x5C
6138+#define _IPAQ_ASIC3_SD_CTRL_DataPort 0x60
6139+#define _IPAQ_ASIC3_SD_CTRL_TransactionCtrl 0x68
6140+#define _IPAQ_ASIC3_SD_CTRL_SoftwareReset 0x1C0
6141+
6142+#define IPAQ_ASIC3_SD_CTRL_Cmd(_b) IPAQ_ASIC3_SD( _b, u16, Cmd ) /* */
6143+#define IPAQ_ASIC3_SD_CTRL_Arg0(_b) IPAQ_ASIC3_SD( _b, u16, Arg0 ) /* */
6144+#define IPAQ_ASIC3_SD_CTRL_Arg1(_b) IPAQ_ASIC3_SD( _b, u16, Arg1 ) /* */
6145+#define IPAQ_ASIC3_SD_CTRL_StopInternal(_b) IPAQ_ASIC3_SD( _b, u16, StopInternal ) /* */
6146+#define IPAQ_ASIC3_SD_CTRL_TransferSectorCount(_b) IPAQ_ASIC3_SD( _b, u16, TransferSectorCount ) /* */
6147+#define IPAQ_ASIC3_SD_CTRL_Response0(_b) IPAQ_ASIC3_SD( _b, u16, Response0 ) /* */
6148+#define IPAQ_ASIC3_SD_CTRL_Response1(_b) IPAQ_ASIC3_SD( _b, u16, Response1 ) /* */
6149+#define IPAQ_ASIC3_SD_CTRL_Response2(_b) IPAQ_ASIC3_SD( _b, u16, Response2 ) /* */
6150+#define IPAQ_ASIC3_SD_CTRL_Response3(_b) IPAQ_ASIC3_SD( _b, u16, Response3 ) /* */
6151+#define IPAQ_ASIC3_SD_CTRL_Response4(_b) IPAQ_ASIC3_SD( _b, u16, Response4 ) /* */
6152+#define IPAQ_ASIC3_SD_CTRL_Response5(_b) IPAQ_ASIC3_SD( _b, u16, Response5 ) /* */
6153+#define IPAQ_ASIC3_SD_CTRL_Response6(_b) IPAQ_ASIC3_SD( _b, u16, Response6 ) /* */
6154+#define IPAQ_ASIC3_SD_CTRL_Response7(_b) IPAQ_ASIC3_SD( _b, u16, Response7 ) /* */
6155+#define IPAQ_ASIC3_SD_CTRL_CardStatus(_b) IPAQ_ASIC3_SD( _b, u16, CardStatus ) /* */
6156+#define IPAQ_ASIC3_SD_CTRL_BufferCtrl(_b) IPAQ_ASIC3_SD( _b, u16, BufferCtrl ) /* and error status*/
6157+#define IPAQ_ASIC3_SD_CTRL_IntMaskCard(_b) IPAQ_ASIC3_SD( _b, u16, IntMaskCard ) /* */
6158+#define IPAQ_ASIC3_SD_CTRL_IntMaskBuffer(_b) IPAQ_ASIC3_SD( _b, u16, IntMaskBuffer ) /* */
6159+#define IPAQ_ASIC3_SD_CTRL_CardClockCtrl(_b) IPAQ_ASIC3_SD( _b, u16, CardClockCtrl ) /* */
6160+#define IPAQ_ASIC3_SD_CTRL_MemCardXferDataLen(_b) IPAQ_ASIC3_SD( _b, u16, MemCardXferDataLen ) /* */
6161+#define IPAQ_ASIC3_SD_CTRL_MemCardOptionSetup(_b) IPAQ_ASIC3_SD( _b, u16, MemCardOptionSetup ) /* */
6162+#define IPAQ_ASIC3_SD_CTRL_ErrorStatus0(_b) IPAQ_ASIC3_SD( _b, u16, ErrorStatus0 ) /* */
6163+#define IPAQ_ASIC3_SD_CTRL_ErrorStatus1(_b) IPAQ_ASIC3_SD( _b, u16, ErrorStatus1 ) /* */
6164+#define IPAQ_ASIC3_SD_CTRL_DataPort(_b) IPAQ_ASIC3_SD( _b, u16, DataPort ) /* */
6165+#define IPAQ_ASIC3_SD_CTRL_TransactionCtrl(_b) IPAQ_ASIC3_SD( _b, u16, TransactionCtrl ) /* */
6166+#define IPAQ_ASIC3_SD_CTRL_SoftwareReset(_b) IPAQ_ASIC3_SD( _b, u16, SoftwareReset ) /* */
6167+
6168+#define SD_CTRL_SOFTWARE_RESET_CLEAR (1<<0)
6169+
6170+#define SD_CTRL_TRANSACTIONCONTROL_SET (1<<8) // 0x0100
6171+
6172+#define SD_CTRL_CARDCLOCKCONTROL_FOR_SD_CARD (1<<15)// 0x8000
6173+#define SD_CTRL_CARDCLOCKCONTROL_ENABLE_CLOCK (1<<8) // 0x0100
6174+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_512 (1<<7) // 0x0080
6175+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_256 (1<<6) // 0x0040
6176+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_128 (1<<5) // 0x0020
6177+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_64 (1<<4) // 0x0010
6178+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_32 (1<<3) // 0x0008
6179+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_16 (1<<2) // 0x0004
6180+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_8 (1<<1) // 0x0002
6181+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_4 (1<<0) // 0x0001
6182+#define SD_CTRL_CARDCLOCKCONTROL_CLK_DIV_2 (0<<0) // 0x0000
6183+
6184+#define MEM_CARD_OPTION_REQUIRED 0x000e
6185+#define MEM_CARD_OPTION_DATA_RESPONSE_TIMEOUT(x) (((x)&0x0f)<<4) /* Four bits */
6186+#define MEM_CARD_OPTION_C2_MODULE_NOT_PRESENT (1<<14) // 0x4000
6187+#define MEM_CARD_OPTION_DATA_XFR_WIDTH_1 (1<<15) // 0x8000
6188+#define MEM_CARD_OPTION_DATA_XFR_WIDTH_4 (0<<15) //~0x8000
6189+
6190+#define SD_CTRL_COMMAND_INDEX(x) ((x)&0x3f) /* 0=CMD0, 1=CMD1, ..., 63=CMD63 */
6191+#define SD_CTRL_COMMAND_TYPE_CMD (0 << 6)
6192+#define SD_CTRL_COMMAND_TYPE_ACMD (1 << 6)
6193+#define SD_CTRL_COMMAND_TYPE_AUTHENTICATION (2 << 6)
6194+#define SD_CTRL_COMMAND_RESPONSE_TYPE_NORMAL (0 << 8)
6195+#define SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R1 (4 << 8)
6196+#define SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R1B (5 << 8)
6197+#define SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R2 (6 << 8)
6198+#define SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R3 (7 << 8)
6199+#define SD_CTRL_COMMAND_DATA_PRESENT (1 << 11)
6200+#define SD_CTRL_COMMAND_TRANSFER_READ (1 << 12)
6201+#define SD_CTRL_COMMAND_TRANSFER_WRITE (0 << 12)
6202+#define SD_CTRL_COMMAND_MULTI_BLOCK (1 << 13)
6203+#define SD_CTRL_COMMAND_SECURITY_CMD (1 << 14)
6204+
6205+#define SD_CTRL_STOP_INTERNAL_ISSSUE_CMD12 (1 << 0)
6206+#define SD_CTRL_STOP_INTERNAL_AUTO_ISSUE_CMD12 (1 << 8)
6207+
6208+#define SD_CTRL_CARDSTATUS_RESPONSE_END (1 << 0)
6209+#define SD_CTRL_CARDSTATUS_RW_END (1 << 2)
6210+#define SD_CTRL_CARDSTATUS_CARD_REMOVED_0 (1 << 3)
6211+#define SD_CTRL_CARDSTATUS_CARD_INSERTED_0 (1 << 4)
6212+#define SD_CTRL_CARDSTATUS_SIGNAL_STATE_PRESENT_0 (1 << 5)
6213+#define SD_CTRL_CARDSTATUS_WRITE_PROTECT (1 << 7)
6214+#define SD_CTRL_CARDSTATUS_CARD_REMOVED_3 (1 << 8)
6215+#define SD_CTRL_CARDSTATUS_CARD_INSERTED_3 (1 << 9)
6216+#define SD_CTRL_CARDSTATUS_SIGNAL_STATE_PRESENT_3 (1 << 10)
6217+
6218+#define SD_CTRL_BUFFERSTATUS_CMD_INDEX_ERROR (1 << 0) // 0x0001
6219+#define SD_CTRL_BUFFERSTATUS_CRC_ERROR (1 << 1) // 0x0002
6220+#define SD_CTRL_BUFFERSTATUS_STOP_BIT_END_ERROR (1 << 2) // 0x0004
6221+#define SD_CTRL_BUFFERSTATUS_DATA_TIMEOUT (1 << 3) // 0x0008
6222+#define SD_CTRL_BUFFERSTATUS_BUFFER_OVERFLOW (1 << 4) // 0x0010
6223+#define SD_CTRL_BUFFERSTATUS_BUFFER_UNDERFLOW (1 << 5) // 0x0020
6224+#define SD_CTRL_BUFFERSTATUS_CMD_TIMEOUT (1 << 6) // 0x0040
6225+#define SD_CTRL_BUFFERSTATUS_UNK7 (1 << 7) // 0x0080
6226+#define SD_CTRL_BUFFERSTATUS_BUFFER_READ_ENABLE (1 << 8) // 0x0100
6227+#define SD_CTRL_BUFFERSTATUS_BUFFER_WRITE_ENABLE (1 << 9) // 0x0200
6228+#define SD_CTRL_BUFFERSTATUS_ILLEGAL_FUNCTION (1 << 13)// 0x2000
6229+#define SD_CTRL_BUFFERSTATUS_CMD_BUSY (1 << 14)// 0x4000
6230+#define SD_CTRL_BUFFERSTATUS_ILLEGAL_ACCESS (1 << 15)// 0x8000
6231+
6232+#define SD_CTRL_INTMASKCARD_RESPONSE_END (1 << 0) // 0x0001
6233+#define SD_CTRL_INTMASKCARD_RW_END (1 << 2) // 0x0004
6234+#define SD_CTRL_INTMASKCARD_CARD_REMOVED_0 (1 << 3) // 0x0008
6235+#define SD_CTRL_INTMASKCARD_CARD_INSERTED_0 (1 << 4) // 0x0010
6236+#define SD_CTRL_INTMASKCARD_SIGNAL_STATE_PRESENT_0 (1 << 5) // 0x0020
6237+#define SD_CTRL_INTMASKCARD_UNK6 (1 << 6) // 0x0040
6238+#define SD_CTRL_INTMASKCARD_WRITE_PROTECT (1 << 7) // 0x0080
6239+#define SD_CTRL_INTMASKCARD_CARD_REMOVED_3 (1 << 8) // 0x0100
6240+#define SD_CTRL_INTMASKCARD_CARD_INSERTED_3 (1 << 9) // 0x0200
6241+#define SD_CTRL_INTMASKCARD_SIGNAL_STATE_PRESENT_3 (1 << 10)// 0x0400
6242+
6243+#define SD_CTRL_INTMASKBUFFER_CMD_INDEX_ERROR (1 << 0) // 0x0001
6244+#define SD_CTRL_INTMASKBUFFER_CRC_ERROR (1 << 1) // 0x0002
6245+#define SD_CTRL_INTMASKBUFFER_STOP_BIT_END_ERROR (1 << 2) // 0x0004
6246+#define SD_CTRL_INTMASKBUFFER_DATA_TIMEOUT (1 << 3) // 0x0008
6247+#define SD_CTRL_INTMASKBUFFER_BUFFER_OVERFLOW (1 << 4) // 0x0010
6248+#define SD_CTRL_INTMASKBUFFER_BUFFER_UNDERFLOW (1 << 5) // 0x0020
6249+#define SD_CTRL_INTMASKBUFFER_CMD_TIMEOUT (1 << 6) // 0x0040
6250+#define SD_CTRL_INTMASKBUFFER_UNK7 (1 << 7) // 0x0080
6251+#define SD_CTRL_INTMASKBUFFER_BUFFER_READ_ENABLE (1 << 8) // 0x0100
6252+#define SD_CTRL_INTMASKBUFFER_BUFFER_WRITE_ENABLE (1 << 9) // 0x0200
6253+#define SD_CTRL_INTMASKBUFFER_ILLEGAL_FUNCTION (1 << 13)// 0x2000
6254+#define SD_CTRL_INTMASKBUFFER_CMD_BUSY (1 << 14)// 0x4000
6255+#define SD_CTRL_INTMASKBUFFER_ILLEGAL_ACCESS (1 << 15)// 0x8000
6256+
6257+#define SD_CTRL_DETAIL0_RESPONSE_CMD_ERROR (1 << 0) // 0x0001
6258+#define SD_CTRL_DETAIL0_END_BIT_ERROR_FOR_RESPONSE_NON_CMD12 (1 << 2) // 0x0004
6259+#define SD_CTRL_DETAIL0_END_BIT_ERROR_FOR_RESPONSE_CMD12 (1 << 3) // 0x0008
6260+#define SD_CTRL_DETAIL0_END_BIT_ERROR_FOR_READ_DATA (1 << 4) // 0x0010
6261+#define SD_CTRL_DETAIL0_END_BIT_ERROR_FOR_WRITE_CRC_STATUS (1 << 5) // 0x0020
6262+#define SD_CTRL_DETAIL0_CRC_ERROR_FOR_RESPONSE_NON_CMD12 (1 << 8) // 0x0100
6263+#define SD_CTRL_DETAIL0_CRC_ERROR_FOR_RESPONSE_CMD12 (1 << 9) // 0x0200
6264+#define SD_CTRL_DETAIL0_CRC_ERROR_FOR_READ_DATA (1 << 10)// 0x0400
6265+#define SD_CTRL_DETAIL0_CRC_ERROR_FOR_WRITE_CMD (1 << 11)// 0x0800
6266+
6267+#define SD_CTRL_DETAIL1_NO_CMD_RESPONSE (1 << 0) // 0x0001
6268+#define SD_CTRL_DETAIL1_TIMEOUT_READ_DATA (1 << 4) // 0x0010
6269+#define SD_CTRL_DETAIL1_TIMEOUT_CRS_STATUS (1 << 5) // 0x0020
6270+#define SD_CTRL_DETAIL1_TIMEOUT_CRC_BUSY (1 << 6) // 0x0040
6271+
6272+#define _IPAQ_ASIC3_SDIO_CTRL_Base 0x1200
6273+
6274+#define IPAQ_ASIC3_SDIO(_b, s,x) \
6275+ (*((volatile s *) ((_b) + _IPAQ_ASIC3_SDIO_CTRL_Base + (_IPAQ_ASIC3_SDIO_CTRL_ ## x))))
6276+
6277+#define _IPAQ_ASIC3_SDIO_CTRL_Cmd 0x00
6278+#define _IPAQ_ASIC3_SDIO_CTRL_CardPortSel 0x04
6279+#define _IPAQ_ASIC3_SDIO_CTRL_Arg0 0x08
6280+#define _IPAQ_ASIC3_SDIO_CTRL_Arg1 0x0C
6281+#define _IPAQ_ASIC3_SDIO_CTRL_TransferBlockCount 0x14
6282+#define _IPAQ_ASIC3_SDIO_CTRL_Response0 0x18
6283+#define _IPAQ_ASIC3_SDIO_CTRL_Response1 0x1C
6284+#define _IPAQ_ASIC3_SDIO_CTRL_Response2 0x20
6285+#define _IPAQ_ASIC3_SDIO_CTRL_Response3 0x24
6286+#define _IPAQ_ASIC3_SDIO_CTRL_Response4 0x28
6287+#define _IPAQ_ASIC3_SDIO_CTRL_Response5 0x2C
6288+#define _IPAQ_ASIC3_SDIO_CTRL_Response6 0x30
6289+#define _IPAQ_ASIC3_SDIO_CTRL_Response7 0x34
6290+#define _IPAQ_ASIC3_SDIO_CTRL_CardStatus 0x38
6291+#define _IPAQ_ASIC3_SDIO_CTRL_BufferCtrl 0x3C
6292+#define _IPAQ_ASIC3_SDIO_CTRL_IntMaskCard 0x40
6293+#define _IPAQ_ASIC3_SDIO_CTRL_IntMaskBuffer 0x44
6294+#define _IPAQ_ASIC3_SDIO_CTRL_CardXferDataLen 0x4C
6295+#define _IPAQ_ASIC3_SDIO_CTRL_CardOptionSetup 0x50
6296+#define _IPAQ_ASIC3_SDIO_CTRL_ErrorStatus0 0x54
6297+#define _IPAQ_ASIC3_SDIO_CTRL_ErrorStatus1 0x58
6298+#define _IPAQ_ASIC3_SDIO_CTRL_DataPort 0x60
6299+#define _IPAQ_ASIC3_SDIO_CTRL_TransactionCtrl 0x68
6300+#define _IPAQ_ASIC3_SDIO_CTRL_CardIntCtrl 0x6C
6301+#define _IPAQ_ASIC3_SDIO_CTRL_ClocknWaitCtrl 0x70
6302+#define _IPAQ_ASIC3_SDIO_CTRL_HostInformation 0x74
6303+#define _IPAQ_ASIC3_SDIO_CTRL_ErrorCtrl 0x78
6304+#define _IPAQ_ASIC3_SDIO_CTRL_LEDCtrl 0x7C
6305+#define _IPAQ_ASIC3_SDIO_CTRL_SoftwareReset 0x1C0
6306+
6307+#define IPAQ_ASIC3_SDIO_CTRL_Cmd(_b) IPAQ_ASIC3_SDIO( _b, u16, Cmd ) /* */
6308+#define IPAQ_ASIC3_SDIO_CTRL_CardPortSel(_b) IPAQ_ASIC3_SDIO( _b, u16, CardPortSel ) /* */
6309+#define IPAQ_ASIC3_SDIO_CTRL_Arg0(_b) IPAQ_ASIC3_SDIO( _b, u16, Arg0 ) /* */
6310+#define IPAQ_ASIC3_SDIO_CTRL_Arg1(_b) IPAQ_ASIC3_SDIO( _b, u16, Arg1 ) /* */
6311+#define IPAQ_ASIC3_SDIO_CTRL_TransferBlockCount(_b) IPAQ_ASIC3_SDIO( _b, u16, TransferBlockCount ) /* */
6312+#define IPAQ_ASIC3_SDIO_CTRL_Response0(_b) IPAQ_ASIC3_SDIO( _b, u16, Response0 ) /* */
6313+#define IPAQ_ASIC3_SDIO_CTRL_Response1(_b) IPAQ_ASIC3_SDIO( _b, u16, Response1 ) /* */
6314+#define IPAQ_ASIC3_SDIO_CTRL_Response2(_b) IPAQ_ASIC3_SDIO( _b, u16, Response2 ) /* */
6315+#define IPAQ_ASIC3_SDIO_CTRL_Response3(_b) IPAQ_ASIC3_SDIO( _b, u16, Response3 ) /* */
6316+#define IPAQ_ASIC3_SDIO_CTRL_Response4(_b) IPAQ_ASIC3_SDIO( _b, u16, Response4 ) /* */
6317+#define IPAQ_ASIC3_SDIO_CTRL_Response5(_b) IPAQ_ASIC3_SDIO( _b, u16, Response5 ) /* */
6318+#define IPAQ_ASIC3_SDIO_CTRL_Response6(_b) IPAQ_ASIC3_SDIO( _b, u16, Response6 ) /* */
6319+#define IPAQ_ASIC3_SDIO_CTRL_Response7(_b) IPAQ_ASIC3_SDIO( _b, u16, Response7 ) /* */
6320+#define IPAQ_ASIC3_SDIO_CTRL_CardStatus(_b) IPAQ_ASIC3_SDIO( _b, u16, CardStatus ) /* */
6321+#define IPAQ_ASIC3_SDIO_CTRL_BufferCtrl(_b) IPAQ_ASIC3_SDIO( _b, u16, BufferCtrl ) /* and error status*/
6322+#define IPAQ_ASIC3_SDIO_CTRL_IntMaskCard(_b) IPAQ_ASIC3_SDIO( _b, u16, IntMaskCard ) /* */
6323+#define IPAQ_ASIC3_SDIO_CTRL_IntMaskBuffer(_b) IPAQ_ASIC3_SDIO( _b, u16, IntMaskBuffer ) /* */
6324+#define IPAQ_ASIC3_SDIO_CTRL_CardXferDataLen(_b) IPAQ_ASIC3_SDIO( _b, u16, CardXferDataLen ) /* */
6325+#define IPAQ_ASIC3_SDIO_CTRL_CardOptionSetup(_b) IPAQ_ASIC3_SDIO( _b, u16, CardOptionSetup ) /* */
6326+#define IPAQ_ASIC3_SDIO_CTRL_ErrorStatus0(_b) IPAQ_ASIC3_SDIO( _b, u16, ErrorStatus0 ) /* */
6327+#define IPAQ_ASIC3_SDIO_CTRL_ErrorStatus1(_b) IPAQ_ASIC3_SDIO( _b, u16, ErrorStatus1 ) /* */
6328+#define IPAQ_ASIC3_SDIO_CTRL_DataPort(_b) IPAQ_ASIC3_SDIO( _b, u16, DataPort ) /* */
6329+#define IPAQ_ASIC3_SDIO_CTRL_TransactionCtrl(_b) IPAQ_ASIC3_SDIO( _b, u16, TransactionCtrl ) /* */
6330+#define IPAQ_ASIC3_SDIO_CTRL_CardIntCtrl(_b) IPAQ_ASIC3_SDIO( _b, u16, CardIntCtrl ) /* */
6331+#define IPAQ_ASIC3_SDIO_CTRL_ClocknWaitCtrl(_b) IPAQ_ASIC3_SDIO( _b, u16, ClocknWaitCtrl ) /* */
6332+#define IPAQ_ASIC3_SDIO_CTRL_HostInformation(_b) IPAQ_ASIC3_SDIO( _b, u16, HostInformation ) /* */
6333+#define IPAQ_ASIC3_SDIO_CTRL_ErrorCtrl(_b) IPAQ_ASIC3_SDIO( _b, u16, ErrorCtrl ) /* */
6334+#define IPAQ_ASIC3_SDIO_CTRL_LEDCtrl(_b) IPAQ_ASIC3_SDIO( _b, u16, LEDCtrl ) /* */
6335+#define IPAQ_ASIC3_SDIO_CTRL_SoftwareReset(_b) IPAQ_ASIC3_SDIO( _b, u16, SoftwareReset ) /* */
6336+
6337+#define IPAQ_ASIC3_MAP_SIZE 0x2000
6338+
6339+#endif
6340Index: linux-2.6.26-rc4/include/linux/gpiodev.h
6341===================================================================
6342--- /dev/null 1970-01-01 00:00:00.000000000 +0000
6343+++ linux-2.6.26-rc4/include/linux/gpiodev.h 2008-06-01 18:49:45.000000000 +0100
6344@@ -0,0 +1,44 @@
6345+#ifndef __GPIODEV_H
6346+#define __GPIODEV_H
6347+
6348+#include <linux/device.h>
6349+#include <linux/platform_device.h>
6350+#include <asm/gpio.h>
6351+
6352+/* Interface */
6353+
6354+/* This structure must be first member of device platform_data structure
6355+ of a device which provides gpiodev interface. All method pointers
6356+ must be non-NULL, so stubs must be used for non-implemented ones. */
6357+struct gpiodev_ops {
6358+ int (*get)(struct device *this, unsigned gpio_no);
6359+ void (*set)(struct device *this, unsigned gpio_no, int val);
6360+ int (*to_irq)(struct device *this, unsigned gpio_no);
6361+};
6362+
6363+/* Generalized GPIO structure */
6364+
6365+struct gpio {
6366+ struct device *gpio_dev;
6367+ unsigned gpio_no;
6368+};
6369+
6370+/* API functions */
6371+
6372+static inline int gpiodev_get_value(struct gpio *gpio)
6373+{
6374+ struct gpiodev_ops *ops = gpio->gpio_dev->platform_data;
6375+ return ops->get(gpio->gpio_dev, gpio->gpio_no);
6376+}
6377+static inline void gpiodev_set_value(struct gpio *gpio, int val)
6378+{
6379+ struct gpiodev_ops *ops = gpio->gpio_dev->platform_data;
6380+ ops->set(gpio->gpio_dev, gpio->gpio_no, val);
6381+}
6382+static inline int gpiodev_to_irq(struct gpio *gpio)
6383+{
6384+ struct gpiodev_ops *ops = gpio->gpio_dev->platform_data;
6385+ return ops->to_irq(gpio->gpio_dev, gpio->gpio_no);
6386+}
6387+
6388+#endif /* __GPIODEV_H */
6389Index: linux-2.6.26-rc4/include/linux/input_pda.h
6390===================================================================
6391--- /dev/null 1970-01-01 00:00:00.000000000 +0000
6392+++ linux-2.6.26-rc4/include/linux/input_pda.h 2008-06-01 18:49:45.000000000 +0100
6393@@ -0,0 +1,47 @@
6394+#ifndef _INPUT_PDA_H
6395+#define _INPUT_PDA_H
6396+
6397+/*
6398+ * This is temporary virtual button key codes map
6399+ * for keyboardless handheld computers.
6400+ * Its purpose is to provide map common to all devices
6401+ * and known to work with current software and its bugs
6402+ * and misfeatures. Once issues with the software are
6403+ * solved, codes from input.h will be used directly
6404+ * (missing key definitions will be added).
6405+ */
6406+
6407+/* Some directly usable keycodes:
6408+KEY_POWER - Power/suspend button
6409+KEY_ENTER - Enter/Action/Central button on joypad
6410+KEY_UP
6411+KEY_DOWN
6412+KEY_LEFT
6413+KEY_RIGHT
6414+*/
6415+
6416+/* XXX Instead of using any values in include/linux/input.h, we have to use
6417+ use values < 128 due to some munging that kdrive does to get keystrokes.
6418+ When kdrive gets its key events from evdev instead of the console,
6419+ we should be able to switch to using input.h values and get rid of
6420+ xmodmap. */
6421+
6422+#define _KEY_APP1 KEY_F9 // xmodmap sees 67 + 8 = 75
6423+#define _KEY_APP2 KEY_F10 // xmodmap 76
6424+#define _KEY_APP3 KEY_F11 // xmodmap 95
6425+#define _KEY_APP4 KEY_F12 // xmodmap 96
6426+
6427+#define _KEY_RECORD KEY_RO
6428+
6429+/* It is highly recommended to use exactly 4 codes above for
6430+ 4 buttons the device has. This will ensure that console and
6431+ framebuffer applications (e.g. games) will work ok on all
6432+ devices. If you'd like more distinguishable names, following
6433+ convenience defines are provided, suiting many devices. */
6434+
6435+#define _KEY_CALENDAR _KEY_APP1
6436+#define _KEY_CONTACTS _KEY_APP2
6437+#define _KEY_MAIL _KEY_APP3
6438+#define _KEY_HOMEPAGE _KEY_APP4
6439+
6440+#endif
6441Index: linux-2.6.26-rc4/include/linux/soc/asic3_base.h
6442===================================================================
6443--- /dev/null 1970-01-01 00:00:00.000000000 +0000
6444+++ linux-2.6.26-rc4/include/linux/soc/asic3_base.h 2008-06-01 18:49:45.000000000 +0100
6445@@ -0,0 +1,104 @@
6446+#include <asm/types.h>
6447+#include <linux/gpiodev.h>
6448+
6449+/* Private API - for ASIC3 devices internal use only */
6450+#define HDR_IPAQ_ASIC3_ACTION(ACTION,action,fn,FN) \
6451+u32 asic3_get_gpio_ ## action ## _ ## fn (struct device *dev); \
6452+void asic3_set_gpio_ ## action ## _ ## fn (struct device *dev, u32 bits, u32 val);
6453+
6454+#define HDR_IPAQ_ASIC3_FN(fn,FN) \
6455+ HDR_IPAQ_ASIC3_ACTION ( MASK,mask,fn,FN) \
6456+ HDR_IPAQ_ASIC3_ACTION ( DIR, dir, fn, FN) \
6457+ HDR_IPAQ_ASIC3_ACTION ( OUT, out, fn, FN) \
6458+ HDR_IPAQ_ASIC3_ACTION ( LEVELTRI, trigtype, fn, FN) \
6459+ HDR_IPAQ_ASIC3_ACTION ( RISING, rising, fn, FN) \
6460+ HDR_IPAQ_ASIC3_ACTION ( LEVEL, triglevel, fn, FN) \
6461+ HDR_IPAQ_ASIC3_ACTION ( SLEEP_MASK, sleepmask, fn, FN) \
6462+ HDR_IPAQ_ASIC3_ACTION ( SLEEP_OUT, sleepout, fn, FN) \
6463+ HDR_IPAQ_ASIC3_ACTION ( BATT_FAULT_OUT, battfaultout, fn, FN) \
6464+ HDR_IPAQ_ASIC3_ACTION ( INT_STATUS, intstatus, fn, FN) \
6465+ HDR_IPAQ_ASIC3_ACTION ( ALT_FUNCTION, alt_fn, fn, FN) \
6466+ HDR_IPAQ_ASIC3_ACTION ( SLEEP_CONF, sleepconf, fn, FN) \
6467+ HDR_IPAQ_ASIC3_ACTION ( STATUS, status, fn, FN)
6468+
6469+/* Public API */
6470+
6471+#define ASIC3_GPIOA_IRQ_BASE 0
6472+#define ASIC3_GPIOB_IRQ_BASE 16
6473+#define ASIC3_GPIOC_IRQ_BASE 32
6474+#define ASIC3_GPIOD_IRQ_BASE 48
6475+#define ASIC3_LED0_IRQ 64
6476+#define ASIC3_LED1_IRQ 65
6477+#define ASIC3_LED2_IRQ 66
6478+#define ASIC3_SPI_IRQ 67
6479+#define ASIC3_SMBUS_IRQ 68
6480+#define ASIC3_OWM_IRQ 69
6481+
6482+#define ASIC3_NR_GPIO_IRQS 64 /* 16 bits each GPIO A...D banks */
6483+#define ASIC3_NR_IRQS (ASIC3_OWM_IRQ + 1)
6484+
6485+extern int asic3_irq_base(struct device *dev);
6486+
6487+extern void asic3_write_register(struct device *dev, unsigned int reg,
6488+ u32 value);
6489+extern u32 asic3_read_register(struct device *dev, unsigned int reg);
6490+
6491+/* old clock api */
6492+extern void asic3_set_clock_sel(struct device *dev, u32 bits, u32 val);
6493+extern u32 asic3_get_clock_cdex(struct device *dev);
6494+extern void asic3_set_clock_cdex(struct device *dev, u32 bits, u32 val);
6495+
6496+extern void asic3_set_extcf_select(struct device *dev, u32 bits, u32 val);
6497+extern void asic3_set_extcf_reset(struct device *dev, u32 bits, u32 val);
6498+extern void asic3_set_sdhwctrl(struct device *dev, u32 bits, u32 val);
6499+
6500+extern void asic3_set_led(struct device *dev, int led_num, int duty_time,
6501+ int cycle_time, int timebase);
6502+
6503+extern int asic3_register_mmc(struct device *dev);
6504+extern int asic3_unregister_mmc(struct device *dev);
6505+
6506+/* Accessors for GPIO banks */
6507+HDR_IPAQ_ASIC3_FN(a, A)
6508+HDR_IPAQ_ASIC3_FN(b, B)
6509+HDR_IPAQ_ASIC3_FN(c, C)
6510+HDR_IPAQ_ASIC3_FN(d, D)
6511+
6512+#define _IPAQ_ASIC3_GPIO_BANK_A 0
6513+#define _IPAQ_ASIC3_GPIO_BANK_B 1
6514+#define _IPAQ_ASIC3_GPIO_BANK_C 2
6515+#define _IPAQ_ASIC3_GPIO_BANK_D 3
6516+
6517+#define ASIC3_GPIO_bit(gpio) (1 << (gpio & 0xf))
6518+
6519+extern int asic3_get_gpio_bit(struct device *dev, int gpio);
6520+extern void asic3_set_gpio_bit(struct device *dev, int gpio, int val);
6521+extern int asic3_gpio_get_value(struct device *dev, unsigned gpio);
6522+extern void asic3_gpio_set_value(struct device *dev, unsigned gpio, int val);
6523+
6524+
6525+struct tmio_mmc_hwconfig;
6526+
6527+struct asic3_platform_data
6528+{
6529+ // Must be first member
6530+ struct gpiodev_ops gpiodev_ops;
6531+
6532+ struct {
6533+ u32 dir;
6534+ u32 init;
6535+ u32 sleep_mask;
6536+ u32 sleep_out;
6537+ u32 batt_fault_out;
6538+ u32 sleep_conf;
6539+ u32 alt_function;
6540+ } gpio_a, gpio_b, gpio_c, gpio_d;
6541+
6542+ int irq_base;
6543+ unsigned int bus_shift;
6544+
6545+ struct platform_device **child_platform_devs;
6546+ int num_child_platform_devs;
6547+
6548+ struct tmio_mmc_hwconfig *tmio_mmc_hwconfig;
6549+};
6550Index: linux-2.6.26-rc4/include/linux/soc/tmio_mmc.h
6551===================================================================
6552--- /dev/null 1970-01-01 00:00:00.000000000 +0000
6553+++ linux-2.6.26-rc4/include/linux/soc/tmio_mmc.h 2008-06-01 18:49:45.000000000 +0100
6554@@ -0,0 +1,17 @@
6555+#include <linux/platform_device.h>
6556+
6557+#define MMC_CLOCK_DISABLED 0
6558+#define MMC_CLOCK_ENABLED 1
6559+
6560+#define TMIO_WP_ALWAYS_RW ((void*)-1)
6561+
6562+struct tmio_mmc_hwconfig {
6563+ void (*hwinit)(struct platform_device *sdev);
6564+ void (*set_mmc_clock)(struct platform_device *sdev, int state);
6565+
6566+ /* NULL - use ASIC3 signal,
6567+ TMIO_WP_ALWAYS_RW - assume always R/W (e.g. miniSD)
6568+ otherwise - machine-specific handler */
6569+ int (*mmc_get_ro)(struct platform_device *pdev);
6570+ short address_shift;
6571+};
6572Index: linux-2.6.26-rc4/include/asm-arm/arch-pxa/pxa-regs.h
6573===================================================================
6574--- linux-2.6.26-rc4.orig/include/asm-arm/arch-pxa/pxa-regs.h 2008-05-26 19:08:11.000000000 +0100
6575+++ linux-2.6.26-rc4/include/asm-arm/arch-pxa/pxa-regs.h 2008-06-01 18:49:45.000000000 +0100
6576@@ -1117,6 +1117,8 @@
6577 #define PWM_PWDUTY1 __REG(0x40C00004) /* PWM 1 Duty Cycle Register */
6578 #define PWM_PERVAL1 __REG(0x40C00008) /* PWM 1 Period Control Register */
6579
6580+#define LCCR4_13M_PCD_EN (1<<25) /* 13M PCD enable */
6581+#define LCCR4_PCDDIV (1<<31) /* PCD selection */
6582
6583 /*
6584 * Interrupt Controller
6585Index: linux-2.6.26-rc4/drivers/mmc/host/Kconfig
6586===================================================================
6587--- linux-2.6.26-rc4.orig/drivers/mmc/host/Kconfig 2008-05-26 19:08:11.000000000 +0100
6588+++ linux-2.6.26-rc4/drivers/mmc/host/Kconfig 2008-06-01 18:49:45.000000000 +0100
6589@@ -130,3 +130,9 @@
6590
6591 If unsure, or if your system has no SPI master driver, say N.
6592
6593+config MMC_ASIC3
6594+ tristate "HTC ASIC3 SD/MMC support"
6595+ depends on MMC && HTC_ASIC3
6596+ help
6597+ This provides support for the ASIC3 SD/MMC controller, used
6598+ in the iPAQ hx4700 and others.
6599Index: linux-2.6.26-rc4/drivers/mmc/host/Makefile
6600===================================================================
6601--- linux-2.6.26-rc4.orig/drivers/mmc/host/Makefile 2008-05-26 19:08:11.000000000 +0100
6602+++ linux-2.6.26-rc4/drivers/mmc/host/Makefile 2008-06-01 18:49:45.000000000 +0100
6603@@ -13,6 +13,7 @@
6604 obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o
6605 obj-$(CONFIG_MMC_WBSD) += wbsd.o
6606 obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
6607+obj-$(CONFIG_MMC_ASIC3) += asic3_mmc.o
6608 obj-$(CONFIG_MMC_OMAP) += omap.o
6609 obj-$(CONFIG_MMC_AT91) += at91_mci.o
6610 obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
6611Index: linux-2.6.26-rc4/drivers/mmc/host/asic3_mmc.c
6612===================================================================
6613--- /dev/null 1970-01-01 00:00:00.000000000 +0000
6614+++ linux-2.6.26-rc4/drivers/mmc/host/asic3_mmc.c 2008-06-01 18:49:45.000000000 +0100
6615@@ -0,0 +1,900 @@
6616+/* Note that this driver can likely be merged into the tmio driver, so
6617+ * consider this code temporary. It works, though.
6618+ */
6619+/*
6620+ * linux/drivers/mmc/asic3_mmc.c
6621+ *
6622+ * Copyright (c) 2005 SDG Systems, LLC
6623+ *
6624+ * based on tmio_mmc.c
6625+ * Copyright (C) 2004 Ian Molton
6626+ *
6627+ * Refactored to support all ASIC3 devices, 2006 Paul Sokolovsky
6628+ *
6629+ * This program is free software; you can redistribute it and/or modify
6630+ * it under the terms of the GNU General Public License version 2 as
6631+ * published by the Free Software Foundation.
6632+ *
6633+ * Driver for the SD / SDIO cell found in:
6634+ *
6635+ * TC6393XB
6636+ *
6637+ * This driver draws mainly on scattered spec sheets, Reverse engineering
6638+ * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit
6639+ * support).
6640+ *
6641+ * Supports MMC 1 bit transfers and SD 1 and 4 bit modes.
6642+ *
6643+ * TODO:
6644+ * Eliminate FIXMEs
6645+ * SDIO support
6646+ * Power management
6647+ * Handle MMC errors (at all)
6648+ *
6649+ */
6650+#include <linux/module.h>
6651+#include <linux/moduleparam.h>
6652+#include <linux/init.h>
6653+#include <linux/ioport.h>
6654+#include <linux/platform_device.h>
6655+#include <linux/interrupt.h>
6656+#include <linux/blkdev.h>
6657+#include <linux/delay.h>
6658+#include <linux/err.h>
6659+#include <linux/mmc/mmc.h>
6660+#include <linux/mmc/host.h>
6661+#include <linux/mmc/card.h>
6662+//#include <linux/mmc/protocol.h>
6663+#include <linux/mmc/sd.h>
6664+#include <linux/scatterlist.h>
6665+//#include <linux/soc-old.h>
6666+#include <linux/soc/asic3_base.h>
6667+#include <linux/soc/tmio_mmc.h>
6668+
6669+#include <asm/io.h>
6670+#include <asm/irq.h>
6671+#include <asm/mach/irq.h>
6672+#include <linux/clk.h>
6673+#include <asm/mach-types.h>
6674+
6675+#include <asm/hardware/ipaq-asic3.h>
6676+#include "asic3_mmc.h"
6677+
6678+struct asic3_mmc_host {
6679+ void *ctl_base;
6680+ struct device *asic3_dev; /* asic3 device */
6681+ struct tmio_mmc_hwconfig *hwconfig; /* HW config data/handlers, guaranteed != NULL */
6682+ unsigned long bus_shift;
6683+ struct mmc_command *cmd;
6684+ struct mmc_request *mrq;
6685+ struct mmc_data *data;
6686+ struct mmc_host *mmc;
6687+ int irq;
6688+ unsigned short clock_for_sd;
6689+
6690+ /* I/O related stuff */
6691+ struct scatterlist *sg_ptr;
6692+ unsigned int sg_len;
6693+ unsigned int sg_off;
6694+};
6695+
6696+static void
6697+mmc_finish_request(struct asic3_mmc_host *host)
6698+{
6699+ struct mmc_request *mrq = host->mrq;
6700+
6701+ /* Write something to end the command */
6702+ host->mrq = NULL;
6703+ host->cmd = NULL;
6704+ host->data = NULL;
6705+
6706+ mmc_request_done(host->mmc, mrq);
6707+}
6708+
6709+
6710+#define ASIC3_MMC_REG(host, block, reg) (*((volatile u16 *) ((host->ctl_base) + ((_IPAQ_ASIC3_## block ## _Base + _IPAQ_ASIC3_ ## block ## _ ## reg) >> (2 - host->bus_shift))) ))
6711+
6712+static void
6713+mmc_start_command(struct asic3_mmc_host *host, struct mmc_command *cmd)
6714+{
6715+ struct mmc_data *data = host->data;
6716+ int c = cmd->opcode;
6717+
6718+ DBG("Opcode: %d, base: %p\n", cmd->opcode, host->ctl_base);
6719+
6720+ if(cmd->opcode == MMC_STOP_TRANSMISSION) {
6721+ ASIC3_MMC_REG(host, SD_CTRL, StopInternal) = SD_CTRL_STOP_INTERNAL_ISSSUE_CMD12;
6722+ cmd->resp[0] = cmd->opcode;
6723+ cmd->resp[1] = 0;
6724+ cmd->resp[2] = 0;
6725+ cmd->resp[3] = 0;
6726+ cmd->resp[4] = 0;
6727+ return;
6728+ }
6729+
6730+ switch(cmd->flags & 0x1f) {
6731+ case MMC_RSP_NONE: c |= SD_CTRL_COMMAND_RESPONSE_TYPE_NORMAL; break;
6732+ case MMC_RSP_R1: c |= SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R1; break;
6733+ case MMC_RSP_R1B: c |= SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R1B; break;
6734+ case MMC_RSP_R2: c |= SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R2; break;
6735+ case MMC_RSP_R3: c |= SD_CTRL_COMMAND_RESPONSE_TYPE_EXT_R3; break;
6736+ default:
6737+ DBG("Unknown response type %d\n", cmd->flags & 0x1f);
6738+ break;
6739+ }
6740+
6741+ host->cmd = cmd;
6742+
6743+ if(cmd->opcode == MMC_APP_CMD) {
6744+ c |= APP_CMD;
6745+ }
6746+ if (cmd->opcode == MMC_GO_IDLE_STATE) {
6747+ c |= (3 << 8); /* This was removed from ipaq-asic3.h for some reason */
6748+ }
6749+ if(data) {
6750+ c |= SD_CTRL_COMMAND_DATA_PRESENT;
6751+ if(data->blocks > 1) {
6752+ ASIC3_MMC_REG(host, SD_CTRL, StopInternal) = SD_CTRL_STOP_INTERNAL_AUTO_ISSUE_CMD12;
6753+ c |= SD_CTRL_COMMAND_MULTI_BLOCK;
6754+ }
6755+ if(data->flags & MMC_DATA_READ) {
6756+ c |= SD_CTRL_COMMAND_TRANSFER_READ;
6757+ }
6758+ /* MMC_DATA_WRITE does not require a bit to be set */
6759+ }
6760+
6761+ /* Enable the command and data interrupts */
6762+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard) = ~(
6763+ SD_CTRL_INTMASKCARD_RESPONSE_END
6764+ | SD_CTRL_INTMASKCARD_RW_END
6765+ | SD_CTRL_INTMASKCARD_CARD_REMOVED_0
6766+ | SD_CTRL_INTMASKCARD_CARD_INSERTED_0
6767+#if 0
6768+ | SD_CTRL_INTMASKCARD_CARD_REMOVED_3
6769+ | SD_CTRL_INTMASKCARD_CARD_INSERTED_3
6770+#endif
6771+ );
6772+
6773+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) = ~(
6774+ SD_CTRL_INTMASKBUFFER_UNK7
6775+ | SD_CTRL_INTMASKBUFFER_CMD_BUSY
6776+#if 0
6777+ | SD_CTRL_INTMASKBUFFER_CMD_INDEX_ERROR
6778+ | SD_CTRL_INTMASKBUFFER_CRC_ERROR
6779+ | SD_CTRL_INTMASKBUFFER_STOP_BIT_END_ERROR
6780+ | SD_CTRL_INTMASKBUFFER_DATA_TIMEOUT
6781+ | SD_CTRL_INTMASKBUFFER_BUFFER_OVERFLOW
6782+ | SD_CTRL_INTMASKBUFFER_BUFFER_UNDERFLOW
6783+ | SD_CTRL_INTMASKBUFFER_CMD_TIMEOUT
6784+ | SD_CTRL_INTMASKBUFFER_BUFFER_READ_ENABLE
6785+ | SD_CTRL_INTMASKBUFFER_BUFFER_WRITE_ENABLE
6786+ | SD_CTRL_INTMASKBUFFER_ILLEGAL_ACCESS
6787+#endif
6788+ );
6789+
6790+ /* Send the command */
6791+ ASIC3_MMC_REG(host, SD_CTRL, Arg1) = cmd->arg >> 16;
6792+ ASIC3_MMC_REG(host, SD_CTRL, Arg0) = cmd->arg & 0xffff;
6793+ ASIC3_MMC_REG(host, SD_CTRL, Cmd) = c;
6794+}
6795+
6796+/* This chip always returns (at least?) as much data as you ask for. I'm
6797+ * unsure what happens if you ask for less than a block. This should be looked
6798+ * into to ensure that a funny length read doesnt mess up the controller data
6799+ * state machine.
6800+ *
6801+ * Aric: Statement above may not apply to ASIC3.
6802+ *
6803+ * FIXME - this chip cannot do 1 and 2 byte data requests in 4 bit mode
6804+ *
6805+ * Aric: Statement above may not apply to ASIC3.
6806+ */
6807+
6808+static struct tasklet_struct mmc_data_read_tasklet;
6809+
6810+static void
6811+mmc_data_transfer(unsigned long h)
6812+{
6813+ struct asic3_mmc_host *host = (struct asic3_mmc_host *)h;
6814+ struct mmc_data *data = host->data;
6815+ unsigned short *buf;
6816+ int count;
6817+ /* unsigned long flags; */
6818+
6819+ if(!data){
6820+ printk(KERN_WARNING DRIVER_NAME ": Spurious Data IRQ\n");
6821+ return;
6822+ }
6823+
6824+ /* local_irq_save(flags); */
6825+ /* buf = kmap_atomic(host->sg_ptr->page, KM_BIO_SRC_IRQ); */
6826+ buf = kmap(host->sg_ptr->page);
6827+ buf += host->sg_ptr->offset/2 + host->sg_off/2;
6828+
6829+ /*
6830+ * Ensure we dont read more than one block. The chip will interrupt us
6831+ * When the next block is available.
6832+ */
6833+ count = host->sg_ptr->length - host->sg_off;
6834+ if(count > data->blksz) {
6835+ count = data->blksz;
6836+ }
6837+
6838+ DBG("count: %08x, page: %p, offset: %08x flags %08x\n",
6839+ count, host->sg_ptr->page, host->sg_off, data->flags);
6840+
6841+ host->sg_off += count;
6842+
6843+ /* Transfer the data */
6844+ if(data->flags & MMC_DATA_READ) {
6845+ while(count > 0) {
6846+ /* Read two bytes from SD/MMC controller. */
6847+ *buf = ASIC3_MMC_REG(host, SD_CTRL, DataPort);
6848+ buf++;
6849+ count -= 2;
6850+ }
6851+ //flush_dcache_page(host->sg_ptr->page);
6852+ } else {
6853+ while(count > 0) {
6854+ /* Write two bytes to SD/MMC controller. */
6855+ ASIC3_MMC_REG(host, SD_CTRL, DataPort) = *buf;
6856+ buf++;
6857+ count -= 2;
6858+ }
6859+ }
6860+
6861+ /* kunmap_atomic(host->sg_ptr->page, KM_BIO_SRC_IRQ); */
6862+ kunmap(host->sg_ptr->page);
6863+ /* local_irq_restore(flags); */
6864+ if(host->sg_off == host->sg_ptr->length) {
6865+ host->sg_ptr++;
6866+ host->sg_off = 0;
6867+ --host->sg_len;
6868+ }
6869+
6870+ return;
6871+}
6872+
6873+static void
6874+mmc_data_end_irq(struct asic3_mmc_host *host)
6875+{
6876+ struct mmc_data *data = host->data;
6877+
6878+ host->data = NULL;
6879+
6880+ if(!data){
6881+ printk(KERN_WARNING DRIVER_NAME ": Spurious data end IRQ\n");
6882+ return;
6883+ }
6884+
6885+ if (data->error == MMC_ERR_NONE) {
6886+ data->bytes_xfered = data->blocks * data->blksz;
6887+ } else {
6888+ data->bytes_xfered = 0;
6889+ }
6890+
6891+ DBG("Completed data request\n");
6892+
6893+ ASIC3_MMC_REG(host, SD_CTRL, StopInternal) = 0;
6894+
6895+ /* Make sure read enable interrupt and write enable interrupt are disabled */
6896+ if(data->flags & MMC_DATA_READ) {
6897+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) |= SD_CTRL_INTMASKBUFFER_BUFFER_READ_ENABLE;
6898+ } else {
6899+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) |= SD_CTRL_INTMASKBUFFER_BUFFER_WRITE_ENABLE;
6900+ }
6901+
6902+ mmc_finish_request(host);
6903+}
6904+
6905+static void
6906+mmc_cmd_irq(struct asic3_mmc_host *host, unsigned int buffer_stat)
6907+{
6908+ struct mmc_command *cmd = host->cmd;
6909+ u8 *buf = (u8 *)cmd->resp;
6910+ u16 data;
6911+
6912+ if(!host->cmd) {
6913+ printk(KERN_WARNING DRIVER_NAME ": Spurious CMD irq\n");
6914+ return;
6915+ }
6916+
6917+ host->cmd = NULL;
6918+ if(cmd->flags & MMC_RSP_PRESENT && cmd->flags & MMC_RSP_136) {
6919+ /* R2 */
6920+ buf[12] = 0xff;
6921+ data = ASIC3_MMC_REG(host, SD_CTRL, Response0);
6922+ buf[13] = data & 0xff;
6923+ buf[14] = data >> 8;
6924+ data = ASIC3_MMC_REG(host, SD_CTRL, Response1);
6925+ buf[15] = data & 0xff;
6926+ buf[8] = data >> 8;
6927+ data = ASIC3_MMC_REG(host, SD_CTRL, Response2);
6928+ buf[9] = data & 0xff;
6929+ buf[10] = data >> 8;
6930+ data = ASIC3_MMC_REG(host, SD_CTRL, Response3);
6931+ buf[11] = data & 0xff;
6932+ buf[4] = data >> 8;
6933+ data = ASIC3_MMC_REG(host, SD_CTRL, Response4);
6934+ buf[5] = data & 0xff;
6935+ buf[6] = data >> 8;
6936+ data = ASIC3_MMC_REG(host, SD_CTRL, Response5);
6937+ buf[7] = data & 0xff;
6938+ buf[0] = data >> 8;
6939+ data = ASIC3_MMC_REG(host, SD_CTRL, Response6);
6940+ buf[1] = data & 0xff;
6941+ buf[2] = data >> 8;
6942+ data = ASIC3_MMC_REG(host, SD_CTRL, Response7);
6943+ buf[3] = data & 0xff;
6944+ } else if(cmd->flags & MMC_RSP_PRESENT) {
6945+ /* R1, R1B, R3 */
6946+ data = ASIC3_MMC_REG(host, SD_CTRL, Response0);
6947+ buf[0] = data & 0xff;
6948+ buf[1] = data >> 8;
6949+ data = ASIC3_MMC_REG(host, SD_CTRL, Response1);
6950+ buf[2] = data & 0xff;
6951+ buf[3] = data >> 8;
6952+ }
6953+ DBG("Response: %08x %08x %08x %08x\n", cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
6954+
6955+ if(buffer_stat & SD_CTRL_BUFFERSTATUS_CMD_TIMEOUT) {
6956+ cmd->error = MMC_ERR_TIMEOUT;
6957+ } else if((buffer_stat & SD_CTRL_BUFFERSTATUS_CRC_ERROR) && (cmd->flags & MMC_RSP_CRC)) {
6958+ cmd->error = MMC_ERR_BADCRC;
6959+ } else if(buffer_stat &
6960+ (
6961+ SD_CTRL_BUFFERSTATUS_ILLEGAL_ACCESS
6962+ | SD_CTRL_BUFFERSTATUS_CMD_INDEX_ERROR
6963+ | SD_CTRL_BUFFERSTATUS_STOP_BIT_END_ERROR
6964+ | SD_CTRL_BUFFERSTATUS_BUFFER_OVERFLOW
6965+ | SD_CTRL_BUFFERSTATUS_BUFFER_UNDERFLOW
6966+ | SD_CTRL_BUFFERSTATUS_DATA_TIMEOUT
6967+ )
6968+ ) {
6969+ DBG("Buffer status ERROR 0x%04x - inside check buffer\n", buffer_stat);
6970+ DBG("detail0 error status 0x%04x\n", ASIC3_MMC_REG(host, SD_CTRL, ErrorStatus0));
6971+ DBG("detail1 error status 0x%04x\n", ASIC3_MMC_REG(host, SD_CTRL, ErrorStatus1));
6972+ cmd->error = MMC_ERR_FAILED;
6973+ }
6974+
6975+ if(cmd->error == MMC_ERR_NONE) {
6976+ switch (cmd->opcode) {
6977+ case SD_APP_SET_BUS_WIDTH:
6978+ if(cmd->arg == SD_BUS_WIDTH_4) {
6979+ host->clock_for_sd = SD_CTRL_CARDCLOCKCONTROL_FOR_SD_CARD;
6980+ ASIC3_MMC_REG(host, SD_CTRL, MemCardOptionSetup) =
6981+ MEM_CARD_OPTION_REQUIRED
6982+ | MEM_CARD_OPTION_DATA_RESPONSE_TIMEOUT(14)
6983+ | MEM_CARD_OPTION_C2_MODULE_NOT_PRESENT
6984+ | MEM_CARD_OPTION_DATA_XFR_WIDTH_4;
6985+ } else {
6986+ host->clock_for_sd = 0;
6987+ ASIC3_MMC_REG(host, SD_CTRL, MemCardOptionSetup) =
6988+ MEM_CARD_OPTION_REQUIRED
6989+ | MEM_CARD_OPTION_DATA_RESPONSE_TIMEOUT(14)
6990+ | MEM_CARD_OPTION_C2_MODULE_NOT_PRESENT
6991+ | MEM_CARD_OPTION_DATA_XFR_WIDTH_1;
6992+ }
6993+ break;
6994+ case MMC_SELECT_CARD:
6995+ if((cmd->arg >> 16) == 0) {
6996+ /* We have been deselected. */
6997+ ASIC3_MMC_REG(host, SD_CTRL, MemCardOptionSetup) =
6998+ MEM_CARD_OPTION_REQUIRED
6999+ | MEM_CARD_OPTION_DATA_RESPONSE_TIMEOUT(14)
7000+ | MEM_CARD_OPTION_C2_MODULE_NOT_PRESENT
7001+ | MEM_CARD_OPTION_DATA_XFR_WIDTH_1;
7002+ }
7003+ }
7004+ }
7005+
7006+ /*
7007+ * If there is data to handle we enable data IRQs here, and we will
7008+ * ultimatley finish the request in the mmc_data_end_irq handler.
7009+ */
7010+ if(host->data && (cmd->error == MMC_ERR_NONE)){
7011+ if(host->data->flags & MMC_DATA_READ) {
7012+ /* Enable the read enable interrupt */
7013+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) &=
7014+ ~SD_CTRL_INTMASKBUFFER_BUFFER_READ_ENABLE;
7015+ } else {
7016+ /* Enable the write enable interrupt */
7017+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) &=
7018+ ~SD_CTRL_INTMASKBUFFER_BUFFER_WRITE_ENABLE;
7019+ }
7020+ } else {
7021+ /* There's no data, or we encountered an error, so finish now. */
7022+ mmc_finish_request(host);
7023+ }
7024+
7025+ return;
7026+}
7027+
7028+static void hwinit2_irqsafe(struct asic3_mmc_host *host);
7029+
7030+static irqreturn_t
7031+mmc_irq(int irq, void *irq_desc)
7032+{
7033+ struct asic3_mmc_host *host;
7034+ unsigned int breg, bmask, bstatus, creg, cmask, cstatus;
7035+
7036+ host = irq_desc;
7037+
7038+ /* asic3 bstatus has errors */
7039+ bstatus = ASIC3_MMC_REG(host, SD_CTRL, BufferCtrl);
7040+ bmask = ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer);
7041+ cstatus = ASIC3_MMC_REG(host, SD_CTRL, CardStatus);
7042+ cmask = ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard);
7043+ breg = bstatus & ~bmask & ~DONT_CARE_BUFFER_BITS;
7044+ creg = cstatus & ~cmask & ~DONT_CARE_CARD_BITS;
7045+
7046+ if (!breg && !creg) {
7047+ /* This occurs sometimes for no known reason. It doesn't hurt
7048+ * anything, so I don't print it. */
7049+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) &= ~breg;
7050+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard) &= ~creg;
7051+ goto out;
7052+ }
7053+
7054+ while (breg || creg) {
7055+
7056+ /* XXX TODO: Need to handle errors in breg here. */
7057+
7058+ /*
7059+ * Card insert/remove. The mmc controlling code is stateless. That
7060+ * is, it doesn't care if it was an insert or a remove. It treats
7061+ * both the same.
7062+ */
7063+ /* XXX Asic3 has _3 versions of these status bits, too, for a second slot, perhaps? */
7064+ if (creg & (SD_CTRL_CARDSTATUS_CARD_INSERTED_0 | SD_CTRL_CARDSTATUS_CARD_REMOVED_0)) {
7065+ ASIC3_MMC_REG(host, SD_CTRL, CardStatus) &=
7066+ ~(SD_CTRL_CARDSTATUS_CARD_REMOVED_0 | SD_CTRL_CARDSTATUS_CARD_INSERTED_0);
7067+ if(creg & SD_CTRL_CARDSTATUS_CARD_INSERTED_0) {
7068+ hwinit2_irqsafe(host);
7069+ }
7070+ mmc_detect_change(host->mmc,1);
7071+ }
7072+
7073+ /* Command completion */
7074+ if (creg & SD_CTRL_CARDSTATUS_RESPONSE_END) {
7075+ ASIC3_MMC_REG(host, SD_CTRL, CardStatus) &=
7076+ ~(SD_CTRL_CARDSTATUS_RESPONSE_END);
7077+ mmc_cmd_irq(host, bstatus);
7078+ }
7079+
7080+ /* Data transfer */
7081+ if (breg & (SD_CTRL_BUFFERSTATUS_BUFFER_READ_ENABLE | SD_CTRL_BUFFERSTATUS_BUFFER_WRITE_ENABLE)) {
7082+ ASIC3_MMC_REG(host, SD_CTRL, BufferCtrl) &=
7083+ ~(SD_CTRL_BUFFERSTATUS_BUFFER_WRITE_ENABLE | SD_CTRL_BUFFERSTATUS_BUFFER_READ_ENABLE);
7084+ tasklet_schedule(&mmc_data_read_tasklet);
7085+ }
7086+
7087+ /* Data transfer completion */
7088+ if (creg & SD_CTRL_CARDSTATUS_RW_END) {
7089+ ASIC3_MMC_REG(host, SD_CTRL, CardStatus) &= ~(SD_CTRL_CARDSTATUS_RW_END);
7090+ mmc_data_end_irq(host);
7091+ }
7092+
7093+ /* Check status - keep going until we've handled it all */
7094+ bstatus = ASIC3_MMC_REG(host, SD_CTRL, BufferCtrl);
7095+ bmask = ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer);
7096+ cstatus = ASIC3_MMC_REG(host, SD_CTRL, CardStatus);
7097+ cmask = ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard);
7098+ breg = bstatus & ~bmask & ~DONT_CARE_BUFFER_BITS;
7099+ creg = cstatus & ~cmask & ~DONT_CARE_CARD_BITS;
7100+ }
7101+
7102+out:
7103+ /* Ensure all interrupt sources are cleared */
7104+ ASIC3_MMC_REG(host, SD_CTRL, BufferCtrl) = 0;
7105+ ASIC3_MMC_REG(host, SD_CTRL, CardStatus) = 0;
7106+ return IRQ_HANDLED;
7107+}
7108+
7109+static void
7110+mmc_start_data(struct asic3_mmc_host *host, struct mmc_data *data)
7111+{
7112+ DBG("setup data transfer: blocksize %08x nr_blocks %d, page: %08x, offset: %08x\n", data->blksz,
7113+ data->blocks, (int)data->sg->page, data->sg->offset);
7114+
7115+ host->sg_len = data->sg_len;
7116+ host->sg_ptr = data->sg;
7117+ host->sg_off = 0;
7118+ host->data = data;
7119+
7120+ /* Set transfer length and blocksize */
7121+ ASIC3_MMC_REG(host, SD_CTRL, TransferSectorCount) = data->blocks;
7122+ ASIC3_MMC_REG(host, SD_CTRL, MemCardXferDataLen) = data->blksz;
7123+}
7124+
7125+/* Process requests from the MMC layer */
7126+static void
7127+mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
7128+{
7129+ struct asic3_mmc_host *host = mmc_priv(mmc);
7130+
7131+ WARN_ON(host->mrq != NULL);
7132+
7133+ host->mrq = mrq;
7134+
7135+ /* If we're performing a data request we need to setup some
7136+ extra information */
7137+ if(mrq->data) {
7138+ mmc_start_data(host, mrq->data);
7139+ }
7140+
7141+ mmc_start_command(host, mrq->cmd);
7142+}
7143+
7144+/* Set MMC clock / power.
7145+ * Note: This controller uses a simple divider scheme therefore it cannot run
7146+ * a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as MMC
7147+ * wont run that fast, it has to be clocked at 12MHz which is the next slowest
7148+ * setting. This is likely not an issue because we are doing single 16-bit
7149+ * writes for data I/O.
7150+ */
7151+static void
7152+mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
7153+{
7154+ struct asic3_mmc_host *host = mmc_priv(mmc);
7155+ u32 clk = 0;
7156+
7157+ DBG("clock %uHz busmode %u powermode %u Vdd %u\n",
7158+ ios->clock, ios->bus_mode, ios->power_mode, ios->vdd);
7159+
7160+ if (ios->clock) {
7161+ clk = 0x80; /* slowest by default */
7162+ if(ios->clock >= 24000000 / 256) clk >>= 1;
7163+ if(ios->clock >= 24000000 / 128) clk >>= 1;
7164+ if(ios->clock >= 24000000 / 64) clk >>= 1;
7165+ if(ios->clock >= 24000000 / 32) clk >>= 1;
7166+ if(ios->clock >= 24000000 / 16) clk >>= 1;
7167+ if(ios->clock >= 24000000 / 8) clk >>= 1;
7168+ if(ios->clock >= 24000000 / 4) clk >>= 1;
7169+ if(ios->clock >= 24000000 / 2) clk >>= 1;
7170+ if(ios->clock >= 24000000 / 1) clk >>= 1;
7171+ if(clk == 0) { /* For fastest speed we disable the divider. */
7172+ ASIC3_MMC_REG(host, SD_CONFIG, ClockMode) = 0;
7173+ } else {
7174+ ASIC3_MMC_REG(host, SD_CONFIG, ClockMode) = 1;
7175+ }
7176+ ASIC3_MMC_REG(host, SD_CTRL, CardClockCtrl) = 0;
7177+ ASIC3_MMC_REG(host, SD_CTRL, CardClockCtrl) =
7178+ host->clock_for_sd
7179+ | SD_CTRL_CARDCLOCKCONTROL_ENABLE_CLOCK
7180+ | clk;
7181+ msleep(10);
7182+ } else {
7183+ ASIC3_MMC_REG(host, SD_CTRL, CardClockCtrl) = 0;
7184+ }
7185+
7186+ switch (ios->power_mode) {
7187+ case MMC_POWER_OFF:
7188+ ASIC3_MMC_REG(host, SD_CONFIG, SDHC_Power1) = 0;
7189+ msleep(1);
7190+ break;
7191+ case MMC_POWER_UP:
7192+ break;
7193+ case MMC_POWER_ON:
7194+ ASIC3_MMC_REG(host, SD_CONFIG, SDHC_Power1) = SD_CONFIG_POWER1_PC_33V;
7195+ msleep(20);
7196+ break;
7197+ }
7198+}
7199+
7200+static int
7201+mmc_get_ro(struct mmc_host *mmc)
7202+{
7203+ struct asic3_mmc_host *host = mmc_priv(mmc);
7204+
7205+ /* Call custom handler for RO status */
7206+ if(host->hwconfig->mmc_get_ro) {
7207+ /* Special case for cards w/o WP lock (like miniSD) */
7208+ if (host->hwconfig->mmc_get_ro == (void*)-1) {
7209+ return 0;
7210+ } else {
7211+ struct platform_device *pdev = to_platform_device(mmc_dev(mmc));
7212+ return host->hwconfig->mmc_get_ro(pdev);
7213+ }
7214+ }
7215+
7216+ /* WRITE_PROTECT is active low */
7217+ return (ASIC3_MMC_REG(host, SD_CTRL, CardStatus) & SD_CTRL_CARDSTATUS_WRITE_PROTECT)?0:1;
7218+}
7219+
7220+static struct mmc_host_ops mmc_ops = {
7221+ .request = mmc_request,
7222+ .set_ios = mmc_set_ios,
7223+ .get_ro = mmc_get_ro,
7224+};
7225+
7226+static void
7227+hwinit2_irqsafe(struct asic3_mmc_host *host)
7228+{
7229+ ASIC3_MMC_REG(host, SD_CONFIG, Addr1) = 0x0000;
7230+ ASIC3_MMC_REG(host, SD_CONFIG, Addr0) = 0x0800;
7231+
7232+ ASIC3_MMC_REG(host, SD_CONFIG, ClkStop) = SD_CONFIG_CLKSTOP_ENABLE_ALL;
7233+ ASIC3_MMC_REG(host, SD_CONFIG, SDHC_CardDetect) = 2;
7234+ ASIC3_MMC_REG(host, SD_CONFIG, Command) = SD_CONFIG_COMMAND_MAE;
7235+
7236+ ASIC3_MMC_REG(host, SD_CTRL, SoftwareReset) = 0; /* reset on */
7237+ mdelay(2);
7238+
7239+ ASIC3_MMC_REG(host, SD_CTRL, SoftwareReset) = 1; /* reset off */
7240+ mdelay(2);
7241+
7242+ ASIC3_MMC_REG(host, SD_CTRL, MemCardOptionSetup) =
7243+ MEM_CARD_OPTION_REQUIRED
7244+ | MEM_CARD_OPTION_DATA_RESPONSE_TIMEOUT(14)
7245+ | MEM_CARD_OPTION_C2_MODULE_NOT_PRESENT
7246+ | MEM_CARD_OPTION_DATA_XFR_WIDTH_1
7247+ ;
7248+ host->clock_for_sd = 0;
7249+
7250+ ASIC3_MMC_REG(host, SD_CTRL, CardClockCtrl) = 0;
7251+ ASIC3_MMC_REG(host, SD_CTRL, CardStatus) = 0;
7252+ ASIC3_MMC_REG(host, SD_CTRL, BufferCtrl) = 0;
7253+ ASIC3_MMC_REG(host, SD_CTRL, ErrorStatus0) = 0;
7254+ ASIC3_MMC_REG(host, SD_CTRL, ErrorStatus1) = 0;
7255+ ASIC3_MMC_REG(host, SD_CTRL, StopInternal) = 0;
7256+
7257+ ASIC3_MMC_REG(host, SDIO_CTRL, ClocknWaitCtrl) = 0x100;
7258+ /* *((unsigned short *)(((char *)host->ctl_base) + 0x938)) = 0x100; */
7259+
7260+ ASIC3_MMC_REG(host, SD_CONFIG, ClockMode) = 0;
7261+ ASIC3_MMC_REG(host, SD_CTRL, CardClockCtrl) = 0;
7262+
7263+ mdelay(1);
7264+
7265+
7266+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard) = ~(
7267+ SD_CTRL_INTMASKCARD_RESPONSE_END
7268+ | SD_CTRL_INTMASKCARD_RW_END
7269+ | SD_CTRL_INTMASKCARD_CARD_REMOVED_0
7270+ | SD_CTRL_INTMASKCARD_CARD_INSERTED_0
7271+#if 0
7272+ | SD_CTRL_INTMASKCARD_CARD_REMOVED_3
7273+ | SD_CTRL_INTMASKCARD_CARD_INSERTED_3
7274+#endif
7275+ )
7276+ ; /* check */
7277+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskBuffer) = 0xffff; /* IRQs off */
7278+
7279+ /*
7280+ * ASIC3_MMC_REG(host, SD_CTRL, TransactionCtrl) = SD_CTRL_TRANSACTIONCONTROL_SET;
7281+ * Wince has 0x1000
7282+ */
7283+ /* ASIC3_MMC_REG(host, SD_CTRL, TransactionCtrl) = 0x1000; */
7284+
7285+
7286+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_SDPWR, ASIC3_SDHWCTRL_SDPWR); /* turn on power at controller(?) */
7287+
7288+}
7289+
7290+static void
7291+hwinit(struct asic3_mmc_host *host, struct platform_device *pdev)
7292+{
7293+ /* Call custom handler for enabling clock (if needed) */
7294+ if(host->hwconfig->set_mmc_clock)
7295+ host->hwconfig->set_mmc_clock(pdev, MMC_CLOCK_ENABLED);
7296+
7297+ /* Not sure if it must be done bit by bit, but leaving as-is */
7298+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_LEVCD, ASIC3_SDHWCTRL_LEVCD);
7299+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_LEVWP, ASIC3_SDHWCTRL_LEVWP);
7300+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_SUSPEND, 0);
7301+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_PCLR, 0);
7302+
7303+ asic3_set_clock_cdex (host->asic3_dev,
7304+ CLOCK_CDEX_EX1 | CLOCK_CDEX_EX0, CLOCK_CDEX_EX1 | CLOCK_CDEX_EX0);
7305+ msleep(1);
7306+
7307+ asic3_set_clock_sel (host->asic3_dev,
7308+ CLOCK_SEL_SD_HCLK_SEL | CLOCK_SEL_SD_BCLK_SEL,
7309+ CLOCK_SEL_SD_HCLK_SEL | 0); /* ? */
7310+
7311+ asic3_set_clock_cdex (host->asic3_dev,
7312+ CLOCK_CDEX_SD_HOST | CLOCK_CDEX_SD_BUS,
7313+ CLOCK_CDEX_SD_HOST | CLOCK_CDEX_SD_BUS);
7314+ msleep(1);
7315+
7316+ asic3_set_extcf_select(host->asic3_dev, ASIC3_EXTCF_SD_MEM_ENABLE, ASIC3_EXTCF_SD_MEM_ENABLE);
7317+
7318+ /* Long Delay */
7319+ if( !machine_is_h4700())
7320+ msleep(500);
7321+
7322+ hwinit2_irqsafe(host);
7323+}
7324+
7325+#ifdef CONFIG_PM
7326+static int
7327+mmc_suspend(struct platform_device *pdev, pm_message_t state)
7328+{
7329+ struct mmc_host *mmc = platform_get_drvdata(pdev);
7330+ struct asic3_mmc_host *host = mmc_priv(mmc);
7331+ int ret;
7332+
7333+ ret = mmc_suspend_host(mmc, state);
7334+
7335+ if (ret) {
7336+ printk(KERN_ERR DRIVER_NAME ": Could not suspend MMC host, hardware not suspended");
7337+ return ret;
7338+ }
7339+
7340+ /* disable the card insert / remove interrupt while sleeping */
7341+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard) = ~(
7342+ SD_CTRL_INTMASKCARD_RESPONSE_END
7343+ | SD_CTRL_INTMASKCARD_RW_END);
7344+
7345+ /* disable clock */
7346+ ASIC3_MMC_REG(host, SD_CTRL, CardClockCtrl) = 0;
7347+ ASIC3_MMC_REG(host, SD_CONFIG, ClkStop) = 0;
7348+
7349+ /* power down */
7350+ ASIC3_MMC_REG(host, SD_CONFIG, SDHC_Power1) = 0;
7351+
7352+ asic3_set_clock_cdex (host->asic3_dev,
7353+ CLOCK_CDEX_SD_HOST | CLOCK_CDEX_SD_BUS, 0);
7354+
7355+ /* disable core clock */
7356+ if(host->hwconfig->set_mmc_clock)
7357+ host->hwconfig->set_mmc_clock(pdev, MMC_CLOCK_DISABLED);
7358+
7359+ /* Put in suspend mode */
7360+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_SUSPEND, ASIC3_SDHWCTRL_SUSPEND);
7361+ return 0;
7362+}
7363+
7364+static int
7365+mmc_resume(struct platform_device *pdev)
7366+{
7367+ struct mmc_host *mmc = platform_get_drvdata(pdev);
7368+ struct asic3_mmc_host *host = mmc_priv(mmc);
7369+
7370+ printk(KERN_INFO "%s: starting resume\n", DRIVER_NAME);
7371+
7372+ asic3_set_sdhwctrl(host->asic3_dev, ASIC3_SDHWCTRL_SUSPEND, 0);
7373+ hwinit(host, pdev);
7374+
7375+ /* re-enable card remove / insert interrupt */
7376+ ASIC3_MMC_REG(host, SD_CTRL, IntMaskCard) = ~(
7377+ SD_CTRL_INTMASKCARD_RESPONSE_END
7378+ | SD_CTRL_INTMASKCARD_RW_END
7379+ | SD_CTRL_INTMASKCARD_CARD_REMOVED_0
7380+ | SD_CTRL_INTMASKCARD_CARD_INSERTED_0 );
7381+
7382+ mmc_resume_host(mmc);
7383+
7384+ printk(KERN_INFO "%s: finished resume\n", DRIVER_NAME);
7385+ return 0;
7386+}
7387+#endif
7388+
7389+static int
7390+mmc_probe(struct platform_device *pdev)
7391+{
7392+ struct mmc_host *mmc;
7393+ struct asic3_mmc_host *host = NULL;
7394+ int retval = 0;
7395+ struct tmio_mmc_hwconfig *mmc_config = (struct tmio_mmc_hwconfig *)pdev->dev.platform_data;
7396+
7397+ /* bus_shift is mandatory */
7398+ if (!mmc_config) {
7399+ printk(KERN_ERR DRIVER_NAME ": Invalid configuration\n");
7400+ return -EINVAL;
7401+ }
7402+
7403+ mmc = mmc_alloc_host(sizeof(struct asic3_mmc_host) + 128, &pdev->dev);
7404+ if (!mmc) {
7405+ retval = -ENOMEM;
7406+ goto exceptional_return;
7407+ }
7408+
7409+ host = mmc_priv(mmc);
7410+ host->mmc = mmc;
7411+ platform_set_drvdata(pdev, mmc);
7412+
7413+ host->ctl_base = 0;
7414+ host->hwconfig = mmc_config;
7415+ host->bus_shift = mmc_config->address_shift;
7416+ host->asic3_dev = pdev->dev.parent;
7417+ host->clock_for_sd = 0;
7418+
7419+ tasklet_init(&mmc_data_read_tasklet, mmc_data_transfer, (unsigned long)host);
7420+
7421+ host->ctl_base = ioremap_nocache ((unsigned long)pdev->resource[0].start, pdev->resource[0].end - pdev->resource[0].start);
7422+ if(!host->ctl_base){
7423+ printk(KERN_ERR DRIVER_NAME ": Could not map ASIC3 SD controller\n");
7424+ retval = -ENODEV;
7425+ goto exceptional_return;
7426+ }
7427+
7428+ printk(DRIVER_NAME ": ASIC3 MMC/SD Driver, controller at 0x%lx\n", (unsigned long)pdev->resource[0].start);
7429+
7430+ mmc->ops = &mmc_ops;
7431+ mmc->caps = MMC_CAP_4_BIT_DATA;
7432+ mmc->f_min = 46875; /* ARIC: not sure what these should be */
7433+ mmc->f_max = 24000000; /* ARIC: not sure what these should be */
7434+ mmc->ocr_avail = MMC_VDD_32_33;
7435+
7436+ hwinit(host, pdev);
7437+
7438+
7439+ host->irq = pdev->resource[1].start;
7440+
7441+ retval = request_irq(host->irq, mmc_irq, 0, DRIVER_NAME, host);
7442+ if(retval) {
7443+ printk(KERN_ERR DRIVER_NAME ": Unable to get interrupt\n");
7444+ retval = -ENODEV;
7445+ goto exceptional_return;
7446+ }
7447+ set_irq_type(host->irq, IRQT_FALLING);
7448+
7449+ mmc_add_host(mmc);
7450+
7451+#ifdef CONFIG_PM
7452+ // resume_timer.function = resume_timer_callback;
7453+ // resume_timer.data = 0;
7454+ // init_timer(&resume_timer);
7455+#endif
7456+
7457+ return 0;
7458+
7459+exceptional_return:
7460+ if (mmc) {
7461+ mmc_free_host(mmc);
7462+ }
7463+ if(host && host->ctl_base) iounmap(host->ctl_base);
7464+ return retval;
7465+}
7466+
7467+static int
7468+mmc_remove(struct platform_device *pdev)
7469+{
7470+ struct mmc_host *mmc = platform_get_drvdata(pdev);
7471+
7472+ platform_set_drvdata(pdev, NULL);
7473+
7474+ if (mmc) {
7475+ struct asic3_mmc_host *host = mmc_priv(mmc);
7476+ mmc_remove_host(mmc);
7477+ free_irq(host->irq, host);
7478+ /* FIXME - we might want to consider stopping the chip here... */
7479+ iounmap(host->ctl_base);
7480+ mmc_free_host(mmc); /* FIXME - why does this call hang? */
7481+ }
7482+ return 0;
7483+}
7484+
7485+/* ------------------- device registration ----------------------- */
7486+
7487+static struct platform_driver mmc_asic3_driver = {
7488+ .driver = {
7489+ .name = DRIVER_NAME,
7490+ },
7491+ .probe = mmc_probe,
7492+ .remove = mmc_remove,
7493+#ifdef CONFIG_PM
7494+ .suspend = mmc_suspend,
7495+ .resume = mmc_resume,
7496+#endif
7497+};
7498+
7499+static int __init mmc_init(void)
7500+{
7501+ return platform_driver_register(&mmc_asic3_driver);
7502+}
7503+
7504+static void __exit mmc_exit(void)
7505+{
7506+ platform_driver_unregister(&mmc_asic3_driver);
7507+}
7508+
7509+late_initcall(mmc_init);
7510+module_exit(mmc_exit);
7511+
7512+MODULE_DESCRIPTION("HTC ASIC3 SD/MMC driver");
7513+MODULE_AUTHOR("Aric Blumer, SDG Systems, LLC");
7514+MODULE_LICENSE("GPL");
7515+
7516Index: linux-2.6.26-rc4/drivers/mmc/host/asic3_mmc.h
7517===================================================================
7518--- /dev/null 1970-01-01 00:00:00.000000000 +0000
7519+++ linux-2.6.26-rc4/drivers/mmc/host/asic3_mmc.h 2008-06-01 18:49:45.000000000 +0100
7520@@ -0,0 +1,25 @@
7521+#ifndef __ASIC3_MMC_H
7522+#define __ASIC3_MMC_H
7523+
7524+#define DRIVER_NAME "asic3_mmc"
7525+
7526+#ifdef CONFIG_MMC_DEBUG
7527+#define DBG(x...) printk(DRIVER_NAME ": " x)
7528+#else
7529+#define DBG(x...) do { } while (0)
7530+#endif
7531+
7532+/* Response types */
7533+#define APP_CMD 0x0040
7534+
7535+#define SD_CONFIG_CLKSTOP_ENABLE_ALL 0x1f
7536+
7537+#define DONT_CARE_CARD_BITS ( \
7538+ SD_CTRL_INTMASKCARD_SIGNAL_STATE_PRESENT_3 \
7539+ | SD_CTRL_INTMASKCARD_WRITE_PROTECT \
7540+ | SD_CTRL_INTMASKCARD_UNK6 \
7541+ | SD_CTRL_INTMASKCARD_SIGNAL_STATE_PRESENT_0 \
7542+ )
7543+#define DONT_CARE_BUFFER_BITS ( SD_CTRL_INTMASKBUFFER_UNK7 | SD_CTRL_INTMASKBUFFER_CMD_BUSY )
7544+
7545+#endif // __ASIC3_MMC_H
7546Index: linux-2.6.26-rc4/drivers/input/keyboard/Makefile
7547===================================================================
7548--- linux-2.6.26-rc4.orig/drivers/input/keyboard/Makefile 2008-05-26 19:08:11.000000000 +0100
7549+++ linux-2.6.26-rc4/drivers/input/keyboard/Makefile 2008-06-01 18:52:37.000000000 +0100
7550@@ -15,6 +15,7 @@
7551 obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o
7552 obj-$(CONFIG_KEYBOARD_CORGI) += corgikbd.o
7553 obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o
7554+obj-$(CONFIG_KEYBOARD_ASIC3) += asic3_keys.o
7555 obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o
7556 obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
7557 obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
7558Index: linux-2.6.26-rc4/drivers/input/keyboard/asic3_keys.c
7559===================================================================
7560--- /dev/null 1970-01-01 00:00:00.000000000 +0000
7561+++ linux-2.6.26-rc4/drivers/input/keyboard/asic3_keys.c 2008-06-01 18:49:45.000000000 +0100
7562@@ -0,0 +1,131 @@
7563+/*
7564+ * Generic buttons driver for ASIC3 SoC.
7565+ *
7566+ * This file is subject to the terms and conditions of the GNU General Public
7567+ * License. See the file COPYING in the main directory of this archive for
7568+ * more details.
7569+ *
7570+ * Copyright (C) 2003 Joshua Wise
7571+ * Copyright (C) 2005 Pawel Kolodziejski
7572+ * Copyright (C) 2006 Paul Sokolovsky
7573+ *
7574+ */
7575+
7576+#include <linux/input.h>
7577+#include <linux/module.h>
7578+#include <linux/init.h>
7579+#include <linux/interrupt.h>
7580+#include <linux/platform_device.h>
7581+#include <linux/irq.h>
7582+#include <linux/soc/asic3_base.h>
7583+#include <asm/mach/arch.h>
7584+#include <asm/mach/map.h>
7585+#include <asm/arch/irqs.h>
7586+#include <asm/hardware.h>
7587+#include <asm/hardware/ipaq-asic3.h>
7588+#include <asm/hardware/asic3_keys.h>
7589+
7590+static irqreturn_t asic3_keys_asic_handle(int irq, void *data)
7591+{
7592+ struct asic3_keys_platform_data *pdata = data;
7593+ int i, base_irq;
7594+
7595+ base_irq = asic3_irq_base(pdata->asic3_dev);
7596+ for (i = 0; i < pdata->nbuttons; i++) {
7597+ struct asic3_keys_button *b = &pdata->buttons[i];
7598+ if ((base_irq + b->gpio) == irq) {
7599+ int state = !!asic3_gpio_get_value(pdata->asic3_dev, b->gpio);
7600+
7601+ if (pdata->buttons[i].type == EV_SW)
7602+ input_report_switch(pdata->input, pdata->buttons[i].keycode, state ^ b->active_low);
7603+ else
7604+ input_report_key(pdata->input, b->keycode, state ^ b->active_low);
7605+ input_sync(pdata->input);
7606+ }
7607+ }
7608+
7609+ return IRQ_HANDLED;
7610+}
7611+
7612+static int __devinit asic3_keys_probe(struct platform_device *pdev)
7613+{
7614+ struct asic3_keys_platform_data *pdata = pdev->dev.platform_data;
7615+ int i, base_irq;
7616+ int j, ret;
7617+
7618+ pdata->input = input_allocate_device();
7619+
7620+ base_irq = asic3_irq_base(pdata->asic3_dev);
7621+
7622+ for (i = 0; i < pdata->nbuttons; i++) {
7623+ struct asic3_keys_button *b = &pdata->buttons[i];
7624+ set_bit(b->keycode, pdata->input->keybit);
7625+ ret=request_irq(base_irq + b->gpio, asic3_keys_asic_handle, SA_SAMPLE_RANDOM, b->desc, pdata);
7626+ if (ret)
7627+ {
7628+ printk(KERN_NOTICE "Failed to allocate asic3_keys irq=%d.\n",b->gpio);
7629+
7630+ for(j=0; j<i ; j++)
7631+ free_irq(base_irq + pdata->buttons[i].gpio, NULL);
7632+
7633+ input_unregister_device (pdata->input);
7634+
7635+ return -ENODEV;
7636+ }
7637+
7638+ set_irq_type(base_irq + b->gpio, IRQT_BOTHEDGE);
7639+ if (pdata->buttons[i].type == EV_SW) {
7640+ pdata->input->evbit[0] |= BIT(EV_SW);
7641+ set_bit(b->keycode, pdata->input->swbit);
7642+ } else {
7643+ pdata->input->evbit[0] |= BIT(EV_KEY);
7644+ set_bit(b->keycode, pdata->input->keybit);
7645+ }
7646+ }
7647+
7648+ pdata->input->name = pdev->name;
7649+ input_register_device(pdata->input);
7650+
7651+ return 0;
7652+}
7653+
7654+static int __devexit asic3_keys_remove(struct platform_device *pdev)
7655+{
7656+ struct asic3_keys_platform_data *pdata = pdev->dev.platform_data;
7657+ int i, base_irq;
7658+
7659+ base_irq = asic3_irq_base(pdata->asic3_dev);
7660+ for (i = 0; i < pdata->nbuttons; i++) {
7661+ free_irq(base_irq + pdata->buttons[i].gpio, NULL);
7662+ }
7663+
7664+ input_unregister_device(pdata->input);
7665+
7666+ return 0;
7667+}
7668+
7669+
7670+static struct platform_driver asic3_keys_driver = {
7671+ .probe = asic3_keys_probe,
7672+ .remove = __devexit_p(asic3_keys_remove),
7673+ .driver = {
7674+ .name = "asic3-keys",
7675+ },
7676+};
7677+
7678+static int __init asic3_keys_init(void)
7679+{
7680+ return platform_driver_register(&asic3_keys_driver);
7681+}
7682+
7683+static void __exit asic3_keys_exit(void)
7684+{
7685+ platform_driver_unregister(&asic3_keys_driver);
7686+}
7687+
7688+module_init(asic3_keys_init);
7689+module_exit(asic3_keys_exit);
7690+
7691+MODULE_AUTHOR("Joshua Wise, Pawel Kolodziejski, Paul Sokolovsky");
7692+MODULE_DESCRIPTION("Buttons driver for HTC ASIC3 SoC");
7693+MODULE_LICENSE("GPL");
7694Index: linux-2.6.26-rc4/include/asm-arm/arch-pxa/irqs.h
7695===================================================================
7696--- linux-2.6.26-rc4.orig/include/asm-arm/arch-pxa/irqs.h 2008-05-26 19:08:11.000000000 +0100
7697+++ linux-2.6.26-rc4/include/asm-arm/arch-pxa/irqs.h 2008-06-01 18:49:45.000000000 +0100
7698@@ -184,6 +184,8 @@
7699 defined(CONFIG_MACH_PCM027) || \
7700 defined(CONFIG_MACH_MAGICIAN)
7701 #define NR_IRQS (IRQ_BOARD_END)
7702+#elif defined(CONFIG_MACH_HTCUNIVERSAL)
7703+#define NR_IRQS (IRQ_BOARD_START + 96)
7704 #else
7705 #define NR_IRQS (IRQ_BOARD_START)
7706 #endif
7707Index: linux-2.6.26-rc4/include/linux/ioport.h
7708===================================================================
7709--- linux-2.6.26-rc4.orig/include/linux/ioport.h 2008-05-26 19:08:11.000000000 +0100
7710+++ linux-2.6.26-rc4/include/linux/ioport.h 2008-06-01 18:49:45.000000000 +0100
7711@@ -59,6 +59,7 @@
7712 #define IORESOURCE_IRQ_HIGHLEVEL (1<<2)
7713 #define IORESOURCE_IRQ_LOWLEVEL (1<<3)
7714 #define IORESOURCE_IRQ_SHAREABLE (1<<4)
7715+#define IORESOURCE_IRQ_SOC_SUBDEVICE (1<<5)
7716
7717 /* ISA PnP DMA specific bits (IORESOURCE_BITS) */
7718 #define IORESOURCE_DMA_TYPE_MASK (3<<0)
7719Index: linux-2.6.26-rc4/include/asm-arm/arch-pxa/serial.h
7720===================================================================
7721--- /dev/null 1970-01-01 00:00:00.000000000 +0000
7722+++ linux-2.6.26-rc4/include/asm-arm/arch-pxa/serial.h 2008-06-01 18:49:45.000000000 +0100
7723@@ -0,0 +1,78 @@
7724+/*
7725+ * linux/include/asm-arm/arch-pxa/serial.h
7726+ *
7727+ * Author: Nicolas Pitre
7728+ * Copyright: (C) 2001 MontaVista Software Inc.
7729+ *
7730+ * This program is free software; you can redistribute it and/or modify
7731+ * it under the terms of the GNU General Public License version 2 as
7732+ * published by the Free Software Foundation.
7733+ */
7734+
7735+#include <asm/arch/pxa-regs.h>
7736+
7737+#define BAUD_BASE 921600
7738+
7739+/* Standard COM flags */
7740+#define STD_COM_FLAGS (ASYNC_SKIP_TEST)
7741+
7742+#define STD_SERIAL_PORT_DEFNS \
7743+ { \
7744+ type: PORT_PXA, \
7745+ xmit_fifo_size: 64, \
7746+ baud_base: BAUD_BASE, \
7747+ iomem_base: &FFUART, \
7748+ iomem_reg_shift: 2, \
7749+ io_type: SERIAL_IO_MEM, \
7750+ irq: IRQ_FFUART, \
7751+ flags: STD_COM_FLAGS, \
7752+ }, { \
7753+ type: PORT_PXA, \
7754+ xmit_fifo_size: 64, \
7755+ baud_base: BAUD_BASE, \
7756+ iomem_base: &STUART, \
7757+ iomem_reg_shift: 2, \
7758+ io_type: SERIAL_IO_MEM, \
7759+ irq: IRQ_STUART, \
7760+ flags: STD_COM_FLAGS, \
7761+ }, { \
7762+ type: PORT_PXA, \
7763+ xmit_fifo_size: 64, \
7764+ baud_base: BAUD_BASE, \
7765+ iomem_base: &BTUART, \
7766+ iomem_reg_shift: 2, \
7767+ io_type: SERIAL_IO_MEM, \
7768+ irq: IRQ_BTUART, \
7769+ flags: STD_COM_FLAGS, \
7770+ }
7771+
7772+#define EXTRA_SERIAL_PORT_DEFNS
7773+
7774+struct platform_pxa_serial_funcs {
7775+
7776+ /* Initialize whatever is connected to this serial port. */
7777+ void (*configure)(int state);
7778+#define PXA_UART_CFG_PRE_STARTUP 0
7779+#define PXA_UART_CFG_POST_STARTUP 1
7780+#define PXA_UART_CFG_PRE_SHUTDOWN 2
7781+#define PXA_UART_CFG_POST_SHUTDOWN 3
7782+
7783+ /* Enable or disable the individual transmitter/receiver submodules.
7784+ * On transceivers without echo cancellation (e.g. SIR)
7785+ * transmitter always has priority; e.g. if both bits are set,
7786+ * only the transmitter is enabled. */
7787+ void (*set_txrx)(int txrx);
7788+#define PXA_SERIAL_TX 1
7789+#define PXA_SERIAL_RX 2
7790+
7791+ /* Get the current state of tx/rx. */
7792+ int (*get_txrx)(void);
7793+
7794+ int (*suspend)(struct platform_device *dev, pm_message_t state);
7795+ int (*resume)(struct platform_device *dev);
7796+};
7797+
7798+void pxa_set_ffuart_info(struct platform_pxa_serial_funcs *ffuart_funcs);
7799+void pxa_set_btuart_info(struct platform_pxa_serial_funcs *btuart_funcs);
7800+void pxa_set_stuart_info(struct platform_pxa_serial_funcs *stuart_funcs);
7801+void pxa_set_hwuart_info(struct platform_pxa_serial_funcs *hwuart_funcs);
7802Index: linux-2.6.26-rc4/drivers/serial/pxa.c
7803===================================================================
7804--- linux-2.6.26-rc4.orig/drivers/serial/pxa.c 2008-05-26 19:08:11.000000000 +0100
7805+++ linux-2.6.26-rc4/drivers/serial/pxa.c 2008-06-01 18:49:45.000000000 +0100
7806@@ -47,6 +47,7 @@
7807 #include <asm/io.h>
7808 #include <asm/hardware.h>
7809 #include <asm/irq.h>
7810+#include <asm/arch/serial.h>
7811 #include <asm/arch/pxa-regs.h>
7812
7813
7814@@ -60,6 +61,14 @@
7815 char *name;
7816 };
7817
7818+
7819+#define IS_METHOD(dev, method) (dev && (dev)->platform_data && ((struct platform_pxa_serial_funcs *)(dev)->platform_data)->method)
7820+#define METHOD_CALL(dev, method) \
7821+ ((struct platform_pxa_serial_funcs *)(dev)->platform_data)->method()
7822+#define SAFE_METHOD_CALL(dev, method, args...) \
7823+ if (IS_METHOD(dev, method)) \
7824+ ((struct platform_pxa_serial_funcs *)(dev)->platform_data)->method(args)
7825+
7826 static inline unsigned int serial_in(struct uart_pxa_port *up, int offset)
7827 {
7828 offset <<= 2;
7829@@ -347,6 +356,9 @@
7830 unsigned long flags;
7831 int retval;
7832
7833+ /* Perform platform-specific port initialization, if needed. */
7834+ SAFE_METHOD_CALL(port->dev, configure, PXA_UART_CFG_PRE_STARTUP);
7835+
7836 if (port->line == 3) /* HWUART */
7837 up->mcr |= UART_MCR_AFE;
7838 else
7839@@ -404,6 +416,12 @@
7840 (void) serial_in(up, UART_IIR);
7841 (void) serial_in(up, UART_MSR);
7842
7843+ /*
7844+ * Perform platform-specific port initialization if needed
7845+ */
7846+ SAFE_METHOD_CALL(port->dev, configure, PXA_UART_CFG_POST_STARTUP);
7847+ SAFE_METHOD_CALL(port->dev, set_txrx, PXA_SERIAL_RX);
7848+
7849 return 0;
7850 }
7851
7852@@ -412,6 +430,8 @@
7853 struct uart_pxa_port *up = (struct uart_pxa_port *)port;
7854 unsigned long flags;
7855
7856+ SAFE_METHOD_CALL(port->dev, configure, PXA_UART_CFG_PRE_SHUTDOWN);
7857+
7858 free_irq(up->port.irq, up);
7859
7860 /*
7861@@ -433,6 +453,8 @@
7862 UART_FCR_CLEAR_RCVR |
7863 UART_FCR_CLEAR_XMIT);
7864 serial_out(up, UART_FCR, 0);
7865+
7866+ SAFE_METHOD_CALL(port->dev, configure, PXA_UART_CFG_POST_SHUTDOWN);
7867 }
7868
7869 static void
7870Index: linux-2.6.26-rc4/drivers/leds/Makefile
7871===================================================================
7872--- linux-2.6.26-rc4.orig/drivers/leds/Makefile 2008-05-26 19:08:11.000000000 +0100
7873+++ linux-2.6.26-rc4/drivers/leds/Makefile 2008-06-01 18:49:45.000000000 +0100
7874@@ -14,6 +14,7 @@
7875 obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
7876 obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o
7877 obj-$(CONFIG_LEDS_H1940) += leds-h1940.o
7878+obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o
7879 obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o
7880 obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o
7881 obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o
7882Index: linux-2.6.26-rc4/drivers/input/keyboard/Kconfig
7883===================================================================
7884--- linux-2.6.26-rc4.orig/drivers/input/keyboard/Kconfig 2008-05-26 19:08:11.000000000 +0100
7885+++ linux-2.6.26-rc4/drivers/input/keyboard/Kconfig 2008-06-01 18:52:13.000000000 +0100
7886@@ -132,6 +132,13 @@
7887 To compile this driver as a module, choose M here: the
7888 module will be called stowaway.
7889
7890+config KEYBOARD_ASIC3
7891+ tristate "Buttons on ASIC3 SoC GPIOs (iPaqs, etc.)"
7892+ depends on HTC_ASIC3
7893+ help
7894+ This enables support for the buttons attached to GPIOs of
7895+ HTC ASIC3 peripheral controller.
7896+
7897 config KEYBOARD_CORGI
7898 tristate "Corgi keyboard"
7899 depends on PXA_SHARPSL