From nobody Mon Sep 17 00:00:00 2001
From: Mika Laitio <lamikr@cc.jyu.fi>
Date: Thu, 13 Jul 2006 13:04:13 +0300
Subject: [PATCH] h6300 patches except in sound.

---

 Makefile                                    |    2 
 arch/arm/Kconfig                            |    2 
 arch/arm/mach-omap1/Kconfig                 |    9 +
 arch/arm/mach-omap1/Makefile                |    2 
 arch/arm/mach-omap1/board-h6300.c           |  424 +++++++++++++++++++++++++++
 arch/arm/mach-omap1/mux.c                   |    8 +
 arch/arm/plat-omap/devices.c                |    2 
 arch/arm/plat-omap/dma.c                    |    5 
 arch/arm/tools/mach-types                   |    2 
 drivers/bluetooth/Kconfig                   |   10 +
 drivers/bluetooth/Makefile                  |    1 
 drivers/bluetooth/omap/Makefile             |    6 
 drivers/bluetooth/omap/h6300_bt_brf6100.c   |  154 ++++++++++
 drivers/bluetooth/omap/h6300_bt_led.c       |   41 +++
 drivers/bluetooth/omap/h6300_bt_led.h       |    9 +
 drivers/i2c/busses/i2c-omap.c               |   19 +
 drivers/i2c/chips/Kconfig                   |   10 +
 drivers/i2c/chips/Makefile                  |    1 
 drivers/i2c/chips/pca9535.c                 |  412 ++++++++++++++++++++++++++
 drivers/input/keyboard/omap-keypad.c        |  217 +++++++++++++-
 drivers/input/touchscreen/omap/Makefile     |    1 
 drivers/input/touchscreen/omap/omap_ts.c    |    2 
 drivers/input/touchscreen/omap/ts_hx.c      |    6 
 drivers/mmc/mmc.c                           |    2 
 drivers/ssi/omap-tsc2101.c                  |   97 ++++--
 drivers/ssi/omap-uwire.c                    |    6 
 drivers/telephony/Kconfig                   |   13 +
 drivers/telephony/Makefile                  |    7 
 drivers/telephony/omap/Makefile             |    6 
 drivers/telephony/omap/h6300_gsm_led.c      |   40 +++
 drivers/telephony/omap/h6300_gsm_led.h      |   10 +
 drivers/telephony/omap/h6300_gsm_p5186.c    |  172 +++++++++++
 drivers/usb/gadget/omap_udc.c               |    9 -
 drivers/usb/host/ohci-omap.c                |    6 
 drivers/video/omap/Makefile                 |    1 
 drivers/video/omap/lcd_h6300.c              |  154 ++++++++++
 drivers/video/omap/omapfb_main.c            |    2 
 include/asm-arm/arch-omap/board-h6300.h     |   40 +++
 include/asm-arm/arch-omap/h6300_uart_info.h |   33 ++
 include/asm-arm/arch-omap/hardware.h        |    4 
 include/asm-arm/arch-omap/mux.h             |    8 +
 include/asm-arm/arch-omap/omap-alsa.h       |    5 
 include/asm-arm/arch-omap/omap_serial.h     |   62 ++++
 include/asm-arm/arch-omap/pca9535.h         |   39 ++
 44 files changed, 1988 insertions(+), 73 deletions(-)
 create mode 100644 arch/arm/mach-omap1/board-h6300.c
 create mode 100644 drivers/bluetooth/omap/Makefile
 create mode 100644 drivers/bluetooth/omap/h6300_bt_brf6100.c
 create mode 100644 drivers/bluetooth/omap/h6300_bt_led.c
 create mode 100644 drivers/bluetooth/omap/h6300_bt_led.h
 create mode 100644 drivers/i2c/chips/pca9535.c
 create mode 100644 drivers/telephony/omap/Makefile
 create mode 100644 drivers/telephony/omap/h6300_gsm_led.c
 create mode 100644 drivers/telephony/omap/h6300_gsm_led.h
 create mode 100644 drivers/telephony/omap/h6300_gsm_p5186.c
 create mode 100644 drivers/video/omap/lcd_h6300.c
 create mode 100644 include/asm-arm/arch-omap/board-h6300.h
 create mode 100644 include/asm-arm/arch-omap/h6300_uart_info.h
 create mode 100644 include/asm-arm/arch-omap/omap_serial.h
 create mode 100644 include/asm-arm/arch-omap/pca9535.h

dd0d96e4b5c52b69c37c3847397a9b14908d048d
diff --git a/Makefile b/Makefile
index 5a32736..1e447e6 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ # Comments in this file are targeted onl
 # expect to learn how to build the kernel reading this file.
 
 # Add custom flags here to avoid conflict with updates
-EXTRAVERSION := $(EXTRAVERSION)-omap1
+EXTRAVERSION := $(EXTRAVERSION)-omap1-h6300
 
 # Do not print "Entering directory ..."
 MAKEFLAGS += --no-print-directory
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5275f69..14969cf 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -855,6 +855,8 @@ source "drivers/media/Kconfig"
 
 source "drivers/video/Kconfig"
 
+source "drivers/telephony/Kconfig"
+
 source "sound/Kconfig"
 
 source "drivers/usb/Kconfig"
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index e4b86c7..8bf72fd 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -26,6 +26,15 @@ config MACH_OMAP_INNOVATOR
           TI OMAP 1510 or 1610 Innovator board support. Say Y here if you
           have such a board.
 
+config MACH_OMAP_H6300
+	bool "HP iPAQ h6300 series"
+	depends on ARCH_OMAP1 && ARCH_OMAP15XX
+	select I2C
+	select PCA9535
+	help
+          HP iPAQ h6315, h6340 and h6365 devices that are based 
+          on the OMAP 1510. Say Y here if you have such a device.
+
 config MACH_OMAP_H2
 	bool "TI H2 Support"
 	depends on ARCH_OMAP1 && ARCH_OMAP16XX
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index 7165f74..256b1b4 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_MACH_VOICEBLUE)		+= board-v
 obj-$(CONFIG_MACH_OMAP_PALMTE)		+= board-palmte.o
 obj-$(CONFIG_MACH_NOKIA770)		+= board-nokia770.o
 obj-$(CONFIG_MACH_AMS_DELTA)		+= board-ams-delta.o
+obj-$(CONFIG_MACH_OMAP_H6300)		+= board-h6300.o
 
 ifeq ($(CONFIG_ARCH_OMAP15XX),y)
 # Innovator-1510 FPGA
@@ -37,4 +38,3 @@ led-$(CONFIG_MACH_OMAP_INNOVATOR)	+= led
 led-$(CONFIG_MACH_OMAP_PERSEUS2)	+= leds-h2p2-debug.o
 led-$(CONFIG_MACH_OMAP_OSK)		+= leds-osk.o
 obj-$(CONFIG_LEDS)			+= $(led-y)
