Merge branch 'org.openembedded.dev' of git@git.openembedded.net:openembedded into...
[openembedded.git] / recipes / linux / linux-h6300-omap1-2.6.16.16 / linux-h6300-omap2-2.6.16.16.patch
1 diff -Naur linux-2.6.16.16/arch/arm/Kconfig h6300_dev/arch/arm/Kconfig
2 --- linux-2.6.16.16/arch/arm/Kconfig    2006-05-17 21:41:27.000000000 +0300
3 +++ h6300_dev/arch/arm/Kconfig  2006-04-02 00:23:01.000000000 +0300
4 @@ -811,6 +811,8 @@
5  
6  source "drivers/video/Kconfig"
7  
8 +source "drivers/telephony/Kconfig"
9 +
10  source "sound/Kconfig"
11  
12  source "drivers/usb/Kconfig"
13 diff -Naur linux-2.6.16.16/arch/arm/mach-omap1/board-h6300.c h6300_dev/arch/arm/mach-omap1/board-h6300.c
14 --- linux-2.6.16.16/arch/arm/mach-omap1/board-h6300.c   1970-01-01 02:00:00.000000000 +0200
15 +++ h6300_dev/arch/arm/mach-omap1/board-h6300.c 2006-04-24 20:53:29.000000000 +0300
16 @@ -0,0 +1,424 @@
17 +/*
18 + * Modified from board-h6300.c
19 + *
20 + * Code for generic OMAP board. Should work on many OMAP systems where
21 + * the device drivers take care of all the necessary hardware initialization.
22 + * Do not put any board specific code to this file; create a new machine
23 + * type if you need custom low-level initializations.
24 + *
25 + * This program is free software; you can redistribute it and/or modify
26 + * it under the terms of the GNU General Public License version 2 as
27 + * published by the Free Software Foundation.
28 + */
29 +
30 +#include <linux/kernel.h>
31 +#include <linux/init.h>
32 +#include <linux/platform_device.h>
33 +#include <linux/delay.h>
34 +#include <linux/mtd/mtd.h>
35 +#include <linux/mtd/partitions.h>
36 +#include <linux/input.h>
37 +
38 +#include <asm/hardware.h>
39 +#include <asm/mach-types.h>
40 +#include <asm/mach/arch.h>
41 +#include <asm/mach/flash.h>
42 +#include <asm/mach/map.h>
43 +
44 +#include <asm/arch/gpio.h>
45 +
46 +#include <asm/arch/tc.h>
47 +#include <asm/arch/usb.h>
48 +#include <asm/arch/keypad.h>
49 +#include <asm/arch/common.h>
50 +#include <asm/arch/mcbsp.h>
51 +#include <asm/arch/omap-alsa.h>
52 +#include <asm/arch/h6300_uart_info.h>
53 +
54 +#define _h6300_KEY_CALENDAR    67      // xmodmap 75 aka F9
55 +#define _H6300_KEY_TELEPHONE   68      // xmodmap 76 aka F10
56 +#define _H6300_KEY_HOMEPAGE    87      // xmodmap 87 aka Num_Lock
57 +#define _H6300_KEY_MAIL                88      // xmodmap 88 aka Scroll_Lock
58 +
59 +/*
60 + * Following 5 keypad events are not really sent to userspace. 
61 + * Instead if the good combination of them is sent, then that is send.
62 + * (up, right, down, left, enter)
63 + */
64 +#define        _H6300_JOYPAD_UP_RIGHT          1       // 00001
65 +#define _H6300_JOYPAD_DOWN_RIGHT       2       // 00010
66 +#define _h6300_JOYPAD_DOWN_LEFT                4       // 00100
67 +#define _h6300_JOYPAD_UP_LEFT          8       // 01000
68 +#define _H6300_JOYPAD_KEY_OK           16      // 10000
69 +
70 +static int h6300_keymap[] = {
71 +       KEY(2, 0, _h6300_KEY_CALENDAR),         // address button in the bottom left    
72 +       KEY(2, 3, _H6300_KEY_TELEPHONE),        // start call button in the bottom
73 +       KEY(3, 1, _H6300_KEY_HOMEPAGE),         // stop call button in the bottom
74 +       KEY(3, 4, _H6300_KEY_MAIL),             // messaging button in the bottom right
75 +
76 +       KEY(0, 0, KEY_VOLUMEUP),        // volume up button in the right side
77 +       KEY(0, 1, KEY_VOLUMEDOWN),      // volume down button in the right side
78 +       KEY(3, 2, KEY_RECORD),          // record button in the left side
79 +       
80 +       KEY(1, 0, _h6300_JOYPAD_UP_LEFT),       
81 +       KEY(1, 1, _h6300_JOYPAD_DOWN_LEFT),     
82 +       KEY(1, 2, _H6300_JOYPAD_KEY_OK),                
83 +       KEY(1, 3, _H6300_JOYPAD_DOWN_RIGHT),
84 +       KEY(1, 4, _H6300_JOYPAD_UP_RIGHT),      
85 +       
86 +       KEY(4, 0, KEY_RIGHT),
87 +       KEY(4, 1, KEY_DOWN),
88 +       KEY(4, 2, KEY_LEFT),            
89 +       KEY(4, 3, KEY_UP),
90 +       KEY(4, 4, KEY_ENTER),
91 +
92 +       0
93 +};
94 +
95 +/*
96 + * Bluetooth - Relies on h6300_bt module,
97 + * so make the calls indirectly through pointers. Requires that the
98 + * h6300_bt bluetooth module be loaded before any attempt to use
99 + * bluetooth (obviously).
100 + */
101 +
102 +static struct h6300_uart_funcs bt_funcs;
103 +static struct h6300_uart_funcs gsm_funcs;
104 +
105 +static void h6300_bt_configure(struct uart_omap_port *up, int enable)
106 +{
107 +       printk(KERN_NOTICE "board-h6300.c, h6300_bt_configure() started\n");
108 +       if (bt_funcs.configure != NULL)
109 +               bt_funcs.configure(up, enable);
110 +       printk(KERN_NOTICE "board-h6300.c, h6300_bt_configure() done\n");
111 +}
112 +
113 +static void h6300_bt_set_txrx(struct uart_omap_port *up, int txrx)
114 +{
115 +       printk(KERN_NOTICE "board-h6300.c, h6300_bt_set_txrx() started\n");
116 +       if (bt_funcs.set_txrx != NULL)
117 +       {
118 +               printk(KERN_NOTICE "board-h6300.c, h6300_bt_set_txrx(), bt_funcs.set_txrx != NULL\n");
119 +               bt_funcs.set_txrx(up, txrx);
120 +       }
121 +       printk(KERN_NOTICE "board-h6300.c, h6300_bt_set_txrx() done\n");
122 +}
123 +
124 +static int h6300_bt_get_txrx(struct uart_omap_port *up)
125 +{
126 +       int     retVal;
127 +       
128 +       printk(KERN_NOTICE "board-h6300.c, h6300_bt_get_txrx() started\n");
129 +       if (bt_funcs.get_txrx != NULL)
130 +       {
131 +               retVal  = bt_funcs.get_txrx(up);
132 +               printk(KERN_NOTICE "board-h6300.c, h6300_bt_get_txrx(), bt_funcs.get_trx != null, done, retVal %d\n", retVal);
133 +               return retVal;
134 +       }
135 +       else
136 +       {
137 +               printk(KERN_NOTICE "board-h6300.c, h6300_bt_get_txrx() done, returning 0\n");
138 +               return 0;
139 +       }
140 +}
141 +
142 +static struct platform_omap_serial_funcs h6300_omap_bt_funcs = {
143 +       .configure      = h6300_bt_configure,
144 +       .set_txrx       = h6300_bt_set_txrx,
145 +       .get_txrx       = h6300_bt_get_txrx,
146 +};
147 +
148 +struct platform_device btuart_device = {
149 +       .name   = "h6300_bt",
150 +       .id     = 1,
151 +};
152 +EXPORT_SYMBOL(btuart_device);
153 +
154 +static void h6300_gsm_configure(struct uart_omap_port *up, int enable)
155 +{
156 +       printk(KERN_NOTICE "board-h6300.c, h6300_gsm_configure() started\n");
157 +       if (gsm_funcs.configure != NULL)
158 +               gsm_funcs.configure(up, enable);
159 +       printk(KERN_NOTICE "board-h6300.c, h6300_gsm_configure() done\n");
160 +}
161 +
162 +static void h6300_gsm_set_txrx(struct uart_omap_port *up, int txrx)
163 +{
164 +       printk(KERN_NOTICE "board-h6300.c, h6300_gsm_set_txrx() started\n");
165 +       if (bt_funcs.set_txrx != NULL)
166 +       {
167 +               printk(KERN_NOTICE "board-h6300.c, h6300_gsm_set_txrx(), bt_funcs.set_txrx != NULL\n");
168 +               gsm_funcs.set_txrx(up, txrx);
169 +       }
170 +       printk(KERN_NOTICE "board-h6300.c, h6300_gsm_set_txrx() done\n");
171 +}
172 +
173 +static int h6300_gsm_get_txrx(struct uart_omap_port *up)
174 +{
175 +       int     retVal;
176 +       
177 +       printk(KERN_NOTICE "board-h6300.c, h6300_gsm_get_txrx() started\n");
178 +       if (bt_funcs.get_txrx != NULL)
179 +       {
180 +               retVal  = gsm_funcs.get_txrx(up);
181 +               printk(KERN_NOTICE "board-h6300.c, h6300_gsm_get_txrx(), bt_funcs.get_trx != null, done, retVal %d\n", retVal);
182 +               return retVal;
183 +       }
184 +       else
185 +       {
186 +               printk(KERN_NOTICE "board-h6300.c, h6300_gsm_get_txrx() done, returning 0\n");
187 +               return 0;
188 +       }
189 +}
190 +
191 +static struct platform_omap_serial_funcs h6300_omap_gsm_funcs = {
192 +       .configure      = h6300_gsm_configure,
193 +       .set_txrx       = h6300_gsm_set_txrx,
194 +       .get_txrx       = h6300_gsm_get_txrx,
195 +};
196 +
197 +struct platform_device gsmuart_device = {
198 +       .name   = "h6300_gsm",
199 +       .id     = 1,
200 +};
201 +EXPORT_SYMBOL(gsmuart_device);
202 +
203 +#if 0
204 +static struct mtd_partition h6300_partitions[] = {
205 +       /* bootloader (U-Boot, etc) in first sector */
206 +       {
207 +             .name             = "bootloader",
208 +             .offset           = 0,
209 +             .size             = SZ_128K,
210 +             .mask_flags       = MTD_WRITEABLE, /* force read-only */
211 +       },
212 +       /* bootloader params in the next sector */
213 +       {
214 +             .name             = "params",
215 +             .offset           = MTDPART_OFS_APPEND,
216 +             .size             = SZ_128K,
217 +             .mask_flags       = 0,
218 +       },
219 +       /* kernel */
220 +       {
221 +             .name             = "kernel",
222 +             .offset           = MTDPART_OFS_APPEND,
223 +             .size             = SZ_2M,
224 +             .mask_flags       = 0
225 +       },
226 +       /* rest of flash1 is a file system */
227 +       {
228 +             .name             = "rootfs",
229 +             .offset           = MTDPART_OFS_APPEND,
230 +             .size             = SZ_16M - SZ_2M - 2 * SZ_128K,
231 +             .mask_flags       = 0
232 +       },
233 +       /* file system */
234 +       {
235 +             .name             = "filesystem",
236 +             .offset           = MTDPART_OFS_APPEND,
237 +             .size             = MTDPART_SIZ_FULL,
238 +             .mask_flags       = 0
239 +       }
240 +};
241 +
242 +static struct flash_platform_data h6300_flash_data = {
243 +       .map_name       = "cfi_probe",
244 +       .width          = 2,
245 +       .parts          = h6300_partitions,
246 +       .nr_parts       = ARRAY_SIZE(h6300_partitions),
247 +};
248 +
249 +static struct resource h6300_flash_resource = {
250 +       .start          = OMAP_CS0_PHYS,
251 +       .end            = OMAP_CS0_PHYS + SZ_32M - 1,
252 +       .flags          = IORESOURCE_MEM,
253 +};
254 +
255 +static struct platform_device h6300_flash_device = {
256 +       .name   = "omapflash",
257 +       .id             = 0,
258 +       .dev    = {
259 +               .platform_data  = &h6300_flash_data,
260 +       },
261 +static struct platform_device h6300_flash_device = {
262 +       .name   = "omapflash",
263 +       .id             = 0,
264 +       .dev    = {
265 +               .platform_data  = &h6300_flash_data,
266 +       },
267 +       .num_resources  = 1,
268 +       .resource       = &h6300_flash_resource,
269 +};
270 +#endif
271 +
272 +static struct resource h6300_kp_resources[] = {
273 +       [0] = {
274 +               .start  = INT_KEYBOARD,
275 +               .end    = INT_KEYBOARD,
276 +               .flags  = IORESOURCE_IRQ,
277 +       },
278 +};
279 +
280 +static struct omap_kp_platform_data h6300_kp_data = {
281 +       .rows   = 8,
282 +       .cols   = 8,
283 +       .keymap = h6300_keymap,
284 +       .rep    = 1,    // turns repeat bit on
285 +};
286 +
287 +static struct platform_device h6300_kp_device = {
288 +       .name           = "omap-keypad",
289 +       .id             = -1,
290 +       .dev            = {
291 +               .platform_data = &h6300_kp_data,
292 +       },
293 +       .num_resources  = ARRAY_SIZE(h6300_kp_resources),
294 +       .resource       = h6300_kp_resources,
295 +};
296 +
297 +static struct resource h6300_wlan_resource[] = {
298 +        [0] = {
299 +                .start          = OMAP_CS1_PHYS,
300 +                .end            = OMAP_CS1_PHYS + SZ_32M -1,
301 +                .flags          = IORESOURCE_MEM,
302 +        },
303 +
304 +        [1] = {
305 +                .start  = OMAP_GPIO_IRQ(11),
306 +                .end    = OMAP_GPIO_IRQ(11),
307 +                .flags  = IORESOURCE_IRQ,
308 +        },
309 +};
310 +
311 +static struct platform_device h6300_wlan_device = {
312 +        .name           = "tnetw1100b",
313 +        .id             = 0,
314 +        .num_resources  = 2,
315 +        .resource       = h6300_wlan_resource,
316 +};
317 +
318 +static struct omap_mcbsp_reg_cfg mcbsp_regs = { 
319 +       .spcr2  = 0x0000,
320 +       .spcr1  = 0x0000,
321 +       .rcr2   = 0x8041,
322 +       .rcr1   = 0x0040,
323 +       .xcr2   = 0x00a1,
324 +       .xcr1   = 0x00a0,
325 +       .srgr2  = 0xb000,
326 +       .srgr1  = 0x0000,
327 +       .pcr0   = 0x0081,
328 +};
329 +
330 +static struct omap_alsa_codec_config alsa_config = {
331 +       .name                   = "iPAQ h6300 TSC2101",
332 +       .mcbsp_regs_alsa        = &mcbsp_regs,
333 +       .codec_configure_dev    = NULL, //tsc2101_configure,
334 +       .codec_set_samplerate   = NULL, //tsc2101_set_samplerate,
335 +       .codec_clock_setup      = NULL, //tsc2101_clock_setup,
336 +       .codec_clock_on         = NULL, //tsc2101_clock_on,
337 +       .codec_clock_off        = NULL, //tsc2101_clock_off,
338 +       .get_default_samplerate = NULL, //tsc2101_get_default_samplerate,
339 +};
340 +
341 +static struct platform_device h6300_mcbsp1_device = {
342 +       .name   = "omap_alsa_mcbsp",
343 +       .id     = 1,
344 +       .dev = {
345 +               .platform_data  = &alsa_config,
346 +       },
347 +};
348 +
349 +static struct platform_device h6300_lcd_device = {
350 +       .name   = "lcd_h6300",
351 +       .id     = -1,
352 +};
353 +
354 +static struct platform_device *h6300_devices[] __initdata = {
355 +       &h6300_lcd_device,
356 +       &btuart_device,
357 +       &gsmuart_device,
358 +       &h6300_kp_device,
359 +       &h6300_mcbsp1_device,
360 +       &h6300_wlan_device,
361 +       //&h6300_flash_device,
362 +};
363 +
364 +static void __init h6300_init_irq(void)
365 +{
366 +       omap1_init_common_hw();
367 +       omap_init_irq();
368 +       omap_gpio_init();
369 +
370 +       /* this is now done in the drivers/input/touschreen/omap/ts_hx.c*/
371 +       //omap_request_gpio(2);
372 +       //omap_set_gpio_direction(2, 0);
373 +       //omap_set_gpio_dataout(2, 1);
374 +}
375 +
376 +/* assume no Mini-AB port */
377 +
378 +static struct omap_usb_config h6300_usb_config __initdata = {
379 +       .hmc_mode       = 0,
380 +       .register_dev   = 1,
381 +       .pins[0]        = 0,
382 +};
383 +
384 +static struct omap_lcd_config h6300_lcd_config __initdata = {
385 +       .ctrl_name      = "internal",
386 +};
387 +
388 +static struct omap_mmc_config h6300_mmc_config __initdata = {
389 +       .mmc [0] = {
390 +               .enabled        = 1,
391 +               .wire4          = 1,
392 +               .wp_pin         = OMAP_GPIO_IRQ(13),
393 +               .power_pin      = -1, // tps65010 ?
394 +               .switch_pin     = -1, // OMAP_MPUIO(1), // = -1, // ARMIO2?
395 +       },
396 +};
397 +
398 +static struct omap_uart_config h6300_uart_config __initdata = {
399 +       .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
400 +};
401 +
402 +static struct omap_board_config_kernel h6300_config[] = {
403 +       { OMAP_TAG_USB,         &h6300_usb_config },
404 +       { OMAP_TAG_MMC,         &h6300_mmc_config },
405 +       { OMAP_TAG_UART,        &h6300_uart_config },
406 +       { OMAP_TAG_LCD,         &h6300_lcd_config },
407 +};
408 +
409 +static void __init h6300_init(void)
410 +{
411 +       int ret;
412 +       
413 +       ret = platform_add_devices(h6300_devices, ARRAY_SIZE(h6300_devices));
414 +       if (ret) 
415 +       {
416 +               printk(KERN_WARNING "Unable to add h6300 platform devices like bluetooth");
417 +       }
418 +       omap_board_config       = h6300_config;
419 +       omap_board_config_size  = ARRAY_SIZE(h6300_config);
420 +       omap_serial_init();
421 +}
422 +
423 +static void __init h6300_map_io(void)
424 +{
425 +       omap1_map_common_io();
426 +       
427 +       btuart_device.dev.platform_data         = &h6300_omap_bt_funcs;
428 +       gsmuart_device.dev.platform_data        = &h6300_omap_gsm_funcs;
429 +}
430 +
431 +MACHINE_START(OMAP_H6300, "HP iPAQ h6300")
432 +       /* MAINTAINER("Everett Coleman II <gcc80x86@fuzzyneural.net>") */
433 +       .phys_io                = 0xfff00000,
434 +       .io_pg_offst    = ((0xfef00000) >> 18) & 0xfffc,
435 +       .boot_params    = 0x10000100,
436 +       .map_io                 = h6300_map_io,
437 +       .init_irq               = h6300_init_irq,
438 +       .init_machine   = h6300_init,
439 +       .timer                  = &omap_timer,
440 +MACHINE_END
441 diff -Naur linux-2.6.16.16/arch/arm/mach-omap1/Kconfig h6300_dev/arch/arm/mach-omap1/Kconfig
442 --- linux-2.6.16.16/arch/arm/mach-omap1/Kconfig 2006-05-17 21:41:27.000000000 +0300
443 +++ h6300_dev/arch/arm/mach-omap1/Kconfig       2006-04-02 20:47:24.000000000 +0300
444 @@ -26,6 +26,15 @@
445            TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
446            have such a board.
447  
448 +config MACH_OMAP_H6300
449 +       bool "HP iPAQ h6300 series"
450 +       depends on ARCH_OMAP1 && ARCH_OMAP15XX
451 +       select I2C
452 +       select PCA9535
453 +       help
454 +          HP iPAQ h6315, h6340 and h6365 devices that are based 
455 +          on the OMAP 1510. Say Y here if you have such a device.
456 +
457  config MACH_OMAP_H2
458         bool "TI H2 Support"
459         depends on ARCH_OMAP1 && ARCH_OMAP16XX
460 diff -Naur linux-2.6.16.16/arch/arm/mach-omap1/Makefile h6300_dev/arch/arm/mach-omap1/Makefile
461 --- linux-2.6.16.16/arch/arm/mach-omap1/Makefile        2006-05-17 21:41:28.000000000 +0300
462 +++ h6300_dev/arch/arm/mach-omap1/Makefile      2006-04-02 00:23:01.000000000 +0300
463 @@ -23,6 +23,7 @@
464  obj-$(CONFIG_MACH_OMAP_PALMTE)         += board-palmte.o
465  obj-$(CONFIG_MACH_NOKIA770)            += board-nokia770.o
466  obj-$(CONFIG_MACH_AMS_DELTA)           += board-ams-delta.o
467 +obj-$(CONFIG_MACH_OMAP_H6300)          += board-h6300.o
468  
469  ifeq ($(CONFIG_ARCH_OMAP15XX),y)
470  # Innovator-1510 FPGA
471 @@ -36,4 +37,3 @@
472  led-$(CONFIG_MACH_OMAP_PERSEUS2)       += leds-h2p2-debug.o
473  led-$(CONFIG_MACH_OMAP_OSK)            += leds-osk.o
474  obj-$(CONFIG_LEDS)                     += $(led-y)
475 -
476 diff -Naur linux-2.6.16.16/arch/arm/mach-omap1/mux.c h6300_dev/arch/arm/mach-omap1/mux.c
477 --- linux-2.6.16.16/arch/arm/mach-omap1/mux.c   2006-05-17 21:41:28.000000000 +0300
478 +++ h6300_dev/arch/arm/mach-omap1/mux.c 2006-02-21 23:54:33.000000000 +0200
479 @@ -200,6 +200,13 @@
480  MUX_CFG("P15_1610_UWIRE_CS3",   8,   12,    1,   1,  22,   0,    1,     1,  1)
481  MUX_CFG("N15_1610_UWIRE_CS1",   7,   18,    2,   1,  14,   0,   NA,     0,  1)
482  
483 +/* OMAP-1510 uWire */
484 +MUX_CFG("P15_1510_UWIRE_CS3",  8,   12,    1,   NA,   0,   0,  NA,  0,  1)
485 +MUX_CFG("N14_1510_UWIRE_CS0",  8,    9,    1,   NA,   0,   0,  NA,  0,  1)
486 +MUX_CFG("V19_1510_UWIRE_SCLK", 8,    6,    0,   NA,   0,   0,  NA,  0,  1)
487 +MUX_CFG("W21_1510_UWIRE_SDO",  8,    3,    0,   NA,   0,   0,  NA,  0,  1)
488 +MUX_CFG("U18_1510_UWIRE_SDI",  8,    0,    0,    1,  18,   0,  NA,  0,  1)
489 +
490  /* OMAP-1610 Flash */
491  MUX_CFG("L3_1610_FLASH_CS2B_OE",10,    6,    1,         NA,   0,   0,   NA,     0,  1)
492  MUX_CFG("M8_1610_FLASH_CS2B_WE",10,    3,    1,         NA,   0,   0,   NA,     0,  1)
493 @@ -262,6 +269,7 @@
494  MUX_CFG("T20_1610_LOW_PWR",     7,   12,    1,   NA,   0,   0,   NA,    0,  0)
495  
496  /* MCLK Settings */
497 +MUX_CFG("R10_1510_MCLK_ON",     B,   18,    0,   2,   22,   1,   NA,    1,  1)
498  MUX_CFG("V5_1710_MCLK_ON",      B,   15,    0,   NA,   0,   0,   NA,    0,  0)
499  MUX_CFG("V5_1710_MCLK_OFF",     B,   15,    6,   NA,   0,   0,   NA,    0,  0)
500  MUX_CFG("R10_1610_MCLK_ON",     B,   18,    0,   NA,  22,   0,   NA,    1,  0)
501 diff -Naur linux-2.6.16.16/arch/arm/plat-omap/devices.c h6300_dev/arch/arm/plat-omap/devices.c
502 --- linux-2.6.16.16/arch/arm/plat-omap/devices.c        2006-05-17 21:41:28.000000000 +0300
503 +++ h6300_dev/arch/arm/plat-omap/devices.c      2006-05-18 00:59:02.000000000 +0300
504 @@ -92,7 +92,7 @@
505  
506  static void omap_init_kp(void)
507  {
508 -       if (machine_is_omap_h2() || machine_is_omap_h3()) {
509 +       if (machine_is_omap_h2() || machine_is_omap_h3() || machine_is_omap_h6300()) {
510                 omap_cfg_reg(F18_1610_KBC0);
511                 omap_cfg_reg(D20_1610_KBC1);
512                 omap_cfg_reg(D19_1610_KBC2);
513 diff -Naur linux-2.6.16.16/arch/arm/plat-omap/dma.c h6300_dev/arch/arm/plat-omap/dma.c
514 --- linux-2.6.16.16/arch/arm/plat-omap/dma.c    2006-05-17 21:41:28.000000000 +0300
515 +++ h6300_dev/arch/arm/plat-omap/dma.c  2006-02-06 15:36:21.000000000 +0200
516 @@ -30,6 +30,7 @@
517  #include <asm/hardware.h>
518  #include <asm/dma.h>
519  #include <asm/io.h>
520 +#include <asm/mach-types.h>
521  
522  #include <asm/arch/tc.h>
523  
524 @@ -1086,6 +1087,10 @@
525         }
526  
527         if (omap_dma_in_1510_mode()) {
528 +               u16 l = omap_readw(OMAP1510_DMA_LCD_CTRL);
529 +               l &= ~(1 << 6);
530 +               omap_writew (l, OMAP1510_DMA_LCD_CTRL);
531 +
532                 omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
533                 omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
534                 omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
535 diff -Naur linux-2.6.16.16/arch/arm/tools/mach-types h6300_dev/arch/arm/tools/mach-types
536 --- linux-2.6.16.16/arch/arm/tools/mach-types   2006-05-11 04:56:24.000000000 +0300
537 +++ h6300_dev/arch/arm/tools/mach-types 2006-04-24 20:53:29.000000000 +0300
538 @@ -576,7 +576,7 @@
539  s3c2460                        MACH_S3C2460            S3C2460                 560
540  pdm                    MACH_PDM                PDM                     561
541  h4700                  MACH_H4700              H4700                   562
542 -h6300                  MACH_H6300              H6300                   563
543 +omap_h6300             MACH_OMAP_H6300         OMAP_H6300              563
544  rz1700                 MACH_RZ1700             RZ1700                  564
545  a716                   MACH_A716               A716                    565
546  estk2440a              MACH_ESTK2440A          ESTK2440A               566
547 diff -Naur linux-2.6.16.16/drivers/bluetooth/Kconfig h6300_dev/drivers/bluetooth/Kconfig
548 --- linux-2.6.16.16/drivers/bluetooth/Kconfig   2006-05-17 21:41:29.000000000 +0300
549 +++ h6300_dev/drivers/bluetooth/Kconfig 2006-02-21 23:54:33.000000000 +0200
550 @@ -166,6 +166,16 @@
551  
552           Say Y here to compile support for virtual HCI devices into the
553           kernel or say M to compile it as module (hci_vhci).
554 +         
555 +config BT_H6300
556 +       tristate "H6300 BRF6100 BT DRIVER"
557 +       help
558 +         Bluetooth H6300 BRF6100 driver.
559 +         This driver provides the firmware loading mechanism for the BRF6100
560 +         bt hardware in iPAQ h6300.
561 +
562 +         Say Y here to compile support for BRF6100 BT devices into the
563 +         kernel or say M to compile it as module (h6300_BT).     
564  
565  endmenu
566  
567 diff -Naur linux-2.6.16.16/drivers/bluetooth/Makefile h6300_dev/drivers/bluetooth/Makefile
568 --- linux-2.6.16.16/drivers/bluetooth/Makefile  2006-05-17 21:41:29.000000000 +0300
569 +++ h6300_dev/drivers/bluetooth/Makefile        2006-02-21 23:54:33.000000000 +0200
570 @@ -13,6 +13,7 @@
571  obj-$(CONFIG_BT_HCIBLUECARD)   += bluecard_cs.o
572  obj-$(CONFIG_BT_HCIBTUART)     += btuart_cs.o
573  obj-$(CONFIG_BT_HCIBRF6150)    += brf6150.o
574 +obj-$(CONFIG_BT_H6300)         += omap/
575  
576  hci_uart-y                             := hci_ldisc.o
577  hci_uart-$(CONFIG_BT_HCIUART_H4)       += hci_h4.o
578 diff -Naur linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_brf6100.c h6300_dev/drivers/bluetooth/omap/h6300_bt_brf6100.c
579 --- linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_brf6100.c   1970-01-01 02:00:00.000000000 +0200
580 +++ h6300_dev/drivers/bluetooth/omap/h6300_bt_brf6100.c 2006-01-23 00:09:23.000000000 +0200
581 @@ -0,0 +1,154 @@
582 +/* 
583 + * Bluetooth interface driver for TI BRF6100 on h6300
584 + * 
585 + * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi>
586 + * Ideas taken from the brf6150 bt driver made by Todd Blumer for the pxa hx4700.
587 + * 
588 + * This program is free software; you can redistribute it and/or modify
589 + * it under the terms of the GNU General Public License version 2 as
590 + * published by the Free Software Foundation.
591 + */
592 +
593 +#include <linux/module.h>
594 +#include <linux/kernel.h>
595 +#include <linux/delay.h>
596 +#include <linux/platform_device.h>
597 +
598 +#include <asm/hardware.h>
599 +#include <asm/arch/gpio.h>
600 +
601 +#include <asm/arch/h6300_uart_info.h>
602 +#include "h6300_bt_led.h"
603 +
604 +static void
605 +h6300_bt_configure(struct uart_omap_port *up, int enable)
606 +{
607 +       printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_configure() started, enable = %d\n", enable);
608 +       
609 +       // printk( KERN_NOTICE "h6300 configure bluetooth: %d\n", enable );
610 +       if (enable == 0) {
611 +               omap_set_gpio_dataout(GPIO_N_BT_RST, 1);        // turn off gpio, note 1 == off for negative gpios
612 +               mdelay(5);
613 +               h6300_clear_led(INDEX_BT_LED);
614 +       }
615 +       else if (enable == 1) {
616 +               omap_set_gpio_dataout(GPIO_N_BT_RST, 1);        // turn on gpio, note 0 == on for negative gpios
617 +               mdelay(5);                              
618 +       }
619 +       else if (enable == 2) {
620 +               /*
621 +                * BRF6150's RTS goes low when firmware is ready
622 +                * so check for CTS=1 (nCTS=0 -> CTS=1). Typical 150ms
623 +                */
624 +/*             
625 +               int tries = 0; 
626 +               do 
627 +               {
628 +                       mdelay(10);
629 +               } 
630 +               while ((BTMSR & MSR_CTS) == 0 && tries++ < 50);
631 +*/                             
632 +               h6300_set_led(INDEX_BT_LED, 16, 16);
633 +       }
634 +       printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_configure() done\n");
635 +}
636 +
637 +static void
638 +h6300_bt_set_txrx(struct uart_omap_port *up, int txrx)
639 +{
640 +       printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_set_txrx(), txrx = %d done\n", txrx);
641 +       /* do nothing */
642 +}
643 +
644 +static int
645 +h6300_bt_get_txrx(struct uart_omap_port *up)
646 +{
647 +       printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_get_txrx() done\n");
648 +       /* do nothing */
649 +       return 0;
650 +}
651 +
652 +static int
653 +h6300_bt_probe(struct platform_device *pdev)
654 +{
655 +       struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
656 +
657 +       omap_request_gpio(GPIO_BT_PWR_EN);              // ask bt_power_en gpio, remember to release in remove_function
658 +       omap_set_gpio_direction(GPIO_BT_PWR_EN, 1);     // set gpio direction to be output
659 +       omap_set_gpio_dataout(GPIO_BT_PWR_EN, 1);       // turn on gpio
660 +
661 +       mdelay(200);
662 +
663 +       omap_request_gpio(GPIO_N_BT_RST);               // ask bt_reset gpio, remember to release in remove_function
664 +       omap_set_gpio_direction(GPIO_N_BT_RST, 1);      // set gpio direction to be output
665 +       omap_set_gpio_dataout(GPIO_N_BT_RST, 0);        // turn on gpio, note 0 == on for negative gpios
666 +       
667 +       /* configure bluetooth UART */
668 +       //h6300_gpio_mode(GPIO_NR_H6300_BT_RXD_MD);
669 +       //h6300_gpio_mode(GPIO_NR_H6300_BT_TXD_MD);
670 +       //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_CTS_MD);
671 +       //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_RTS_MD);
672 +
673 +       funcs->configure        = h6300_bt_configure;
674 +       funcs->set_txrx         = h6300_bt_set_txrx;
675 +       funcs->get_txrx         = h6300_bt_get_txrx;
676 +
677 +       /* Make sure the LED is off */
678 +       h6300_clear_led(INDEX_BT_LED);
679 +       
680 +       printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_probe() done\n");       
681 +
682 +       return 0;
683 +}
684 +
685 +static int
686 +h6300_bt_remove(struct platform_device *pdev)
687 +{
688 +       struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
689 +       
690 +       printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_remove() started\n");   
691 +       
692 +       omap_free_gpio(GPIO_BT_PWR_EN);
693 +       omap_free_gpio(GPIO_N_BT_RST);
694 +
695 +       funcs->configure        = NULL;
696 +       funcs->set_txrx         = NULL;
697 +       funcs->get_txrx         = NULL;
698 +
699 +       /* Make sure the LED is off */
700 +       h6300_clear_led(INDEX_BT_LED);
701 +       
702 +       printk(KERN_NOTICE "h6300_bt_brf6100.c, h6300_bt_remove() done\n");
703 +
704 +       return 0;
705 +}
706 +
707 +static struct platform_driver bt_driver = {
708 +       .probe    = h6300_bt_probe,
709 +       .remove   = h6300_bt_remove,
710 +       .driver = {
711 +               .name = "h6300_bt",
712 +       },
713 +};
714 +
715 +static int __init
716 +h6300_bt_init(void)
717 +{
718 +       printk(KERN_NOTICE "h6300 Bluetooth Driver init()\n");
719 +       return platform_driver_register(&bt_driver);
720 +}
721 +
722 +static void __exit
723 +h6300_bt_exit(void)
724 +{
725 +       printk(KERN_NOTICE "h6300 Bluetooth Driver exit()\n");
726 +       platform_driver_unregister(&bt_driver);
727 +}
728 +
729 +module_init(h6300_bt_init);
730 +module_exit(h6300_bt_exit);
731 +
732 +MODULE_AUTHOR("Mika Laitio, <lamikr@cc.jyu.fi>");
733 +MODULE_DESCRIPTION("iPAQ h6300 BRF6100 Bluetooth driver.");
734 +MODULE_LICENSE("GPL");
735 +
736 diff -Naur linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_led.c h6300_dev/drivers/bluetooth/omap/h6300_bt_led.c
737 --- linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_led.c       1970-01-01 02:00:00.000000000 +0200
738 +++ h6300_dev/drivers/bluetooth/omap/h6300_bt_led.c     2005-10-06 02:34:39.000000000 +0300
739 @@ -0,0 +1,41 @@
740 +/* 
741 + * Bluetooth interface driver helper for controlling bluetooth leds available in iPAQ h6300.
742 + * 
743 + * Copyright (C) 2005 Mika Laitio  <lamikr@cc.jyu.fi>
744 + * Ideas from the brf6150 bt driver made by Todd Blumer for the pxa hx4700.
745 + * 
746 + * This program is free software; you can redistribute it and/or modify
747 + * it under the terms of the GNU General Public License version 2 as
748 + * published by the Free Software Foundation.
749 + */
750 +
751 +#include <linux/module.h>
752 +#include <linux/kernel.h>
753 +#include <linux/delay.h>
754 +#include <linux/device.h>
755 +
756 +#include <asm/hardware.h>
757 +#include <asm/arch/gpio.h>
758 +
759 +/* 
760 + * Low level access for disabling h6300 bt led.
761 + *
762 + * TODO: implement for h6300 
763 + */
764 +void h6300_clear_led(int led_num)
765 +{
766 +       printk(KERN_NOTICE "h6300_bt_led.c h6300_clear_led() done\n");
767 +       //hx4700_set_led(led_num, 0, 16);
768 +}
769 +EXPORT_SYMBOL(h6300_clear_led);
770 +
771 +/* 
772 + * Low level access for setting up the bt led.
773 + *
774 + * TODO: implement for h6300 
775 + */
776 +void h6300_set_led(int led_num, int duty_time, int cycle_time)
777 +{
778 +       printk(KERN_NOTICE "h6300_bt_led.c h6300_set_led() done\n");
779 +}
780 +EXPORT_SYMBOL(h6300_set_led);
781 diff -Naur linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_led.h h6300_dev/drivers/bluetooth/omap/h6300_bt_led.h
782 --- linux-2.6.16.16/drivers/bluetooth/omap/h6300_bt_led.h       1970-01-01 02:00:00.000000000 +0200
783 +++ h6300_dev/drivers/bluetooth/omap/h6300_bt_led.h     2005-10-06 02:34:39.000000000 +0300
784 @@ -0,0 +1,9 @@
785 +#ifndef H6300_BT_LED_H_
786 +#define H6300_BT_LED_H_
787 +
788 +#define INDEX_BT_LED   2
789 +
790 +void h6300_clear_led(int led_num);
791 +void h6300_set_led(int led_num, int duty_time, int cycle_time);
792 +
793 +#endif /*H6300_BT_LED_H_*/
794 diff -Naur linux-2.6.16.16/drivers/bluetooth/omap/Makefile h6300_dev/drivers/bluetooth/omap/Makefile
795 --- linux-2.6.16.16/drivers/bluetooth/omap/Makefile     1970-01-01 02:00:00.000000000 +0200
796 +++ h6300_dev/drivers/bluetooth/omap/Makefile   2005-10-06 02:34:39.000000000 +0300
797 @@ -0,0 +1,6 @@
798 +#
799 +# Makefile for the Linux iPAQ H6300 BRF6100 Bluetooth device drivers.
800 +#
801 +
802 +h6300_bt-objs                          := h6300_bt_led.o h6300_bt_brf6100.o
803 +obj-$(CONFIG_BT_H6300)         += h6300_bt.o
804 diff -Naur linux-2.6.16.16/drivers/i2c/busses/i2c-omap.c h6300_dev/drivers/i2c/busses/i2c-omap.c
805 --- linux-2.6.16.16/drivers/i2c/busses/i2c-omap.c       2006-05-17 21:41:29.000000000 +0300
806 +++ h6300_dev/drivers/i2c/busses/i2c-omap.c     2006-04-02 00:23:01.000000000 +0300
807 @@ -163,17 +163,22 @@
808  
809  static int omap_i2c_get_clocks(struct omap_i2c_dev *dev)
810  {
811 -       if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
812 +       if (cpu_is_omap24xx()) {
813                 dev->iclk = clk_get(dev->dev, "i2c_ick");
814 -               if (IS_ERR(dev->iclk))
815 +               if (IS_ERR(dev->iclk)) {
816                         return -ENODEV;
817 +               }
818 +               dev->fclk = clk_get(dev->dev, "i2c_fck");
819 +               if (IS_ERR(dev->fclk)) {
820 +                       clk_put(dev->fclk);
821 +                       return -ENODEV;
822 +               }
823         }
824  
825 -       dev->fclk = clk_get(dev->dev, "i2c_fck");
826 -       if (IS_ERR(dev->fclk)) {
827 -               if (dev->iclk != NULL)
828 -                       clk_put(dev->iclk);
829 -               return -ENODEV;
830 +       if (cpu_class_is_omap1()) {
831 +               dev->fclk = clk_get(dev->dev, "i2c_fck");
832 +               if (IS_ERR(dev->fclk))
833 +                       return -ENODEV;
834         }
835  
836         return 0;
837 diff -Naur linux-2.6.16.16/drivers/i2c/chips/Kconfig h6300_dev/drivers/i2c/chips/Kconfig
838 --- linux-2.6.16.16/drivers/i2c/chips/Kconfig   2006-05-17 21:41:29.000000000 +0300
839 +++ h6300_dev/drivers/i2c/chips/Kconfig 2006-04-24 20:53:29.000000000 +0300
840 @@ -46,6 +46,16 @@
841           This driver can also be built as a module.  If so, the module
842           will be called pcf8574.
843  
844 +config PCA9535
845 +        tristate "Philips PCA9535 16-bit I/O port"
846 +        depends on I2C 
847 +        help
848 +          If you say yes here you get support for the Philips PCA9535
849 +          16-bit I/O port.
850 +       
851 +          This driver can also be built as a module.  If so, the module
852 +          will be called pca9535.
853 +
854  config SENSORS_PCA9539
855         tristate "Philips PCA9539 16-bit I/O port"
856         depends on I2C && EXPERIMENTAL
857 diff -Naur linux-2.6.16.16/drivers/i2c/chips/Makefile h6300_dev/drivers/i2c/chips/Makefile
858 --- linux-2.6.16.16/drivers/i2c/chips/Makefile  2006-05-17 21:41:29.000000000 +0300
859 +++ h6300_dev/drivers/i2c/chips/Makefile        2006-04-24 20:53:29.000000000 +0300
860 @@ -7,6 +7,7 @@
861  obj-$(CONFIG_SENSORS_EEPROM)   += eeprom.o
862  obj-$(CONFIG_SENSORS_MAX6875)  += max6875.o
863  obj-$(CONFIG_SENSORS_M41T00)   += m41t00.o
864 +obj-$(CONFIG_PCA9535)                  += pca9535.o
865  obj-$(CONFIG_SENSORS_PCA9539)  += pca9539.o
866  obj-$(CONFIG_SENSORS_PCF8574)  += pcf8574.o
867  obj-$(CONFIG_SENSORS_PCF8591)  += pcf8591.o
868 diff -Naur linux-2.6.16.16/drivers/i2c/chips/pca9535.c h6300_dev/drivers/i2c/chips/pca9535.c
869 --- linux-2.6.16.16/drivers/i2c/chips/pca9535.c 1970-01-01 02:00:00.000000000 +0200
870 +++ h6300_dev/drivers/i2c/chips/pca9535.c       2006-04-24 20:53:29.000000000 +0300
871 @@ -0,0 +1,412 @@
872 +/*
873 +    Driver for Philips PCA9535 16-bit low power I/O port with interrupt
874 +
875 +    This program is free software; you can redistribute it and/or modify
876 +    it under the terms of the GNU General Public License as published by
877 +    the Free Software Foundation; either version 2 of the License, or
878 +    (at your option) any later version.
879 +    
880 +    This program is distributed in the hope that it will be useful,
881 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
882 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
883 +    GNU General Public License for more details.
884 +
885 +    You should have received a copy of the GNU General Public License
886 +    along with this program; if not, write to the Free Software
887 +    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
888 +    
889 +    Copyright (C) 2005 Husam Senussi
890 +    Framework based on Pawel Kolodziejski's pca9535 driver in 
891 +    handheld.org's 2.6.13 kernel. Driver updated by Mika Laitio.
892 +*/
893 +
894 +#include <linux/module.h>
895 +#include <linux/init.h>
896 +#include <linux/slab.h>
897 +#include <linux/i2c.h>
898 +#include <linux/hwmon-sysfs.h>
899 +#include <linux/hwmon.h>
900 +#include <linux/err.h>
901 +
902 +#include <asm/arch/pca9535.h>
903 +#include <linux/delay.h>
904 +
905 +#include <linux/interrupt.h>
906 +#include <asm/mach-types.h>
907 +#include <asm/irq.h>
908 +#include <asm/mach/arch.h>
909 +#include <asm/hardware.h>
910 +
911 +EXPORT_SYMBOL(pca9535_gpio_read);
912 +EXPORT_SYMBOL(pca9535_gpio_write);
913 +EXPORT_SYMBOL(pca9535_gpio_direction);
914 +
915 +static int pca9535_attach_adapter(struct i2c_adapter *adapter);
916 +static int pca9535_detach_client(struct i2c_client *client);
917 +static int pca9535_attach(struct i2c_adapter *adapter, int address, int zero_or_minus_one);
918 +static u32 pca9535_read_reg(struct i2c_client *client, u8 regaddr);
919 +static void pca9535_write_reg(struct i2c_client *client, u8 regaddr, u16 param);
920 +
921 +enum pca9535_cmd
922 +{
923 +        PCA9535_INPUT_0         = 0,
924 +        PCA9535_INPUT_1         = 1,
925 +        PCA9535_OUTPUT_0        = 2,
926 +        PCA9535_OUTPUT_1        = 3,
927 +        PCA9535_INVERT_0        = 4,
928 +        PCA9535_INVERT_1        = 5,
929 +        PCA9535_DIRECTION_0     = 6,
930 +        PCA9535_DIRECTION_1     = 7,
931 +};
932 +
933 +struct pca9535_data {
934 +       struct semaphore  lock;
935 +        struct i2c_client client;
936 +};
937 +
938 +static struct i2c_driver pca9535_driver = {
939 +        .driver = {
940 +                .name   = "pca9535",
941 +        },
942 +       .attach_adapter         = pca9535_attach_adapter,
943 +       .detach_client          = pca9535_detach_client,
944 +};
945 +
946 +static struct i2c_client   *pca9535_i2c_client = NULL;
947 +static struct pca9535_data pca9535_inited;
948 +
949 +static unsigned short normal_i2c[] = { 0x20, I2C_CLIENT_END };
950 +
951 +#define DRIVER_VERSION  "20 OCT 2005"
952 +#define DRIVER_NAME     "PCA9535"
953 +
954 +/* 
955 + * sysfs callback function.
956 + */ 
957 +static ssize_t pca9535_show(struct device *dev, struct device_attribute *attr,
958 +                            char *buf)
959 +{
960 +        struct sensor_device_attribute *psa = to_sensor_dev_attr(attr);
961 +        struct i2c_client *client = to_i2c_client(dev);
962 +        return sprintf(buf, "%02X\n", (pca9535_read_reg(client, psa->index) >> 8));
963 +}
964 +
965 +/* 
966 + * sysfs callback function.
967 + */ 
968 +static ssize_t pca9535_store(struct device *dev, struct device_attribute *attr,
969 +                             const char *buf, size_t count)
970 +{
971 +        struct sensor_device_attribute *psa = to_sensor_dev_attr(attr);
972 +        struct i2c_client *client = to_i2c_client(dev);
973 +        unsigned long val = simple_strtoul(buf, NULL, 0);
974 +       unsigned long old = pca9535_read_reg(client, psa->index);
975 +
976 +        if (val > 0xff)
977 +                return -EINVAL;
978 +       
979 +       val = (old & 0xff) | (val << 8);
980 +        pca9535_write_reg(client, psa->index, val);
981 +        return count;
982 +}
983 +
984 +#define PCA9535_ENTRY_RO(name, cmd_idx) \
985 +        static SENSOR_DEVICE_ATTR(name, S_IRUGO, pca9535_show, NULL, cmd_idx)
986 +
987 +#define PCA9535_ENTRY_RW(name, cmd_idx) \
988 +        static SENSOR_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, pca9535_show, \
989 +                                  pca9535_store, cmd_idx)
990 +
991 +PCA9535_ENTRY_RO(input0, PCA9535_INPUT_0);
992 +PCA9535_ENTRY_RO(input1, PCA9535_INPUT_1);
993 +PCA9535_ENTRY_RW(output0, PCA9535_OUTPUT_0);
994 +PCA9535_ENTRY_RW(output1, PCA9535_OUTPUT_1);
995 +PCA9535_ENTRY_RW(invert0, PCA9535_INVERT_0);
996 +PCA9535_ENTRY_RW(invert1, PCA9535_INVERT_1);
997 +PCA9535_ENTRY_RW(direction0, PCA9535_DIRECTION_0);
998 +PCA9535_ENTRY_RW(direction1, PCA9535_DIRECTION_1);
999 +
1000 +static struct attribute *pca9535_attributes[] = {
1001 +        &sensor_dev_attr_input0.dev_attr.attr,
1002 +        &sensor_dev_attr_input1.dev_attr.attr,
1003 +        &sensor_dev_attr_output0.dev_attr.attr,
1004 +        &sensor_dev_attr_output1.dev_attr.attr,
1005 +        &sensor_dev_attr_invert0.dev_attr.attr,
1006 +        &sensor_dev_attr_invert1.dev_attr.attr,
1007 +        &sensor_dev_attr_direction0.dev_attr.attr,
1008 +        &sensor_dev_attr_direction1.dev_attr.attr,
1009 +        NULL
1010 +};
1011 +
1012 +static struct attribute_group pca9535_defattr_group = {
1013 +        .attrs = pca9535_attributes,
1014 +};
1015 +//End of sysfs management code. 
1016 +
1017 +I2C_CLIENT_INSMOD;
1018 +
1019 +u32 pca9535_read_input(void)
1020 +{
1021 +       return pca9535_read_reg(pca9535_i2c_client, 0);
1022 +}
1023 +EXPORT_SYMBOL(pca9535_read_input);
1024 +
1025 +void pca9535_write_output(u16 param)
1026 +{
1027 +       pca9535_write_reg(pca9535_i2c_client, 2, param);
1028 +}
1029 +EXPORT_SYMBOL(pca9535_write_output);
1030 +
1031 +void pca9535_set_dir(u16 param)
1032 +{
1033 +       pca9535_write_reg(pca9535_i2c_client, 6, param);
1034 +}
1035 +EXPORT_SYMBOL(pca9535_set_dir);
1036 +
1037 +static int pca9535_attach_adapter(struct i2c_adapter *adapter)
1038 +{
1039 +       return i2c_probe(adapter, &addr_data, pca9535_attach);
1040 +}
1041 +
1042 +static int pca9535_attach(struct i2c_adapter *adapter, int address, int zero_or_minus_one)
1043 +{
1044 +       struct i2c_client *new_client;
1045 +       int err = 0;
1046 +
1047 +       new_client = &(pca9535_inited.client);
1048 +       i2c_set_clientdata(new_client, 0);
1049 +       new_client->addr = address;
1050 +       new_client->adapter = adapter;
1051 +       new_client->driver = &pca9535_driver;
1052 +       strcpy(new_client->name, DRIVER_NAME);
1053 +
1054 +       if ((err = i2c_attach_client(new_client)))
1055 +               goto exit_free;
1056 +
1057 +       pca9535_i2c_client = new_client;
1058 +       
1059 +       init_MUTEX(&pca9535_inited.lock);
1060 +       i2c_set_clientdata(pca9535_i2c_client, &pca9535_inited);
1061 +       
1062 +       sysfs_create_group(&pca9535_i2c_client->dev.kobj, &pca9535_defattr_group);
1063 +       
1064 +       printk("pca9535_attach() ok, address = %d, zero_or_minus_one = %d\n", address, zero_or_minus_one);
1065 +       return 0;
1066 +
1067 +exit_free:
1068 +       printk("pca9535_attach() failed, error code = %d\n", err);
1069 +       return err;
1070 +}
1071 +
1072 +static int pca9535_detach_client(struct i2c_client *client)
1073 +{
1074 +       int err;
1075 +
1076 +       if ((err = i2c_detach_client(client))) {
1077 +               dev_err(&client->dev, "Client deregistration failed, client not detached.\n");
1078 +               return err;
1079 +       }
1080 +       pca9535_i2c_client = NULL;
1081 +
1082 +       return 0;
1083 +}
1084 +
1085 +static int __init pca9535_init(void)
1086 +{
1087 +       return i2c_add_driver(&pca9535_driver);
1088 +}
1089 +
1090 +static void __exit pca9535_exit(void)
1091 +{
1092 +        i2c_del_driver(&pca9535_driver);
1093 +}
1094 +
1095 +/* 
1096 + * Reads the value of GPIO available via I2C.
1097 + */
1098 +int pca9535_gpio_read(int gpio){
1099 +       unsigned char reg = 0;
1100 +       unsigned long val = 0;
1101 +
1102 +       printk("9535_gpio_read() called\n");
1103 +       if(!pca9535_i2c_client)
1104 +               return -ENODEV;
1105 +
1106 +       if(gpio < GPIO0 || gpio > GPIO17)
1107 +               return -EINVAL;
1108 +
1109 +       if(gpio >= GPIO0 && gpio <= GPIO7){
1110 +               reg      = PCA9535_INPUT_0;
1111 +               gpio    -= GPIO0;
1112 +       }else if(gpio >= GPIO8 && gpio <= GPIO17){
1113 +               reg      = PCA9535_INPUT_1;
1114 +                gpio    -= GPIO8;
1115 +       }
1116 +
1117 +       down(&pca9535_inited.lock);
1118 +
1119 +       // Read the existing values first
1120 +       val = pca9535_read_reg(pca9535_i2c_client, reg) >> 8;
1121 +       val = (val >> gpio) & 0x01;
1122 +
1123 +       up(&pca9535_inited.lock);
1124 +
1125 +       return val;
1126 +}
1127 +
1128 +/* 
1129 + * Set the value of I2C GPIO.
1130 + */
1131 +int pca9535_gpio_write(int gpio, unsigned char value){
1132 +       unsigned char in_reg  = 0;
1133 +        unsigned char out_reg = 0;
1134 +        unsigned long val = 0;
1135 +       unsigned long old = 0;
1136 +       int           ret = 0;
1137 +
1138 +        if(!pca9535_i2c_client)
1139 +                return -ENODEV;
1140 +
1141 +        if(gpio < GPIO0 || gpio > GPIO17)
1142 +                return -EINVAL;
1143 +
1144 +        if(gpio >= GPIO0 && gpio <= GPIO7){
1145 +                in_reg   = PCA9535_INPUT_0;
1146 +                out_reg  = PCA9535_OUTPUT_0;
1147 +                gpio    -= GPIO0;
1148 +        }else if(gpio >= GPIO8 && gpio <= GPIO17){
1149 +                in_reg   = PCA9535_INPUT_1;
1150 +                out_reg  = PCA9535_OUTPUT_1;
1151 +                gpio    -= GPIO8;
1152 +        }
1153 +
1154 +       down(&pca9535_inited.lock);
1155 +
1156 +        // Read the existing values first
1157 +        val = pca9535_read_reg(pca9535_i2c_client, in_reg);
1158 +       old = val >> 8;
1159 +
1160 +       switch(value){
1161 +       case LOW:
1162 +               old |= (1 << gpio);
1163 +               break;
1164 +       case HI:
1165 +               old &= ~(1 << gpio);
1166 +               break;
1167 +       default:
1168 +               ret = -EINVAL;
1169 +               goto error;
1170 +       }
1171 +
1172 +       val = (val & 0xff) | (old << 8);        
1173 +
1174 +       // write the values back to the register
1175 +       pca9535_write_reg(pca9535_i2c_client, out_reg, val);
1176 +error:
1177 +
1178 +       up(&pca9535_inited.lock);
1179 +       return ret;
1180 +}
1181 +
1182 +/*
1183 + * Set the direction of I2C GPIO.
1184 + */ 
1185 +int pca9535_gpio_direction(int gpio, unsigned char direction){
1186 +        unsigned char reg = 0;
1187 +        unsigned long val = 0;
1188 +       unsigned long old = 0;
1189 +        int           ret = 0;
1190 +
1191 +        if(!pca9535_i2c_client)
1192 +                return -ENODEV;
1193 +
1194 +        if(gpio < GPIO0 || gpio > GPIO17)
1195 +                return -EINVAL;
1196 +
1197 +        if(gpio >= GPIO0 && gpio <= GPIO7){
1198 +                reg     = PCA9535_DIRECTION_0;
1199 +                gpio    -= GPIO0;
1200 +        }else if(gpio >= GPIO8 && gpio <= GPIO17){
1201 +                reg     = PCA9535_DIRECTION_1;
1202 +                gpio    -= GPIO8;
1203 +        }
1204 +
1205 +        down(&pca9535_inited.lock);
1206 +
1207 +        // Read the existing values first
1208 +        old = pca9535_read_reg(pca9535_i2c_client, reg);
1209 +       val = old >> 8;
1210 +
1211 +        switch(direction){
1212 +        case GPIO_INPUT: 
1213 +                val |= (1 << gpio);
1214 +                break;
1215 +        case GPIO_OUTPUT: 
1216 +                val &= ~(1 << gpio);
1217 +                break;
1218 +        default:
1219 +                ret = -EINVAL;
1220 +                goto error;
1221 +        }
1222 +
1223 +       val = (old & 0xff) | (val << 8);
1224 +
1225 +        // write the values back to the register
1226 +        pca9535_write_reg(pca9535_i2c_client, reg, val);
1227 +error:
1228 +
1229 +        up(&pca9535_inited.lock);
1230 +        return ret;
1231 +}
1232 +
1233 +static u32 pca9535_read_reg(struct i2c_client *client, u8 regaddr)
1234 +{
1235 +       char buffer[3];
1236 +       int r;
1237 +       u32 data;
1238 +
1239 +       buffer[0] = regaddr;
1240 +       buffer[1] = 0;
1241 +       buffer[2] = 0;
1242 +
1243 +       r = i2c_master_send(client, buffer, 1);
1244 +       if (r != 1) {
1245 +               printk(KERN_ERR "pca9535: read failed, status %d\n", r);
1246 +               return 0xffffffff;
1247 +       }
1248 +
1249 +       r = i2c_master_recv(client, buffer, 3);
1250 +       if (r != 3) {
1251 +               printk(KERN_ERR "pca9535: read failed, status %d\n", r);
1252 +               return 0xffffffff;
1253 +       }
1254 +
1255 +       data = buffer[1];
1256 +       data |= buffer[2] << 8;
1257 +       //printk(KERN_ERR "%s: reading %x in %x\n", __FUNCTION__, data, regaddr);
1258 +
1259 +       return data;
1260 +}
1261 +
1262 +static void pca9535_write_reg(struct i2c_client *client, u8 regaddr, u16 data)
1263 +{
1264 +       char buffer[3];
1265 +       int r;
1266 +
1267 +       //printk(KERN_ERR "%s: writing %x in %x\n", __FUNCTION__, data, regaddr);
1268 +       buffer[0] = regaddr;
1269 +       buffer[1] = data >> 8;
1270 +       buffer[2] = data & 0xff;
1271 +
1272 +       r = i2c_master_send(client, buffer, 3);
1273 +       if (r != 3) {
1274 +               printk(KERN_ERR "pca9535: write failed, status %d\n", r);
1275 +       }
1276 +}
1277 +
1278 +MODULE_AUTHOR("Husam Senussi <husamsenussi@gmail.com>");
1279 +MODULE_DESCRIPTION("PCA9535 driver");
1280 +MODULE_LICENSE("GPL");
1281 +
1282 +module_init(pca9535_init);
1283 +module_exit(pca9535_exit);
1284 diff -Naur linux-2.6.16.16/drivers/input/keyboard/omap-keypad.c h6300_dev/drivers/input/keyboard/omap-keypad.c
1285 --- linux-2.6.16.16/drivers/input/keyboard/omap-keypad.c        2006-05-17 21:41:29.000000000 +0300
1286 +++ h6300_dev/drivers/input/keyboard/omap-keypad.c      2006-04-24 20:53:29.000000000 +0300
1287 @@ -4,11 +4,12 @@
1288   * OMAP Keypad Driver
1289   *
1290   * Copyright (C) 2003 Nokia Corporation
1291 - * Written by Timo Teräs <ext-timo.teras@nokia.com>
1292 + * Written by Timo Ter�s <ext-timo.teras@nokia.com>
1293 + * iPAQ h6300 key and joypad support added by Mika Laitio. (2005)
1294   *
1295   * Added support for H2 & H3 Keypad
1296   * Copyright (C) 2004 Texas Instruments
1297 - *
1298 + * 
1299   * This program is free software; you can redistribute it and/or modify
1300   * it under the terms of the GNU General Public License as published by
1301   * the Free Software Foundation; either version 2 of the License, or
1302 @@ -44,6 +45,19 @@
1303  #include <asm/arch/mux.h>
1304  
1305  #undef NEW_BOARD_LEARNING_MODE
1306 +//#define NEW_BOARD_LEARNING_MODE 1
1307 +
1308 +/*
1309 + * Following 5 keypad events are not really sent to userspace. 
1310 + * Instead if the good combination of them is sent, then that is send.
1311 + * (up, right, down, left, enter)
1312 + */
1313 +#define        _H6300_JOYPAD_UP_RIGHT          1       // 00001
1314 +#define _H6300_JOYPAD_DOWN_RIGHT       2       // 00010
1315 +#define _h6300_JOYPAD_DOWN_LEFT                4       // 00100
1316 +#define _h6300_JOYPAD_UP_LEFT          8       // 01000
1317 +#define _H6300_JOYPAD_KEY_OK           16      // 10000
1318 +#define _H6300_JOYPAD_REPORT_COLUMN    4
1319  
1320  static void omap_kp_tasklet(unsigned long);
1321  static void omap_kp_timer(unsigned long);
1322 @@ -53,6 +67,8 @@
1323  static int kp_enable = 1;
1324  static int kp_cur_group = -1;
1325  
1326 +static int prevJoypadKeycodePressEmulated;
1327 +
1328  struct omap_kp {
1329         struct input_dev *input;
1330         struct timer_list timer;
1331 @@ -139,7 +155,7 @@
1332                 for (col = 0; col < omap_kp->cols; col++) {
1333                         omap_writew(~(1 << col) & 0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
1334  
1335 -                       if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3()) {
1336 +                       if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3() || machine_is_omap_h6300()) {
1337                                 udelay(9);
1338                         } else {
1339                                 udelay(4);
1340 @@ -169,17 +185,26 @@
1341         return -1;
1342  }
1343  
1344 +int is_key_down(unsigned char new_state[],
1345 +               int col,
1346 +               int row)
1347 +{
1348 +       return (new_state[col] & (1 << row)) ? 1 : 0;
1349 +}
1350 +
1351  static void omap_kp_tasklet(unsigned long data)
1352  {
1353         struct omap_kp *omap_kp_data = (struct omap_kp *) data;
1354         unsigned char new_state[8], changed, key_down = 0;
1355         int col, row;
1356         int spurious = 0;
1357 +       int report_key, report_col, report_row, joypad_checked; // h6300-joypad specific variables
1358  
1359         /* check for any changes */
1360         omap_kp_scan_keypad(omap_kp_data, new_state);
1361  
1362         /* check for changes and print those */
1363 +       joypad_checked  = 0;
1364         for (col = 0; col < omap_kp_data->cols; col++) {
1365                 changed = new_state[col] ^ keypad_state[col];
1366                 key_down |= new_state[col];
1367 @@ -201,14 +226,177 @@
1368                                 spurious = 1;
1369                                 continue;
1370                         }
1371 -
1372 -                       if (!(kp_cur_group == (key & GROUP_MASK) ||
1373 -                             kp_cur_group == -1))
1374 -                               continue;
1375 -
1376 -                       kp_cur_group = key & GROUP_MASK;
1377 -                       input_report_key(omap_kp_data->input, key & ~GROUP_MASK,
1378 -                                        !!(new_state[col] & (1 << row)));
1379 +                       if (machine_is_omap_h6300() && 
1380 +                          ((col == 1) || (col == _H6300_JOYPAD_REPORT_COLUMN)))
1381 +                       {
1382 +                               if (col == _H6300_JOYPAD_REPORT_COLUMN)
1383 +                               {
1384 +                                       continue;
1385 +                               }
1386 +                               if ((joypad_checked == 0) &&
1387 +                                   ((key == _H6300_JOYPAD_KEY_OK) ||
1388 +                                    (key == _h6300_JOYPAD_UP_LEFT) ||
1389 +                                    (key == _H6300_JOYPAD_UP_RIGHT) ||
1390 +                                    (key == _H6300_JOYPAD_DOWN_RIGHT) ||
1391 +                                    (key == _h6300_JOYPAD_DOWN_LEFT)))
1392 +                               {
1393 +                                       if (is_key_down(new_state, col, row))
1394 +                                       {
1395 +                                               /*
1396 +                                                * only enter pressed
1397 +                                                * 1 0 0 _H6300_JOYPAD_KEY_OK 0 0
1398 +                                                * --> 100100 == 36
1399 +                                                */
1400 +                                                if (new_state[1] == 36)
1401 +                                                {
1402 +                                                       joypad_checked  = 1;
1403 +                                                       prevJoypadKeycodePressEmulated  = KEY_ENTER;
1404 +                                                       new_state[_H6300_JOYPAD_REPORT_COLUMN]  = 48;   //110000
1405 +                                                       report_key      = prevJoypadKeycodePressEmulated;
1406 +                                                       report_col      = _H6300_JOYPAD_REPORT_COLUMN;
1407 +                                                       report_row      = 4;
1408 +                                                       input_report_key(omap_kp_data->input,
1409 +                                                                       report_key,
1410 +                                                                       new_state[report_col] & (1 << report_row));
1411 +                                                }                                              
1412 +                                               /*
1413 +                                                * enter, up_left and up_right sensors pressed.
1414 +                                                * 1 _H6300_JOYPAD_UP_RIGHT 0 _H6300_JOYPAD_KEY_OK 0 _h6300_JOYPAD_UP_LEFT
1415 +                                                * --> 110101 == 53
1416 +                                                * OR
1417 +                                                * 1 KEY_UP_RIGHT 0 0 0 _h6300_JOYPAD_UP_LEFT
1418 +                                                * --> 110001 == 42
1419 +                                                * --> move to up
1420 +                                                */
1421 +                                               else if ((new_state[1] == 53) ||
1422 +                                                        (new_state[1] == 49))
1423 +                                               {
1424 +                                                       joypad_checked  = 1;
1425 +                                                       prevJoypadKeycodePressEmulated  = KEY_UP;
1426 +                                                       new_state[_H6300_JOYPAD_REPORT_COLUMN]  = 40;   //101000
1427 +                                                       report_key      = prevJoypadKeycodePressEmulated;
1428 +                                                       report_col      = _H6300_JOYPAD_REPORT_COLUMN;
1429 +                                                       report_row      = 3;
1430 +                                                       input_report_key(omap_kp_data->input,
1431 +                                                                       report_key,
1432 +                                                                       new_state[report_col] & (1 << report_row));
1433 +                                               }
1434 +                                               /*
1435 +                                                * enter, down_left and down_right sensors pressed
1436 +                                                * --> 101110 == 46
1437 +                                                * OR
1438 +                                                * down_left and down_right
1439 +                                                * -->101010 == 42
1440 +                                                * --> move to down
1441 +                                                */
1442 +                                               else if ((new_state[1] == 46) ||
1443 +                                                        (new_state[1] == 42))
1444 +                                               {
1445 +                                                       joypad_checked  = 1;
1446 +                                                       prevJoypadKeycodePressEmulated  = KEY_DOWN;
1447 +                                                       new_state[_H6300_JOYPAD_REPORT_COLUMN]  = 34;   //100010
1448 +                                                       report_key      = prevJoypadKeycodePressEmulated;
1449 +                                                       report_col      = _H6300_JOYPAD_REPORT_COLUMN;
1450 +                                                       report_row      = 1;
1451 +                                                       input_report_key(omap_kp_data->input,
1452 +                                                                       report_key,
1453 +                                                                       new_state[report_col] & (1 << report_row));
1454 +                                               }                                                                                               
1455 +                                               /*
1456 +                                                * enter, up_right and down_right sensors pressed
1457 +                                                * --> 111100 == 60
1458 +                                                * or
1459 +                                                * down_right and up_right
1460 +                                                * --> 111000 == 56
1461 +                                                * --> move to right
1462 +                                                */
1463 +                                               else if ((new_state[1] == 60) ||
1464 +                                                        (new_state[1] == 56))
1465 +                                               {
1466 +                                                       joypad_checked  = 1;
1467 +                                                       prevJoypadKeycodePressEmulated  = KEY_RIGHT;
1468 +                                                       new_state[_H6300_JOYPAD_REPORT_COLUMN]  = 33;   //100001
1469 +                                                       report_key      = prevJoypadKeycodePressEmulated;
1470 +                                                       report_col      = _H6300_JOYPAD_REPORT_COLUMN;
1471 +                                                       report_row      = 0;
1472 +                                                       input_report_key(omap_kp_data->input,
1473 +                                                                       report_key,
1474 +                                                                       new_state[report_col] & (1 << report_row));
1475 +                                               }
1476 +                                               /*
1477 +                                                * enter, up_left and down_left sensors pressed
1478 +                                                * --> 100111 == 39
1479 +                                                * or up_left and down_left
1480 +                                                * --> 100011 == 35
1481 +                                                * --> move to left
1482 +                                                */
1483 +                                               else if ((new_state[1] == 39) ||
1484 +                                                        (new_state[1] == 35))
1485 +                                               {
1486 +                                                       joypad_checked  = 1;
1487 +                                                       prevJoypadKeycodePressEmulated  = KEY_LEFT;
1488 +                                                       new_state[_H6300_JOYPAD_REPORT_COLUMN]  = 36;   //100100
1489 +                                                       report_key      = prevJoypadKeycodePressEmulated;
1490 +                                                       report_col      = _H6300_JOYPAD_REPORT_COLUMN;
1491 +                                                       report_row      = 2;
1492 +                                                       input_report_key(omap_kp_data->input,
1493 +                                                                       report_key,
1494 +                                                                       new_state[report_col] & (1 << report_row));
1495 +                                               }
1496 +                                               else
1497 +                                               {
1498 +                                                       //printk("missed new_state = %d\n", new_state[1]);
1499 +                                               }
1500 +                                       }
1501 +                                       else
1502 +                                       {
1503 +                                               if (prevJoypadKeycodePressEmulated != 0)
1504 +                                               {
1505 +                                                       // report key up event
1506 +                                                       joypad_checked  = 1;
1507 +                                                       new_state[_H6300_JOYPAD_REPORT_COLUMN]  = 32;   //100000
1508 +                                                       report_key      = prevJoypadKeycodePressEmulated;
1509 +                                                       report_col      = _H6300_JOYPAD_REPORT_COLUMN;
1510 +                                                       switch(prevJoypadKeycodePressEmulated)
1511 +                                                       {
1512 +                                                               case KEY_RIGHT:
1513 +                                                                       report_row      = 0;
1514 +                                                                       break;
1515 +                                                               case KEY_DOWN:
1516 +                                                                       report_row      = 1;
1517 +                                                                       break;
1518 +                                                               case KEY_LEFT:
1519 +                                                                       report_row      = 2;
1520 +                                                                       break;
1521 +                                                               case KEY_UP:
1522 +                                                                       report_row      = 3;
1523 +                                                                       break;
1524 +                                                               case KEY_ENTER:
1525 +                                                                       report_row      = 4;
1526 +                                                                       break;
1527 +                                                               default:
1528 +                                                                       printk(KERN_WARNING "Unknown iPAQ h6300 column 1 key = %d released. This should newer happen!\n",
1529 +                                                                               key);
1530 +                                                                       report_row      = 0;
1531 +                                                       }
1532 +                                                       input_report_key(omap_kp_data->input,
1533 +                                                                       report_key,
1534 +                                                                       new_state[report_col] & (1 << report_row));
1535 +                                                       prevJoypadKeycodePressEmulated  = 0;
1536 +                                               }
1537 +                                       }
1538 +                               }
1539 +                       }
1540 +                       else
1541 +                       {
1542 +                               if (!(kp_cur_group == (key & GROUP_MASK) ||
1543 +                                     kp_cur_group == -1))
1544 +                                       continue;
1545 +
1546 +                               kp_cur_group = key & GROUP_MASK;
1547 +                               input_report_key(omap_kp_data->input, key & ~GROUP_MASK,
1548 +                                                !!(new_state[col] & (1 << row)));
1549 +                       }
1550  #endif
1551                 }
1552         }
1553 @@ -348,10 +536,11 @@
1554                         omap_set_gpio_direction(row_gpios[i], 1);
1555                 }
1556         }
1557 +       prevJoypadKeycodePressEmulated          = 0;
1558  
1559         init_timer(&omap_kp->timer);
1560         omap_kp->timer.function = omap_kp_timer;
1561 -       omap_kp->timer.data = (unsigned long) omap_kp;
1562 +       omap_kp->timer.data = (unsigned long)omap_kp;
1563  
1564         /* get the irq and init timer*/
1565         tasklet_enable(&kp_tasklet);
1566 @@ -376,7 +565,7 @@
1567         input_register_device(omap_kp->input);
1568  
1569         if (machine_is_omap_h2() || machine_is_omap_h3() ||
1570 -           machine_is_omap_perseus2()) {
1571 +           machine_is_omap_perseus2() || machine_is_omap_h6300()) {
1572                 omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_DEBOUNCING);
1573         }
1574         /* scan current status and enable interrupt */
1575 @@ -447,6 +636,6 @@
1576  module_init(omap_kp_init);
1577  module_exit(omap_kp_exit);
1578  
1579 -MODULE_AUTHOR("Timo Teräs");
1580 +MODULE_AUTHOR("Timo Ter�s");
1581  MODULE_DESCRIPTION("OMAP Keypad Driver");
1582  MODULE_LICENSE("GPL");
1583 diff -Naur linux-2.6.16.16/drivers/input/touchscreen/omap/Makefile h6300_dev/drivers/input/touchscreen/omap/Makefile
1584 --- linux-2.6.16.16/drivers/input/touchscreen/omap/Makefile     2006-05-17 21:41:30.000000000 +0300
1585 +++ h6300_dev/drivers/input/touchscreen/omap/Makefile   2005-10-22 03:52:45.000000000 +0300
1586 @@ -8,5 +8,6 @@
1587  objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_H3) += ts_hx.o
1588  objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += ts_inn1510.o
1589  objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_OSK) += ts_osk.o
1590 +objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_H6300) += ts_hx.o
1591  
1592  omapts-objs := omap_ts.o $(objs-yy)
1593 diff -Naur linux-2.6.16.16/drivers/input/touchscreen/omap/omap_ts.c h6300_dev/drivers/input/touchscreen/omap/omap_ts.c
1594 --- linux-2.6.16.16/drivers/input/touchscreen/omap/omap_ts.c    2006-05-17 21:41:30.000000000 +0300
1595 +++ h6300_dev/drivers/input/touchscreen/omap/omap_ts.c  2006-02-21 23:54:33.000000000 +0200
1596 @@ -46,7 +46,7 @@
1597  #define OMAP_TS_NAME   "omap_ts"
1598  
1599  static struct ts_device *__initdata ts_devs[] = {
1600 -#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3)
1601 +#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3) || defined(CONFIG_MACH_OMAP_H6300)
1602         &hx_ts,
1603  #endif
1604  #ifdef CONFIG_MACH_OMAP_OSK
1605 diff -Naur linux-2.6.16.16/drivers/input/touchscreen/omap/ts_hx.c h6300_dev/drivers/input/touchscreen/omap/ts_hx.c
1606 --- linux-2.6.16.16/drivers/input/touchscreen/omap/ts_hx.c      2006-05-17 21:41:30.000000000 +0300
1607 +++ h6300_dev/drivers/input/touchscreen/omap/ts_hx.c    2006-04-24 20:53:29.000000000 +0300
1608 @@ -39,6 +39,7 @@
1609  
1610  #define        H2_GPIO_NUM             4
1611  #define        H3_GPIO_NUM             48
1612 +#define H6300_GPIO_NUM 2
1613  
1614  #define OMAP_TSC2101_XRES                     500
1615  #define TOUCHSCREEN_DATA_REGISTERS_PAGE         0x0
1616 @@ -88,6 +89,9 @@
1617         } else if (machine_is_omap_h3()) {
1618                 gpio = H3_GPIO_NUM;
1619                 omap_cfg_reg(W19_1610_GPIO48);
1620 +       } else if (machine_is_omap_h6300 ()) {
1621 +               gpio = H6300_GPIO_NUM;
1622 +               omap_cfg_reg(M14_1510_GPIO2);   
1623         } else
1624                 return -ENODEV;
1625  
1626 @@ -180,5 +184,7 @@
1627                 omap_free_gpio(H2_GPIO_NUM);
1628         else if (machine_is_omap_h3())
1629                 omap_free_gpio(H3_GPIO_NUM);
1630 +       else if (machine_is_omap_h6300())
1631 +               omap_free_gpio(H6300_GPIO_NUM);
1632  }
1633  #endif
1634 diff -Naur linux-2.6.16.16/drivers/mmc/mmc.c h6300_dev/drivers/mmc/mmc.c
1635 --- linux-2.6.16.16/drivers/mmc/mmc.c   2006-05-17 21:41:30.000000000 +0300
1636 +++ h6300_dev/drivers/mmc/mmc.c 2006-03-28 10:34:39.000000000 +0300
1637 @@ -964,7 +964,7 @@
1638                 mmc_decode_scr(card);
1639         }
1640  
1641 -       mmc_deselect_cards(host);
1642 +       //mmc_deselect_cards(host);
1643  }
1644  
1645  static unsigned int mmc_calculate_clock(struct mmc_host *host)
1646 diff -Naur linux-2.6.16.16/drivers/ssi/omap-tsc2101.c h6300_dev/drivers/ssi/omap-tsc2101.c
1647 --- linux-2.6.16.16/drivers/ssi/omap-tsc2101.c  2006-05-17 21:41:30.000000000 +0300
1648 +++ h6300_dev/drivers/ssi/omap-tsc2101.c        2006-04-24 20:53:29.000000000 +0300
1649 @@ -36,10 +36,11 @@
1650  #include <asm/arch/hardware.h>
1651  #include <asm/hardware/tsc2101.h>
1652  #include <asm/arch/gpioexpander.h>
1653 +#include <asm/arch/gpio.h>
1654  
1655  #include "omap-tsc2101.h"
1656  
1657 -#if CONFIG_ARCH_OMAP16XX
1658 +#if CONFIG_ARCH_OMAP1
1659  #include <../drivers/ssi/omap-uwire.h>
1660  #else
1661  #error "Unsupported configuration"
1662 @@ -66,27 +67,28 @@
1663         if (count++ == 0) {
1664                 int ret = 0;
1665                 /* set the Mux to provide MCLK to TSC2101 */
1666 -               if (machine_is_omap_h3()) {
1667 +               if (machine_is_omap_h3())
1668                         ret = omap_cfg_reg(V5_1710_MCLK_ON);
1669 -               } else {
1670 -                       if (machine_is_omap_h2()) {
1671 -                               ret = omap_cfg_reg(R10_1610_MCLK_ON);
1672 +               else if (machine_is_omap_h2())
1673 +                       ret = omap_cfg_reg(R10_1610_MCLK_ON);
1674 +               else if (machine_is_omap_h6300())
1675 +                       ret = omap_cfg_reg(R10_1510_MCLK_ON);
1676 +
1677 +               if (!cpu_is_omap1510 ()) {
1678 +                       /* Get the MCLK */
1679 +                       tsc2101_mclk_ck = clk_get(NULL, "mclk");
1680 +                       if (NULL == tsc2101_mclk_ck) {
1681 +                               printk(KERN_ERR "Unable to get the clock MCLK!!!\n");;
1682 +                               ret = -EPERM;
1683 +                               goto done;
1684                         }
1685 -               }
1686 -
1687 -               /* Get the MCLK */
1688 -               tsc2101_mclk_ck = clk_get(NULL, "mclk");
1689 -               if (NULL == tsc2101_mclk_ck) {
1690 -                       printk(KERN_ERR "Unable to get the clock MCLK!!!\n");;
1691 -                       ret = -EPERM;
1692 -                       goto done;
1693 -               }
1694 -               if (clk_set_rate(tsc2101_mclk_ck, 12000000)) {
1695 -                       printk(KERN_ERR "Unable to set rate to the MCLK!!!\n");;
1696 -                       ret = -EPERM;
1697 -                       goto done;
1698 -               }
1699 -               clk_enable(tsc2101_mclk_ck);
1700 +                       if (clk_set_rate(tsc2101_mclk_ck, 12000000)) {
1701 +                               printk(KERN_ERR "Unable to set rate to the MCLK!!!\n");;
1702 +                               ret = -EPERM;
1703 +                               goto done;
1704 +                       }
1705 +                       clk_enable(tsc2101_mclk_ck);
1706 +               } /* if (!cpu_is_omap1510 ()) */
1707  
1708                 ret = omap_tsc2101_configure();
1709  
1710 @@ -116,10 +118,16 @@
1711                         }
1712                 }
1713  
1714 -               /* Release the MCLK */
1715 -               clk_disable(tsc2101_mclk_ck);
1716 -               clk_put(tsc2101_mclk_ck);
1717 -               tsc2101_mclk_ck = NULL;
1718 +               if (!cpu_is_omap1510 ()) {
1719 +                       /* Release the MCLK */
1720 +                       clk_disable(tsc2101_mclk_ck);
1721 +                       clk_put(tsc2101_mclk_ck);
1722 +                       tsc2101_mclk_ck = NULL;
1723 +               }
1724 +
1725 +#if defined(CONFIG_MACH_OMAP_H6300)
1726 +               omap_free_gpio(8);
1727 +#endif
1728  
1729                 module_put(THIS_MODULE);
1730         }
1731 @@ -150,7 +158,10 @@
1732                         return;
1733                 }
1734         }
1735 -       if (machine_is_omap_h3()) {
1736 +       if (machine_is_omap_h3() || machine_is_omap_h6300()) {
1737 +
1738 +               if (machine_is_omap_h6300())
1739 +                       omap_set_gpio_dataout (8, 0);
1740  
1741                 ret =
1742                     omap_uwire_data_transfer(0, ((page << 11) | (address << 5)),
1743 @@ -159,6 +170,8 @@
1744                         printk(KERN_ERR
1745                                "uwire-write returned error for address %x\n",
1746                                address);
1747 +               if (machine_is_omap_h6300())
1748 +                       omap_set_gpio_dataout (8, 1);
1749                         return;
1750                 }
1751                 ret = omap_uwire_data_transfer(0, data, 16, 0, NULL, 0);
1752 @@ -166,10 +179,14 @@
1753                         printk(KERN_ERR
1754                                "uwire-write returned error for address %x\n",
1755                                address);
1756 +                       if (machine_is_omap_h6300())
1757 +                               omap_set_gpio_dataout (8, 1);
1758                         return;
1759                 }
1760 -       }
1761  
1762 +               if (machine_is_omap_h6300())
1763 +                       omap_set_gpio_dataout (8, 1);
1764 +       }
1765  }
1766  
1767  void omap_tsc2101_reads(int page, u8 startaddress, u16 * data, int numregs)
1768 @@ -178,9 +195,13 @@
1769         if (machine_is_omap_h2()) {
1770                 cs = 1;
1771         }
1772 -       if (machine_is_omap_h3()) {
1773 +       if (machine_is_omap_h3() || machine_is_omap_h6300()) {
1774                 cs = 0;
1775         }
1776 +
1777 +       if (machine_is_omap_h6300())
1778 +               omap_set_gpio_dataout(8, 0);
1779 +
1780         (void)omap_uwire_data_transfer(cs, (0x8000 | (page << 11)
1781                                             | (startaddress << 5)),
1782                                        16, 0, NULL, 1);
1783 @@ -188,6 +209,9 @@
1784                 omap_uwire_data_transfer(cs, 0, 0, 16, data, 1);
1785         }
1786         omap_uwire_data_transfer(cs, 0, 0, 16, data, 0);
1787 +
1788 +       if (machine_is_omap_h6300())
1789 +               omap_set_gpio_dataout(8, 1);
1790  }
1791  
1792  u16 omap_tsc2101_read(int page, u8 address)
1793 @@ -228,9 +252,24 @@
1794                 omap_cfg_reg(N14_1610_UWIRE_CS0);
1795                 omap_uwire_configure_mode(0, uwire_flags);
1796         }
1797 +       if (machine_is_omap_h6300()) {
1798 +               uwire_flags = UWIRE_READ_RISING_EDGE | UWIRE_WRITE_RISING_EDGE;
1799 +               omap_cfg_reg(N14_1510_UWIRE_CS0);
1800 +               omap_uwire_configure_mode(0, uwire_flags);
1801 +
1802 +               omap_request_gpio(8);
1803 +               omap_set_gpio_dataout(8, 0);
1804 +               omap_set_gpio_direction (8, 0);
1805 +       }
1806  
1807         /* Configure MCLK enable */
1808 -       omap_writel(omap_readl(PU_PD_SEL_2) | (1 << 22), PU_PD_SEL_2);  
1809 +       if (cpu_is_omap16xx() || cpu_is_omap1710())
1810 +               omap_writel(omap_readl(PU_PD_SEL_2) | (1 << 22), PU_PD_SEL_2);  
1811 +       if (machine_is_omap_h6300()) {
1812 +               omap_cfg_reg(V19_1510_UWIRE_SCLK);
1813 +               omap_cfg_reg(W21_1510_UWIRE_SDO);
1814 +               omap_cfg_reg(U18_1510_UWIRE_SDI);
1815 +       }
1816  
1817         return 0;
1818  }
1819 @@ -243,5 +282,5 @@
1820  
1821  MODULE_AUTHOR("Texas Instruments");
1822  MODULE_DESCRIPTION
1823 -    ("Glue audio driver for the TI OMAP1610/OMAP1710 TSC2101 codec.");
1824 +    ("Glue audio driver for the TI OMAP1510/1610/OMAP1710 TSC2101 codec.");
1825  MODULE_LICENSE("GPL");
1826 diff -Naur linux-2.6.16.16/drivers/ssi/omap-uwire.c h6300_dev/drivers/ssi/omap-uwire.c
1827 --- linux-2.6.16.16/drivers/ssi/omap-uwire.c    2006-05-17 21:41:30.000000000 +0300
1828 +++ h6300_dev/drivers/ssi/omap-uwire.c  2006-04-24 20:53:29.000000000 +0300
1829 @@ -10,7 +10,7 @@
1830   * Ported to 2.6 uwire interface.
1831   * Copyright (C) 2004 Texas Instruments.
1832   *
1833 - * Generalization patches by Juha Yrjölä <juha.yrjola@nokia.com>
1834 + * Generalization patches by Juha Yrj�l� <juha.yrjola@nokia.com>
1835   *
1836   *  This program is free software; you can redistribute         it and/or modify it
1837   *  under  the terms of         the GNU General  Public License as published by the
1838 @@ -212,6 +212,10 @@
1839                 omap_cfg_reg(N14_1610_UWIRE_CS0);
1840                 omap_cfg_reg(P15_1610_UWIRE_CS3);
1841         }
1842 +       if (machine_is_omap_h6300()) {
1843 +               omap_cfg_reg(N14_1510_UWIRE_CS0);
1844 +               omap_cfg_reg(P15_1510_UWIRE_CS3);
1845 +       }
1846         if (machine_is_omap_perseus2()) {
1847                 /* configure pins: MPU_UW_nSCS1, MPU_UW_SDO, MPU_UW_SCLK */
1848                 int val = omap_readl(OMAP730_IO_CONF_9) & ~0x00EEE000;
1849 diff -Naur linux-2.6.16.16/drivers/telephony/Kconfig h6300_dev/drivers/telephony/Kconfig
1850 --- linux-2.6.16.16/drivers/telephony/Kconfig   2006-05-11 04:56:24.000000000 +0300
1851 +++ h6300_dev/drivers/telephony/Kconfig 2005-10-06 02:34:39.000000000 +0300
1852 @@ -41,7 +41,18 @@
1853         help
1854           Say Y here to configure in PCMCIA service support for the Quicknet
1855           cards manufactured by Quicknet Technologies, Inc.  This changes the
1856 -         card initialization code to work with the card manager daemon.
1857 +         card initialization code to work with the card manager daemon.          
1858 +
1859 +config GSM_H6300
1860 +       tristate "H6300 P5186 GSM/GPRS DRIVER"
1861 +       depends on PHONE && I2C && PCA9535
1862 +       help
1863 +         Bluetooth H6300 P5186 gsm/gprs driver.
1864 +         This driver provides the firmware loading mechanism for the P5185
1865 +         gsm/gprs hardware in iPAQ h6300.
1866 +
1867 +         Say Y here to compile support for P5186 gsm/gprs devices into the
1868 +         kernel or say M to compile it as module (h6300_gsm).
1869  
1870  endmenu
1871  
1872 diff -Naur linux-2.6.16.16/drivers/telephony/Makefile h6300_dev/drivers/telephony/Makefile
1873 --- linux-2.6.16.16/drivers/telephony/Makefile  2006-05-11 04:56:24.000000000 +0300
1874 +++ h6300_dev/drivers/telephony/Makefile        2005-10-06 02:34:39.000000000 +0300
1875 @@ -2,6 +2,7 @@
1876  # Makefile for drivers/telephony
1877  #
1878  
1879 -obj-$(CONFIG_PHONE) += phonedev.o
1880 -obj-$(CONFIG_PHONE_IXJ) += ixj.o
1881 -obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o
1882 +obj-$(CONFIG_PHONE)                            += phonedev.o
1883 +obj-$(CONFIG_PHONE_IXJ)                        += ixj.o
1884 +obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o
1885 +obj-$(CONFIG_GSM_H6300)                        += omap/
1886 diff -Naur linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_led.c h6300_dev/drivers/telephony/omap/h6300_gsm_led.c
1887 --- linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_led.c      1970-01-01 02:00:00.000000000 +0200
1888 +++ h6300_dev/drivers/telephony/omap/h6300_gsm_led.c    2005-10-06 02:34:39.000000000 +0300
1889 @@ -0,0 +1,40 @@
1890 +/* 
1891 + * GSM interface driver helper for controlling bluetooth leds available in iPAQ h6300.
1892 + * 
1893 + * Copyright (C) 2005 Mika Laitio  <lamikr@cc.jyu.fi>
1894 + * 
1895 + * This program is free software; you can redistribute it and/or modify
1896 + * it under the terms of the GNU General Public License version 2 as
1897 + * published by the Free Software Foundation.
1898 + */
1899 +
1900 +#include <linux/module.h>
1901 +#include <linux/kernel.h>
1902 +#include <linux/delay.h>
1903 +#include <linux/device.h>
1904 +
1905 +#include <asm/hardware.h>
1906 +#include <asm/arch/gpio.h>
1907 +
1908 +/* 
1909 + * Low level access for disabling h6300 gsm led.
1910 + *
1911 + * TODO: implement for h6300 
1912 + */
1913 +void h6300_clear_gsm_led(int led_num)
1914 +{
1915 +       printk(KERN_NOTICE "h6300_gsm_led.c h6300_clear_gsm_led() done\n");
1916 +       //hx4700_set_led(led_num, 0, 16);
1917 +}
1918 +EXPORT_SYMBOL(h6300_clear_gsm_led);
1919 +
1920 +/* 
1921 + * Low level access for setting up the gsm led.
1922 + *
1923 + * TODO: implement for h6300 
1924 + */
1925 +void h6300_set_gsm_led(int led_num, int duty_time, int cycle_time)
1926 +{
1927 +       printk(KERN_NOTICE "h6300_gsm_led.c h6300_set_gsm_led() done\n");
1928 +}
1929 +EXPORT_SYMBOL(h6300_set_gsm_led);
1930 diff -Naur linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_led.h h6300_dev/drivers/telephony/omap/h6300_gsm_led.h
1931 --- linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_led.h      1970-01-01 02:00:00.000000000 +0200
1932 +++ h6300_dev/drivers/telephony/omap/h6300_gsm_led.h    2005-10-06 02:34:39.000000000 +0300
1933 @@ -0,0 +1,10 @@
1934 +#ifndef H6300_GSM_LED_H_
1935 +#define H6300_GSM_LED_H_
1936 +
1937 +#define INDEX_GSM_LED  1
1938 +
1939 +void h6300_clear_gsm_led(int led_num);
1940 +void h6300_set_gsm_led(int led_num, int duty_time, int cycle_time);
1941 +
1942 +
1943 +#endif /*H6300_GSM_LED_H_*/
1944 diff -Naur linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_p5186.c h6300_dev/drivers/telephony/omap/h6300_gsm_p5186.c
1945 --- linux-2.6.16.16/drivers/telephony/omap/h6300_gsm_p5186.c    1970-01-01 02:00:00.000000000 +0200
1946 +++ h6300_dev/drivers/telephony/omap/h6300_gsm_p5186.c  2006-01-23 00:09:23.000000000 +0200
1947 @@ -0,0 +1,172 @@
1948 +/* 
1949 + * Wavecom P5186 GPRS and GSM module driver for iPAQ h6300.
1950 + * 
1951 + * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi>
1952 + * 
1953 + * This program is free software; you can redistribute it and/or modify
1954 + * it under the terms of the GNU General Public License version 2 as
1955 + * published by the Free Software Foundation.
1956 + */
1957 +
1958 +#include <linux/module.h>
1959 +#include <linux/kernel.h>
1960 +#include <linux/delay.h>
1961 +#include <linux/platform_device.h>
1962 +
1963 +#include <asm/hardware.h>
1964 +#include <asm/arch/gpio.h>
1965 +
1966 +#include <asm/arch/pca9535.h>
1967 +#include <asm/arch/h6300_uart_info.h>
1968 +#include "h6300_gsm_led.h"
1969 +
1970 +static void
1971 +h6300_gsm_configure(struct uart_omap_port *up, int enable)
1972 +{
1973 +       printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_configure() started, enable = %d\n", enable);
1974 +       
1975 +       // printk( KERN_NOTICE "h6300 configure bluetooth: %d\n", enable );
1976 +       if (enable == 0) {
1977 +               pca9535_gpio_write(GPIO_I2C_GPRS_RESET, GPIO_VALUE_OFF);        // turn off gpio
1978 +               mdelay(5);
1979 +               h6300_clear_gsm_led(INDEX_GSM_LED);
1980 +       }
1981 +       else if (enable == 1) {
1982 +               pca9535_gpio_write(GPIO_I2C_GPRS_RESET, GPIO_VALUE_ON); // turn on gpio
1983 +               mdelay(5);                              
1984 +       }
1985 +       else if (enable == 2) {
1986 +               h6300_set_gsm_led(INDEX_GSM_LED, 16, 16);
1987 +       }
1988 +       printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_configure() done\n");
1989 +}
1990 +
1991 +static void
1992 +h6300_gsm_set_txrx(struct uart_omap_port *up, int txrx)
1993 +{
1994 +       printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_set_txrx(), txrx = %d done\n", txrx);
1995 +       /* do nothing */
1996 +}
1997 +
1998 +static int
1999 +h6300_gsm_get_txrx(struct uart_omap_port *up)
2000 +{
2001 +       printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_get_txrx() done\n");
2002 +       /* do nothing */
2003 +       return 0;
2004 +}
2005 +
2006 +static int
2007 +h6300_gsm_probe(struct platform_device *pdev)
2008 +{
2009 +       int     ii;
2010 +       int     curVal;
2011 +       
2012 +       struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
2013 +/*
2014 +       printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_probe() started\n");    
2015 +       for (ii = 0; ii < 8; ii++)
2016 +       {
2017 +               curVal  = pca9535_gpio_read(ii);
2018 +               printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal);
2019 +       }
2020 +       for (ii = 10; ii < 18; ii++)
2021 +       {
2022 +               curVal  = pca9535_gpio_read(ii);
2023 +               printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal);
2024 +       }
2025 +       printk(KERN_NOTICE "\nfirst check done\n");
2026 +*/
2027 +       pca9535_gpio_direction(GPIO_I2C_GPRS_RESET, GPIO_DIR_OUTPUT);   // set gpio direction to be output
2028 +       pca9535_gpio_write(GPIO_I2C_GPRS_RESET, GPIO_VALUE_ON); // turn on gpio
2029 +       mdelay(200);
2030 +       
2031 +       pca9535_gpio_direction(GPIO_I2C_MIC_OP_EN, GPIO_DIR_OUTPUT);    // set gpio direction to be output
2032 +       pca9535_gpio_write(GPIO_I2C_MIC_OP_EN, GPIO_VALUE_ON);  // turn on gpio
2033 +       mdelay(200);
2034 +
2035 +       pca9535_gpio_direction(GPIO_I2C_SPK_OP_PD, GPIO_DIR_OUTPUT);    // set gpio direction to be output
2036 +       pca9535_gpio_write(GPIO_I2C_SPK_OP_PD, GPIO_VALUE_ON);  // pd = pulldown?, normal off = on
2037 +
2038 +       mdelay(200);
2039 +       
2040 +       //pca9535_gpio_direction(
2041 +       /* configure bluetooth UART */
2042 +       //h6300_gpio_mode(GPIO_NR_H6300_BT_RXD_MD);
2043 +       //h6300_gpio_mode(GPIO_NR_H6300_BT_TXD_MD);
2044 +       //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_CTS_MD);
2045 +       //h6300_gpio_mode(GPIO_NR_H6300_BT_UART_RTS_MD);
2046 +
2047 +       funcs->configure        = h6300_gsm_configure;
2048 +       funcs->set_txrx         = h6300_gsm_set_txrx;
2049 +       funcs->get_txrx         = h6300_gsm_get_txrx;
2050 +
2051 +       /* Make sure the LED is off */
2052 +       h6300_clear_gsm_led(INDEX_GSM_LED);     
2053 +/*     
2054 +       for (ii = 0; ii < 8; ii++)
2055 +       {
2056 +               curVal  = pca9535_gpio_read(ii);
2057 +               printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal);
2058 +       }
2059 +       for (ii = 10; ii < 18; ii++)
2060 +       {
2061 +               curVal  = pca9535_gpio_read(ii);
2062 +               printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal);
2063 +       }
2064 +*/     
2065 +       printk(KERN_NOTICE "\nh6300_gsm_p5186.c h6300_gsm_probe() done\n");
2066 +               
2067 +       return 0;
2068 +}
2069 +
2070 +static int
2071 +h6300_gsm_remove(struct platform_device *pdev)
2072 +{
2073 +       struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
2074 +       
2075 +       printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_remove() started\n");   
2076 +
2077 +       pca9535_gpio_write(GPIO_I2C_GPRS_RESET, 0);     // turn off gpio
2078 +       
2079 +       funcs->configure        = NULL;
2080 +       funcs->set_txrx         = NULL;
2081 +       funcs->get_txrx         = NULL;
2082 +
2083 +       /* Make sure the LED is off */
2084 +       h6300_clear_gsm_led(INDEX_GSM_LED);
2085 +       
2086 +       printk(KERN_NOTICE "h6300_gsm_p5186.c, h6300_gsm_remove() done\n");
2087 +
2088 +       return 0;
2089 +}
2090 +
2091 +static struct platform_driver gsm_driver = {
2092 +       .probe    = h6300_gsm_probe,
2093 +       .remove   = h6300_gsm_remove,
2094 +       .driver = {
2095 +               .name   = "h6300_gsm",
2096 +       },
2097 +};
2098 +
2099 +static int __init
2100 +h6300_gsm_init(void)
2101 +{
2102 +       printk(KERN_NOTICE "h6300 GSM Driver init()\n");
2103 +       return platform_driver_register(&gsm_driver);
2104 +}
2105 +
2106 +static void __exit
2107 +h6300_gsm_exit(void)
2108 +{
2109 +       printk(KERN_NOTICE "h6300 GSM Driver exit()\n");
2110 +       platform_driver_unregister(&gsm_driver);
2111 +}
2112 +
2113 +module_init(h6300_gsm_init);
2114 +module_exit(h6300_gsm_exit);
2115 +
2116 +MODULE_AUTHOR("Mika Laitio, <lamikr@cc.jyu.fi>");
2117 +MODULE_DESCRIPTION("iPAQ h6300 Wavecom P5186 GPRS and GSM module driver.");
2118 +MODULE_LICENSE("GPL");
2119 +
2120 diff -Naur linux-2.6.16.16/drivers/telephony/omap/Makefile h6300_dev/drivers/telephony/omap/Makefile
2121 --- linux-2.6.16.16/drivers/telephony/omap/Makefile     1970-01-01 02:00:00.000000000 +0200
2122 +++ h6300_dev/drivers/telephony/omap/Makefile   2005-10-06 02:34:39.000000000 +0300
2123 @@ -0,0 +1,6 @@
2124 +#
2125 +# Makefile for the Linux iPAQ H6300 BRF6100 Bluetooth device drivers.
2126 +#
2127 +
2128 +h6300_gsm-objs                 := h6300_gsm_led.o h6300_gsm_p5186.o
2129 +obj-$(CONFIG_GSM_H6300)        += h6300_gsm.o
2130 diff -Naur linux-2.6.16.16/drivers/usb/gadget/omap_udc.c h6300_dev/drivers/usb/gadget/omap_udc.c
2131 --- linux-2.6.16.16/drivers/usb/gadget/omap_udc.c       2006-05-17 21:41:30.000000000 +0300
2132 +++ h6300_dev/drivers/usb/gadget/omap_udc.c     2006-04-24 20:53:29.000000000 +0300
2133 @@ -60,7 +60,8 @@
2134  #undef USB_TRACE
2135  
2136  /* bulk DMA seems to be behaving for both IN and OUT */
2137 -#define        USE_DMA
2138 +//#define      USE_DMA
2139 +#undef USE_DMA
2140  
2141  /* ISO too */
2142  #define        USE_ISO
2143 @@ -2147,7 +2148,7 @@
2144         /* boards that don't have VBUS sensing can't autogate 48MHz;
2145          * can't enter deep sleep while a gadget driver is active.
2146          */
2147 -       if (machine_is_omap_innovator() || machine_is_omap_osk())
2148 +       if (machine_is_omap_innovator() || machine_is_omap_osk() || machine_is_omap_h6300())
2149                 omap_vbus_session(&udc->gadget, 1);
2150  
2151  done:
2152 @@ -2170,7 +2171,7 @@
2153         if (udc->dc_clk != NULL)
2154                 omap_udc_enable_clock(1);
2155  
2156 -       if (machine_is_omap_innovator() || machine_is_omap_osk())
2157 +       if (machine_is_omap_innovator() || machine_is_omap_osk() || machine_is_omap_h6300())
2158                 omap_vbus_session(&udc->gadget, 0);
2159  
2160         if (udc->transceiver)
2161 @@ -2791,7 +2792,7 @@
2162                 hmc = HMC_1510;
2163                 type = "(unknown)";
2164  
2165 -               if (machine_is_omap_innovator()) {
2166 +               if (machine_is_omap_innovator() || machine_is_omap_h6300()) {
2167                         /* just set up software VBUS detect, and then
2168                          * later rig it so we always report VBUS.
2169                          * FIXME without really sensing VBUS, we can't
2170 diff -Naur linux-2.6.16.16/drivers/usb/host/ohci-omap.c h6300_dev/drivers/usb/host/ohci-omap.c
2171 --- linux-2.6.16.16/drivers/usb/host/ohci-omap.c        2006-05-17 21:41:30.000000000 +0300
2172 +++ h6300_dev/drivers/usb/host/ohci-omap.c      2006-02-06 15:36:21.000000000 +0200
2173 @@ -353,11 +353,7 @@
2174         if (IS_ERR(usb_host_ck))
2175                 return PTR_ERR(usb_host_ck);
2176  
2177 -       if (!cpu_is_omap1510())
2178 -               usb_dc_ck = clk_get(0, "usb_dc_ck");
2179 -       else
2180 -               usb_dc_ck = clk_get(0, "lb_ck");
2181 -
2182 +       usb_dc_ck = clk_get(0, "usb_dc_ck");
2183         if (IS_ERR(usb_dc_ck)) {
2184                 clk_put(usb_host_ck);
2185                 return PTR_ERR(usb_dc_ck);
2186 diff -Naur linux-2.6.16.16/drivers/video/omap/lcd_h6300.c h6300_dev/drivers/video/omap/lcd_h6300.c
2187 --- linux-2.6.16.16/drivers/video/omap/lcd_h6300.c      1970-01-01 02:00:00.000000000 +0200
2188 +++ h6300_dev/drivers/video/omap/lcd_h6300.c    2006-04-24 20:53:29.000000000 +0300
2189 @@ -0,0 +1,159 @@
2190 +/*
2191 + * File: drivers/video/omap_new/lcd-h6300.c
2192 + *
2193 + * LCD panel support for the TI OMAP1510 Innovator board
2194 + *
2195 + * Copyright (C) 2004 Nokia Corporation
2196 + * Author: Imre Deak <imre.deak@nokia.com>
2197 + *
2198 + * This program is free software; you can redistribute it and/or modify it
2199 + * under the terms of the GNU General Public License as published by the
2200 + * Free Software Foundation; either version 2 of the License, or (at your
2201 + * option) any later version.
2202 + *
2203 + * This program is distributed in the hope that it will be useful, but
2204 + * WITHOUT ANY WARRANTY; without even the implied warranty of
2205 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2206 + * General Public License for more details.
2207 + *
2208 + * You should have received a copy of the GNU General Public License along
2209 + * with this program; if not, write to the Free Software Foundation, Inc.,
2210 + * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
2211 + */
2212 +
2213 +#include <linux/module.h>
2214 +#include <linux/platform_device.h>
2215 +#include <asm/io.h>
2216 +
2217 +#include <asm/arch/pca9535.h>
2218 +#include <asm/arch/omapfb.h>
2219 +
2220 +/* #define OMAPFB_DBG 1 */
2221 +
2222 +#include "debug.h"
2223 +
2224 +//static struct clk *h6300_lcd_ck;
2225 +
2226 +static int h6300_panel_init(struct omapfb_device *fbdev)
2227 +{
2228 +       DBGENTER(1);
2229 +/*
2230 +       if ((h6300_lcd_ck = clk_get (NULL, "lcd_ck")) == NULL) {
2231 +               printk(KERN_ERR "Unable to get the clock LCD_CK!!!\n");
2232 +               return -EPERM;
2233 +       } clk_enable(h6300_lcd_ck);
2234 +*/
2235 +       DBGLEAVE(1);
2236 +       printk(KERN_INFO "lcd_h6300.c: h6300_panel_init() done\n");
2237 +       return 0;
2238 +}
2239 +
2240 +static void h6300_panel_cleanup(void)
2241 +{
2242 +       DBGENTER(1);
2243 +/*
2244 +       if (h6300_lcd_ck) {
2245 +               clk_disable(h6300_lcd_ck);
2246 +               clk_put(h6300_lcd_ck);
2247 +               h6300_lcd_ck = NULL;
2248 +       }
2249 +*/
2250 +       DBGLEAVE(1);
2251 +       printk(KERN_INFO "lcd_h6300.c: h6300_panel_cleanup() done\n");
2252 +}
2253 +
2254 +static int h6300_panel_enable(void)
2255 +{
2256 +       DBGENTER(1);
2257 +       DBGLEAVE(1);
2258 +       printk(KERN_INFO "lcd_h6300.c: h6300_panel_enable() done\n");
2259 +       return 0;
2260 +}
2261 +
2262 +static void h6300_panel_disable(void)
2263 +{
2264 +       DBGENTER(1);
2265 +       DBGLEAVE(1);
2266 +       printk(KERN_INFO "lcd_h6300.c: h6300_panel_disable() done\n");  
2267 +}
2268 +
2269 +static unsigned long h6300_panel_get_caps(void)
2270 +{
2271 +       printk(KERN_INFO "lcd_h6300.c: h6300_panel_get_caps() called\n");       
2272 +       return 0;
2273 +}
2274 +
2275 +struct lcd_panel h6300_panel = {
2276 +       .name           = "h6300",
2277 +       .config         = OMAP_LCDC_PANEL_TFT,
2278 +
2279 +       .bpp            = 16,
2280 +       .data_lines     = 16,
2281 +       .x_res          = 240,
2282 +       .y_res          = 320,
2283 +       .pixel_clock    = 21000,
2284 +       .hsw            = 12,
2285 +       .hfp            = 10,
2286 +       .hbp            = 10,
2287 +       .vsw            = 3,
2288 +       .vfp            = 10,
2289 +       .vbp            = 3,
2290 +       .pcd            = 0,
2291 +
2292 +       .init           = h6300_panel_init,
2293 +       .cleanup        = h6300_panel_cleanup,
2294 +       .enable         = h6300_panel_enable,
2295 +       .disable        = h6300_panel_disable,
2296 +       .get_caps       = h6300_panel_get_caps,
2297 +};
2298 +
2299 +static int h6300_panel_probe(struct platform_device *pdev)
2300 +{
2301 +       DBGENTER(1);
2302 +       omapfb_register_panel(&h6300_panel);
2303 +       return 0;
2304 +}
2305 +
2306 +static int h6300_panel_remove(struct platform_device *pdev)
2307 +{
2308 +       DBGENTER(1);
2309 +       return 0;
2310 +}
2311 +
2312 +static int h6300_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
2313 +{
2314 +       DBGENTER(1);
2315 +       pca9535_gpio_write(GPIO3, HI);
2316 +       return 0;
2317 +}
2318 +
2319 +static int h6300_panel_resume(struct platform_device *pdev)
2320 +{
2321 +       DBGENTER(1);
2322 +       pca9535_gpio_write(GPIO3, LOW);
2323 +       return 0;
2324 +}
2325 +
2326 +struct platform_driver h6300_panel_driver = {
2327 +       .probe          = h6300_panel_probe,
2328 +       .remove         = h6300_panel_remove,
2329 +       .suspend        = h6300_panel_suspend,
2330 +       .resume         = h6300_panel_resume,
2331 +       .driver         = {
2332 +               .name   = "lcd_h6300",
2333 +               .owner  = THIS_MODULE,
2334 +       },
2335 +};
2336 +
2337 +static int h6300_panel_drv_init(void)
2338 +{
2339 +       return platform_driver_register(&h6300_panel_driver);
2340 +}
2341 +
2342 +static void h6300_panel_drv_cleanup(void)
2343 +{
2344 +       platform_driver_unregister(&h6300_panel_driver);
2345 +}
2346 +
2347 +module_init(h6300_panel_drv_init);
2348 +module_exit(h6300_panel_drv_cleanup);
2349 diff -Naur linux-2.6.16.16/drivers/video/omap/Makefile h6300_dev/drivers/video/omap/Makefile
2350 --- linux-2.6.16.16/drivers/video/omap/Makefile 2006-05-17 21:41:30.000000000 +0300
2351 +++ h6300_dev/drivers/video/omap/Makefile       2006-02-21 23:54:33.000000000 +0200
2352 @@ -23,6 +23,7 @@
2353  objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
2354  objs-y$(CONFIG_MACH_OMAP_PERSEUS2) += lcd_p2.o
2355  objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
2356 +objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_H6300) += lcd_h6300.o
2357  
2358  objs-y$(CONFIG_FB_OMAP_LCD_LPH8923) += lcd_lph8923.o
2359  
2360 diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/board-h6300.h h6300_dev/include/asm-arm/arch-omap/board-h6300.h
2361 --- linux-2.6.16.16/include/asm-arm/arch-omap/board-h6300.h     1970-01-01 02:00:00.000000000 +0200
2362 +++ h6300_dev/include/asm-arm/arch-omap/board-h6300.h   2006-04-24 20:53:29.000000000 +0300
2363 @@ -0,0 +1,40 @@
2364 +/*
2365 + * linux/include/asm-arm/arch-omap/board-innovator.h
2366 + *
2367 + * Copyright (C) 2001 RidgeRun, Inc.
2368 + *
2369 + * This program is free software; you can redistribute it and/or modify it
2370 + * under the terms of the GNU General Public License as published by the
2371 + * Free Software Foundation; either version 2 of the License, or (at your
2372 + * option) any later version.
2373 + *
2374 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2375 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2376 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
2377 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2378 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2379 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
2380 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2381 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2382 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2383 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2384 + *
2385 + * You should have received a copy of the GNU General Public License along
2386 + * with this program; if not, write to the Free Software Foundation, Inc.,
2387 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2388 + */
2389 +#ifndef __ASM_ARCH_OMAP_H6300_H
2390 +#define __ASM_ARCH_OMAP_H6300_H
2391 +
2392 +#ifndef OMAP_SDRAM_DEVICE
2393 +#define OMAP_SDRAM_DEVICE                              D256M_1X16_4B
2394 +#endif
2395 +
2396 +#define OMAP1510P1_IMIF_PRI_VALUE              0x00
2397 +#define OMAP1510P1_EMIFS_PRI_VALUE             0x00
2398 +#define OMAP1510P1_EMIFF_PRI_VALUE             0x00
2399 +
2400 +#define NR_FPGA_IRQS                                   24
2401 +#define NR_IRQS                                IH_BOARD_BASE + NR_FPGA_IRQS
2402 +
2403 +#endif /* __ASM_ARCH_OMAP_H6300_H */
2404 diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/h6300_uart_info.h h6300_dev/include/asm-arm/arch-omap/h6300_uart_info.h
2405 --- linux-2.6.16.16/include/asm-arm/arch-omap/h6300_uart_info.h 1970-01-01 02:00:00.000000000 +0200
2406 +++ h6300_dev/include/asm-arm/arch-omap/h6300_uart_info.h       2005-10-14 18:55:31.000000000 +0300
2407 @@ -0,0 +1,33 @@
2408 +/*
2409 + * Support file for calling h6300 uart configuration functions.
2410 + * Used at least by h6300_bt driver.
2411 + * 
2412 + * Copyright (c) 2005 SDG Systems, LLC
2413 + * 2005-03-29   Todd Blumer     Converted  basic structure to support hx4700
2414 + * 2005-10-03   Mika Laitio (lamikr@cc.jyu.fi) Reorganized for the iPAQ h6300 bt driver.
2415 + */
2416 +
2417 +#ifndef _H6300_UART_INFO_H
2418 +#define _H6300_UART_INFO_H
2419 +
2420 +#include "omap_serial.h"
2421 +
2422 +#define GPIO_BT_PWR_EN 3
2423 +#define GPIO_N_BT_RST 9
2424 +
2425 +#define GPIO_I2C_GPRS_RESET 16
2426 +#define GPIO_I2C_MIC_OP_EN 10
2427 +#define GPIO_I2C_SPK_OP_PD 11
2428 +
2429 +#define GPIO_VALUE_OFF 0
2430 +#define GPIO_VALUE_ON  1
2431 +
2432 +#define GPIO_DIR_OUTPUT 1
2433 +
2434 +struct h6300_uart_funcs {
2435 +       void (*configure)( struct uart_omap_port *up, int state);
2436 +       void (*set_txrx)( struct uart_omap_port *up, int txrx);
2437 +       int (*get_txrx)( struct uart_omap_port *up);
2438 +};
2439 +
2440 +#endif
2441 diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/hardware.h h6300_dev/include/asm-arm/arch-omap/hardware.h
2442 --- linux-2.6.16.16/include/asm-arm/arch-omap/hardware.h        2006-05-17 21:41:31.000000000 +0300
2443 +++ h6300_dev/include/asm-arm/arch-omap/hardware.h      2006-02-06 15:36:21.000000000 +0200
2444 @@ -290,6 +290,10 @@
2445  #include "board-innovator.h"
2446  #endif
2447  
2448 +#ifdef CONFIG_MACH_OMAP_H6300
2449 +#include "board-h6300.h"
2450 +#endif
2451 +
2452  #ifdef CONFIG_MACH_OMAP_H2
2453  #include "board-h2.h"
2454  #endif
2455 diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/mux.h h6300_dev/include/asm-arm/arch-omap/mux.h
2456 --- linux-2.6.16.16/include/asm-arm/arch-omap/mux.h     2006-05-17 21:41:31.000000000 +0300
2457 +++ h6300_dev/include/asm-arm/arch-omap/mux.h   2006-05-18 00:38:24.000000000 +0300
2458 @@ -320,6 +320,13 @@
2459         P15_1610_UWIRE_CS3,
2460         N15_1610_UWIRE_CS1,
2461  
2462 +       /* OMAP-1510 uWire */
2463 +       P15_1510_UWIRE_CS3,
2464 +       N14_1510_UWIRE_CS0,
2465 +       V19_1510_UWIRE_SCLK,
2466 +       W21_1510_UWIRE_SDO,
2467 +       U18_1510_UWIRE_SDI,
2468 +
2469         /* OMAP-1610 Flash */
2470         L3_1610_FLASH_CS2B_OE,
2471         M8_1610_FLASH_CS2B_WE,
2472 @@ -384,6 +391,7 @@
2473         T20_1610_LOW_PWR,
2474  
2475         /* MCLK Settings */
2476 +       R10_1510_MCLK_ON,
2477         V5_1710_MCLK_ON,
2478         V5_1710_MCLK_OFF,
2479         R10_1610_MCLK_ON,
2480 diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/omap-alsa.h h6300_dev/include/asm-arm/arch-omap/omap-alsa.h
2481 --- linux-2.6.16.16/include/asm-arm/arch-omap/omap-alsa.h       2006-05-17 21:41:31.000000000 +0300
2482 +++ h6300_dev/include/asm-arm/arch-omap/omap-alsa.h     2006-03-08 13:28:16.000000000 +0200
2483 @@ -1,6 +1,6 @@
2484  /*
2485   * linux/include/asm-arm/arch-omap/omap-alsa.h
2486 - *
2487 + * 
2488   * Alsa Driver for AIC23 and TSC2101 codecs on OMAP platform boards.
2489   *
2490   * Copyright (C) 2006 Mika Laitio <lamikr@cc.jyu.fi>
2491 diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/omap_serial.h h6300_dev/include/asm-arm/arch-omap/omap_serial.h
2492 --- linux-2.6.16.16/include/asm-arm/arch-omap/omap_serial.h     1970-01-01 02:00:00.000000000 +0200
2493 +++ h6300_dev/include/asm-arm/arch-omap/omap_serial.h   2005-10-04 00:58:34.000000000 +0300
2494 @@ -0,0 +1,62 @@
2495 +/*
2496 + * Omap/h6300 serial driver private interface. 
2497 + * Code originates from the pxa-serial.h available in the handheld org drivers
2498 + * for iPAQ PXA4700.
2499 + *
2500 + * Copyright (c) 2005 SDG Systems, LLC
2501 + * 2005-03-29   Todd Blumer     Converted  basic structure to support hx4700
2502 + * 2005-10-03   Mika Laitio (lamikr@cc.jyu.fi) Reorganized for the iPAQ h6300 bt driver.
2503 + */
2504
2505 +#ifndef _OMAP_SERIAL_H
2506 +#define _OMAP_SERIAL_H
2507 +
2508 +#define OMAP_SERIAL_TX 1
2509 +#define OMAP_SERIAL_RX 2
2510 +
2511 +#include <linux/tty.h>
2512 +#include <linux/serial_core.h>
2513 +
2514 +struct platform_omap_serial_funcs;
2515 +
2516 +struct uart_omap_port {
2517 +       struct uart_port                        port;
2518 +       unsigned char                           ier;
2519 +       unsigned char                           lcr;
2520 +       unsigned char                           mcr;
2521 +       unsigned int                            lsr_break_flag;
2522 +       unsigned int                            cken;
2523 +       char                                    *name;
2524 +       struct platform_omap_serial_funcs       *pf;
2525 +};
2526 +
2527 +/* A pointer to such a structure can be contained in the platform_data
2528 + * field of every PXA UART platform_device. If the field is NULL, the
2529 + * serial port works as usual.
2530 + *
2531 + * For the sake of simplicity/performance no one of the function pointers
2532 + * in the structure below can be NULL.
2533 + */
2534 +struct platform_omap_serial_funcs {
2535 +       /* Platform-specific function to initialize whatever is connected
2536 +         to this serial port... enable=1 -> enable transceiver,
2537 +         0 -> disable transceiver. */
2538 +       void (*configure) (struct uart_omap_port *up, int enable);
2539 +        /* Platform-specific function to enable or disable the individual
2540 +           transmitter/receiver submodules. On transceivers without echo
2541 +           cancellation (e.g. SIR) transmitter always has priority, e.g.
2542 +           if both bits are set, only the transmitter is enabled. */
2543 +        void (*set_txrx) (struct uart_omap_port *up, int txrx);
2544 +       /* Get the current state of tx/rx (see bitflags above) */
2545 +       int (*get_txrx) (struct uart_omap_port *up);
2546 +};
2547 +
2548 +/*
2549 + * The variables below are located in arch/arm/mach-omap/board_h6300.c
2550 + * Machine-specific code may want to put a pointer to a static
2551 + * platform_pxa_serial_funcs structure in the dev.platform_data
2552 + * field of the respective port device.
2553 + */
2554 +extern struct platform_device btuart_device;
2555 +
2556 +#endif
2557 diff -Naur linux-2.6.16.16/include/asm-arm/arch-omap/pca9535.h h6300_dev/include/asm-arm/arch-omap/pca9535.h
2558 --- linux-2.6.16.16/include/asm-arm/arch-omap/pca9535.h 1970-01-01 02:00:00.000000000 +0200
2559 +++ h6300_dev/include/asm-arm/arch-omap/pca9535.h       2005-10-25 03:24:45.000000000 +0300
2560 @@ -0,0 +1,39 @@
2561 +#ifndef _PCA9535_H
2562 +#define _PCA9535_H
2563 +
2564 +enum  pca9535_gpios {
2565 +       GPIO0 = 0,
2566 +       GPIO1 = 1,
2567 +       GPIO2 = 2,
2568 +       GPIO3 = 3,
2569 +       GPIO4 = 4,
2570 +       GPIO5 = 5,
2571 +       GPIO6 = 6,
2572 +       GPIO7 = 7,
2573 +       GPIO8 = 8,
2574 +       GPIO9 = 9,
2575 +       GPIO10 = 10,
2576 +       GPIO11 = 11,
2577 +       GPIO12 = 12,
2578 +       GPIO13 = 13,
2579 +       GPIO14 = 14,
2580 +       GPIO15 = 15,
2581 +       GPIO16 = 16,
2582 +       GPIO17 = 17
2583 +};
2584 +
2585 +enum gpio_values {
2586 +       HI      = 0,
2587 +       LOW     = 1
2588 +};
2589 +
2590 +enum gpio_direction {
2591 +       GPIO_INPUT      = 0,
2592 +       GPIO_OUTPUT     = 1
2593 +};
2594 +
2595 +extern int pca9535_gpio_read(int gpio);
2596 +extern int pca9535_gpio_write(int gpio, unsigned char val);    
2597 +extern int pca9535_gpio_direction(int gpio, unsigned char direction);
2598 +
2599 +#endif
2600 diff -Naur linux-2.6.16.16/Makefile h6300_dev/Makefile
2601 --- linux-2.6.16.16/Makefile    2006-05-17 21:41:27.000000000 +0300
2602 +++ h6300_dev/Makefile  2006-05-18 01:45:17.000000000 +0300
2603 @@ -11,7 +11,7 @@
2604  # expect to learn how to build the kernel reading this file.
2605  
2606  # Add custom flags here to avoid conflict with updates
2607 -EXTRAVERSION := $(EXTRAVERSION)-omap2
2608 +EXTRAVERSION := $(EXTRAVERSION)-omap1-h6300
2609  
2610  # Do not print "Entering directory ..."
2611  MAKEFLAGS += --no-print-directory
2612 diff -Naur linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101.c h6300_dev/sound/arm/omap/omap-alsa-tsc2101.c
2613 --- linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101.c  2006-05-17 21:41:31.000000000 +0300
2614 +++ h6300_dev/sound/arm/omap/omap-alsa-tsc2101.c        2006-03-30 23:15:31.000000000 +0300
2615 @@ -96,7 +96,11 @@
2616  static snd_pcm_hardware_t tsc2101_snd_omap_alsa_playback = {
2617         .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
2618                  SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),      
2619 -       .formats = (SNDRV_PCM_FMTBIT_S16_LE),
2620 +#ifdef CONFIG_MACH_OMAP_H6300
2621 +       .formats = (SNDRV_PCM_FMTBIT_S8),
2622 +#else
2623 +       .formats = (SNDRV_PCM_FMTBIT_S16_LE),
2624 +#endif
2625         .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |
2626                   SNDRV_PCM_RATE_16000 |
2627                   SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
2628 @@ -136,7 +140,7 @@
2629  };
2630  
2631  /* 
2632 - * Simplified write for tsc Audio
2633 + * Simplified write for tsc2101 audio registers.
2634   */
2635  inline void tsc2101_audio_write(u8 address, u16 data)
2636  {
2637 @@ -144,7 +148,7 @@
2638  }
2639  
2640  /* 
2641 - * Simplified read for tsc  Audio
2642 + * Simplified read for tsc2101 audio registers.
2643   */
2644  inline u16 tsc2101_audio_read(u8 address)
2645  {
2646 @@ -246,14 +250,17 @@
2647  #endif                         /* #ifdef TSC_MASTER */
2648         tsc2101_audio_write(TSC2101_AUDIO_CTRL_3, data);
2649  
2650 -       /* program the PLLs */
2651 +       /* Program the PLLs. This code assumes that the 12 Mhz MCLK is in use.
2652 +         * If MCLK rate is something else, these values must be changed.
2653 +        * See the tsc2101 specification for the details.
2654 +        */
2655         if (rate_reg_info[count].fs_44kHz) {
2656 -               /* 44.1 khz - 12 MHz Mclk */
2657 +               /* samplerate = (44.1kHZ / x), where x is int. */
2658                 tsc2101_audio_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL |
2659                                 PLL1_PVAL(1) | PLL1_I_VAL(7));  /* PVAL 1; I_VAL 7 */
2660                 tsc2101_audio_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x1490));    /* D_VAL 5264 */
2661         } else {
2662 -               /* 48 khz - 12 Mhz Mclk */
2663 +               /* samplerate = (48.kHZ / x), where x is int. */
2664                 tsc2101_audio_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL |
2665                                PLL1_PVAL(1) | PLL1_I_VAL(8));   /* PVAL 1; I_VAL 8 */
2666                 tsc2101_audio_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x780));     /* D_VAL 1920 */
2667 @@ -317,21 +324,14 @@
2668                        CODEC_CLOCK);
2669         }
2670         curRate = (uint)clk_get_rate(tsc2101_mclk);
2671 -       DPRINTK("old clock rate = %d\n", curRate);
2672         if (curRate != CODEC_CLOCK) {
2673                 err     = clk_set_rate(tsc2101_mclk, CODEC_CLOCK);
2674                 if (err) {
2675                         printk(KERN_WARNING
2676                                "Cannot set MCLK clock rate for TSC2101 CODEC, error code = %d\n", err);
2677 -                       //return -ECANCELED;
2678 +                       return -ECANCELED;
2679                 }
2680         }
2681 -       else
2682 -       {
2683 -               printk(KERN_INFO
2684 -                      "omap_alsa_tsc2101_clock_on(), no need to change rate, no need to change clock rate, rate already %d Hz.\n",
2685 -                      CODEC_CLOCK);
2686 -       }
2687         err             = clk_enable(tsc2101_mclk);
2688         curRate         = (uint)clk_get_rate(tsc2101_mclk);
2689         curUseCount     = clk_get_usecount(tsc2101_mclk);
2690 @@ -349,8 +349,7 @@
2691  }
2692  
2693  /*
2694 - * Do some sanity check, turn clock off and then turn
2695 - *  codec audio off
2696 + * Do some sanity check, turn clock off and then turn codec audio off
2697   */
2698  int tsc2101_clock_off(void) 
2699  {
2700 @@ -374,10 +373,6 @@
2701         tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
2702                             ~(CPC_SP1PWDN | CPC_SP2PWDN | CPC_BASSBC));
2703         DPRINTK("audio codec off\n");
2704 -#ifdef DUMP_TSC2101_AUDIO_REGISTERS
2705 -       printk("tsc2101_clock_off()\n");
2706 -       dump_tsc2101_audio_reg();
2707 -#endif 
2708         return 0;       
2709  }
2710  
2711 @@ -420,18 +415,22 @@
2712  };
2713  
2714  static int __init omap_alsa_tsc2101_init(void)
2715 -{
2716 -       int err;
2717 -       
2718 +{      
2719         ADEBUG();
2720 -       err = platform_driver_register(&omap_alsa_driver);
2721 -
2722 -       return err;
2723 +#ifdef DUMP_TSC2101_AUDIO_REGISTERS
2724 +       printk("omap_alsa_tsc2101_init()\n");
2725 +       dump_tsc2101_audio_reg();
2726 +#endif
2727 +       return platform_driver_register(&omap_alsa_driver);
2728  }
2729  
2730  static void __exit omap_alsa_tsc2101_exit(void)
2731  {
2732         ADEBUG();
2733 +#ifdef DUMP_TSC2101_AUDIO_REGISTERS
2734 +       printk("omap_alsa_tsc2101_exit()\n");
2735 +       dump_tsc2101_audio_reg();
2736 +#endif
2737         platform_driver_unregister(&omap_alsa_driver);
2738  }
2739  
2740 diff -Naur linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101-mixer.c h6300_dev/sound/arm/omap/omap-alsa-tsc2101-mixer.c
2741 --- linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101-mixer.c    2006-05-17 21:41:31.000000000 +0300
2742 +++ h6300_dev/sound/arm/omap/omap-alsa-tsc2101-mixer.c  2006-05-10 02:42:13.000000000 +0300
2743 @@ -50,47 +50,53 @@
2744  //#define M_DPRINTK(ARGS...)  printk(KERN_INFO "<%s>: ",__FUNCTION__);printk(ARGS)
2745  #define M_DPRINTK(ARGS...)             /* nop */
2746  
2747 +#define CHECK_BIT(INDX, ARG) (((ARG) & TSC2101_BIT(INDX)) >> INDX)
2748 +#define IS_UNMUTED(INDX, ARG) (((CHECK_BIT(INDX, ARG)) == 0))
2749 +
2750  #define DGC_DALVL_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
2751  #define DGC_DARVL_EXTRACT(ARG) ((ARG & 0x007f))
2752 -#define GET_DGC_DALMU_BIT_VALUE(ARG)  (((ARG) & TSC2101_BIT(15)) >> 15)
2753 -#define GET_DGC_DARMU_BIT_VALUE(ARG)  (((ARG) & TSC2101_BIT(7)) >> 7)
2754 -#define IS_DGC_DALMU_UNMUTED(ARG)  (((GET_DGC_DALMU_BIT_VALUE(ARG)) == 0))
2755 -#define IS_DGC_DARMU_UNMUTED(ARG) (((GET_DGC_DARMU_BIT_VALUE(ARG)) == 0))
2756  
2757  #define HGC_ADPGA_HED_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
2758 -#define GET_DGC_HGCMU_BIT_VALUE(ARG) (((ARG) & TSC2101_BIT(15)) >> 15)
2759 -#define IS_DGC_HGCMU_UNMUTED(ARG) (((GET_DGC_HGCMU_BIT_VALUE(ARG)) == 0))
2760 -
2761  #define HNGC_ADPGA_HND_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
2762 -#define GET_DGC_HNGCMU_BIT_VALUE(ARG) (((ARG) & TSC2101_BIT(15)) >> 15)
2763 -#define IS_DGC_HNGCMU_UNMUTED(ARG) (((GET_DGC_HNGCMU_BIT_VALUE(ARG)) == 0))
2764 +#define BGC_ADPGA_BGC_EXTRACT(ARG) ((ARG & 0x7f00) >> 8)
2765  
2766  static int current_playback_target     = PLAYBACK_TARGET_LOUDSPEAKER;
2767  static int current_rec_src             = REC_SRC_SINGLE_ENDED_MICIN_HED;
2768  
2769 +/* 
2770 + * Simplified write for the tsc2101 audio registers.
2771 + */
2772 +inline void omap_tsc2101_audio_write(u8 address, u16 data)
2773 +{
2774 +       omap_tsc2101_write(PAGE2_AUDIO_CODEC_REGISTERS, address, data);
2775 +}
2776 +
2777 +/* 
2778 + * Simplified read for the tsc2101 audio registers.
2779 + */
2780 +inline u16 omap_tsc2101_audio_read(u8 address)
2781 +{
2782 +       return (omap_tsc2101_read(PAGE2_AUDIO_CODEC_REGISTERS, address));
2783 +}
2784 +
2785  /*
2786 - * Used for switching between TSC2101 recourd sources.
2787 - * Logic is adjusted from the TSC2101 OSS code.
2788 + * For selecting tsc2101 recourd source.
2789   */
2790 -static int set_record_source(int val)
2791 +static void set_record_source(int val)
2792  {
2793         u16     data;
2794 -       int     maskedVal;
2795         
2796 -       FN_IN;
2797 -       maskedVal       = 0xe0 & val;   
2798 -
2799 -       data    = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
2800 -                               TSC2101_MIXER_PGA_CTRL);
2801 +       /* Mute Analog Sidetone
2802 +        * Analog sidetone gain db?
2803 +        * Input selected by MICSEL connected to ADC
2804 +        */
2805 +       data    = MPC_ASTMU | MPC_ASTG(0x45);
2806         data    &= ~MPC_MICSEL(7); /* clear all MICSEL bits */
2807 -       data    |= maskedVal;
2808 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
2809 -                               TSC2101_MIXER_PGA_CTRL,
2810 -                               data);
2811 +       data    |= MPC_MICSEL(val);
2812 +       data    |= MPC_MICADC;
2813 +       omap_tsc2101_audio_write(TSC2101_MIXER_PGA_CTRL, data);
2814 +       
2815         current_rec_src = val;
2816 -
2817 -       FN_OUT(0);
2818 -       return 0;
2819  }
2820  
2821  /*
2822 @@ -147,32 +153,34 @@
2823         volL    = get_mixer_volume_as_dac_gain_control_volume(mixerVolL);
2824         volR    = get_mixer_volume_as_dac_gain_control_volume(mixerVolR);
2825         
2826 -       val     = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL);
2827 +       val     = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
2828         /* keep the old mute bit settings */
2829         val     &= ~(DGC_DALVL(OUTPUT_VOLUME_MIN) | DGC_DARVL(OUTPUT_VOLUME_MIN));
2830         val     |= DGC_DALVL(volL) | DGC_DARVL(volR);
2831         retVal  = 2;
2832         if (retVal) {
2833 -               omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
2834 -                               TSC2101_DAC_GAIN_CTRL, 
2835 -                               val);
2836 +               omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val);
2837         }
2838         M_DPRINTK("to registry: left = %d, right = %d, total = %d\n", DGC_DALVL_EXTRACT(val), DGC_DARVL_EXTRACT(val), val);
2839         return retVal;
2840  }
2841  
2842 -int dac_gain_control_unmute_control(int muteLeft, int muteRight)
2843 +/**
2844 + * If unmuteLeft/unmuteRight == 0  --> mute
2845 + * If unmuteLeft/unmuteRight == 1 --> unmute
2846 + */
2847 +int dac_gain_control_unmute(int unmuteLeft, int unmuteRight)
2848  {
2849         u16 val;
2850         int count;
2851  
2852         count   = 0;
2853 -       val     = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL);
2854 +       val     = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
2855         /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on
2856          * so if values are same, it's time to change the registry value.
2857          */
2858 -       if (muteLeft == GET_DGC_DALMU_BIT_VALUE(val)) {
2859 -               if (muteLeft == 0) {
2860 +       if (unmuteLeft != IS_UNMUTED(15, val)) {
2861 +               if (unmuteLeft == 0) {
2862                         /* mute --> turn bit on */
2863                         val     = val | DGC_DALMU;
2864                 }
2865 @@ -182,8 +190,8 @@
2866                 }
2867                 count++;
2868         } /* L */
2869 -       if (muteRight == GET_DGC_DARMU_BIT_VALUE(val)) {
2870 -               if (muteRight == 0) {
2871 +       if (unmuteRight != IS_UNMUTED(7, val)) {
2872 +               if (unmuteRight == 0) {
2873                         /* mute --> turn bit on */
2874                         val     = val | DGC_DARMU;
2875                 }
2876 @@ -194,14 +202,47 @@
2877                 count++;
2878         } /* R */
2879         if (count) {
2880 -               omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL, val);
2881 +               omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val);
2882                 M_DPRINTK("changed value, is_unmuted left = %d, right = %d\n", 
2883 -                       IS_DGC_DALMU_UNMUTED(val),
2884 -                       IS_DGC_DARMU_UNMUTED(val));
2885 +                       IS_UNMUTED(15, val),
2886 +                       IS_UNMUTED(7, val));
2887         }
2888         return count;   
2889  }
2890  
2891 +/**
2892 + * unmute: 0 --> mute, 1 --> unmute
2893 + * page2RegIndx: Registry index in tsc2101 page2.
2894 + * muteBitIndx: Index number for the bit in registry that indicates whether muted or unmuted.
2895 + */
2896 +int adc_pga_unmute_control(int unmute, int page2regIndx, int muteBitIndx)
2897 +{
2898 +       int count;
2899 +       u16 val;
2900 +       
2901 +       count   = 0;
2902 +       val     = omap_tsc2101_audio_read(page2regIndx);
2903 +       /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on
2904 +        * so if the values are same, it's time to change the registry value...
2905 +        */
2906 +       if (unmute != IS_UNMUTED(muteBitIndx, val)) {
2907 +               if (unmute == 0) {
2908 +                       /* mute --> turn bit on */
2909 +                       val     = val | TSC2101_BIT(muteBitIndx);
2910 +               }
2911 +               else {
2912 +                       /* unmute --> turn bit off */
2913 +                       val     = val & ~TSC2101_BIT(muteBitIndx);
2914 +               }
2915 +               M_DPRINTK("changed value, is_unmuted = %d\n", IS_UNMUTED(muteBitIndx, val));
2916 +               count++;
2917 +       }
2918 +       if (count) {
2919 +               omap_tsc2101_audio_write(page2regIndx, val);
2920 +       }
2921 +       return count;
2922 +}
2923 +
2924  /*
2925   * Converts the DGC registry value read from the TSC2101 registry to 
2926   * Alsa mixer volume format (0 - 100).
2927 @@ -271,14 +312,11 @@
2928         /* Convert 0 -> 100 volume to 0x0(min) -> 0x7D(max) volume range */
2929         /* NOTE: 0 is minimum volume and not mute */
2930         volume  = get_mixer_volume_as_headset_gain_control_volume(mixerVol);    
2931 -       val     = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
2932 -                               TSC2101_HEADSET_GAIN_CTRL);
2933 +       val     = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL);
2934         /* preserve the old mute settings */
2935         val     &= ~(HGC_ADPGA_HED(INPUT_VOLUME_MAX));
2936         val     |= HGC_ADPGA_HED(volume);
2937 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
2938 -                       TSC2101_HEADSET_GAIN_CTRL,
2939 -                       val);   
2940 +       omap_tsc2101_audio_write(TSC2101_HEADSET_GAIN_CTRL, val);       
2941         retVal  = 1;
2942         
2943         M_DPRINTK("to registry = %d\n", val);   
2944 @@ -305,71 +343,37 @@
2945          * NOTE: 0 is minimum volume and not mute 
2946          */
2947         volume  = get_mixer_volume_as_headset_gain_control_volume(mixerVol);
2948 -       val     = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_HANDSET_GAIN_CTRL);
2949 +       val     = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
2950         /* preserve the old mute settigns */
2951         val     &= ~(HNGC_ADPGA_HND(INPUT_VOLUME_MAX));
2952         val     |= HNGC_ADPGA_HND(volume);
2953 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
2954 -                       TSC2101_HANDSET_GAIN_CTRL,
2955 -                       val);
2956 +       omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val);
2957         retVal  = 1;
2958         
2959         M_DPRINTK("to registry = %d\n", val);   
2960         return retVal;
2961  }
2962  
2963 -void init_record_sources(void)
2964 -{
2965 -       /* Mute Analog Sidetone
2966 -        * analog sidetone gain db?
2967 -        * Cell Phone In not connected to ADC
2968 -        * Input selected by MICSEL connected to ADC
2969 -        */
2970 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
2971 -                         TSC2101_MIXER_PGA_CTRL,
2972 -                         MPC_ASTMU | MPC_ASTG(0x40) | ~MPC_CPADC | MPC_MICADC);
2973 -       /* Set record source, Select MIC_INHED input for headset */
2974 -       set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HED);      
2975 -}
2976 -
2977  void set_loudspeaker_to_playback_target(void)
2978  {
2979 -       u16     val;
2980 -
2981 -       /* power down sp1, sp2 and loudspeaker */
2982 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
2983 -                       TSC2101_CODEC_POWER_CTRL,
2984 +       /* power down SPK1, SPK2 and loudspeaker */
2985 +       omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
2986                         CPC_SP1PWDN | CPC_SP2PWDN | CPC_LDAPWDF);       
2987         /* ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled
2988          * 1dB AGC hysteresis
2989          * MICes bias 2V
2990          */
2991 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
2992 -                       TSC2101_AUDIO_CTRL_4, 
2993 -                       AC4_MB_HED(0));
2994 +       omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0));
2995  
2996         /* DAC left and right routed to SPK1/SPK2
2997          * SPK1/SPK2 unmuted
2998 -        * keyclicks routed to SPK1/SPK2
2999 -        */
3000 -       val     = AC5_DIFFIN |
3001 +        * Keyclicks routed to SPK1/SPK2 */
3002 +       omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5, 
3003 +                       AC5_DIFFIN |
3004                         AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 |
3005 -                       AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 |
3006 -                       AC5_HDSCPTC;
3007 -       val     = val & ~AC5_HDSCPTC;
3008 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
3009 -                       TSC2101_AUDIO_CTRL_5,
3010 -                       val);
3011 -       
3012 -       /* powerdown spk1/out32n and spk2 */
3013 -       val     = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
3014 -                               TSC2101_POWERDOWN_STS);
3015 -       val     = val & ~(~PS_SPK1FL | ~PS_HNDFL | PS_LSPKFL);
3016 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
3017 -                       TSC2101_POWERDOWN_STS,
3018 -                       val);
3019 -
3020 -       /* routing selected to SPK1 goes to OUT8P/OUT84 alsa. (loudspeaker)
3021 +                       AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2);
3022 +       
3023 +       /* routing selected to SPK1 goes also to OUT8P/OUT8N. (loudspeaker)
3024          * analog sidetone routed to loudspeaker
3025          * buzzer pga routed to loudspeaker
3026          * keyclick routing to loudspeaker
3027 @@ -381,43 +385,242 @@
3028          * Enable loudspeaker short protection control (0 = enable protection)
3029          * VGND short protection control (0 = enable protection)
3030          */
3031 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
3032 -                       TSC2101_AUDIO_CTRL_6,
3033 +       omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6,
3034                         AC6_SPL2LSK | AC6_AST2LSK | AC6_BUZ2LSK | AC6_KCL2LSK |
3035 -                       AC6_CPI2LSK | AC6_MIC2CPO | AC6_SPL2CPO |
3036 -                       ~AC6_MUTLSPK | ~AC6_MUTSPK2 | ~AC6_LDSCPTC | ~AC6_VGNDSCPTC);
3037 +                       AC6_CPI2LSK | AC6_MIC2CPO | AC6_SPL2CPO);
3038         current_playback_target = PLAYBACK_TARGET_LOUDSPEAKER;
3039  }
3040  
3041  void set_headphone_to_playback_target(void)
3042  {
3043 -       /* power down sp1, sp2 and loudspeaker */
3044 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
3045 -                       TSC2101_CODEC_POWER_CTRL,
3046 +       /* power down SPK1, SPK2 and loudspeaker */
3047 +       omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
3048                         CPC_SP1PWDN | CPC_SP2PWDN | CPC_LDAPWDF);
3049         /* ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled */
3050         /* 1dB AGC hysteresis */
3051         /* MICes bias 2V */
3052 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
3053 -                               TSC2101_AUDIO_CTRL_4, 
3054 -                               AC4_MB_HED(0));
3055 -
3056 -       /* DAC left and right routed to SPK2 */
3057 -       /* SPK1/2 unmuted */
3058 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
3059 -                       TSC2101_AUDIO_CTRL_5,
3060 +       omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, AC4_MB_HED(0));
3061 +                               
3062 +       /* DAC left and right routed to SPK1/SPK2
3063 +        * SPK1/SPK2 unmuted
3064 +        * Keyclicks routed to SPK1/SPK2 */
3065 +       omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5,
3066                         AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 |
3067                         AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 |
3068                         AC5_HDSCPTC);
3069 -
3070 -       /* OUT8P/N muted, CPOUT muted */
3071 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
3072 -                       TSC2101_AUDIO_CTRL_6,
3073 +                       
3074 +       /* OUT8P/OUT8N muted, CPOUT muted */
3075 +       omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6,
3076                         AC6_MUTLSPK | AC6_MUTSPK2 | AC6_LDSCPTC |
3077                         AC6_VGNDSCPTC);
3078         current_playback_target = PLAYBACK_TARGET_HEADPHONE;
3079  }
3080  
3081 +void set_telephone_to_playback_target(void)
3082 +{
3083 +       /* 
3084 +        * 0110 1101 0101 1100
3085 +        * power down MICBIAS_HED, Analog sidetone, SPK2, DAC, 
3086 +        * Driver virtual ground, loudspeaker. Values D2-d5 are flags.
3087 +        */      
3088 +       omap_tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL,
3089 +                       CPC_MBIAS_HED | CPC_ASTPWD | CPC_SP2PWDN | CPC_DAPWDN |
3090 +                       CPC_VGPWDN | CPC_LSPWDN);
3091 +                       
3092 +       /* 
3093 +        * 0010 1010 0100 0000
3094 +        * ADC, DAC, Analog Sidetone, cellphone, buzzer softstepping enabled
3095 +        * 1dB AGC hysteresis
3096 +        * MICes bias 2V
3097 +        */
3098 +       omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4,
3099 +                       AC4_MB_HND | AC4_MB_HED(0) | AC4_AGCHYS(1) | 
3100 +                       AC4_BISTPD | AC4_ASSTPD | AC4_DASTPD);
3101 +       printk("set_telephone_to_playback_target(), TSC2101_AUDIO_CTRL_4 = %d\n", omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_4));
3102 +                       
3103 +       /* 
3104 +        * 1110 0010 0000 0010
3105 +        * DAC left and right routed to SPK1/SPK2
3106 +        * SPK1/SPK2 unmuted
3107 +        * keyclicks routed to SPK1/SPK2
3108 +        */      
3109 +       omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_5,
3110 +                       AC5_DIFFIN | AC5_DAC2SPK1(3) | 
3111 +                       AC5_CPI2SPK1 | AC5_MUTSPK2);
3112 +       
3113 +       omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_6,
3114 +                       AC6_MIC2CPO | AC6_MUTLSPK | 
3115 +                       AC6_LDSCPTC | AC6_VGNDSCPTC | AC6_CAPINTF);
3116 +       current_playback_target = PLAYBACK_TARGET_CELLPHONE;
3117 +}
3118 +
3119 +/*
3120 + * 1100 0101 1101 0000
3121 + * 
3122 + * #define MPC_ASTMU           TSC2101_BIT(15)
3123 + * #define MPC_ASTG(ARG)       (((ARG) & 0x7F) << 8)
3124 + * #define MPC_MICSEL(ARG)     (((ARG) & 0x07) << 5)
3125 + * #define MPC_MICADC          TSC2101_BIT(4)
3126 + * #define MPC_CPADC           TSC2101_BIT(3)
3127 + * #define MPC_ASTGF           (0x01)
3128 + */
3129 +static void set_telephone_to_record_source(void)
3130 +{
3131 +       u16     val;
3132 +       
3133 +       /* 
3134 +        * D0       = 0: 
3135 +        *              --> AGC is off for handset input.
3136 +        *              --> ADC PGA is controlled by the ADMUT_HDN + ADPGA_HND
3137 +        *          (D15, D14-D8)
3138 +        * D4 - D1  = 0000 
3139 +        *              --> AGC time constant for handset input, 
3140 +        *              attack time = 8 mc, decay time = 100 ms
3141 +        * D7 - D5  = 000
3142 +        *              --> AGC Target gain for handset input = -5.5 db
3143 +        * D14 - D8 = 011 1100
3144 +        *              --> ADC handset PGA settings = 60 = 30 db
3145 +        * D15          = 0
3146 +        *              --> Handset input ON (unmuted)
3147 +        */
3148 +       val     = 0x3c00;       // 0011 1100 0000 0000 = 60 = 30
3149 +       omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val);
3150 +       
3151 +       /*
3152 +        * D0           = 0
3153 +        *              --> AGC is off for headset/Aux input
3154 +        *              --> ADC headset/Aux PGA is contoller by ADMUT_HED + ADPGA_HED
3155 +        *          (D15, D14-D8)
3156 +        * D4 - D1      = 0000 
3157 +        *              --> Agc constant for headset/Aux input,
3158 +        *              attack time = 8 mc, decay time = 100 ms      
3159 +        * D7 - D5      = 000
3160 +        *              --> AGC target gain for headset input = -5.5 db
3161 +        * D14 - D8 = 000 0000
3162 +        *              --> Adc headset/AUX pga settings = 0 db
3163 +        * D15          = 1
3164 +        *              --> Headset/AUX input muted
3165 +        * 
3166 +        * Mute headset aux input
3167 +        */
3168 +       val     = 0x8000;       // 1000 0000 0000 0000
3169 +       omap_tsc2101_audio_write(TSC2101_HEADSET_GAIN_CTRL, val);
3170 +       set_record_source(REC_SRC_MICIN_HND_AND_AUX1);
3171 +
3172 +       // hacks start
3173 +       /* D0           = flag, Headset/Aux or handset PGA flag
3174 +        *              --> & with 1 (= 1 -->gain applied == pga register settings)
3175 +        * D1           = 0, DAC channel PGA soft stepping control
3176 +        *              --> 0.5 db change every WCLK
3177 +        * D2           = flag, DAC right channel PGA flag
3178 +        *              --> & with 1
3179 +        * D3           = flag, DAC left channel PGA flag
3180 +        *              -- > & with 1
3181 +        * D7 - D4      = 0001, keyclick length
3182 +        *              --> 4 periods key clicks
3183 +        * D10 - D8 = 100, keyclick frequenzy
3184 +        *              --> 1 kHz, 
3185 +        * D11          = 0, Headset/Aux or handset soft stepping control
3186 +        *              --> 0,5 db change every WCLK or ADWS
3187 +        * D14 -D12 = 100, Keyclick applitude control
3188 +        *              --> Medium amplitude
3189 +        * D15          = 0, keyclick disabled
3190 +        */
3191 +       val     = omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_2);
3192 +       val     = val & 0x441d;
3193 +       val     = val | 0x4410; // D14, D10, D4 bits == 1
3194 +       omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_2, val);
3195 +
3196 +       /*
3197 +        * D0           = 0     (reserved, write always 0)
3198 +        * D1           = flag,
3199 +        *                      --> & with 1
3200 +        * D2 - D5      = 0000 (reserved, write always 0000)
3201 +        * D6           = 1
3202 +        *                      --> MICBIAS_HND = 2.0 v
3203 +        * D8 - D7      = 00
3204 +        *                      --> MICBIAS_HED = 3.3 v
3205 +        * D10 - D9     = 01, 
3206 +        *                      --> Mic AGC hysteric selection = 2 db
3207 +        * D11          = 1, 
3208 +        *                      --> Disable buzzer PGA soft stepping
3209 +        * D12          = 0,
3210 +        *                      --> Enable CELL phone PGA soft stepping control
3211 +        * D13          = 1
3212 +        *                      --> Disable analog sidetone soft stepping control
3213 +        * D14          = 0
3214 +        *                      --> Enable DAC PGA soft stepping control
3215 +        * D15          = 0,
3216 +        *                      --> Enable headset/Aux or Handset soft stepping control
3217 +        */
3218 +       val     = omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_4);
3219 +       val     = val & 0x2a42; // 0010 1010 0100 0010
3220 +       val     = val | 0x2a40; // bits D13, D11, D9, D6 == 1
3221 +       omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_4, val);
3222 +       printk("set_telephone_to_record_source(), TSC2101_AUDIO_CTRL_4 = %d\n", omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_4));
3223 +       /*
3224 +        * D0           = 0
3225 +        *              --> reserved, write always = 0
3226 +        * D1           = flag, read only
3227 +        *              --> & with 1
3228 +        * D5 - D2      = 1111, Buzzer input PGA settings
3229 +        *              --> 0 db
3230 +        * D6           = 1,
3231 +        *              --> power down buzzer input pga
3232 +        * D7           = flag, read only
3233 +        *              --> & with 1
3234 +        * D14 - D8     = 101 1101
3235 +        *              --> 12 DB
3236 +        * D15          = 0
3237 +        *              --> power up cell phone input PGA
3238 +        */
3239 +       val     = omap_tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL);
3240 +       val     = val & 0x5dfe;
3241 +       val     = val | 0x5dfe; // bits, D14, D12, D11, D10, D8, D6, D5,D4,D3,D2
3242 +       omap_tsc2101_audio_write(TSC2101_BUZZER_GAIN_CTRL, val);
3243 +       
3244 +       /* D6 - D0      = 000 1001
3245 +        *              --> -4.5 db for DAC right channel volume control
3246 +        * D7           = 1
3247 +        *              -->  DAC right channel muted
3248 +        * D14 - D8 = 000 1001
3249 +        *              --> -4.5 db for DAC left channel volume control
3250 +        * D15          = 1
3251 +        *              --> DAC left channel muted
3252 +        */
3253 +       //val   = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
3254 +       val     = 0x8989;
3255 +       omap_tsc2101_audio_write(TSC2101_DAC_GAIN_CTRL, val);   
3256 +       
3257 +       /*  0000 0000 0100 0000
3258 +        * 
3259 +        * D1 - D0      = 0
3260 +        *              --> GPIO 1 pin output is three stated
3261 +        * D2           = 0
3262 +        *              --> Disaple GPIO2 for CLKOUT mode
3263 +        * D3           = 0
3264 +        *              --> Disable GPUI1 for interrupt detection
3265 +        * D4           = 0
3266 +        *              --> Disable GPIO2 for headset detection interrupt
3267 +        * D5           = reserved, always 0
3268 +        * D7 - D6      = 01
3269 +        *              --> 8 ms clitch detection
3270 +        * D8           = reserved, write only 0
3271 +        * D10 -D9      = 00
3272 +        *              --> 16 ms de bouncing programmatitily 
3273 +        *          for glitch detection during headset detection
3274 +        * D11          = flag for button press
3275 +        * D12          = flag for headset detection
3276 +        * D14-D13      = 00
3277 +        *              --> type of headset detected = 00 == no stereo headset deected
3278 +        * D15          = 0
3279 +        *              --> Disable headset detection
3280 +        * 
3281 +        * */
3282 +       val     = 0x40;
3283 +       omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_7, val);    
3284 +}
3285 +
3286  /*
3287   * Checks whether the headset is detected.
3288   * If headset is detected, the type is returned. Type can be
3289 @@ -433,8 +636,7 @@
3290         u16     curVal;
3291         
3292         curType = 0;    /* not detected */
3293 -       curVal  = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
3294 -                                       TSC2101_AUDIO_CTRL_7);
3295 +       curVal  = omap_tsc2101_audio_read(TSC2101_AUDIO_CTRL_7);
3296         curDetected     = curVal & AC7_HDDETFL;
3297         if (curDetected) {
3298                 printk("headset detected, checking type from %d \n", curVal);
3299 @@ -461,13 +663,10 @@
3300          * AGC enable for handset input
3301          * Handset input not muted
3302          */
3303 -       val     = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
3304 -                               TSC2101_HANDSET_GAIN_CTRL);
3305 +       val     = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
3306         val     = val | HNGC_AGCEN_HND; 
3307         val     = val & ~HNGC_ADMUT_HND;
3308 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
3309 -                       TSC2101_HANDSET_GAIN_CTRL,
3310 -                       val);   
3311 +       omap_tsc2101_audio_write(TSC2101_HANDSET_GAIN_CTRL, val);       
3312                         
3313         /* mic input volume control
3314          * SET_MIC in the OSS driver 
3315 @@ -479,7 +678,7 @@
3316          */
3317         set_mixer_volume_as_dac_gain_control_volume(DEFAULT_OUTPUT_VOLUME, DEFAULT_OUTPUT_VOLUME);      
3318         /* unmute */
3319 -       dac_gain_control_unmute_control(1, 1);
3320 +       dac_gain_control_unmute(1, 1);
3321  }
3322  
3323  /*
3324 @@ -490,11 +689,11 @@
3325         FN_IN;
3326         
3327         /* Headset/Hook switch detect enabled */
3328 -       omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2,
3329 -                       TSC2101_AUDIO_CTRL_7,
3330 -                       AC7_DETECT);
3331 +       omap_tsc2101_audio_write(TSC2101_AUDIO_CTRL_7, AC7_DETECT);
3332  
3333 -       init_record_sources();
3334 +       /* Select headset to record source (MIC_INHED)*/
3335 +       set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HED);
3336 +       /* Init loudspeaker as a default playback target*/
3337         init_playback_targets();
3338  
3339         FN_OUT(0);
3340 @@ -503,7 +702,7 @@
3341  static int __pcm_playback_target_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 
3342  {
3343         static char *texts[PLAYBACK_TARGET_COUNT] = {
3344 -               "Loudspeaker", "Headphone"
3345 +               "Loudspeaker", "Headphone", "Cellphone"
3346         };
3347  
3348         uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3349 @@ -533,12 +732,18 @@
3350         if ((curVal >= 0) &&
3351             (curVal < PLAYBACK_TARGET_COUNT) &&
3352             (curVal != current_playback_target)) {              
3353 -               if (curVal == 0) {
3354 -                       set_loudspeaker_to_playback_target();           
3355 +               if (curVal == PLAYBACK_TARGET_LOUDSPEAKER) {
3356 +                       set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HED);
3357 +                       set_loudspeaker_to_playback_target();
3358                 }
3359 -               else {
3360 +               else if (curVal == PLAYBACK_TARGET_HEADPHONE) {
3361 +                       set_record_source(REC_SRC_SINGLE_ENDED_MICIN_HND);
3362                         set_headphone_to_playback_target();
3363                 }
3364 +               else if (curVal == PLAYBACK_TARGET_CELLPHONE) {
3365 +                       set_telephone_to_record_source();
3366 +                       set_telephone_to_playback_target();
3367 +               }
3368                 retVal  = 1;
3369         }
3370         return retVal;
3371 @@ -563,7 +768,7 @@
3372         u16 volR;       
3373         u16 val;
3374         
3375 -       val     = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL);
3376 +       val     = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
3377         M_DPRINTK("registry value = %d!\n", val);
3378         volL    = DGC_DALVL_EXTRACT(val);
3379         volR    = DGC_DARVL_EXTRACT(val);
3380 @@ -603,16 +808,16 @@
3381   */
3382  static int __pcm_playback_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 
3383  {
3384 -       u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_DAC_GAIN_CTRL);
3385 +       u16 val = omap_tsc2101_audio_read(TSC2101_DAC_GAIN_CTRL);
3386         
3387 -       ucontrol->value.integer.value[0]        = IS_DGC_DALMU_UNMUTED(val);
3388 -       ucontrol->value.integer.value[1]        = IS_DGC_DARMU_UNMUTED(val);
3389 +       ucontrol->value.integer.value[0]        = IS_UNMUTED(15, val);  // left
3390 +       ucontrol->value.integer.value[1]        = IS_UNMUTED(7, val);   // right
3391         return 0;
3392  }
3393  
3394  static int __pcm_playback_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 
3395  {
3396 -       return dac_gain_control_unmute_control(ucontrol->value.integer.value[0], 
3397 +       return dac_gain_control_unmute(ucontrol->value.integer.value[0], 
3398                                         ucontrol->value.integer.value[1]);
3399  }
3400  
3401 @@ -630,8 +835,7 @@
3402         u16 val;
3403         u16 vol;
3404         
3405 -       val     = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
3406 -                               TSC2101_HEADSET_GAIN_CTRL);
3407 +       val     = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL);
3408         M_DPRINTK("registry value = %d\n", val);
3409         vol     = HGC_ADPGA_HED_EXTRACT(val);
3410         vol     = vol & ~HGC_ADMUT_HED;
3411 @@ -662,38 +866,17 @@
3412   */
3413  static int __headset_playback_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 
3414  {
3415 -       u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
3416 -                               TSC2101_HEADSET_GAIN_CTRL);
3417 -       ucontrol->value.integer.value[0]        = IS_DGC_HGCMU_UNMUTED(val);
3418 +       u16 val = omap_tsc2101_audio_read(TSC2101_HEADSET_GAIN_CTRL);
3419 +       ucontrol->value.integer.value[0]        = IS_UNMUTED(15, val);
3420         return 0;
3421  }
3422  
3423  static int __headset_playback_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 
3424  {
3425 -       int count = 0;
3426 -       u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
3427 -                               TSC2101_HEADSET_GAIN_CTRL);
3428 -       /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on
3429 -        * so if values are same, it's time to change the registry value...
3430 -        */
3431 -       if (ucontrol->value.integer.value[0] == GET_DGC_HGCMU_BIT_VALUE(val)) {
3432 -               if (ucontrol->value.integer.value[0] == 0) {
3433 -                       /* mute --> turn bit on */
3434 -                       val     = val | HGC_ADMUT_HED;
3435 -               }
3436 -               else {
3437 -                       /* unmute --> turn bit off */
3438 -                       val     = val & ~HGC_ADMUT_HED;
3439 -               }
3440 -               count++;
3441 -               M_DPRINTK("changed value, is_unmuted = %d\n", IS_DGC_HGCMU_UNMUTED(val));
3442 -       }
3443 -       if (count) {
3444 -               omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
3445 -                               TSC2101_HEADSET_GAIN_CTRL, 
3446 -                               val);
3447 -       }
3448 -       return count;
3449 +       // mute/unmute headset
3450 +       return adc_pga_unmute_control(ucontrol->value.integer.value[0],
3451 +                               TSC2101_HEADSET_GAIN_CTRL,
3452 +                               15);
3453  }
3454  
3455  static int __handset_playback_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 
3456 @@ -710,7 +893,7 @@
3457         u16 val;
3458         u16 vol;
3459         
3460 -       val     = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_HANDSET_GAIN_CTRL);
3461 +       val     = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
3462         M_DPRINTK("registry value = %d\n", val);
3463         vol     = HNGC_ADPGA_HND_EXTRACT(val);
3464         vol     = vol & ~HNGC_ADMUT_HND;
3465 @@ -740,42 +923,74 @@
3466   */
3467  static int __handset_playback_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 
3468  {
3469 -       u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_HANDSET_GAIN_CTRL);
3470 -       ucontrol->value.integer.value[0]        = IS_DGC_HNGCMU_UNMUTED(val);
3471 +       u16 val = omap_tsc2101_audio_read(TSC2101_HANDSET_GAIN_CTRL);
3472 +       ucontrol->value.integer.value[0]        = IS_UNMUTED(15, val);
3473         return 0;
3474  }
3475  
3476  static int __handset_playback_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 
3477  {
3478 -       int count = 0;
3479 -       u16 val = omap_tsc2101_read(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, TSC2101_HANDSET_GAIN_CTRL);
3480 -       
3481 -       /* in alsa mixer 1 --> on, 0 == off. In tsc2101 registry 1 --> off, 0 --> on
3482 -        * so if values are same, it's time to change the registry value...
3483 -        */
3484 -       if (ucontrol->value.integer.value[0] == GET_DGC_HNGCMU_BIT_VALUE(val)) {
3485 -               if (ucontrol->value.integer.value[0] == 0) {
3486 -                       /* mute --> turn bit on */
3487 -                       val     = val | HNGC_ADMUT_HND;
3488 -               }
3489 -               else {
3490 -                       /* unmute --> turn bit off */
3491 -                       val     = val & ~HNGC_ADMUT_HND;
3492 -               }
3493 -               M_DPRINTK("changed value, is_unmuted = %d\n", IS_DGC_HNGCMU_UNMUTED(val));
3494 -               count++;
3495 -       }
3496 -       if (count) {
3497 -               omap_tsc2101_write(TSC2101_AUDIO_CODEC_REGISTERS_PAGE2, 
3498 -                               TSC2101_HANDSET_GAIN_CTRL, 
3499 -                               val);
3500 -       }
3501 -       return count;
3502 +       // handset mute/unmute
3503 +       return adc_pga_unmute_control(ucontrol->value.integer.value[0],
3504 +                               TSC2101_HANDSET_GAIN_CTRL,
3505 +                               15);
3506 +}
3507 +
3508 +static int __cellphone_input_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 
3509 +{
3510 +       uinfo->type                     = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
3511 +       uinfo->count                    = 1;
3512 +       uinfo->value.integer.min        = 0;
3513 +       uinfo->value.integer.max        = 1;
3514 +       return 0;
3515 +}
3516 +
3517 +/* When BGC_MUT_CP (bit 15) = 1, power down cellphone input pga.
3518 + * When BGC_MUT_CP = 0, power up cellphone input pga.
3519 + */
3520 +static int __cellphone_input_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 
3521 +{
3522 +       u16 val = omap_tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL);
3523 +       ucontrol->value.integer.value[0]        = IS_UNMUTED(15, val);
3524 +       return 0;
3525 +}
3526 +
3527 +static int __cellphone_input_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 
3528 +{
3529 +       return adc_pga_unmute_control(ucontrol->value.integer.value[0],
3530 +                               TSC2101_BUZZER_GAIN_CTRL,
3531 +                               15);    
3532 +}
3533 +
3534 +static int __buzzer_input_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo) 
3535 +{
3536 +       uinfo->type                     = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
3537 +       uinfo->count                    = 1;
3538 +       uinfo->value.integer.min        = 0;
3539 +       uinfo->value.integer.max        = 1;
3540 +       return 0;
3541 +}
3542 +
3543 +/* When BGC_MUT_BU (bit 6) = 1, power down cellphone input pga.
3544 + * When BGC_MUT_BU = 0, power up cellphone input pga.
3545 + */
3546 +static int __buzzer_input_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 
3547 +{
3548 +       u16 val = omap_tsc2101_audio_read(TSC2101_BUZZER_GAIN_CTRL);
3549 +       ucontrol->value.integer.value[0]        = IS_UNMUTED(6, val);
3550 +       return 0;
3551 +}
3552 +
3553 +static int __buzzer_input_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol) 
3554 +{
3555 +       return adc_pga_unmute_control(ucontrol->value.integer.value[0],
3556 +                               TSC2101_BUZZER_GAIN_CTRL,
3557 +                               6);     
3558  }
3559  
3560  static snd_kcontrol_new_t tsc2101_control[] __devinitdata = {
3561         {
3562 -               .name  = "Playback Playback Route",
3563 +               .name  = "Target Playback Route",
3564                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3565                 .index = 0,
3566                 .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
3567 @@ -801,7 +1016,7 @@
3568         }, {
3569                 .name  = "Headset Playback Volume",
3570                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3571 -               .index = 1,
3572 +               .index = 0,
3573                 .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
3574                 .info  = __headset_playback_volume_info,
3575                 .get   = __headset_playback_volume_get,
3576 @@ -809,7 +1024,7 @@
3577         }, {
3578                 .name  = "Headset Playback Switch",
3579                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3580 -               .index = 1,
3581 +               .index = 0,
3582                 .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
3583                 .info  = __headset_playback_switch_info,
3584                 .get   = __headset_playback_switch_get,
3585 @@ -817,7 +1032,7 @@
3586         }, {
3587                 .name  = "Handset Playback Volume",
3588                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3589 -               .index = 2,
3590 +               .index = 0,
3591                 .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
3592                 .info  = __handset_playback_volume_info,
3593                 .get   = __handset_playback_volume_get,
3594 @@ -825,12 +1040,28 @@
3595         }, {
3596                 .name  = "Handset Playback Switch",
3597                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3598 -               .index = 2,
3599 +               .index = 0,
3600                 .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
3601                 .info  = __handset_playback_switch_info,
3602                 .get   = __handset_playback_switch_get,
3603                 .put   = __handset_playback_switch_put,
3604 -       }       
3605 +       }, {
3606 +               .name  = "Cellphone Input Switch",
3607 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3608 +               .index = 0,
3609 +               .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
3610 +               .info  = __cellphone_input_switch_info,
3611 +               .get   = __cellphone_input_switch_get,
3612 +               .put   = __cellphone_input_switch_put,
3613 +       }, {
3614 +               .name  = "Buzzer Input Switch",
3615 +               .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3616 +               .index = 0,
3617 +               .access= SNDRV_CTL_ELEM_ACCESS_READWRITE,
3618 +               .info  = __buzzer_input_switch_info,
3619 +               .get   = __buzzer_input_switch_get,
3620 +               .put   = __buzzer_input_switch_put,
3621 +       }
3622  };
3623  
3624  #ifdef CONFIG_PM
3625 diff -Naur linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101-mixer.h h6300_dev/sound/arm/omap/omap-alsa-tsc2101-mixer.h
3626 --- linux-2.6.16.16/sound/arm/omap/omap-alsa-tsc2101-mixer.h    2006-05-17 21:41:31.000000000 +0300
3627 +++ h6300_dev/sound/arm/omap/omap-alsa-tsc2101-mixer.h  2006-03-30 23:15:31.000000000 +0300
3628 @@ -56,20 +56,21 @@
3629  #define INPUT_VOLUME_MAX               0x7D
3630  #define INPUT_VOLUME_RANGE             (INPUT_VOLUME_MAX - INPUT_VOLUME_MIN)
3631  
3632 -#define PLAYBACK_TARGET_COUNT          0x02
3633 +#define PLAYBACK_TARGET_COUNT          0x03
3634  #define PLAYBACK_TARGET_LOUDSPEAKER    0x00
3635  #define PLAYBACK_TARGET_HEADPHONE      0x01
3636 +#define PLAYBACK_TARGET_CELLPHONE      0x02
3637  
3638  /* following are used for register 03h Mixer PGA control bits D7-D5 for selecting record source */
3639  #define REC_SRC_TARGET_COUNT           0x08
3640 -#define REC_SRC_SINGLE_ENDED_MICIN_HED MPC_MICSEL(0)   // oss code referred to MIXER_LINE
3641 -#define REC_SRC_SINGLE_ENDED_MICIN_HND MPC_MICSEL(1)   // oss code referred to MIXER_MIC
3642 -#define REC_SRC_SINGLE_ENDED_AUX1      MPC_MICSEL(2)
3643 -#define REC_SRC_SINGLE_ENDED_AUX2      MPC_MICSEL(3)
3644 -#define REC_SRC_MICIN_HED_AND_AUX1     MPC_MICSEL(4)
3645 -#define REC_SRC_MICIN_HED_AND_AUX2     MPC_MICSEL(5)
3646 -#define REC_SRC_MICIN_HND_AND_AUX1     MPC_MICSEL(6)
3647 -#define REC_SRC_MICIN_HND_AND_AUX2     MPC_MICSEL(7)
3648 +#define REC_SRC_SINGLE_ENDED_MICIN_HED 0x00    // oss code referred to MIXER_LINE
3649 +#define REC_SRC_SINGLE_ENDED_MICIN_HND 0x01    // oss code referred to MIXER_MIC
3650 +#define REC_SRC_SINGLE_ENDED_AUX1      0x02
3651 +#define REC_SRC_SINGLE_ENDED_AUX2      0x03
3652 +#define REC_SRC_MICIN_HED_AND_AUX1     0x04
3653 +#define REC_SRC_MICIN_HED_AND_AUX2     0x05
3654 +#define REC_SRC_MICIN_HND_AND_AUX1     0x06
3655 +#define REC_SRC_MICIN_HND_AND_AUX2     0x07
3656  
3657  #define DEFAULT_OUTPUT_VOLUME          90      // default output volume to dac dgc
3658  #define DEFAULT_INPUT_VOLUME           20      // default record volume
3659 diff -Naur linux-2.6.16.16/sound/oss/Kconfig h6300_dev/sound/oss/Kconfig
3660 --- linux-2.6.16.16/sound/oss/Kconfig   2006-05-17 21:41:31.000000000 +0300
3661 +++ h6300_dev/sound/oss/Kconfig 2006-02-06 15:36:21.000000000 +0200
3662 @@ -13,8 +13,8 @@
3663  
3664  config SOUND_OMAP_TSC2101
3665         tristate "TSC2101 Stereo Codec"
3666 -       depends on SOUND_OMAP && ( MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4 || MACH_OMAP_APOLLON)
3667 -       select OMAP_TSC2101 if ( MACH_OMAP_H2 || MACH_OMAP_H3 )
3668 +       depends on SOUND_OMAP && ( MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4 || MACH_OMAP_APOLLON || MACH_OMAP_H6300)
3669 +       select OMAP_TSC2101 if ( MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H6300 )
3670         select OMAP_UWIRE if ARCH_OMAP1
3671         ---help---
3672           Tsc2101 Audio Codec Driver for OMAP will be enabled.
3673 diff -Naur linux-2.6.16.16/sound/oss/omap-audio-tsc2101.c h6300_dev/sound/oss/omap-audio-tsc2101.c
3674 --- linux-2.6.16.16/sound/oss/omap-audio-tsc2101.c      2006-05-17 21:41:31.000000000 +0300
3675 +++ h6300_dev/sound/oss/omap-audio-tsc2101.c    2006-04-02 00:23:01.000000000 +0300
3676 @@ -48,7 +48,7 @@
3677  #include "omap-audio.h"
3678  #include "omap-audio-dma-intfc.h"
3679  #include <asm/arch/mcbsp.h>
3680 -#ifdef CONFIG_ARCH_OMAP16XX
3681 +#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_MACH_OMAP_H6300)
3682  #include <../drivers/ssi/omap-uwire.h>
3683  #include <asm/arch/dsp_common.h>
3684  #elif defined(CONFIG_ARCH_OMAP24XX)
3685 @@ -73,10 +73,16 @@
3686  
3687  #ifdef CONFIG_ARCH_OMAP16XX
3688  #define PLATFORM_NAME "OMAP16XX"
3689 +#elif CONFIG_MACH_OMAP_H6300
3690 +#define PLATFORM_NAME "OMAP15XX"
3691  #elif defined(CONFIG_ARCH_OMAP24XX)
3692  #define PLATFORM_NAME "OMAP2"
3693  #endif
3694  
3695 +#if CONFIG_ARCH_OMAP16XX
3696 +#define OMAP_DSP_BASE        0xE0000000
3697 +#endif
3698 +
3699  /* Define to set the tsc as the master w.r.t McBSP */
3700  #define TSC_MASTER
3701  
3702 @@ -123,7 +129,7 @@
3703  /*********** Debug Macros ********/
3704  /* To Generate a rather shrill tone -test the entire path */
3705  //#define TONE_GEN
3706 -/* To Generate a tone for each keyclick - test the tsc,spi paths*/
3707 +///* To Generate a tone for each keyclick - test the tsc,spi paths*/
3708  //#define TEST_KEYCLICK
3709  /* To dump the tsc registers for debug */
3710  //#define TSC_DUMP_REGISTERS
3711 @@ -230,6 +236,17 @@
3712  };
3713  
3714  static struct omap_mcbsp_reg_cfg initial_config = {
3715 +#ifdef CONFIG_MACH_OMAP_H6300
3716 +       .spcr2 = 0x0005,
3717 +       .spcr1 = 0x0005,
3718 +       .rcr2  = 0x8041,
3719 +       .rcr1  = 0x8041,
3720 +       .xcr2  = 0x00a1,
3721 +       .xcr1  = 0x00a1,
3722 +       .srgr2 = 0xb000,
3723 +       .srgr1 = 0xb000,
3724 +       .pcr0  = 0x0081,
3725 +#else
3726         .spcr2 = FREE | FRST | GRST | XRST | XINTM(3),
3727         .spcr1 = RINTM(3) | RRST,
3728         .rcr2  = RPHASE | RFRLEN2(OMAP_MCBSP_WORD_8) |
3729 @@ -253,6 +270,7 @@
3730  #endif                         /* tsc Master defs */
3731  
3732  #endif                         /* platform specific inits */
3733 +#endif /* CONFIG_MACH_OMAP_H6300 */
3734  };
3735  
3736  /***************************** MODULES SPECIFIC FUNCTION PROTOTYPES ********************/