-
diff --git a/arch/arm/mach-omap1/board-h6300.c b/arch/arm/mach-omap1/board-h6300.c
new file mode 100644
index 0000000..c497872
--- /dev/null
+++ b/arch/arm/mach-omap1/board-h6300.c
@@ -0,0 +1,424 @@
+/*
+ * Modified from board-h6300.c
+ *
+ * Code for generic OMAP board. Should work on many OMAP systems where
+ * the device drivers take care of all the necessary hardware initialization.
+ * Do not put any board specific code to this file; create a new machine
+ * type if you need custom low-level initializations.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/input.h>
+
+#include <asm/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <asm/arch/gpio.h>
+
+#include <asm/arch/tc.h>
+#include <asm/arch/usb.h>
+#include <asm/arch/keypad.h>
+#include <asm/arch/common.h>
+#include <asm/arch/mcbsp.h>
+#include <asm/arch/omap-alsa.h>
+#include <asm/arch/h6300_uart_info.h>
+
+#define _h6300_KEY_CALENDAR	67 	// xmodmap 75 aka F9
+#define _H6300_KEY_TELEPHONE	68 	// xmodmap 76 aka F10
+#define _H6300_KEY_HOMEPAGE	87 	// xmodmap 87 aka Num_Lock
+#define _H6300_KEY_MAIL		88 	// xmodmap 88 aka Scroll_Lock
+
+/*
+ * Following 5 keypad events are not really sent to userspace. 
+ * Instead if the good combination of them is sent, then that is send.
+ * (up, right, down, left, enter)
+ */
+#define	_H6300_JOYPAD_UP_RIGHT		1	// 00001
+#define _H6300_JOYPAD_DOWN_RIGHT	2	// 00010
+#define _h6300_JOYPAD_DOWN_LEFT		4	// 00100
+#define _h6300_JOYPAD_UP_LEFT		8	// 01000
+#define _H6300_JOYPAD_KEY_OK		16	// 10000
+
+static int h6300_keymap[] = {
+	KEY(2, 0, _h6300_KEY_CALENDAR),		// address button in the bottom left	
+	KEY(2, 3, _H6300_KEY_TELEPHONE),	// start call button in the bottom
+	KEY(3, 1, _H6300_KEY_HOMEPAGE),		// stop call button in the bottom
+	KEY(3, 4, _H6300_KEY_MAIL),		// messaging button in the bottom right
+
+	KEY(0, 0, KEY_VOLUMEUP),	// volume up button in the right side
+	KEY(0, 1, KEY_VOLUMEDOWN),	// volume down button in the right side
+	KEY(3, 2, KEY_RECORD),		// record button in the left side
+	
+	KEY(1, 0, _h6300_JOYPAD_UP_LEFT),	
+	KEY(1, 1, _h6300_JOYPAD_DOWN_LEFT),	
+	KEY(1, 2, _H6300_JOYPAD_KEY_OK),		
+	KEY(1, 3, _H6300_JOYPAD_DOWN_RIGHT),
+	KEY(1, 4, _H6300_JOYPAD_UP_RIGHT),	
+	
+	KEY(4, 0, KEY_RIGHT),
+	KEY(4, 1, KEY_DOWN),
+	KEY(4, 2, KEY_LEFT),		
+	KEY(4, 3, KEY_UP),
+	KEY(4, 4, KEY_ENTER),
+
+	0
+};
+
+/*
+ * Bluetooth - Relies on h6300_bt module,
+ * so make the calls indirectly through pointers. Requires that the
+ * h6300_bt bluetooth module be loaded before any attempt to use
+ * bluetooth (obviously).
+ */
+
+static struct h6300_uart_funcs bt_funcs;
+static struct h6300_uart_funcs gsm_funcs;
+
+static void h6300_bt_configure(struct uart_omap_port *up, int enable)
+{
+	printk(KERN_NOTICE "board-h6300.c, h6300_bt_configure() started\n");
+	if (bt_funcs.configure != NULL)
+		bt_funcs.configure(up, enable);
+	printk(KERN_NOTICE "board-h6300.c, h6300_bt_configure() done\n");
+}
+
+static void h6300_bt_set_txrx(struct uart_omap_port *up, int txrx)
+{
+	printk(KERN_NOTICE "board-h6300.c, h6300_bt_set_txrx() started\n");
+	if (bt_funcs.set_txrx != NULL)
+	{
+		printk(KERN_NOTICE "board-h6300.c, h6300_bt_set_txrx(), bt_funcs.set_txrx != NULL\n");
+		bt_funcs.set_txrx(up, txrx);
+	}
+	printk(KERN_NOTICE "board-h6300.c, h6300_bt_set_txrx() done\n");
+}
+
+static int h6300_bt_get_txrx(struct uart_omap_port *up)
+{
+	int	retVal;
+	
+	printk(KERN_NOTICE "board-h6300.c, h6300_bt_get_txrx() started\n");
+	if (bt_funcs.get_txrx != NULL)
+	{
+		retVal	= bt_funcs.get_txrx(up);
+		printk(KERN_NOTICE "board-h6300.c, h6300_bt_get_txrx(), bt_funcs.get_trx != null, done, retVal %d\n", retVal);
+		return retVal;
+	}
+	else
+	{
+		printk(KERN_NOTICE "board-h6300.c, h6300_bt_get_txrx() done, returning 0\n");
+		return 0;
+	}
+}
+
+static struct platform_omap_serial_funcs h6300_omap_bt_funcs = {
+	.configure	= h6300_bt_configure,
+	.set_txrx	= h6300_bt_set_txrx,
+	.get_txrx	= h6300_bt_get_txrx,
+};
+
+struct platform_device btuart_device = {
+	.name	= "h6300_bt",
+	.id	= 1,
+};
+EXPORT_SYMBOL(btuart_device);
+
+static void h6300_gsm_configure(struct uart_omap_port *up, int enable)
+{
+	printk(KERN_NOTICE "board-h6300.c, h6300_gsm_configure() started\n");
+	if (gsm_funcs.configure != NULL)
+		gsm_funcs.configure(up, enable);
+	printk(KERN_NOTICE "board-h6300.c, h6300_gsm_configure() done\n");
+}
+
+static void h6300_gsm_set_txrx(struct uart_omap_port *up, int txrx)
+{
+	printk(KERN_NOTICE "board-h6300.c, h6300_gsm_set_txrx() started\n");
+	if (bt_funcs.set_txrx != NULL)
+	{
+		printk(KERN_NOTICE "board-h6300.c, h6300_gsm_set_txrx(), bt_funcs.set_txrx != NULL\n");
+		gsm_funcs.set_txrx(up, txrx);
+	}
+	printk(KERN_NOTICE "board-h6300.c, h6300_gsm_set_txrx() done\n");
+}
+
+static int h6300_gsm_get_txrx(struct uart_omap_port *up)
+{
+	int	retVal;
+	
+	printk(KERN_NOTICE "board-h6300.c, h6300_gsm_get_txrx() started\n");
+	if (bt_funcs.get_txrx != NULL)
+	{
+		retVal	= gsm_funcs.get_txrx(up);
+		printk(KERN_NOTICE "board-h6300.c, h6300_gsm_get_txrx(), bt_funcs.get_trx != null, done, retVal %d\n", retVal);
+		return retVal;
+	}
+	else
+	{
+		printk(KERN_NOTICE "board-h6300.c, h6300_gsm_get_txrx() done, returning 0\n");
+		return 0;
+	}
+}
+
+static struct platform_omap_serial_funcs h6300_omap_gsm_funcs = {
+	.configure	= h6300_gsm_configure,
+	.set_txrx	= h6300_gsm_set_txrx,
+	.get_txrx	= h6300_gsm_get_txrx,
+};
+
+struct platform_device gsmuart_device = {
+	.name	= "h6300_gsm",
+	.id	= 1,
+};
+EXPORT_SYMBOL(gsmuart_device);
+
+#if 0
+static struct mtd_partition h6300_partitions[] = {
+	/* bootloader (U-Boot, etc) in first sector */
+	{
+	      .name		= "bootloader",
+	      .offset		= 0,
+	      .size		= SZ_128K,
+	      .mask_flags	= MTD_WRITEABLE, /* force read-only */
+	},
+	/* bootloader params in the next sector */
+	{
+	      .name		= "params",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_128K,
+	      .mask_flags	= 0,
+	},
+	/* kernel */
+	{
+	      .name		= "kernel",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_2M,
+	      .mask_flags	= 0
+	},
+	/* rest of flash1 is a file system */
+	{
+	      .name		= "rootfs",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= SZ_16M - SZ_2M - 2 * SZ_128K,
+	      .mask_flags	= 0
+	},
+	/* file system */
+	{
+	      .name		= "filesystem",
+	      .offset		= MTDPART_OFS_APPEND,
+	      .size		= MTDPART_SIZ_FULL,
+	      .mask_flags	= 0
+	}
+};
+
+static struct flash_platform_data h6300_flash_data = {
+	.map_name	= "cfi_probe",
+	.width		= 2,
+	.parts		= h6300_partitions,
+	.nr_parts	= ARRAY_SIZE(h6300_partitions),
+};
+
+static struct resource h6300_flash_resource = {
+	.start		= OMAP_CS0_PHYS,
+	.end		= OMAP_CS0_PHYS + SZ_32M - 1,
+	.flags		= IORESOURCE_MEM,
+};
+
+static struct platform_device h6300_flash_device = {
+	.name	= "omapflash",
+	.id		= 0,
+	.dev	= {
+		.platform_data	= &h6300_flash_data,
+	},
+static struct platform_device h6300_flash_device = {
+	.name	= "omapflash",
+	.id		= 0,
+	.dev	= {
+		.platform_data	= &h6300_flash_data,
+	},
+	.num_resources	= 1,
+	.resource	= &h6300_flash_resource,
+};
+#endif
+
+static struct resource h6300_kp_resources[] = {
+	[0] = {
+		.start	= INT_KEYBOARD,
+		.end	= INT_KEYBOARD,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct omap_kp_platform_data h6300_kp_data = {
+	.rows	= 8,
+	.cols	= 8,
+	.keymap = h6300_keymap,
+	.rep	= 1,	// turns repeat bit on
+};
+
+static struct platform_device h6300_kp_device = {
+	.name		= "omap-keypad",
+	.id		= -1,
+	.dev		= {
+		.platform_data = &h6300_kp_data,
+	},
+	.num_resources	= ARRAY_SIZE(h6300_kp_resources),
+	.resource	= h6300_kp_resources,
+};
+
+static struct resource h6300_wlan_resource[] = {
+        [0] = {
+                .start          = OMAP_CS1_PHYS,
+                .end            = OMAP_CS1_PHYS + SZ_32M -1,
+                .flags          = IORESOURCE_MEM,
+        },
+
+        [1] = {
+                .start  = OMAP_GPIO_IRQ(11),
+                .end    = OMAP_GPIO_IRQ(11),
+                .flags  = IORESOURCE_IRQ,
+        },
+};
+
+static struct platform_device h6300_wlan_device = {
+        .name           = "tnetw1100b",
+        .id             = 0,
+        .num_resources  = 2,
+        .resource       = h6300_wlan_resource,
+};
+
+static struct omap_mcbsp_reg_cfg mcbsp_regs = { 
+	.spcr2	= 0x0000,
+	.spcr1	= 0x0000,
+	.rcr2	= 0x8041,
+	.rcr1	= 0x0040,
+	.xcr2	= 0x00a1,
+	.xcr1	= 0x00a0,
+	.srgr2	= 0xb000,
+	.srgr1	= 0x0000,
+	.pcr0	= 0x0081,
+};
+
+static struct omap_alsa_codec_config alsa_config = {
+	.name                   = "iPAQ h6300 TSC2101",
+	.mcbsp_regs_alsa        = &mcbsp_regs,
+	.codec_configure_dev    = NULL, //tsc2101_configure,
+	.codec_set_samplerate   = NULL, //tsc2101_set_samplerate,
+	.codec_clock_setup      = NULL, //tsc2101_clock_setup,
+	.codec_clock_on         = NULL, //tsc2101_clock_on,
+	.codec_clock_off        = NULL, //tsc2101_clock_off,
+	.get_default_samplerate = NULL, //tsc2101_get_default_samplerate,
+};
+
+static struct platform_device h6300_mcbsp1_device = {
+	.name	= "omap_alsa_mcbsp",
+	.id	= 1,
+	.dev = {
+		.platform_data	= &alsa_config,
+	},
+};
+
+static struct platform_device h6300_lcd_device = {
+	.name	= "lcd_h6300",
+	.id	= -1,
+};
+
+static struct platform_device *h6300_devices[] __initdata = {
+	&h6300_lcd_device,
+	&btuart_device,
+	&gsmuart_device,
+	&h6300_kp_device,
+	&h6300_mcbsp1_device,
+	&h6300_wlan_device,
+	//&h6300_flash_device,
+};
+
+static void __init h6300_init_irq(void)
+{
+	omap1_init_common_hw();
+	omap_init_irq();
+	omap_gpio_init();
+
+	/* this is now done in the drivers/input/touschreen/omap/ts_hx.c*/
+	//omap_request_gpio(2);
+	//omap_set_gpio_direction(2, 0);
+	//omap_set_gpio_dataout(2, 1);
+}
+
+/* assume no Mini-AB port */
+
+static struct omap_usb_config h6300_usb_config __initdata = {
+	.hmc_mode	= 0,
+	.register_dev	= 1,
+	.pins[0]	= 0,
+};
+
+static struct omap_lcd_config h6300_lcd_config __initdata = {
+	.ctrl_name	= "internal",
+};
+
+static struct omap_mmc_config h6300_mmc_config __initdata = {
+	.mmc [0] = {
+		.enabled 	= 1,
+		.wire4		= 1,
+		.wp_pin		= OMAP_GPIO_IRQ(13),
+		.power_pin	= -1, // tps65010 ?
+		.switch_pin	= -1, // OMAP_MPUIO(1),	// = -1, // ARMIO2?
+	},
+};
+
+static struct omap_uart_config h6300_uart_config __initdata = {
+	.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
+};
+
+static struct omap_board_config_kernel h6300_config[] = {
+	{ OMAP_TAG_USB, 	&h6300_usb_config },
+	{ OMAP_TAG_MMC,		&h6300_mmc_config },
+	{ OMAP_TAG_UART,	&h6300_uart_config },
+	{ OMAP_TAG_LCD,		&h6300_lcd_config },
+};
+
+static void __init h6300_init(void)
+{
+	int ret;
+	
+	ret = platform_add_devices(h6300_devices, ARRAY_SIZE(h6300_devices));
+	if (ret) 
+	{
+		printk(KERN_WARNING "Unable to add h6300 platform devices like bluetooth");
+	}
+	omap_board_config	= h6300_config;
+	omap_board_config_size	= ARRAY_SIZE(h6300_config);
+	omap_serial_init();
+}
+
+static void __init h6300_map_io(void)
+{
+	omap1_map_common_io();
+	
+	btuart_device.dev.platform_data		= &h6300_omap_bt_funcs;
+	gsmuart_device.dev.platform_data	= &h6300_omap_gsm_funcs;
+}
+
+MACHINE_START(OMAP_H6300, "HP iPAQ h6300")
+	/* MAINTAINER("Everett Coleman II <gcc80x86@fuzzyneural.net>") */
+	.phys_io		= 0xfff00000,
+	.io_pg_offst	= ((0xfef00000) >> 18) & 0xfffc,
+	.boot_params	= 0x10000100,
+	.map_io			= h6300_map_io,
+	.init_irq		= h6300_init_irq,
+	.init_machine	= h6300_init,
+	.timer			= &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
index 10fe0b3..d4eade5 100644
--- a/arch/arm/mach-omap1/mux.c
+++ b/arch/arm/mach-omap1/mux.c
@@ -200,6 +200,13 @@ MUX_CFG("N14_1610_UWIRE_CS0",	 8,    9, 
 MUX_CFG("P15_1610_UWIRE_CS3",	 8,   12,    1,	  1,  22,   0,	  1,	 1,  1)
 MUX_CFG("N15_1610_UWIRE_CS1",	 7,   18,    2,	  1,  14,   0,	 NA,	 0,  1)
 
+/* OMAP-1510 uWire */
+MUX_CFG("P15_1510_UWIRE_CS3",  8,   12,    1,	 NA,   0,   0,  NA,  0,  1)
+MUX_CFG("N14_1510_UWIRE_CS0",  8,    9,    1,	 NA,   0,   0,  NA,  0,  1)
+MUX_CFG("V19_1510_UWIRE_SCLK", 8,    6,    0,	 NA,   0,   0,  NA,  0,  1)
+MUX_CFG("W21_1510_UWIRE_SDO",  8,    3,    0,	 NA,   0,   0,  NA,  0,  1)
+MUX_CFG("U18_1510_UWIRE_SDI",  8,    0,    0,	  1,  18,   0,  NA,  0,  1)
+
 /* OMAP-1610 Flash */
 MUX_CFG("L3_1610_FLASH_CS2B_OE",10,    6,    1,	 NA,   0,   0,	 NA,	 0,  1)
 MUX_CFG("M8_1610_FLASH_CS2B_WE",10,    3,    1,	 NA,   0,   0,	 NA,	 0,  1)
@@ -262,6 +269,7 @@ MUX_CFG("N19_1610_KBR5",	 6,  12,     1,
 MUX_CFG("T20_1610_LOW_PWR",	 7,   12,    1,	  NA,   0,   0,   NA,	 0,  0)
 
 /* MCLK Settings */
+MUX_CFG("R10_1510_MCLK_ON",	 B,   18,    0,	  2,   22,   1,   NA,	 1,  1)
 MUX_CFG("V5_1710_MCLK_ON",	 B,   15,    0,	  NA,   0,   0,   NA,	 0,  0)
 MUX_CFG("V5_1710_MCLK_OFF",	 B,   15,    6,	  NA,   0,   0,   NA,	 0,  0)
 MUX_CFG("R10_1610_MCLK_ON",	 B,   18,    0,	  NA,  22,   0,	  NA,	 1,  0)
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 8bff566..82589fa 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -92,7 +92,7 @@ #if	defined(CONFIG_KEYBOARD_OMAP) || def
 
 static void omap_init_kp(void)
 {
-	if (machine_is_omap_h2() || machine_is_omap_h3()) {
+	if (machine_is_omap_h2() || machine_is_omap_h3() || machine_is_omap_h6300()) {
 		omap_cfg_reg(F18_1610_KBC0);
 		omap_cfg_reg(D20_1610_KBC1);
 		omap_cfg_reg(D19_1610_KBC2);
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index ab0eff0..46982c7 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -30,6 +30,7 @@ #include <asm/irq.h>
 #include <asm/hardware.h>
 #include <asm/dma.h>
 #include <asm/io.h>
+#include <asm/mach-types.h>
 
 #include <asm/arch/tc.h>
 
@@ -1171,6 +1172,10 @@ #define PIXSTEP(sx, sy, dx, dy) (PIXADDR
 	}
 
 	if (omap_dma_in_1510_mode()) {
+		u16 l = omap_readw(OMAP1510_DMA_LCD_CTRL);
+		l &= ~(1 << 6);
+		omap_writew (l, OMAP1510_DMA_LCD_CTRL);
+
 		omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
 		omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
 		omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 6d7de9c..6e442ae 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -576,7 +576,7 @@ tengine			MACH_TENGINE		TENGINE			559
 s3c2460			MACH_S3C2460		S3C2460			560
 pdm			MACH_PDM		PDM			561
 h4700			MACH_H4700		H4700			562
-h6300			MACH_H6300		H6300			563
+omap_h6300		MACH_OMAP_H6300		OMAP_H6300		563
 rz1700			MACH_RZ1700		RZ1700			564
 a716			MACH_A716		A716			565
 estk2440a		MACH_ESTK2440A		ESTK2440A		566
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
index 9abcd62..e05424c 100644
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -166,6 +166,16 @@ config BT_HCIVHCI
 
 	  Say Y here to compile support for virtual HCI devices into the
 	  kernel or say M to compile it as module (hci_vhci).
+	  
+config BT_H6300
+	tristate "H6300 BRF6100 BT DRIVER"
+	help
+	  Bluetooth H6300 BRF6100 driver.
+	  This driver provides the firmware loading mechanism for the BRF6100
+	  bt hardware in iPAQ h6300.
+
+	  Say Y here to compile support for BRF6100 BT devices into the
+	  kernel or say M to compile it as module (h6300_BT).	  
 
 endmenu
 
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 18aa038..8f9df82 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_BT_HCIBT3C)	+= bt3c_cs.o
 obj-$(CONFIG_BT_HCIBLUECARD)	+= bluecard_cs.o
 obj-$(CONFIG_BT_HCIBTUART)	+= btuart_cs.o
 obj-$(CONFIG_BT_HCIBRF6150)	+= brf6150.o
+obj-$(CONFIG_BT_H6300)		+= omap/
 
 hci_uart-y				:= hci_ldisc.o
 hci_uart-$(CONFIG_BT_HCIUART_H4)	+= hci_h4.o
diff --git a/drivers/bluetooth/omap/Makefile b/drivers/bluetooth/omap/Makefile
new file mode 100644
index 0000000..5465d7f
--- /dev/null
+++ b/drivers/bluetooth/omap/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the Linux iPAQ H6300 BRF6100 Bluetooth device drivers.
+#
+
+h6300_bt-objs				:= h6300_bt_led.o h6300_bt_brf6100.o
+obj-$(CONFIG_BT_H6300)		+= h6300_bt.o
diff --git a/drivers/bluetooth/omap/h6300_bt_brf6100.c b/drivers/bluetooth/omap/h6300_bt_brf6100.c
new file mode 100644
index 0000000..3c9b564
--- /dev/null
+++ b/drivers/bluetooth/omap/h6300_bt_brf6100.c
@@ -0,0 +1,154 @@
+/* 
+ * Bluetooth interface driver for TI BRF6100 on h6300
+ * 
+ * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi>
+ * Ideas taken from the brf6150 bt driver made by Todd Blumer for the pxa hx4700.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/gpio.h>
+
+#include <asm/arch/h6300_uart_info.h>
+#include "h6300_bt_led.h"
+
+static void
+h6300_bt_configure(struct uart_omap_port *up, int enable)
+{
+	printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_configure() started, enable = %d\n", enable);
+	
+	// printk( KERN_NOTICE "h6300 configure bluetooth: %d\n", enable );
+	if (enable == 0) {
+		omap_set_gpio_dataout(GPIO_N_BT_RST, 1);	// turn off gpio, note 1 == off for negative gpios
+		mdelay(5);
+		h6300_clear_led(INDEX_BT_LED);
+	}
+	else if (enable == 1) {
+		omap_set_gpio_dataout(GPIO_N_BT_RST, 1);	// turn on gpio, note 0 == on for negative gpios
+		mdelay(5);				
+	}
+	else if (enable == 2) {
+		/*
+		 * BRF6150's RTS goes low when firmware is ready
+		 * so check for CTS=1 (nCTS=0 -> CTS=1). Typical 150ms
+		 */
+/*		
+		int tries = 0; 
+		do 
+		{
+			mdelay(10);
+		} 
+		while ((BTMSR & MSR_CTS) == 0 && tries++ < 50);
+*/				
+		h6300_set_led(INDEX_BT_LED, 16, 16);
+	}
+	printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_configure() done\n");
+}
+
+static void
+h6300_bt_set_txrx(struct uart_omap_port *up, int txrx)
+{
+	printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_set_txrx(), txrx = %d done\n", txrx);
+	/* do nothing */
+}
+
+static int
+h6300_bt_get_txrx(struct uart_omap_port *up)
+{
+	printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_get_txrx() done\n");
+	/* do nothing */
+	return 0;
+}
+
+static int
+h6300_bt_probe(struct platform_device *pdev)
+{
+	struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
+
+	omap_request_gpio(GPIO_BT_PWR_EN);		// ask bt_power_en gpio, remember to release in remove_function
+	omap_set_gpio_direction(GPIO_BT_PWR_EN, 1);	// set gpio direction to be output
+	omap_set_gpio_dataout(GPIO_BT_PWR_EN, 1);	// turn on gpio
+
+	mdelay(200);
+
+	omap_request_gpio(GPIO_N_BT_RST);		// ask bt_reset gpio, remember to release in remove_function
+	omap_set_gpio_direction(GPIO_N_BT_RST, 1);	// set gpio direction to be output
+	omap_set_gpio_dataout(GPIO_N_BT_RST, 0);	// turn on gpio, note 0 == on for negative gpios
+	
+	/* configure bluetooth UART */
+	//h6300_gpio_mode(GPIO_NR_H6300_BT_RXD_MD);
+	//h6300_gpio_mode(GPIO_NR_H6300_BT_TXD_MD);
+	//h6300_gpio_mode(GPIO_NR_H6300_BT_UART_CTS_MD);
+	//h6300_gpio_mode(GPIO_NR_H6300_BT_UART_RTS_MD);
+
+	funcs->configure	= h6300_bt_configure;
+	funcs->set_txrx		= h6300_bt_set_txrx;
+	funcs->get_txrx		= h6300_bt_get_txrx;
+
+	/* Make sure the LED is off */
+	h6300_clear_led(INDEX_BT_LED);
+	
+	printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_probe() done\n");	
+
+	return 0;
+}
+
+static int
+h6300_bt_remove(struct platform_device *pdev)
+{
+	struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
+	
+	printk(KERN_NOTICE "h6300_bt_brf6100.c h6300_bt_remove() started\n");	
+	
+	omap_free_gpio(GPIO_BT_PWR_EN);
+	omap_free_gpio(GPIO_N_BT_RST);
+
+	funcs->configure	= NULL;
+	funcs->set_txrx		= NULL;
+	funcs->get_txrx		= NULL;
+
+	/* Make sure the LED is off */
+	h6300_clear_led(INDEX_BT_LED);
+	
+	printk(KERN_NOTICE "h6300_bt_brf6100.c, h6300_bt_remove() done\n");
+
+	return 0;
+}
+
+static struct platform_driver bt_driver = {
+	.probe    = h6300_bt_probe,
+	.remove   = h6300_bt_remove,
+	.driver = {
+		.name =	"h6300_bt",
+	},
+};
+
+static int __init
+h6300_bt_init(void)
+{
+	printk(KERN_NOTICE "h6300 Bluetooth Driver init()\n");
+	return platform_driver_register(&bt_driver);
+}
+
+static void __exit
+h6300_bt_exit(void)
+{
+	printk(KERN_NOTICE "h6300 Bluetooth Driver exit()\n");
+	platform_driver_unregister(&bt_driver);
+}
+
+module_init(h6300_bt_init);
+module_exit(h6300_bt_exit);
+
+MODULE_AUTHOR("Mika Laitio, <lamikr@cc.jyu.fi>");
+MODULE_DESCRIPTION("iPAQ h6300 BRF6100 Bluetooth driver.");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/bluetooth/omap/h6300_bt_led.c b/drivers/bluetooth/omap/h6300_bt_led.c
new file mode 100644
index 0000000..18458c3
--- /dev/null
+++ b/drivers/bluetooth/omap/h6300_bt_led.c
@@ -0,0 +1,41 @@
+/* 
+ * Bluetooth interface driver helper for controlling bluetooth leds available in iPAQ h6300.
+ * 
+ * Copyright (C) 2005 Mika Laitio  <lamikr@cc.jyu.fi>
+ * Ideas from the brf6150 bt driver made by Todd Blumer for the pxa hx4700.
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/gpio.h>
+
+/* 
+ * Low level access for disabling h6300 bt led.
+ *
+ * TODO: implement for h6300 
+ */
+void h6300_clear_led(int led_num)
+{
+	printk(KERN_NOTICE "h6300_bt_led.c h6300_clear_led() done\n");
+	//hx4700_set_led(led_num, 0, 16);
+}
+EXPORT_SYMBOL(h6300_clear_led);
+
+/* 
+ * Low level access for setting up the bt led.
+ *
+ * TODO: implement for h6300 
+ */
+void h6300_set_led(int led_num, int duty_time, int cycle_time)
+{
+	printk(KERN_NOTICE "h6300_bt_led.c h6300_set_led() done\n");
+}
+EXPORT_SYMBOL(h6300_set_led);
diff --git a/drivers/bluetooth/omap/h6300_bt_led.h b/drivers/bluetooth/omap/h6300_bt_led.h
new file mode 100644
index 0000000..23a7174
--- /dev/null
+++ b/drivers/bluetooth/omap/h6300_bt_led.h
@@ -0,0 +1,9 @@
+#ifndef H6300_BT_LED_H_
+#define H6300_BT_LED_H_
+
+#define INDEX_BT_LED	2
+
+void h6300_clear_led(int led_num);
+void h6300_set_led(int led_num, int duty_time, int cycle_time);
+
+#endif /*H6300_BT_LED_H_*/
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 6c58b1b..2502cb1 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -163,17 +163,22 @@ static inline u16 omap_i2c_read_reg(stru
 
 static int omap_i2c_get_clocks(struct omap_i2c_dev *dev)
 {
-	if (cpu_is_omap16xx() || cpu_is_omap24xx()) {
+	if (cpu_is_omap24xx()) {
 		dev->iclk = clk_get(dev->dev, "i2c_ick");
-		if (IS_ERR(dev->iclk))
+		if (IS_ERR(dev->iclk)) {
 			return -ENODEV;
+		}
+		dev->fclk = clk_get(dev->dev, "i2c_fck");
+		if (IS_ERR(dev->fclk)) {
+			clk_put(dev->fclk);
+			return -ENODEV;
+		}
 	}
 
-	dev->fclk = clk_get(dev->dev, "i2c_fck");
-	if (IS_ERR(dev->fclk)) {
-		if (dev->iclk != NULL)
-			clk_put(dev->iclk);
-		return -ENODEV;
+	if (cpu_class_is_omap1()) {
+		dev->fclk = clk_get(dev->dev, "i2c_fck");
+		if (IS_ERR(dev->fclk))
+			return -ENODEV;
 	}
 
 	return 0;
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index cd20ae2..646044a 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -46,6 +46,16 @@ config SENSORS_PCF8574
 	  This driver can also be built as a module.  If so, the module
 	  will be called pcf8574.
 
+config PCA9535
+        tristate "Philips PCA9535 16-bit I/O port"
+        depends on I2C 
+        help
+          If you say yes here you get support for the Philips PCA9535
+          16-bit I/O port.
+	
+          This driver can also be built as a module.  If so, the module
+          will be called pca9535.
+
 config SENSORS_PCA9539
 	tristate "Philips PCA9539 16-bit I/O port"
 	depends on I2C && EXPERIMENTAL
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index 027dede..b078fe2 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_SENSORS_DS1374)	+= ds1374.o
 obj-$(CONFIG_SENSORS_EEPROM)	+= eeprom.o
 obj-$(CONFIG_SENSORS_MAX6875)	+= max6875.o
 obj-$(CONFIG_SENSORS_M41T00)	+= m41t00.o
+obj-$(CONFIG_PCA9535)   		+= pca9535.o
 obj-$(CONFIG_SENSORS_PCA9539)	+= pca9539.o
 obj-$(CONFIG_SENSORS_PCF8574)	+= pcf8574.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
diff --git a/drivers/i2c/chips/pca9535.c b/drivers/i2c/chips/pca9535.c
new file mode 100644
index 0000000..34483db
--- /dev/null
+++ b/drivers/i2c/chips/pca9535.c
@@ -0,0 +1,412 @@
+/*
+    Driver for Philips PCA9535 16-bit low power I/O port with interrupt
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+    
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+    
+    Copyright (C) 2005 Husam Senussi
+    Framework based on Pawel Kolodziejski's pca9535 driver in 
+    handheld.org's 2.6.13 kernel. Driver updated by Mika Laitio.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon.h>
+#include <linux/err.h>
+
+#include <asm/arch/pca9535.h>
+#include <linux/delay.h>
+
+#include <linux/interrupt.h>
+#include <asm/mach-types.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/hardware.h>
+
+EXPORT_SYMBOL(pca9535_gpio_read);
+EXPORT_SYMBOL(pca9535_gpio_write);
+EXPORT_SYMBOL(pca9535_gpio_direction);
+
+static int pca9535_attach_adapter(struct i2c_adapter *adapter);
+static int pca9535_detach_client(struct i2c_client *client);
+static int pca9535_attach(struct i2c_adapter *adapter, int address, int zero_or_minus_one);
+static u32 pca9535_read_reg(struct i2c_client *client, u8 regaddr);
+static void pca9535_write_reg(struct i2c_client *client, u8 regaddr, u16 param);
+
+enum pca9535_cmd
+{
+        PCA9535_INPUT_0         = 0,
+        PCA9535_INPUT_1         = 1,
+        PCA9535_OUTPUT_0        = 2,
+        PCA9535_OUTPUT_1        = 3,
+        PCA9535_INVERT_0        = 4,
+        PCA9535_INVERT_1        = 5,
+        PCA9535_DIRECTION_0     = 6,
+        PCA9535_DIRECTION_1     = 7,
+};
+
+struct pca9535_data {
+	struct semaphore  lock;
+        struct i2c_client client;
+};
+
+static struct i2c_driver pca9535_driver = {
+        .driver = {
+                .name   = "pca9535",
+        },
+	.attach_adapter		= pca9535_attach_adapter,
+	.detach_client		= pca9535_detach_client,
+};
+
+static struct i2c_client   *pca9535_i2c_client = NULL;
+static struct pca9535_data pca9535_inited;
+
+static unsigned short normal_i2c[] = { 0x20, I2C_CLIENT_END };
+
+#define DRIVER_VERSION  "20 OCT 2005"
+#define DRIVER_NAME     "PCA9535"
+
+/* 
+ * sysfs callback function.
+ */ 
+static ssize_t pca9535_show(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+{
+        struct sensor_device_attribute *psa = to_sensor_dev_attr(attr);
+        struct i2c_client *client = to_i2c_client(dev);
+        return sprintf(buf, "%02X\n", (pca9535_read_reg(client, psa->index) >> 8));
+}
+
+/* 
+ * sysfs callback function.
+ */ 
+static ssize_t pca9535_store(struct device *dev, struct device_attribute *attr,
+                             const char *buf, size_t count)
+{
+        struct sensor_device_attribute *psa = to_sensor_dev_attr(attr);
+        struct i2c_client *client = to_i2c_client(dev);
+        unsigned long val = simple_strtoul(buf, NULL, 0);
+	unsigned long old = pca9535_read_reg(client, psa->index);
+
+        if (val > 0xff)
+                return -EINVAL;
+	
+	val = (old & 0xff) | (val << 8);
+        pca9535_write_reg(client, psa->index, val);
+        return count;
+}
+
+#define PCA9535_ENTRY_RO(name, cmd_idx) \
+        static SENSOR_DEVICE_ATTR(name, S_IRUGO, pca9535_show, NULL, cmd_idx)
+
+#define PCA9535_ENTRY_RW(name, cmd_idx) \
+        static SENSOR_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, pca9535_show, \
+                                  pca9535_store, cmd_idx)
+
+PCA9535_ENTRY_RO(input0, PCA9535_INPUT_0);
+PCA9535_ENTRY_RO(input1, PCA9535_INPUT_1);
+PCA9535_ENTRY_RW(output0, PCA9535_OUTPUT_0);
+PCA9535_ENTRY_RW(output1, PCA9535_OUTPUT_1);
+PCA9535_ENTRY_RW(invert0, PCA9535_INVERT_0);
+PCA9535_ENTRY_RW(invert1, PCA9535_INVERT_1);
+PCA9535_ENTRY_RW(direction0, PCA9535_DIRECTION_0);
+PCA9535_ENTRY_RW(direction1, PCA9535_DIRECTION_1);
+
+static struct attribute *pca9535_attributes[] = {
+        &sensor_dev_attr_input0.dev_attr.attr,
+        &sensor_dev_attr_input1.dev_attr.attr,
+        &sensor_dev_attr_output0.dev_attr.attr,
+        &sensor_dev_attr_output1.dev_attr.attr,
+        &sensor_dev_attr_invert0.dev_attr.attr,
+        &sensor_dev_attr_invert1.dev_attr.attr,
+        &sensor_dev_attr_direction0.dev_attr.attr,
+        &sensor_dev_attr_direction1.dev_attr.attr,
+        NULL
+};
+
+static struct attribute_group pca9535_defattr_group = {
+        .attrs = pca9535_attributes,
+};
+//End of sysfs management code. 
+
+I2C_CLIENT_INSMOD;
+
+u32 pca9535_read_input(void)
+{
+	return pca9535_read_reg(pca9535_i2c_client, 0);
+}
+EXPORT_SYMBOL(pca9535_read_input);
+
+void pca9535_write_output(u16 param)
+{
+	pca9535_write_reg(pca9535_i2c_client, 2, param);
+}
+EXPORT_SYMBOL(pca9535_write_output);
+
+void pca9535_set_dir(u16 param)
+{
+	pca9535_write_reg(pca9535_i2c_client, 6, param);
+}
+EXPORT_SYMBOL(pca9535_set_dir);
+
+static int pca9535_attach_adapter(struct i2c_adapter *adapter)
+{
+	return i2c_probe(adapter, &addr_data, pca9535_attach);
+}
+
+static int pca9535_attach(struct i2c_adapter *adapter, int address, int zero_or_minus_one)
+{
+	struct i2c_client *new_client;
+	int err = 0;
+
+	new_client = &(pca9535_inited.client);
+	i2c_set_clientdata(new_client, 0);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &pca9535_driver;
+	strcpy(new_client->name, DRIVER_NAME);
+
+	if ((err = i2c_attach_client(new_client)))
+		goto exit_free;
+
+	pca9535_i2c_client = new_client;
+	
+	init_MUTEX(&pca9535_inited.lock);
+	i2c_set_clientdata(pca9535_i2c_client, &pca9535_inited);
+	
+	sysfs_create_group(&pca9535_i2c_client->dev.kobj, &pca9535_defattr_group);
+	
+	printk("pca9535_attach() ok, address = %d, zero_or_minus_one = %d\n", address, zero_or_minus_one);
+	return 0;
+
+exit_free:
+	printk("pca9535_attach() failed, error code = %d\n", err);
+	return err;
+}
+
+static int pca9535_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev, "Client deregistration failed, client not detached.\n");
+		return err;
+	}
+	pca9535_i2c_client = NULL;
+
+	return 0;
+}
+
+static int __init pca9535_init(void)
+{
+	return i2c_add_driver(&pca9535_driver);
+}
+
+static void __exit pca9535_exit(void)
+{
+        i2c_del_driver(&pca9535_driver);
+}
+
+/* 
+ * Reads the value of GPIO available via I2C.
+ */
+int pca9535_gpio_read(int gpio){
+	unsigned char reg = 0;
+	unsigned long val = 0;
+
+	printk("9535_gpio_read() called\n");
+	if(!pca9535_i2c_client)
+		return -ENODEV;
+
+	if(gpio < GPIO0 || gpio > GPIO17)
+		return -EINVAL;
+
+	if(gpio >= GPIO0 && gpio <= GPIO7){
+		reg   	 = PCA9535_INPUT_0;
+		gpio	-= GPIO0;
+	}else if(gpio >= GPIO8 && gpio <= GPIO17){
+		reg    	 = PCA9535_INPUT_1;
+                gpio    -= GPIO8;
+	}
+
+	down(&pca9535_inited.lock);
+
+	// Read the existing values first
+	val = pca9535_read_reg(pca9535_i2c_client, reg) >> 8;
+	val = (val >> gpio) & 0x01;
+
+	up(&pca9535_inited.lock);
+
+	return val;
+}
+
+/* 
+ * Set the value of I2C GPIO.
+ */
+int pca9535_gpio_write(int gpio, unsigned char value){
+	unsigned char in_reg  = 0;
+        unsigned char out_reg = 0;
+        unsigned long val = 0;
+	unsigned long old = 0;
+	int	      ret = 0;
+
+        if(!pca9535_i2c_client)
+                return -ENODEV;
+
+        if(gpio < GPIO0 || gpio > GPIO17)
+                return -EINVAL;
+
+        if(gpio >= GPIO0 && gpio <= GPIO7){
+                in_reg   = PCA9535_INPUT_0;
+                out_reg  = PCA9535_OUTPUT_0;
+                gpio    -= GPIO0;
+        }else if(gpio >= GPIO8 && gpio <= GPIO17){
+                in_reg   = PCA9535_INPUT_1;
+                out_reg  = PCA9535_OUTPUT_1;
+                gpio    -= GPIO8;
+        }
+
+	down(&pca9535_inited.lock);
+
+        // Read the existing values first
+        val = pca9535_read_reg(pca9535_i2c_client, in_reg);
+	old = val >> 8;
+
+	switch(value){
+	case LOW:
+		old |= (1 << gpio);
+		break;
+	case HI:
+		old &= ~(1 << gpio);
+		break;
+	default:
+		ret = -EINVAL;
+		goto error;
+	}
+
+	val = (val & 0xff) | (old << 8);	
+
+	// write the values back to the register
+	pca9535_write_reg(pca9535_i2c_client, out_reg, val);
+error:
+
+	up(&pca9535_inited.lock);
+	return ret;
+}
+
+/*
+ * Set the direction of I2C GPIO.
+ */ 
+int pca9535_gpio_direction(int gpio, unsigned char direction){
+        unsigned char reg = 0;
+        unsigned long val = 0;
+	unsigned long old = 0;
+        int           ret = 0;
+
+        if(!pca9535_i2c_client)
+                return -ENODEV;
+
+        if(gpio < GPIO0 || gpio > GPIO17)
+                return -EINVAL;
+
+        if(gpio >= GPIO0 && gpio <= GPIO7){
+                reg   	 = PCA9535_DIRECTION_0;
+                gpio    -= GPIO0;
+        }else if(gpio >= GPIO8 && gpio <= GPIO17){
+                reg   	 = PCA9535_DIRECTION_1;
+                gpio    -= GPIO8;
+        }
+
+        down(&pca9535_inited.lock);
+
+        // Read the existing values first
+        old = pca9535_read_reg(pca9535_i2c_client, reg);
+	val = old >> 8;
+
+        switch(direction){
+        case GPIO_INPUT: 
+                val |= (1 << gpio);
+                break;
+        case GPIO_OUTPUT: 
+                val &= ~(1 << gpio);
+                break;
+        default:
+                ret = -EINVAL;
+                goto error;
+        }
+
+	val = (old & 0xff) | (val << 8);
+
+        // write the values back to the register
+        pca9535_write_reg(pca9535_i2c_client, reg, val);
+error:
+
+        up(&pca9535_inited.lock);
+        return ret;
+}
+
+static u32 pca9535_read_reg(struct i2c_client *client, u8 regaddr)
+{
+	char buffer[3];
+	int r;
+	u32 data;
+
+	buffer[0] = regaddr;
+	buffer[1] = 0;
+	buffer[2] = 0;
+
+	r = i2c_master_send(client, buffer, 1);
+	if (r != 1) {
+		printk(KERN_ERR "pca9535: read failed, status %d\n", r);
+		return 0xffffffff;
+	}
+
+	r = i2c_master_recv(client, buffer, 3);
+	if (r != 3) {
+		printk(KERN_ERR "pca9535: read failed, status %d\n", r);
+		return 0xffffffff;
+	}
+
+	data = buffer[1];
+	data |= buffer[2] << 8;
+	//printk(KERN_ERR "%s: reading %x in %x\n", __FUNCTION__, data, regaddr);
+
+	return data;
+}
+
+static void pca9535_write_reg(struct i2c_client *client, u8 regaddr, u16 data)
+{
+	char buffer[3];
+	int r;
+
+	//printk(KERN_ERR "%s: writing %x in %x\n", __FUNCTION__, data, regaddr);
+	buffer[0] = regaddr;
+	buffer[1] = data >> 8;
+	buffer[2] = data & 0xff;
+
+	r = i2c_master_send(client, buffer, 3);
+	if (r != 3) {
+		printk(KERN_ERR "pca9535: write failed, status %d\n", r);
+	}
+}
+
+MODULE_AUTHOR("Husam Senussi <husamsenussi@gmail.com>");
+MODULE_DESCRIPTION("PCA9535 driver");
+MODULE_LICENSE("GPL");
+
+module_init(pca9535_init);
+module_exit(pca9535_exit);
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c
index 98bbe97..f2568ce 100644
--- a/drivers/input/keyboard/omap-keypad.c
+++ b/drivers/input/keyboard/omap-keypad.c
@@ -4,11 +4,12 @@
  * OMAP Keypad Driver
  *
  * Copyright (C) 2003 Nokia Corporation
- * Written by Timo Ters <ext-timo.teras@nokia.com>
+ * Written by Timo Ter�s <ext-timo.teras@nokia.com>
+ * iPAQ h6300 key and joypad support added by Mika Laitio. (2005)
  *
  * Added support for H2 & H3 Keypad
  * Copyright (C) 2004 Texas Instruments
- *
+ * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -44,6 +45,19 @@ #include <asm/mach-types.h>
 #include <asm/arch/mux.h>
 
 #undef NEW_BOARD_LEARNING_MODE
+//#define NEW_BOARD_LEARNING_MODE 1
+
+/*
+ * Following 5 keypad events are not really sent to userspace. 
+ * Instead if the good combination of them is sent, then that is send.
+ * (up, right, down, left, enter)
+ */
+#define	_H6300_JOYPAD_UP_RIGHT		1	// 00001
+#define _H6300_JOYPAD_DOWN_RIGHT	2	// 00010
+#define _h6300_JOYPAD_DOWN_LEFT		4	// 00100
+#define _h6300_JOYPAD_UP_LEFT		8	// 01000
+#define _H6300_JOYPAD_KEY_OK		16	// 10000
+#define _H6300_JOYPAD_REPORT_COLUMN	4
 
 static void omap_kp_tasklet(unsigned long);
 static void omap_kp_timer(unsigned long);
@@ -53,6 +67,8 @@ static DEFINE_MUTEX(kp_enable_mutex);
 static int kp_enable = 1;
 static int kp_cur_group = -1;
 
+static int prevJoypadKeycodePressEmulated;
+
 struct omap_kp {
 	struct input_dev *input;
 	struct timer_list timer;
@@ -139,7 +155,7 @@ static void omap_kp_scan_keypad(struct o
 		for (col = 0; col < omap_kp->cols; col++) {
 			omap_writew(~(1 << col) & 0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_KBC);
 
-			if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3()) {
+			if (machine_is_omap_osk() || machine_is_omap_h2() || machine_is_omap_h3() || machine_is_omap_h6300()) {
 				udelay(9);
 			} else {
 				udelay(4);
@@ -169,17 +185,26 @@ static inline int omap_kp_find_key(int c
 	return -1;
 }
 
+int is_key_down(unsigned char new_state[],
+		int col,
+		int row)
+{
+	return (new_state[col] & (1 << row)) ? 1 : 0;
+}
+
 static void omap_kp_tasklet(unsigned long data)
 {
 	struct omap_kp *omap_kp_data = (struct omap_kp *) data;
 	unsigned char new_state[8], changed, key_down = 0;
 	int col, row;
 	int spurious = 0;
+	int report_key, report_col, report_row, joypad_checked;	// h6300-joypad specific variables
 
 	/* check for any changes */
 	omap_kp_scan_keypad(omap_kp_data, new_state);
 
 	/* check for changes and print those */
+	joypad_checked	= 0;
 	for (col = 0; col < omap_kp_data->cols; col++) {
 		changed = new_state[col] ^ keypad_state[col];
 		key_down |= new_state[col];
@@ -201,14 +226,177 @@ #else
 				spurious = 1;
 				continue;
 			}
-
-			if (!(kp_cur_group == (key & GROUP_MASK) ||
-			      kp_cur_group == -1))
-				continue;
-
-			kp_cur_group = key & GROUP_MASK;
-			input_report_key(omap_kp_data->input, key & ~GROUP_MASK,
-					 !!(new_state[col] & (1 << row)));
+ 			if (machine_is_omap_h6300() && 
+ 			   ((col == 1) || (col == _H6300_JOYPAD_REPORT_COLUMN)))
+ 			{
+ 				if (col == _H6300_JOYPAD_REPORT_COLUMN)
+ 				{
+ 					continue;
+ 				}
+ 				if ((joypad_checked == 0) &&
+ 				    ((key == _H6300_JOYPAD_KEY_OK) ||
+ 				     (key == _h6300_JOYPAD_UP_LEFT) ||
+ 	    			     (key == _H6300_JOYPAD_UP_RIGHT) ||
+ 				     (key == _H6300_JOYPAD_DOWN_RIGHT) ||
+ 				     (key == _h6300_JOYPAD_DOWN_LEFT)))
+ 				{
+ 					if (is_key_down(new_state, col, row))
+ 					{
+ 						/*
+ 						 * only enter pressed
+ 						 * 1 0 0 _H6300_JOYPAD_KEY_OK 0 0
+ 						 * --> 100100 == 36
+ 						 */
+ 						 if (new_state[1] == 36)
+ 						 {
+ 						 	joypad_checked	= 1;
+ 							prevJoypadKeycodePressEmulated	= KEY_ENTER;
+ 							new_state[_H6300_JOYPAD_REPORT_COLUMN]	= 48;	//110000
+ 							report_key	= prevJoypadKeycodePressEmulated;
+ 							report_col	= _H6300_JOYPAD_REPORT_COLUMN;
+ 							report_row	= 4;
+ 							input_report_key(omap_kp_data->input,
+ 									report_key,
+ 							 		new_state[report_col] & (1 << report_row));
+ 						 }						
+ 						/*
+ 						 * enter, up_left and up_right sensors pressed.
+ 						 * 1 _H6300_JOYPAD_UP_RIGHT 0 _H6300_JOYPAD_KEY_OK 0 _h6300_JOYPAD_UP_LEFT
+ 						 * --> 110101 == 53
+ 						 * OR
+ 						 * 1 KEY_UP_RIGHT 0 0 0 _h6300_JOYPAD_UP_LEFT
+ 						 * --> 110001 == 42
+ 						 * --> move to up
+ 						 */
+ 						else if ((new_state[1] == 53) ||
+ 						         (new_state[1] == 49))
+ 						{
+ 							joypad_checked	= 1;
+ 							prevJoypadKeycodePressEmulated	= KEY_UP;
+ 							new_state[_H6300_JOYPAD_REPORT_COLUMN]	= 40;	//101000
+ 							report_key	= prevJoypadKeycodePressEmulated;
+ 							report_col	= _H6300_JOYPAD_REPORT_COLUMN;
+ 							report_row	= 3;
+ 							input_report_key(omap_kp_data->input,
+ 									report_key,
+ 							 		new_state[report_col] & (1 << report_row));
+ 						}
+ 						/*
+ 						 * enter, down_left and down_right sensors pressed
+ 						 * --> 101110 == 46
+ 						 * OR
+ 						 * down_left and down_right
+ 						 * -->101010 == 42
+ 						 * --> move to down
+ 						 */
+ 						else if ((new_state[1] == 46) ||
+ 							 (new_state[1] == 42))
+ 						{
+ 							joypad_checked	= 1;
+ 							prevJoypadKeycodePressEmulated	= KEY_DOWN;
+ 							new_state[_H6300_JOYPAD_REPORT_COLUMN]	= 34;	//100010
+ 							report_key	= prevJoypadKeycodePressEmulated;
+ 							report_col	= _H6300_JOYPAD_REPORT_COLUMN;
+ 							report_row	= 1;
+ 							input_report_key(omap_kp_data->input,
+ 									report_key,
+ 							 		new_state[report_col] & (1 << report_row));
+ 						}												
+ 						/*
+ 						 * enter, up_right and down_right sensors pressed
+ 						 * --> 111100 == 60
+ 						 * or
+ 						 * down_right and up_right
+ 						 * --> 111000 == 56
+ 						 * --> move to right
+ 						 */
+ 						else if ((new_state[1] == 60) ||
+ 							 (new_state[1] == 56))
+ 						{
+ 							joypad_checked	= 1;
+ 							prevJoypadKeycodePressEmulated	= KEY_RIGHT;
+ 							new_state[_H6300_JOYPAD_REPORT_COLUMN]	= 33;	//100001
+ 							report_key	= prevJoypadKeycodePressEmulated;
+ 							report_col	= _H6300_JOYPAD_REPORT_COLUMN;
+ 							report_row	= 0;
+ 							input_report_key(omap_kp_data->input,
+ 									report_key,
+ 							 		new_state[report_col] & (1 << report_row));
+ 						}
+ 						/*
+ 						 * enter, up_left and down_left sensors pressed
+ 						 * --> 100111 == 39
+ 						 * or up_left and down_left
+ 						 * --> 100011 == 35
+ 						 * --> move to left
+ 						 */
+ 						else if ((new_state[1] == 39) ||
+ 							 (new_state[1] == 35))
+ 						{
+ 							joypad_checked	= 1;
+ 							prevJoypadKeycodePressEmulated	= KEY_LEFT;
+ 							new_state[_H6300_JOYPAD_REPORT_COLUMN]	= 36;	//100100
+ 							report_key	= prevJoypadKeycodePressEmulated;
+ 							report_col	= _H6300_JOYPAD_REPORT_COLUMN;
+ 							report_row	= 2;
+ 							input_report_key(omap_kp_data->input,
+ 									report_key,
+ 							 		new_state[report_col] & (1 << report_row));
+ 						}
+ 						else
+ 						{
+ 							//printk("missed new_state = %d\n", new_state[1]);
+ 						}
+ 					}
+ 					else
+ 					{
+ 						if (prevJoypadKeycodePressEmulated != 0)
+ 						{
+ 							// report key up event
+ 							joypad_checked	= 1;
+ 							new_state[_H6300_JOYPAD_REPORT_COLUMN]	= 32;	//100000
+ 							report_key	= prevJoypadKeycodePressEmulated;
+ 							report_col	= _H6300_JOYPAD_REPORT_COLUMN;
+ 							switch(prevJoypadKeycodePressEmulated)
+ 							{
+ 								case KEY_RIGHT:
+									report_row	= 0;
+ 									break;
+ 								case KEY_DOWN:
+ 									report_row	= 1;
+ 									break;
+ 								case KEY_LEFT:
+ 									report_row	= 2;
+ 									break;
+ 								case KEY_UP:
+ 									report_row	= 3;
+ 									break;
+ 								case KEY_ENTER:
+ 									report_row	= 4;
+ 									break;
+ 								default:
+ 									printk(KERN_WARNING "Unknown iPAQ h6300 column 1 key = %d released. This should newer happen!\n",
+ 										key);
+ 									report_row	= 0;
+ 							}
+ 							input_report_key(omap_kp_data->input,
+ 									report_key,
+ 							 		new_state[report_col] & (1 << report_row));
+ 							prevJoypadKeycodePressEmulated	= 0;
+ 						}
+ 					}
+ 				}
+ 			}
+ 			else
+ 			{
+				if (!(kp_cur_group == (key & GROUP_MASK) ||
+				      kp_cur_group == -1))
+					continue;
+
+				kp_cur_group = key & GROUP_MASK;
+				input_report_key(omap_kp_data->input, key & ~GROUP_MASK,
+						 !!(new_state[col] & (1 << row)));
+ 			}
 #endif
 		}
 	}
@@ -348,10 +536,11 @@ static int __init omap_kp_probe(struct p
 			omap_set_gpio_direction(row_gpios[i], 1);
 		}
 	}
+	prevJoypadKeycodePressEmulated		= 0;
 
 	init_timer(&omap_kp->timer);
 	omap_kp->timer.function = omap_kp_timer;
-	omap_kp->timer.data = (unsigned long) omap_kp;
+	omap_kp->timer.data = (unsigned long)omap_kp;
 
 	/* get the irq and init timer*/
 	tasklet_enable(&kp_tasklet);
@@ -376,7 +565,7 @@ static int __init omap_kp_probe(struct p
 	input_register_device(omap_kp->input);
 
 	if (machine_is_omap_h2() || machine_is_omap_h3() ||
-	    machine_is_omap_perseus2()) {
+	    machine_is_omap_perseus2() || machine_is_omap_h6300()) {
 		omap_writew(0xff, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_DEBOUNCING);
 	}
 	/* scan current status and enable interrupt */
@@ -447,6 +636,6 @@ static void __exit omap_kp_exit(void)
 module_init(omap_kp_init);
 module_exit(omap_kp_exit);
 
-MODULE_AUTHOR("Timo Ters");
+MODULE_AUTHOR("Timo Ter�s");
 MODULE_DESCRIPTION("OMAP Keypad Driver");
 MODULE_LICENSE("GPL");
diff --git a/drivers/input/touchscreen/omap/Makefile b/drivers/input/touchscreen/omap/Makefile
index af6344e..4b94104 100644
--- a/drivers/input/touchscreen/omap/Makefile
+++ b/drivers/input/touchscreen/omap/Makefile
@@ -6,5 +6,6 @@ obj-$(CONFIG_TOUCHSCREEN_OMAP) += omapts
 
 objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_H2) += ts_hx.o
 objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_H3) += ts_hx.o
+objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_H6300) += ts_hx.o
 
 omapts-objs := omap_ts.o $(objs-yy)
diff --git a/drivers/input/touchscreen/omap/omap_ts.c b/drivers/input/touchscreen/omap/omap_ts.c
index bd85d0a..71345a2 100644
--- a/drivers/input/touchscreen/omap/omap_ts.c
+++ b/drivers/input/touchscreen/omap/omap_ts.c
@@ -46,7 +46,7 @@ #include "omap_ts.h"
 #define OMAP_TS_NAME	"omap_ts"
 
 static struct ts_device *__initdata ts_devs[] = {
-#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3)
+#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3) || defined(CONFIG_MACH_OMAP_H6300)
 	&hx_ts,
 #endif
 };
diff --git a/drivers/input/touchscreen/omap/ts_hx.c b/drivers/input/touchscreen/omap/ts_hx.c
index f148f19..9880873 100644
--- a/drivers/input/touchscreen/omap/ts_hx.c
+++ b/drivers/input/touchscreen/omap/ts_hx.c
@@ -39,6 +39,7 @@ #include "omap_ts.h"
 
 #define	H2_GPIO_NUM		4
 #define	H3_GPIO_NUM		48
+#define H6300_GPIO_NUM	2
 
 #define OMAP_TSC2101_XRES		       500
 #define TOUCHSCREEN_DATA_REGISTERS_PAGE	 0x0
@@ -88,6 +89,9 @@ static int __init hx_ts_probe(struct oma
 	} else if (machine_is_omap_h3()) {
 		gpio = H3_GPIO_NUM;
 		omap_cfg_reg(W19_1610_GPIO48);
+	} else if (machine_is_omap_h6300 ()) {
+		gpio = H6300_GPIO_NUM;
+		omap_cfg_reg(M14_1510_GPIO2);	
 	} else
 		return -ENODEV;
 
@@ -180,5 +184,7 @@ static void __exit hx_ts_remove(void)
 		omap_free_gpio(H2_GPIO_NUM);
 	else if (machine_is_omap_h3())
 		omap_free_gpio(H3_GPIO_NUM);
+	else if (machine_is_omap_h6300())
+		omap_free_gpio(H6300_GPIO_NUM);
 }
 #endif
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 6201f30..c223650 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -977,7 +977,7 @@ static void mmc_read_scrs(struct mmc_hos
 		mmc_decode_scr(card);
 	}
 
-	mmc_deselect_cards(host);
+	//mmc_deselect_cards(host);
 }
 
 static unsigned int mmc_calculate_clock(struct mmc_host *host)
diff --git a/drivers/ssi/omap-tsc2101.c b/drivers/ssi/omap-tsc2101.c
index 5dfe994..f21c179 100644
--- a/drivers/ssi/omap-tsc2101.c
+++ b/drivers/ssi/omap-tsc2101.c
@@ -36,10 +36,11 @@ #include <asm/arch/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/hardware/tsc2101.h>
 #include <asm/arch/gpioexpander.h>
+#include <asm/arch/gpio.h>
 
 #include "omap-tsc2101.h"
 
-#if CONFIG_ARCH_OMAP16XX
+#if CONFIG_ARCH_OMAP1
 #include <../drivers/ssi/omap-uwire.h>
 #else
 #error "Unsupported configuration"
@@ -66,27 +67,28 @@ int omap_tsc2101_enable(void)
 	if (count++ == 0) {
 		int ret = 0;
 		/* set the Mux to provide MCLK to TSC2101 */
-		if (machine_is_omap_h3()) {
+		if (machine_is_omap_h3())
 			ret = omap_cfg_reg(V5_1710_MCLK_ON);
-		} else {
-			if (machine_is_omap_h2()) {
-				ret = omap_cfg_reg(R10_1610_MCLK_ON);
+		else if (machine_is_omap_h2())
+			ret = omap_cfg_reg(R10_1610_MCLK_ON);
+		else if (machine_is_omap_h6300())
+			ret = omap_cfg_reg(R10_1510_MCLK_ON);
+
+		if (!cpu_is_omap1510 ()) {
+			/* Get the MCLK */
+			tsc2101_mclk_ck = clk_get(NULL, "mclk");
+			if (NULL == tsc2101_mclk_ck) {
+				printk(KERN_ERR "Unable to get the clock MCLK!!!\n");;
+				ret = -EPERM;
+				goto done;
 			}
-		}
-
-		/* Get the MCLK */
-		tsc2101_mclk_ck = clk_get(NULL, "mclk");
-		if (NULL == tsc2101_mclk_ck) {
-			printk(KERN_ERR "Unable to get the clock MCLK!!!\n");;
-			ret = -EPERM;
-			goto done;
-		}
-		if (clk_set_rate(tsc2101_mclk_ck, 12000000)) {
-			printk(KERN_ERR "Unable to set rate to the MCLK!!!\n");;
-			ret = -EPERM;
-			goto done;
-		}
-		clk_enable(tsc2101_mclk_ck);
+			if (clk_set_rate(tsc2101_mclk_ck, 12000000)) {
+				printk(KERN_ERR "Unable to set rate to the MCLK!!!\n");;
+				ret = -EPERM;
+				goto done;
+			}
+			clk_enable(tsc2101_mclk_ck);
+		} /* if (!cpu_is_omap1510 ()) */
 
 		ret = omap_tsc2101_configure();
 
@@ -116,10 +118,16 @@ void omap_tsc2101_disable(void)
 			}
 		}
 
-		/* Release the MCLK */
-		clk_disable(tsc2101_mclk_ck);
-		clk_put(tsc2101_mclk_ck);
-		tsc2101_mclk_ck = NULL;
+		if (!cpu_is_omap1510 ()) {
+			/* Release the MCLK */
+			clk_disable(tsc2101_mclk_ck);
+			clk_put(tsc2101_mclk_ck);
+			tsc2101_mclk_ck = NULL;
+		}
+
+#if defined(CONFIG_MACH_OMAP_H6300)
+		omap_free_gpio(8);
+#endif
 
 		module_put(THIS_MODULE);
 	}
@@ -150,7 +158,10 @@ void omap_tsc2101_write(int page, u8 add
 			return;
 		}
 	}
-	if (machine_is_omap_h3()) {
+	if (machine_is_omap_h3() || machine_is_omap_h6300()) {
+
+		if (machine_is_omap_h6300())
+			omap_set_gpio_dataout (8, 0);
 
 		ret =
 		    omap_uwire_data_transfer(0, ((page << 11) | (address << 5)),
@@ -159,6 +170,8 @@ void omap_tsc2101_write(int page, u8 add
 			printk(KERN_ERR
 			       "uwire-write returned error for address %x\n",
 			       address);
+		if (machine_is_omap_h6300())
+			omap_set_gpio_dataout (8, 1);
 			return;
 		}
 		ret = omap_uwire_data_transfer(0, data, 16, 0, NULL, 0);
@@ -166,10 +179,14 @@ void omap_tsc2101_write(int page, u8 add
 			printk(KERN_ERR
 			       "uwire-write returned error for address %x\n",
 			       address);
+			if (machine_is_omap_h6300())
+				omap_set_gpio_dataout (8, 1);
 			return;
 		}
-	}
 
+		if (machine_is_omap_h6300())
+			omap_set_gpio_dataout (8, 1);
+	}
 }
 
 void omap_tsc2101_reads(int page, u8 startaddress, u16 * data, int numregs)
@@ -178,9 +195,13 @@ void omap_tsc2101_reads(int page, u8 sta
 	if (machine_is_omap_h2()) {
 		cs = 1;
 	}
-	if (machine_is_omap_h3()) {
+	if (machine_is_omap_h3() || machine_is_omap_h6300()) {
 		cs = 0;
 	}
+
+	if (machine_is_omap_h6300())
+		omap_set_gpio_dataout(8, 0);
+
 	(void)omap_uwire_data_transfer(cs, (0x8000 | (page << 11)
 					    | (startaddress << 5)),
 				       16, 0, NULL, 1);
@@ -188,6 +209,9 @@ void omap_tsc2101_reads(int page, u8 sta
 		omap_uwire_data_transfer(cs, 0, 0, 16, data, 1);
 	}
 	omap_uwire_data_transfer(cs, 0, 0, 16, data, 0);
+
+	if (machine_is_omap_h6300())
+		omap_set_gpio_dataout(8, 1);
 }
 
 u16 omap_tsc2101_read(int page, u8 address)
@@ -228,9 +252,24 @@ #endif
 		omap_cfg_reg(N14_1610_UWIRE_CS0);
 		omap_uwire_configure_mode(0, uwire_flags);
 	}
+	if (machine_is_omap_h6300()) {
+		uwire_flags = UWIRE_READ_RISING_EDGE | UWIRE_WRITE_RISING_EDGE;
+		omap_cfg_reg(N14_1510_UWIRE_CS0);
+		omap_uwire_configure_mode(0, uwire_flags);
+
+		omap_request_gpio(8);
+		omap_set_gpio_dataout(8, 0);
+		omap_set_gpio_direction (8, 0);
+	}
 
 	/* Configure MCLK enable */
-	omap_writel(omap_readl(PU_PD_SEL_2) | (1 << 22), PU_PD_SEL_2);	
+	if (cpu_is_omap16xx() || cpu_is_omap1710())
+		omap_writel(omap_readl(PU_PD_SEL_2) | (1 << 22), PU_PD_SEL_2);	
+	if (machine_is_omap_h6300()) {
+		omap_cfg_reg(V19_1510_UWIRE_SCLK);
+		omap_cfg_reg(W21_1510_UWIRE_SDO);
+		omap_cfg_reg(U18_1510_UWIRE_SDI);
+	}
 
 	return 0;
 }
@@ -243,5 +282,5 @@ EXPORT_SYMBOL(omap_tsc2101_disable);
 
 MODULE_AUTHOR("Texas Instruments");
 MODULE_DESCRIPTION
-    ("Glue audio driver for the TI OMAP1610/OMAP1710 TSC2101 codec.");
+    ("Glue audio driver for the TI OMAP1510/1610/OMAP1710 TSC2101 codec.");
 MODULE_LICENSE("GPL");
diff --git a/drivers/ssi/omap-uwire.c b/drivers/ssi/omap-uwire.c
index 61b3ca1..01e6d9d 100644
--- a/drivers/ssi/omap-uwire.c
+++ b/drivers/ssi/omap-uwire.c
@@ -10,7 +10,7 @@
  * Ported to 2.6 uwire interface.
  * Copyright (C) 2004 Texas Instruments.
  *
- * Generalization patches by Juha Yrjl <juha.yrjola@nokia.com>
+ * Generalization patches by Juha Yrj�l� <juha.yrjola@nokia.com>
  *
  *  This program is free software; you can redistribute	 it and/or modify it
  *  under  the terms of	 the GNU General  Public License as published by the
@@ -212,6 +212,10 @@ static int __init omap_uwire_init(void)
 		omap_cfg_reg(N14_1610_UWIRE_CS0);
 		omap_cfg_reg(P15_1610_UWIRE_CS3);
 	}
+	if (machine_is_omap_h6300()) {
+		omap_cfg_reg(N14_1510_UWIRE_CS0);
+		omap_cfg_reg(P15_1510_UWIRE_CS3);
+	}
 	if (machine_is_omap_perseus2()) {
 		/* configure pins: MPU_UW_nSCS1, MPU_UW_SDO, MPU_UW_SCLK */
 		int val = omap_readl(OMAP730_IO_CONF_9) & ~0x00EEE000;
diff --git a/drivers/telephony/Kconfig b/drivers/telephony/Kconfig
index 7625b18..7ff3391 100644
--- a/drivers/telephony/Kconfig
+++ b/drivers/telephony/Kconfig
@@ -41,7 +41,18 @@ config PHONE_IXJ_PCMCIA
 	help
 	  Say Y here to configure in PCMCIA service support for the Quicknet
 	  cards manufactured by Quicknet Technologies, Inc.  This changes the
-	  card initialization code to work with the card manager daemon.
+	  card initialization code to work with the card manager daemon.	  
+
+config GSM_H6300
+	tristate "H6300 P5186 GSM/GPRS DRIVER"
+	depends on PHONE && I2C && PCA9535
+	help
+	  Bluetooth H6300 P5186 gsm/gprs driver.
+	  This driver provides the firmware loading mechanism for the P5185
+	  gsm/gprs hardware in iPAQ h6300.
+
+	  Say Y here to compile support for P5186 gsm/gprs devices into the
+	  kernel or say M to compile it as module (h6300_gsm).
 
 endmenu
 
diff --git a/drivers/telephony/Makefile b/drivers/telephony/Makefile
index 1206615..4338257 100644
--- a/drivers/telephony/Makefile
+++ b/drivers/telephony/Makefile
@@ -2,6 +2,7 @@ #
 # Makefile for drivers/telephony
 #
 
-obj-$(CONFIG_PHONE) += phonedev.o
-obj-$(CONFIG_PHONE_IXJ) += ixj.o
-obj-$(CONFIG_PHONE_IXJ_PCMCIA) += ixj_pcmcia.o
+obj-$(CONFIG_PHONE)				+= phonedev.o
+obj-$(CONFIG_PHONE_IXJ)			+= ixj.o
+obj-$(CONFIG_PHONE_IXJ_PCMCIA)	+= ixj_pcmcia.o
+obj-$(CONFIG_GSM_H6300)			+= omap/
diff --git a/drivers/telephony/omap/Makefile b/drivers/telephony/omap/Makefile
new file mode 100644
index 0000000..170d1f1
--- /dev/null
+++ b/drivers/telephony/omap/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the Linux iPAQ H6300 BRF6100 Bluetooth device drivers.
+#
+
+h6300_gsm-objs			:= h6300_gsm_led.o h6300_gsm_p5186.o
+obj-$(CONFIG_GSM_H6300)	+= h6300_gsm.o
diff --git a/drivers/telephony/omap/h6300_gsm_led.c b/drivers/telephony/omap/h6300_gsm_led.c
new file mode 100644
index 0000000..7842c87
--- /dev/null
+++ b/drivers/telephony/omap/h6300_gsm_led.c
@@ -0,0 +1,40 @@
+/* 
+ * GSM interface driver helper for controlling bluetooth leds available in iPAQ h6300.
+ * 
+ * Copyright (C) 2005 Mika Laitio  <lamikr@cc.jyu.fi>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/gpio.h>
+
+/* 
+ * Low level access for disabling h6300 gsm led.
+ *
+ * TODO: implement for h6300 
+ */
+void h6300_clear_gsm_led(int led_num)
+{
+	printk(KERN_NOTICE "h6300_gsm_led.c h6300_clear_gsm_led() done\n");
+	//hx4700_set_led(led_num, 0, 16);
+}
+EXPORT_SYMBOL(h6300_clear_gsm_led);
+
+/* 
+ * Low level access for setting up the gsm led.
+ *
+ * TODO: implement for h6300 
+ */
+void h6300_set_gsm_led(int led_num, int duty_time, int cycle_time)
+{
+	printk(KERN_NOTICE "h6300_gsm_led.c h6300_set_gsm_led() done\n");
+}
+EXPORT_SYMBOL(h6300_set_gsm_led);
diff --git a/drivers/telephony/omap/h6300_gsm_led.h b/drivers/telephony/omap/h6300_gsm_led.h
new file mode 100644
index 0000000..fe11f4d
--- /dev/null
+++ b/drivers/telephony/omap/h6300_gsm_led.h
@@ -0,0 +1,10 @@
+#ifndef H6300_GSM_LED_H_
+#define H6300_GSM_LED_H_
+
+#define INDEX_GSM_LED	1
+
+void h6300_clear_gsm_led(int led_num);
+void h6300_set_gsm_led(int led_num, int duty_time, int cycle_time);
+
+
+#endif /*H6300_GSM_LED_H_*/
diff --git a/drivers/telephony/omap/h6300_gsm_p5186.c b/drivers/telephony/omap/h6300_gsm_p5186.c
new file mode 100644
index 0000000..b007c5f
--- /dev/null
+++ b/drivers/telephony/omap/h6300_gsm_p5186.c
@@ -0,0 +1,172 @@
+/* 
+ * Wavecom P5186 GPRS and GSM module driver for iPAQ h6300.
+ * 
+ * Copyright (C) 2005 Mika Laitio <lamikr@cc.jyu.fi>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+
+#include <asm/hardware.h>
+#include <asm/arch/gpio.h>
+
+#include <asm/arch/pca9535.h>
+#include <asm/arch/h6300_uart_info.h>
+#include "h6300_gsm_led.h"
+
+static void
+h6300_gsm_configure(struct uart_omap_port *up, int enable)
+{
+	printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_configure() started, enable = %d\n", enable);
+	
+	// printk( KERN_NOTICE "h6300 configure bluetooth: %d\n", enable );
+	if (enable == 0) {
+		pca9535_gpio_write(GPIO_I2C_GPRS_RESET, GPIO_VALUE_OFF);	// turn off gpio
+		mdelay(5);
+		h6300_clear_gsm_led(INDEX_GSM_LED);
+	}
+	else if (enable == 1) {
+		pca9535_gpio_write(GPIO_I2C_GPRS_RESET, GPIO_VALUE_ON);	// turn on gpio
+		mdelay(5);				
+	}
+	else if (enable == 2) {
+		h6300_set_gsm_led(INDEX_GSM_LED, 16, 16);
+	}
+	printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_configure() done\n");
+}
+
+static void
+h6300_gsm_set_txrx(struct uart_omap_port *up, int txrx)
+{
+	printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_set_txrx(), txrx = %d done\n", txrx);
+	/* do nothing */
+}
+
+static int
+h6300_gsm_get_txrx(struct uart_omap_port *up)
+{
+	printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_get_txrx() done\n");
+	/* do nothing */
+	return 0;
+}
+
+static int
+h6300_gsm_probe(struct platform_device *pdev)
+{
+	int	ii;
+	int	curVal;
+	
+	struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
+/*
+	printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_probe() started\n");	
+	for (ii = 0; ii < 8; ii++)
+	{
+		curVal	= pca9535_gpio_read(ii);
+		printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal);
+	}
+	for (ii = 10; ii < 18; ii++)
+	{
+		curVal	= pca9535_gpio_read(ii);
+		printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal);
+	}
+	printk(KERN_NOTICE "\nfirst check done\n");
+*/
+	pca9535_gpio_direction(GPIO_I2C_GPRS_RESET, GPIO_DIR_OUTPUT);	// set gpio direction to be output
+	pca9535_gpio_write(GPIO_I2C_GPRS_RESET, GPIO_VALUE_ON);	// turn on gpio
+	mdelay(200);
+	
+	pca9535_gpio_direction(GPIO_I2C_MIC_OP_EN, GPIO_DIR_OUTPUT);	// set gpio direction to be output
+	pca9535_gpio_write(GPIO_I2C_MIC_OP_EN, GPIO_VALUE_ON);	// turn on gpio
+	mdelay(200);
+
+	pca9535_gpio_direction(GPIO_I2C_SPK_OP_PD, GPIO_DIR_OUTPUT);	// set gpio direction to be output
+	pca9535_gpio_write(GPIO_I2C_SPK_OP_PD, GPIO_VALUE_ON);	// pd = pulldown?, normal off = on
+
+	mdelay(200);
+	
+	//pca9535_gpio_direction(
+	/* configure bluetooth UART */
+	//h6300_gpio_mode(GPIO_NR_H6300_BT_RXD_MD);
+	//h6300_gpio_mode(GPIO_NR_H6300_BT_TXD_MD);
+	//h6300_gpio_mode(GPIO_NR_H6300_BT_UART_CTS_MD);
+	//h6300_gpio_mode(GPIO_NR_H6300_BT_UART_RTS_MD);
+
+	funcs->configure	= h6300_gsm_configure;
+	funcs->set_txrx		= h6300_gsm_set_txrx;
+	funcs->get_txrx		= h6300_gsm_get_txrx;
+
+	/* Make sure the LED is off */
+	h6300_clear_gsm_led(INDEX_GSM_LED);	
+/*	
+	for (ii = 0; ii < 8; ii++)
+	{
+		curVal	= pca9535_gpio_read(ii);
+		printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal);
+	}
+	for (ii = 10; ii < 18; ii++)
+	{
+		curVal	= pca9535_gpio_read(ii);
+		printk(KERN_NOTICE "I2C[%d] = %d ", ii, curVal);
+	}
+*/	
+	printk(KERN_NOTICE "\nh6300_gsm_p5186.c h6300_gsm_probe() done\n");
+		
+	return 0;
+}
+
+static int
+h6300_gsm_remove(struct platform_device *pdev)
+{
+	struct h6300_uart_funcs *funcs = (struct h6300_uart_funcs *)pdev->dev.platform_data;
+	
+	printk(KERN_NOTICE "h6300_gsm_p5186.c h6300_gsm_remove() started\n");	
+
+	pca9535_gpio_write(GPIO_I2C_GPRS_RESET, 0);	// turn off gpio
+	
+	funcs->configure	= NULL;
+	funcs->set_txrx		= NULL;
+	funcs->get_txrx		= NULL;
+
+	/* Make sure the LED is off */
+	h6300_clear_gsm_led(INDEX_GSM_LED);
+	
+	printk(KERN_NOTICE "h6300_gsm_p5186.c, h6300_gsm_remove() done\n");
+
+	return 0;
+}
+
+static struct platform_driver gsm_driver = {
+	.probe    = h6300_gsm_probe,
+	.remove   = h6300_gsm_remove,
+	.driver = {
+		.name	= "h6300_gsm",
+	},
+};
+
+static int __init
+h6300_gsm_init(void)
+{
+	printk(KERN_NOTICE "h6300 GSM Driver init()\n");
+	return platform_driver_register(&gsm_driver);
+}
+
+static void __exit
+h6300_gsm_exit(void)
+{
+	printk(KERN_NOTICE "h6300 GSM Driver exit()\n");
+	platform_driver_unregister(&gsm_driver);
+}
+
+module_init(h6300_gsm_init);
+module_exit(h6300_gsm_exit);
+
+MODULE_AUTHOR("Mika Laitio, <lamikr@cc.jyu.fi>");
+MODULE_DESCRIPTION("iPAQ h6300 Wavecom P5186 GPRS and GSM module driver.");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 4b564bf..cb8c597 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -60,7 +60,8 @@ #include "omap_udc.h"
 #undef	USB_TRACE
 
 /* bulk DMA seems to be behaving for both IN and OUT */
-#define	USE_DMA
+//#define	USE_DMA
+#undef USE_DMA
 
 /* ISO too */
 #define	USE_ISO
@@ -2146,7 +2147,7 @@ int usb_gadget_register_driver (struct u
 	/* boards that don't have VBUS sensing can't autogate 48MHz;
 	 * can't enter deep sleep while a gadget driver is active.
 	 */
-	if (machine_is_omap_innovator() || machine_is_omap_osk())
+	if (machine_is_omap_innovator() || machine_is_omap_osk() || machine_is_omap_h6300())
 		omap_vbus_session(&udc->gadget, 1);
 
 done:
@@ -2169,7 +2170,7 @@ int usb_gadget_unregister_driver (struct
 	if (udc->dc_clk != NULL)
 		omap_udc_enable_clock(1);
 
-	if (machine_is_omap_innovator() || machine_is_omap_osk())
+	if (machine_is_omap_innovator() || machine_is_omap_osk() || machine_is_omap_h6300())
 		omap_vbus_session(&udc->gadget, 0);
 
 	if (udc->transceiver)
@@ -2789,7 +2790,7 @@ static int __init omap_udc_probe(struct 
 		hmc = HMC_1510;
 		type = "(unknown)";
 
-		if (machine_is_omap_innovator()) {
+		if (machine_is_omap_innovator() || machine_is_omap_h6300()) {
 			/* just set up software VBUS detect, and then
 			 * later rig it so we always report VBUS.
 			 * FIXME without really sensing VBUS, we can't
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index 7c3b461..9f819bd 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -315,11 +315,7 @@ static int usb_hcd_omap_probe (const str
 	if (IS_ERR(usb_host_ck))
 		return PTR_ERR(usb_host_ck);
 
-	if (!cpu_is_omap1510())
-		usb_dc_ck = clk_get(0, "usb_dc_ck");
-	else
-		usb_dc_ck = clk_get(0, "lb_ck");
-
+	usb_dc_ck = clk_get(0, "usb_dc_ck");
 	if (IS_ERR(usb_dc_ck)) {
 		clk_put(usb_host_ck);
 		return PTR_ERR(usb_dc_ck);
diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile
index 444643e..256cd93 100644
--- a/drivers/video/omap/Makefile
+++ b/drivers/video/omap/Makefile
@@ -23,6 +23,7 @@ objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MAC
 objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
 objs-y$(CONFIG_MACH_OMAP_PERSEUS2) += lcd_p2.o
 objs-y$(CONFIG_MACH_OMAP_APOLLON) += lcd_apollon.o
+objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_H6300) += lcd_h6300.o
 
 objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
 
diff --git a/drivers/video/omap/lcd_h6300.c b/drivers/video/omap/lcd_h6300.c
new file mode 100644
index 0000000..749f01c
--- /dev/null
+++ b/drivers/video/omap/lcd_h6300.c
@@ -0,0 +1,154 @@
+/*
+ * File: drivers/video/omap_new/lcd-h6300.c
+ *
+ * LCD panel support for the TI OMAP1510 Innovator board
+ *
+ * Copyright (C) 2004 Nokia Corporation
+ * Author: Imre Deak <imre.deak@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <asm/io.h>
+
+#include <asm/arch/pca9535.h>
+#include <asm/arch/omapfb.h>
+
+/* #define OMAPFB_DBG 1 */
+
+//static struct clk *h6300_lcd_ck;
+
+static int h6300_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
+{
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_init() started\n");
+/*
+	if ((h6300_lcd_ck = clk_get (NULL, "lcd_ck")) == NULL) {
+		printk(KERN_ERR "Unable to get the clock LCD_CK!!!\n");
+		return -EPERM;
+	} clk_enable(h6300_lcd_ck);
+*/
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_init() done\n");
+	return 0;
+}
+
+static void h6300_panel_cleanup(struct lcd_panel *panel)
+{
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_cleanup() started\n");
+/*
+	if (h6300_lcd_ck) {
+		clk_disable(h6300_lcd_ck);
+		clk_put(h6300_lcd_ck);
+		h6300_lcd_ck = NULL;
+	}
+*/
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_cleanup() done\n");
+}
+
+static int h6300_panel_enable(struct lcd_panel *panel)
+{
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_enable() done\n");
+	return 0;
+}
+
+static void h6300_panel_disable(struct lcd_panel *panel)
+{
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_disable() done\n");	
+}
+
+static unsigned long h6300_panel_get_caps(struct lcd_panel *panel)
+{
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_get_caps() done\n");	
+	return 0;
+}
+
+struct lcd_panel h6300_panel = {
+	.name		= "h6300",
+	.config		= OMAP_LCDC_PANEL_TFT,
+
+	.bpp		= 16,
+	.data_lines	= 16,
+	.x_res		= 240,
+	.y_res		= 320,
+	.pixel_clock	= 21000,
+	.hsw		= 12,
+	.hfp		= 10,
+	.hbp		= 10,
+	.vsw		= 3,
+	.vfp		= 10,
+	.vbp		= 3,
+	.pcd		= 0,
+
+	.init		= h6300_panel_init,
+	.cleanup	= h6300_panel_cleanup,
+	.enable		= h6300_panel_enable,
+	.disable	= h6300_panel_disable,
+	.get_caps	= h6300_panel_get_caps,
+};
+
+static int h6300_panel_probe(struct platform_device *pdev)
+{
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_probe() started\n");
+	omapfb_register_panel(&h6300_panel);
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_probe() done\n");
+	return 0;
+}
+
+static int h6300_panel_remove(struct platform_device *pdev)
+{
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_remove() done\n");
+	return 0;
+}
+
+static int h6300_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
+{
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_suspend() started\n");
+	pca9535_gpio_write(GPIO3, HI);
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_suspend() done\n");
+	return 0;
+}
+
+static int h6300_panel_resume(struct platform_device *pdev)
+{
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_resume() started\n");
+	pca9535_gpio_write(GPIO3, LOW);
+	printk(KERN_INFO "lcd_h6300.c: h6300_panel_resume() done\n");
+	return 0;
+}
+
+struct platform_driver h6300_panel_driver = {
+	.probe		= h6300_panel_probe,
+	.remove	= h6300_panel_remove,
+	.suspend	= h6300_panel_suspend,
+	.resume	= h6300_panel_resume,
+	.driver		= {
+		.name	= "lcd_h6300",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int h6300_panel_drv_init(void)
+{
+	return platform_driver_register(&h6300_panel_driver);
+}
+
+static void h6300_panel_drv_cleanup(void)
+{
+	platform_driver_unregister(&h6300_panel_driver);
+}
+
+module_init(h6300_panel_drv_init);
+module_exit(h6300_panel_drv_cleanup);
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 4e73cd4..77ac419 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -1438,7 +1438,7 @@ #endif
 #ifdef CONFIG_FB_OMAP_DMA_TUNE
 	/* Set DMA priority for EMIFF access to highest */
 	if (cpu_class_is_omap1())
-		omap_set_dma_priority(OMAP_DMA_PORT_EMIFF, 15);
+		omap_set_dma_priority(0, OMAP_DMA_PORT_EMIFF, 15);
 #endif
 
 	r = ctrl_change_mode(fbdev->fb_info[0]);
diff --git a/include/asm-arm/arch-omap/board-h6300.h b/include/asm-arm/arch-omap/board-h6300.h
new file mode 100644
index 0000000..0938fff
--- /dev/null
+++ b/include/asm-arm/arch-omap/board-h6300.h
@@ -0,0 +1,40 @@
+/*
+ * linux/include/asm-arm/arch-omap/board-innovator.h
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __ASM_ARCH_OMAP_H6300_H
+#define __ASM_ARCH_OMAP_H6300_H
+
+#ifndef OMAP_SDRAM_DEVICE
+#define OMAP_SDRAM_DEVICE				D256M_1X16_4B
+#endif
+
+#define OMAP1510P1_IMIF_PRI_VALUE		0x00
+#define OMAP1510P1_EMIFS_PRI_VALUE		0x00
+#define OMAP1510P1_EMIFF_PRI_VALUE		0x00
+
+#define NR_FPGA_IRQS					24
+#define NR_IRQS                 		IH_BOARD_BASE + NR_FPGA_IRQS
+
+#endif /* __ASM_ARCH_OMAP_H6300_H */
diff --git a/include/asm-arm/arch-omap/h6300_uart_info.h b/include/asm-arm/arch-omap/h6300_uart_info.h
new file mode 100644
index 0000000..7c36104
--- /dev/null
+++ b/include/asm-arm/arch-omap/h6300_uart_info.h
@@ -0,0 +1,33 @@
+/*
+ * Support file for calling h6300 uart configuration functions.
+ * Used at least by h6300_bt driver.
+ * 
+ * Copyright (c) 2005 SDG Systems, LLC
+ * 2005-03-29   Todd Blumer     Converted  basic structure to support hx4700
+ * 2005-10-03   Mika Laitio (lamikr@cc.jyu.fi)	Reorganized for the iPAQ h6300 bt driver.
+ */
+
+#ifndef _H6300_UART_INFO_H
+#define _H6300_UART_INFO_H
+
+#include "omap_serial.h"
+
+#define GPIO_BT_PWR_EN 3
+#define GPIO_N_BT_RST 9
+
+#define GPIO_I2C_GPRS_RESET 16
+#define GPIO_I2C_MIC_OP_EN 10
+#define GPIO_I2C_SPK_OP_PD 11
+
+#define GPIO_VALUE_OFF	0
+#define GPIO_VALUE_ON	1
+
+#define GPIO_DIR_OUTPUT 1
+
+struct h6300_uart_funcs {
+	void (*configure)( struct uart_omap_port *up, int state);
+	void (*set_txrx)( struct uart_omap_port *up, int txrx);
+	int (*get_txrx)( struct uart_omap_port *up);
+};
+
+#endif
diff --git a/include/asm-arm/arch-omap/hardware.h b/include/asm-arm/arch-omap/hardware.h
index 4d226b2..88d88dc 100644
--- a/include/asm-arm/arch-omap/hardware.h
+++ b/include/asm-arm/arch-omap/hardware.h
@@ -290,6 +290,10 @@ #ifdef CONFIG_MACH_OMAP_INNOVATOR
 #include "board-innovator.h"
 #endif
 
+#ifdef CONFIG_MACH_OMAP_H6300
+#include "board-h6300.h"
+#endif
+
 #ifdef CONFIG_MACH_OMAP_H2
 #include "board-h2.h"
 #endif
diff --git a/include/asm-arm/arch-omap/mux.h b/include/asm-arm/arch-omap/mux.h
index 679869c..406de31 100644
--- a/include/asm-arm/arch-omap/mux.h
+++ b/include/asm-arm/arch-omap/mux.h
@@ -320,6 +320,13 @@ enum omap1xxx_index {
 	P15_1610_UWIRE_CS3,
 	N15_1610_UWIRE_CS1,
 
+	/* OMAP-1510 uWire */
+	P15_1510_UWIRE_CS3,
+	N14_1510_UWIRE_CS0,
+	V19_1510_UWIRE_SCLK,
+	W21_1510_UWIRE_SDO,
+	U18_1510_UWIRE_SDI,
+
 	/* OMAP-1610 Flash */
 	L3_1610_FLASH_CS2B_OE,
 	M8_1610_FLASH_CS2B_WE,
@@ -384,6 +391,7 @@ enum omap1xxx_index {
 	T20_1610_LOW_PWR,
 
 	/* MCLK Settings */
+	R10_1510_MCLK_ON,
 	V5_1710_MCLK_ON,
 	V5_1710_MCLK_OFF,
 	R10_1610_MCLK_ON,
diff --git a/include/asm-arm/arch-omap/omap-alsa.h b/include/asm-arm/arch-omap/omap-alsa.h
index e655d35..b4ec45a 100644
--- a/include/asm-arm/arch-omap/omap-alsa.h
+++ b/include/asm-arm/arch-omap/omap-alsa.h
@@ -1,6 +1,6 @@
 /*
  * linux/include/asm-arm/arch-omap/omap-alsa.h
- *
+ * 
  * Alsa Driver for AIC23 and TSC2101 codecs on OMAP platform boards.
  *
  * Copyright (C) 2006 Mika Laitio <lamikr@cc.jyu.fi>
@@ -101,7 +101,7 @@ struct snd_card_omap_codec {
 	struct audio_stream s[2];	/* playback & capture */
 };
 
-/* Codec specific information and function pointers.
+/* Codec specific information and function pointers. 
  * Codec (omap-alsa-aic23.c and omap-alsa-tsc2101.c)
  * are responsible for defining the function pointers.
  */
@@ -138,6 +138,7 @@ #define snd_omap_alsa_suspend	NULL
 #define snd_omap_alsa_resume	NULL
 #endif
 
+/*********** function prototype to function called from the dma interrupt handler ******/
 void callback_omap_alsa_sound_dma(void *);
 
 #endif
diff --git a/include/asm-arm/arch-omap/omap_serial.h b/include/asm-arm/arch-omap/omap_serial.h
new file mode 100644
index 0000000..add09dc
--- /dev/null
+++ b/include/asm-arm/arch-omap/omap_serial.h
@@ -0,0 +1,62 @@
+/*
+ * Omap/h6300 serial driver private interface. 
+ * Code originates from the pxa-serial.h available in the handheld org drivers
+ * for iPAQ PXA4700.
+ *
+ * Copyright (c) 2005 SDG Systems, LLC
+ * 2005-03-29   Todd Blumer     Converted  basic structure to support hx4700
+ * 2005-10-03   Mika Laitio (lamikr@cc.jyu.fi)	Reorganized for the iPAQ h6300 bt driver.
+ */
+ 
+#ifndef _OMAP_SERIAL_H
+#define _OMAP_SERIAL_H
+
+#define OMAP_SERIAL_TX 1
+#define OMAP_SERIAL_RX 2
+
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+
+struct platform_omap_serial_funcs;
+
+struct uart_omap_port {
+	struct uart_port			port;
+	unsigned char				ier;
+	unsigned char				lcr;
+	unsigned char				mcr;
+	unsigned int    			lsr_break_flag;
+	unsigned int				cken;
+	char					*name;
+	struct platform_omap_serial_funcs	*pf;
+};
+
+/* A pointer to such a structure can be contained in the platform_data
+ * field of every PXA UART platform_device. If the field is NULL, the
+ * serial port works as usual.
+ *
+ * For the sake of simplicity/performance no one of the function pointers
+ * in the structure below can be NULL.
+ */
+struct platform_omap_serial_funcs {
+	/* Platform-specific function to initialize whatever is connected
+         to this serial port... enable=1 -> enable transceiver,
+         0 -> disable transceiver. */
+	void (*configure) (struct uart_omap_port *up, int enable);
+        /* Platform-specific function to enable or disable the individual
+           transmitter/receiver submodules. On transceivers without echo
+           cancellation (e.g. SIR) transmitter always has priority, e.g.
+           if both bits are set, only the transmitter is enabled. */
+        void (*set_txrx) (struct uart_omap_port *up, int txrx);
+	/* Get the current state of tx/rx (see bitflags above) */
+	int (*get_txrx) (struct uart_omap_port *up);
+};
+
+/*
+ * The variables below are located in arch/arm/mach-omap/board_h6300.c
+ * Machine-specific code may want to put a pointer to a static
+ * platform_pxa_serial_funcs structure in the dev.platform_data
+ * field of the respective port device.
+ */
+extern struct platform_device btuart_device;
+
+#endif
diff --git a/include/asm-arm/arch-omap/pca9535.h b/include/asm-arm/arch-omap/pca9535.h
new file mode 100644
index 0000000..edf8f54
--- /dev/null
+++ b/include/asm-arm/arch-omap/pca9535.h
@@ -0,0 +1,39 @@
+#ifndef _PCA9535_H
+#define _PCA9535_H
+
+enum  pca9535_gpios {
+	GPIO0 = 0,
+	GPIO1 = 1,
+	GPIO2 = 2,
+	GPIO3 = 3,
+	GPIO4 = 4,
+	GPIO5 = 5,
+	GPIO6 = 6,
+	GPIO7 = 7,
+	GPIO8 = 8,
+	GPIO9 = 9,
+	GPIO10 = 10,
+	GPIO11 = 11,
+	GPIO12 = 12,
+	GPIO13 = 13,
+	GPIO14 = 14,
+	GPIO15 = 15,
+	GPIO16 = 16,
+	GPIO17 = 17
+};
+
+enum gpio_values {
+	HI	= 0,
+	LOW	= 1
+};
+
+enum gpio_direction {
+	GPIO_INPUT	= 0,
+	GPIO_OUTPUT	= 1
+};
+
+extern int pca9535_gpio_read(int gpio);
+extern int pca9535_gpio_write(int gpio, unsigned char val);	
+extern int pca9535_gpio_direction(int gpio, unsigned char direction);
+
+#endif
-- 
1.3.3

