---
 arch/arm/mach-pxa/Kconfig         |   10 
 arch/arm/mach-pxa/Makefile        |    1 
 arch/arm/mach-pxa/hx2750.c        |  450 ++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-pxa/hx2750_test.c   |  433 ++++++++++++++++++++++++++++++++++++
 arch/arm/mach-pxa/pm.c            |    5 
 arch/arm/mach-pxa/pxa25x.c        |    4 
 arch/arm/mach-pxa/pxa27x.c        |    4 
 include/asm-arm/arch-pxa/hx2750.h |   90 +++++++
 8 files changed, 995 insertions(+), 2 deletions(-)

Index: linux-2.6.22/include/asm-arm/arch-pxa/hx2750.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.22/include/asm-arm/arch-pxa/hx2750.h	2007-08-28 20:34:43.000000000 +0100
@@ -0,0 +1,90 @@
+/*
+ * Hardware specific definitions for iPAQ hx2750
+ *
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * Author: Richard Purdie <richard@o-hand.com>
+ *
+ * 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.
+ *
+ */
+#ifndef __ASM_ARCH_HX2750_H
+#define __ASM_ARCH_HX2750_H  1
+
+/*
+ * HX2750 (Non Standard) GPIO Definitions
+ */
+
+#define HX2750_GPIO_KEYPWR      (0)    /* Power button */
+#define HX2750_GPIO_BATTCOVER1  (9)    /* Battery Cover Switch */
+#define HX2750_GPIO_CF_IRQ      (11)   /* CF IRQ? */
+#define HX2750_GPIO_USBCONNECT  (12)   /* USB Connected? */
+#define HX2750_GPIO_CF_DETECT   (13)   /* CF Card Detect? */
+#define HX2750_GPIO_EXTPWR      (14)   /* External Power Detect */
+#define HX2750_GPIO_BATLVL      (15)   /* Battery Level Detect */
+#define HX2750_GPIO_CF_PWR      (17)   /* CF Power? */
+#define HX2750_GPIO_SR_STROBE   (18)   /* Shift Register Strobe */
+#define HX2750_GPIO_CHARGE      (22)   /* Charging Enable (active low) */
+#define HX2750_GPIO_TSC2101_SS  (24)   /* TSC2101 SS# */
+#define HX2750_GPIO_BTPWR       (27)   /* Bluetooth Power? */
+#define HX2750_GPIO_BATTCOVER2  (33)   /* Battery Cover Switch */
+#define HX2750_GPIO_SD_DETECT   (38)   /* MMC Card Detect */
+#define HX2750_GPIO_SR_CLK1     (52)   /* Shift Register Clock */
+#define HX2750_GPIO_SR_CLK2     (53)
+#define HX2750_GPIO_CF_WIFIIRQ  (54)   /* CF Wifi IRQ? */
+#define HX2750_GPIO_GPIO_DIN    (88)   /* Shift Register Data */
+#define HX2750_GPIO_KEYLEFT     (90)   /* Left button */
+#define HX2750_GPIO_KEYRIGHT    (91)   /* Right button */
+#define HX2750_GPIO_KEYCAL      (93)   /* Calander button */
+#define HX2750_GPIO_KEYTASK     (94)   /* Task button */
+#define HX2750_GPIO_KEYSIDE     (95)   /* Side button */
+#define HX2750_GPIO_KEYENTER    (96)   /* Enter Button*/
+#define HX2750_GPIO_KEYCON      (97)   /* Contacts button */
+#define HX2750_GPIO_KEYMAIL     (98)   /* Mail button */
+#define HX2750_GPIO_BIOPWR      (99)   /* BIO Reader Power? */
+#define HX2750_GPIO_KEYUP       (100)  /* Up button */
+#define HX2750_GPIO_KEYDOWN     (101)  /* Down button*/
+#define HX2750_GPIO_SD_READONLY (103)  /* MMC/SD Write Protection */
+#define HX2750_GPIO_LEDMAIL     (106)  /* Green Mail LED */
+#define HX2750_GPIO_HP_JACK     (108)  /* Head Phone Jack Present */
+#define HX2750_GPIO_PENDOWN     (117)  /* Touch Screen Pendown */
+
+
+//#define HX2750_GPIO_     () /* */
+
+/*
+ * HX2750 Interrupts
+ */
+#define HX2750_IRQ_GPIO_EXTPWR      IRQ_GPIO(HX2750_GPIO_EXTPWR)
+#define HX2750_IRQ_GPIO_SD_DETECT   IRQ_GPIO(HX2750_GPIO_SD_DETECT)
+#define HX2750_IRQ_GPIO_PENDOWN     IRQ_GPIO(HX2750_GPIO_PENDOWN)
+#define HX2750_IRQ_GPIO_CF_DETECT   IRQ_GPIO(HX2750_GPIO_CF_DETECT)
+#define HX2750_IRQ_GPIO_CF_IRQ      IRQ_GPIO(HX2750_GPIO_CF_IRQ)
+#define HX2750_IRQ_GPIO_CF_WIFIIRQ  IRQ_GPIO(HX2750_GPIO_CF_WIFIIRQ)
+
+/*
+ * HX2750 Extra GPIO Definitions
+ */
+
+#define HX2750_EGPIO_WIFI_PWR	(1 << 11)  /* Wifi power */
+#define HX2750_EGPIO_LCD_PWR	(1 << 10)  /* LCD Power */
+#define HX2750_EGPIO_BL_PWR     (1 << 9)   /* Backlight LED Power */
+#define HX2750_EGPIO_8          (1 << 8)   /* */
+#define HX2750_EGPIO_7          (1 << 7)   /* */
+#define HX2750_EGPIO_SD_PWR     (1 << 6)   /* SD Power */
+#define HX2750_EGPIO_TSC_PWR    (1 << 5)   /* TS Power */
+#define HX2750_EGPIO_CF0_RESET  (1 << 4)   /* CF0 Reset */
+#define HX2750_EGPIO_CF1_RESET  (1 << 3)   /* CF1 Reset */
+#define HX2750_EGPIO_2          (1 << 2)   /* Power/Red LED Related?*/
+#define HX2750_EGPIO_1          (1 << 1)   /* Power/Red LED Related?*/
+#define HX2750_EGPIO_PWRLED     (1 << 0)   /* Power/Red LED Related?*/
+
+
+void hx2750_set_egpio(unsigned int gpio);
+void hx2750_clear_egpio(unsigned int gpio);
+
+
+#endif /* __ASM_ARCH_HX2750_H  */
+
Index: linux-2.6.22/arch/arm/mach-pxa/Makefile
===================================================================
--- linux-2.6.22.orig/arch/arm/mach-pxa/Makefile	2007-08-28 20:33:10.000000000 +0100
+++ linux-2.6.22/arch/arm/mach-pxa/Makefile	2007-08-28 20:35:14.000000000 +0100
@@ -19,6 +19,7 @@ obj-$(CONFIG_MACH_AKITA)	+= akita-ioexp.
 obj-$(CONFIG_MACH_POODLE)	+= poodle.o corgi_ssp.o
 obj-$(CONFIG_MACH_TOSA)         += tosa.o
 obj-$(CONFIG_MACH_EM_X270) += em-x270.o
+obj-$(CONFIG_MACH_HX2750)	+= hx2750.o hx2750_test.o
 
 # Support for blinky lights
 led-y := leds.o
Index: linux-2.6.22/arch/arm/mach-pxa/hx2750_test.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.22/arch/arm/mach-pxa/hx2750_test.c	2007-08-28 20:34:43.000000000 +0100
@@ -0,0 +1,433 @@
+/*
+ * HP iPAQ hx2750 Test Development Code
+ *
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * Author: Richard Purdie <richard@o-hand.com>
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/mach/arch.h>
+
+#include <asm/arch/hx2750.h>
+#include <asm/arch/pxa-regs.h>
+
+
+static int prodval;
+
+/*
+ * Sysfs functions
+ */
+static ssize_t test1_show(struct device *dev, char *buf)
+{
+	unsigned long rp;
+
+	asm ("mrc	p15, 0, %0, cr1, cr0;\n" :"=r"(rp) );
+	printk("%lx\n",rp);
+
+	asm ("mrc	p15, 0, %0, cr1, cr1;\n" :"=r"(rp) );
+	printk("%lx\n",rp);
+
+	asm ("mrc	p15, 0, %0, cr2, cr0;\n" :"=r"(rp) );
+	printk("%lx\n",rp);
+
+	asm ("mrc	p15, 0, %0, cr3, cr0;\n" :"=r"(rp) );
+	printk("%lx\n",rp);
+
+	asm ("mrc	p15, 0, %0, cr13, cr0;\n" :"=r"(rp) );
+	printk("%lx\n",rp);
+
+	return sprintf(buf, "%d\n",prodval);
+}
+extern void tsc2101_print_miscdata(struct device *dev);
+extern struct platform_device tsc2101_device;
+
+static ssize_t test1_store(struct device *dev, const char *buf, size_t count)
+{
+	prodval = simple_strtoul(buf, NULL, 10);
+
+ 	tsc2101_print_miscdata(&tsc2101_device.dev);
+
+	return count;
+}
+
+static DEVICE_ATTR(test1, 0644, test1_show, test1_store);
+
+static ssize_t test2_show(struct device *dev, char *buf)
+{
+	printk(KERN_ERR "SSCR0_P2: %08x\n", SSCR0_P2);
+	printk(KERN_ERR "SSCR1_P2: %08x\n", SSCR1_P2);
+	printk(KERN_ERR "SSSR_P2:  %08x\n", SSSR_P2);
+	printk(KERN_ERR "SSITR_P2: %08x\n", SSITR_P2);
+	printk(KERN_ERR "SSDR_P2:  %08x\n", SSDR_P2);
+	printk(KERN_ERR "SSTO_P2:  %08x\n", SSTO_P2);
+	printk(KERN_ERR "SSPSP_P2: %08x\n", SSPSP_P2);
+
+	hx2750_ssp_init2();
+
+	printk(KERN_ERR "SSCR0_P2: %08x\n", SSCR0_P2);
+	printk(KERN_ERR "SSCR1_P2: %08x\n", SSCR1_P2);
+	printk(KERN_ERR "SSSR_P2:  %08x\n", SSSR_P2);
+	printk(KERN_ERR "SSITR_P2: %08x\n", SSITR_P2);
+	printk(KERN_ERR "SSDR_P2:  %08x\n", SSDR_P2);
+	printk(KERN_ERR "SSTO_P2:  %08x\n", SSTO_P2);
+	printk(KERN_ERR "SSPSP_P2: %08x\n", SSPSP_P2);
+
+	return sprintf(buf, "%d\n",0);
+}
+
+static DEVICE_ATTR(test2, 0444, test2_show, NULL);
+
+extern unsigned int hx2750_egpio_current;
+
+static ssize_t setegpio_show(struct device *dev, char *buf)
+{
+	return sprintf(buf, "%x\n",hx2750_egpio_current);
+}
+
+static ssize_t setegpio_store(struct device *dev, const char *buf, size_t count)
+{
+	unsigned int val = simple_strtoul(buf, NULL, 10);
+
+	hx2750_set_egpio(1 << val);
+
+	return count;
+}
+
+static DEVICE_ATTR(setegpio, 0644, setegpio_show, setegpio_store);
+
+static ssize_t clregpio_show(struct device *dev, char *buf)
+{
+	return sprintf(buf, "%x\n",hx2750_egpio_current);
+}
+
+static ssize_t gpio_show(struct device *dev, char *buf)
+{
+	int i;
+
+	printk(KERN_ERR "GPIO# D S A INTER\n");
+
+	for (i=0;i<119;i++) {
+		printk(KERN_ERR " %3d: ",i);
+		if (GPDR(i) & GPIO_bit(i))
+			printk("O ");
+		else
+  			printk("I ");
+		printk("%d ",(GPLR(i) & GPIO_bit(i)) != 0);
+		printk("%d ",((GAFR(i) & (0x3 << (((i) & 0xf)*2)))) >> (((i) & 0xf)*2) );
+		if (GEDR(i) & GPIO_bit(i))
+			printk("ED ");
+		if (GRER(i) & GPIO_bit(i))
+			printk("RE ");
+		if (GFER(i) & GPIO_bit(i))
+			printk("FE ");
+
+ 		printk("\n");
+	}
+	return sprintf(buf, "EGPIO: %x\n",hx2750_egpio_current);
+}
+
+static ssize_t clregpio_store(struct device *dev, const char *buf, size_t count)
+{
+	unsigned int val = simple_strtoul(buf, NULL, 10);
+
+	hx2750_clear_egpio(1 << val);
+
+	return count;
+}
+
+static DEVICE_ATTR(clregpio, 0644, clregpio_show, clregpio_store);
+
+
+static ssize_t gpioclr_store(struct device *dev, const char *buf, size_t count)
+{
+	int prod;
+	prod = simple_strtoul(buf, NULL, 10);
+
+	GPCR(prod) = GPIO_bit(prod);
+
+	return count;
+}
+
+static DEVICE_ATTR(gpioclr, 0644, gpio_show, gpioclr_store);
+
+static ssize_t gpioset_store(struct device *dev, const char *buf, size_t count)
+{
+	int prod;
+	prod = simple_strtoul(buf, NULL, 10);
+
+	GPSR(prod) = GPIO_bit(prod);
+
+	return count;
+}
+
+static DEVICE_ATTR(gpioset, 0644, gpio_show, gpioset_store);
+
+
+static ssize_t ssp2read_store(struct device *dev, const char *buf, size_t count)
+{
+	unsigned int val = simple_strtoul(buf, NULL, 16);
+
+	printk("Read: %08x\n",hx2750_ssp2_read(val));
+
+	return count;
+}
+
+static DEVICE_ATTR(ssp2read, 0200, NULL, ssp2read_store);
+
+static ssize_t ssp2write_store(struct device *dev, const char *buf, size_t count)
+{
+	unsigned int val = simple_strtoul(buf, NULL, 16);
+
+	printk("Write: %08x\n",hx2750_ssp2_write(val));
+
+	return count;
+}
+
+static DEVICE_ATTR(ssp2write, 0200, NULL, ssp2write_store);
+
+
+static ssize_t sspr_store(struct device *dev, const char *buf, size_t count)
+{
+	unsigned long val,ret;
+	val = simple_strtoul(buf, NULL, 0);
+
+	hx2750_tsc2101_send(1<<15,val,&ret,1);
+
+	printk("Response: %x\n",ret);
+
+	return count;
+}
+
+static DEVICE_ATTR(sspr, 0200, NULL, sspr_store);
+
+static ssize_t sspw_store(struct device *dev, const char *buf, size_t count)
+{
+	int val,ret;
+	sscanf(buf, "%lx %lx", &val, &ret);
+
+	hx2750_tsc2101_send(0,val,&ret,1);
+
+	return count;
+}
+
+static DEVICE_ATTR(sspw, 0200, NULL, sspw_store);
+
+
+extern struct pm_ops pxa_pm_ops;
+extern void pxa_cpu_resume(void);
+extern unsigned long pxa_pm_pspr_value;
+
+static int (*pxa_pm_enter_orig)(suspend_state_t state);
+
+//static struct {
+//	u32 ffier, fflcr, ffmcr, ffspr, ffisr, ffdll, ffdlh;
+//} sys_ctx;
+
+u32 resstruct[20];
+
+static int hx2750_pxa_pm_enter(suspend_state_t state)
+{
+	int i;
+	u32 save[10];
+
+	PWER = 0xC0000003;// | PWER_RTC;
+	PFER = 0x00000003;
+	PRER = 0x00000003;
+
+	PGSR0=0x00000018;
+	PGSR1=0x00000380;
+	PGSR2=0x00800000;
+	PGSR3=0x00500400;
+
+	//PVCR=0x494; or 0x14;
+	//PVCR=0x14;
+	//PCMD0=0x41f;
+	//i=PISR;
+	//PICR=0x00000062;
+
+	//PCFR=0x457;
+	//PCFR=0x70; // Does not resume from sleep
+	PCFR=0x077; // was 0x477
+	PSLR=0xff100004;
+
+	resstruct[0]=0x0000b4e6;
+	resstruct[1]=0x00000001;
+	resstruct[2]=virt_to_phys(pxa_cpu_resume);
+	resstruct[3]=0xffffffff; //value for r0
+
+	resstruct[14]=0x00000078;  //mcr	15, 0, r0, cr1, cr0, {0}
+	resstruct[15]=0x00000000;  //mcr	15, 0, r0, cr1, cr1, {0} 0xffffffff
+	resstruct[16]=0xa0000000;  //mcr	15, 0, r0, cr2, cr0, {0} 0xa0748000
+	resstruct[17]=0x00000001;  //mcr	15, 0, r0, cr3, cr0, {0} 0x00000015
+	resstruct[18]=0x00000000;  //mcr	15, 0, r0, cr13, cr0, {0} 0x00000000
+
+	pxa_pm_pspr_value=virt_to_phys(&resstruct[0]);
+
+	hx2750_send_egpio(3);
+
+	pxa_gpio_mode(87 | GPIO_OUT  | GPIO_DFLT_HIGH);
+
+	//sys_ctx.ffier = FFIER;
+	//sys_ctx.fflcr = FFLCR;
+	//sys_ctx.ffmcr = FFMCR;
+	//sys_ctx.ffspr = FFSPR;
+	//sys_ctx.ffisr = FFISR;
+	//FFLCR |= 0x80;
+	//sys_ctx.ffdll = FFDLL;
+	//sys_ctx.ffdlh = FFDLH;
+	//FFLCR &= 0xef;
+
+	pxa_pm_enter_orig(state);
+
+	//FFMCR = sys_ctx.ffmcr;
+	//FFSPR = sys_ctx.ffspr;
+	//FFLCR = sys_ctx.fflcr;
+	//FFLCR |= 0x80;
+	//FFDLH = sys_ctx.ffdlh;
+	//FFDLL = sys_ctx.ffdll;
+	//FFLCR = sys_ctx.fflcr;
+	//FFISR = sys_ctx.ffisr;
+	//FFLCR = 0x07;
+	//FFIER = sys_ctx.ffier;
+
+	return 0;
+}
+
+static irqreturn_t hx2750_charge_int(int irq, void *dev_id, struct pt_regs *regs)
+{
+	if ((GPLR(HX2750_GPIO_EXTPWR) & GPIO_bit(HX2750_GPIO_EXTPWR)) == 0) {
+		printk("Charging On\n");
+		GPCR(HX2750_GPIO_CHARGE);
+	} else {
+		printk("Charging Off\n");
+		GPSR(HX2750_GPIO_CHARGE);
+	}
+
+	return IRQ_HANDLED;
+}
+
+
+
+
+static irqreturn_t hx2750_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+    printk("Input %d changed.\n", irq-32);
+
+	return IRQ_HANDLED;
+}
+
+
+static int __init hx2750_test_probe(struct device *dev)
+{
+	pxa_gpio_mode(21 | GPIO_OUT | GPIO_DFLT_HIGH);
+	pxa_gpio_mode(HX2750_GPIO_CHARGE | GPIO_OUT | GPIO_DFLT_HIGH);
+	pxa_gpio_mode(83 | GPIO_OUT | GPIO_DFLT_HIGH);
+	pxa_gpio_mode(HX2750_GPIO_BIOPWR | GPIO_OUT | GPIO_DFLT_HIGH);
+	pxa_gpio_mode(116 | GPIO_OUT | GPIO_DFLT_HIGH);
+	pxa_gpio_mode(118 | GPIO_OUT | GPIO_DFLT_HIGH);
+
+
+	//pxa_gpio_mode(HX2750_GPIO_CF_PWR | GPIO_OUT | GPIO_DFLT_LOW);
+	pxa_gpio_mode(HX2750_GPIO_CF_PWR | GPIO_OUT | GPIO_DFLT_HIGH);
+	pxa_gpio_mode(HX2750_GPIO_BTPWR | GPIO_OUT | GPIO_DFLT_LOW);
+	pxa_gpio_mode(79 | GPIO_OUT | GPIO_DFLT_LOW);
+	pxa_gpio_mode(85 | GPIO_OUT | GPIO_DFLT_LOW);
+	pxa_gpio_mode(HX2750_GPIO_LEDMAIL | GPIO_OUT | GPIO_DFLT_LOW);
+	pxa_gpio_mode(107 | GPIO_OUT | GPIO_DFLT_LOW);
+	pxa_gpio_mode(114 | GPIO_OUT | GPIO_DFLT_LOW);
+
+	pxa_gpio_mode(HX2750_GPIO_BATTCOVER1 | GPIO_IN);
+	pxa_gpio_mode(HX2750_GPIO_BATTCOVER2 | GPIO_IN);
+	pxa_gpio_mode(HX2750_GPIO_CF_IRQ | GPIO_IN);
+	pxa_gpio_mode(HX2750_GPIO_USBCONNECT | GPIO_IN);
+	pxa_gpio_mode(HX2750_GPIO_CF_DETECT | GPIO_IN);
+	pxa_gpio_mode(HX2750_GPIO_EXTPWR | GPIO_IN);
+
+	pxa_gpio_mode(HX2750_GPIO_BATLVL | GPIO_IN);
+	//pxa_gpio_mode(HX2750_GPIO_CF_WIFIIRQ | GPIO_IN);
+	pxa_gpio_mode(80 | GPIO_IN);
+	pxa_gpio_mode(HX2750_GPIO_HP_JACK | GPIO_IN);
+	pxa_gpio_mode(115 | GPIO_IN);
+	pxa_gpio_mode(119 | GPIO_IN);
+
+	request_irq(IRQ_GPIO(HX2750_GPIO_BATLVL), hx2750_interrupt, SA_INTERRUPT, "hx2750test", NULL);
+	//request_irq(IRQ_GPIO(HX2750_GPIO_CF_WIFIIRQ), hx2750_interrupt, SA_INTERRUPT, "hx2750test", NULL);
+	request_irq(IRQ_GPIO(80), hx2750_interrupt, SA_INTERRUPT, "hx2750test", NULL);
+	request_irq(IRQ_GPIO(115), hx2750_interrupt, SA_INTERRUPT, "hx2750test", NULL);
+	request_irq(IRQ_GPIO(119), hx2750_interrupt, SA_INTERRUPT, "hx2750test", NULL);
+	request_irq(IRQ_GPIO(HX2750_GPIO_SR_CLK2), hx2750_interrupt, SA_INTERRUPT, "hx2750test", NULL);
+
+	//request_irq(IRQ_GPIO(10), hx2750_interrupt, SA_INTERRUPT, "hx2750test", NULL);
+
+	set_irq_type(IRQ_GPIO(HX2750_GPIO_BATLVL),IRQT_BOTHEDGE);
+	//set_irq_type(IRQ_GPIO(HX2750_GPIO_CF_WIFIIRQ),IRQT_BOTHEDGE);
+	set_irq_type(IRQ_GPIO(80),IRQT_BOTHEDGE);
+	set_irq_type(IRQ_GPIO(115),IRQT_BOTHEDGE);
+	set_irq_type(IRQ_GPIO(119),IRQT_BOTHEDGE);
+	set_irq_type(IRQ_GPIO(HX2750_GPIO_SR_CLK2),IRQT_BOTHEDGE);
+
+	//set_irq_type(IRQ_GPIO(10),IRQT_BOTHEDGE);
+
+	printk("hx2750 Test Code Initialized.\n");
+	device_create_file(dev, &dev_attr_test1);
+	device_create_file(dev, &dev_attr_test2);
+	device_create_file(dev, &dev_attr_setegpio);
+	device_create_file(dev, &dev_attr_clregpio);
+	device_create_file(dev, &dev_attr_gpioset);
+	device_create_file(dev, &dev_attr_gpioclr);
+	device_create_file(dev, &dev_attr_sspr);
+	device_create_file(dev, &dev_attr_sspw);
+	device_create_file(dev, &dev_attr_ssp2read);
+	device_create_file(dev, &dev_attr_ssp2write);
+
+	request_irq(HX2750_IRQ_GPIO_EXTPWR, hx2750_charge_int, SA_INTERRUPT, "hx2750_extpwr", NULL);
+	set_irq_type(HX2750_IRQ_GPIO_EXTPWR, IRQT_BOTHEDGE);
+
+	pxa_pm_enter_orig=pxa_pm_ops.enter;
+	pxa_pm_ops.enter=hx2750_pxa_pm_enter;
+
+	return 0;
+}
+
+static struct device_driver hx2750_test_driver = {
+	.name		= "hx2750-test",
+	.bus		= &platform_bus_type,
+	.probe		= hx2750_test_probe,
+//	.remove		= hx2750_bl_remove,
+//	.suspend	= hx2750_bl_suspend,
+//	.resume		= hx2750_bl_resume,
+};
+
+
+static int __init hx2750_test_init(void)
+{
+	return driver_register(&hx2750_test_driver);
+}
+
+
+static void __exit hx2750_test_exit(void)
+{
+ 	driver_unregister(&hx2750_test_driver);
+}
+
+module_init(hx2750_test_init);
+module_exit(hx2750_test_exit);
+
+MODULE_AUTHOR("Richard Purdie <richard@o-hand.com>");
+MODULE_DESCRIPTION("iPAQ hx2750 Backlight Driver");
+MODULE_LICENSE("GPLv2");
Index: linux-2.6.22/arch/arm/mach-pxa/Kconfig
===================================================================
--- linux-2.6.22.orig/arch/arm/mach-pxa/Kconfig	2007-08-28 20:33:10.000000000 +0100
+++ linux-2.6.22/arch/arm/mach-pxa/Kconfig	2007-08-28 20:34:43.000000000 +0100
@@ -41,6 +41,15 @@ config MACH_EM_X270
 	bool "CompuLab EM-x270 platform"
 	select PXA27x
 
+config MACH_HX2750
+	bool "HP iPAQ hx2750"
+	select PXA27x
+	select PXA_KEYS
+	select MFD_TSC2101
+	select PXA_SSP
+	help
+	  This enables support for the HP iPAQ HX2750 handheld.
+
 endchoice
 
 if PXA_SHARPSL
@@ -149,3 +158,4 @@ config PXA_SSP
 	help
 	  Enable support for PXA2xx SSP ports
 endif
+
Index: linux-2.6.22/arch/arm/mach-pxa/hx2750.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.22/arch/arm/mach-pxa/hx2750.c	2007-08-28 20:34:43.000000000 +0100
@@ -0,0 +1,450 @@
+/*
+ * Machine definitions for HP iPAQ hx2750
+ *
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * Author: Richard Purdie <richard@o-hand.com>
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/irq.h>
+#include <linux/mmc/host.h>
+#include <linux/mfd/tsc2101.h>
+
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/mach/arch.h>
+
+#include <asm/arch/hx2750.h>
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/pxa_keys.h>
+#include <asm/mach/map.h>
+#include <asm/arch/udc.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/audio.h>
+#include <asm/arch/pxafb.h>
+#include <asm/arch/ssp.h>
+
+#include "generic.h"
+
+
+/*
+ * Keys Support
+ */
+static struct pxa_keys_button hx2750_button_table[] = {
+	{ KEY_POWER, HX2750_GPIO_KEYPWR, PXAKEY_PWR_KEY },
+	{ KEY_LEFT, HX2750_GPIO_KEYLEFT, 0 },
+	{ KEY_RIGHT, HX2750_GPIO_KEYRIGHT, 0 },
+	{ KEY_KP0, HX2750_GPIO_KEYCAL, 0 },
+	{ KEY_KP1, HX2750_GPIO_KEYTASK, 0 },
+	{ KEY_KP2, HX2750_GPIO_KEYSIDE, 0 },
+	{ KEY_ENTER, HX2750_GPIO_KEYENTER, 0 },
+	{ KEY_KP3, HX2750_GPIO_KEYCON, 0 }, //KEY_CONTACTS
+	{ KEY_MAIL, HX2750_GPIO_KEYMAIL, 0 },
+	{ KEY_UP, HX2750_GPIO_KEYUP, 0 },
+	{ KEY_DOWN, HX2750_GPIO_KEYDOWN, 0 },
+};
+
+static struct pxa_keys_platform_data hx2750_pxa_keys_data = {
+	.buttons = hx2750_button_table,
+	.nbuttons = ARRAY_SIZE(hx2750_button_table),
+};
+
+static struct platform_device hx2750_pxa_keys = {
+	.name = "pxa2xx-keys",
+	.dev = {
+		.platform_data = &hx2750_pxa_keys_data,
+	},
+};
+
+
+/*
+ * Backlight Device
+ */
+extern struct platform_device pxafb_device;
+
+static struct platform_device hx2750_bl_device = {
+	.name		= "hx2750-bl",
+	.id		= -1,
+//	.dev	= {
+//		.parent = &pxafb_device.dev,
+//	}
+};
+
+
+/*
+ * UDC/USB
+ */
+static int hx2750_udc_is_connected (void)
+{
+	return GPLR0 & GPIO_bit(HX2750_GPIO_USBCONNECT);
+}
+
+//static void hx2750_udc_command (int cmd)
+//{
+//}
+
+static struct pxa2xx_udc_mach_info hx2750_udc_mach_info = {
+	.udc_is_connected = hx2750_udc_is_connected,
+//	.udc_command      = hx2750_udc_command,
+};
+
+
+/*
+ * SSP Devices Setup
+ */
+static struct ssp_dev hx2750_ssp_dev1;
+static struct ssp_dev hx2750_ssp_dev2;
+static struct ssp_dev hx2750_ssp_dev3;
+
+void hx2750_ssp_init(void)
+{
+	pxa_gpio_mode(HX2750_GPIO_TSC2101_SS | GPIO_OUT | GPIO_DFLT_HIGH);
+
+	if (ssp_init(&hx2750_ssp_dev1, 1, 0))
+		printk(KERN_ERR "Unable to register SSP1 handler!\n");
+	else {
+		ssp_disable(&hx2750_ssp_dev1);
+		ssp_config(&hx2750_ssp_dev1, (SSCR0_Motorola | (SSCR0_DSS & 0x0f )), SSCR1_SPH, 0, SSCR0_SerClkDiv(6));
+		ssp_enable(&hx2750_ssp_dev1);
+		hx2750_set_egpio(HX2750_EGPIO_TSC_PWR);
+	}
+
+//	if (ssp_init(&hx2750_ssp_dev2, 2, 0))
+//		printk(KERN_ERR "Unable to register SSP2 handler!\n");
+//	else {
+//		ssp_disable(&hx2750_ssp_dev2);
+//		ssp_config(&hx2750_ssp_dev2, (SSCR0_TI | (SSCR0_DSS & 0x09 )), 0, 0, SSCR0_SerClkDiv(140));
+//		ssp_enable(&hx2750_ssp_dev2);
+//	}
+//
+	if (ssp_init(&hx2750_ssp_dev3, 3, 0))
+		printk(KERN_ERR "Unable to register SSP3 handler!\n");
+	else {
+		ssp_disable(&hx2750_ssp_dev3);
+		ssp_config(&hx2750_ssp_dev3, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), SSCR1_SPO | SSCR1_SPH, 0, SSCR0_SerClkDiv(166));
+		ssp_enable(&hx2750_ssp_dev3);
+	}
+
+	printk("SSP Devices Initialised\n");
+
+	return;
+}
+
+struct ssp_state ssp1;
+
+void hx2750_ssp_suspend(void)
+{
+	ssp_disable(&hx2750_ssp_dev1);
+	ssp_save_state(&hx2750_ssp_dev1,&ssp1);
+	hx2750_clear_egpio(HX2750_EGPIO_TSC_PWR);
+}
+
+void hx2750_ssp_resume(void)
+{
+	hx2750_set_egpio(HX2750_EGPIO_TSC_PWR);
+	ssp_restore_state(&hx2750_ssp_dev1,&ssp1);
+	ssp_enable(&hx2750_ssp_dev1);
+}
+
+void hx2750_ssp_init2(void)
+{
+	printk("Stage 1: %x\n",CKEN);
+	if (ssp_init(&hx2750_ssp_dev2, 2, 0))
+		printk(KERN_ERR "Unable to register SSP2 handler!\n");
+	else {
+		printk("Stage 2: %x\n",CKEN);
+		ssp_disable(&hx2750_ssp_dev2);
+		printk("Stage 3: %x\n",CKEN);
+		ssp_config(&hx2750_ssp_dev2, (SSCR0_TI | (SSCR0_DSS & 0x09 )) | SSCR0_SSE, 0, 0, SSCR0_SerClkDiv(212));
+		printk("Stage 4: %x\n",CKEN);
+		ssp_enable(&hx2750_ssp_dev2);
+		printk("Stage 5: %x\n",CKEN);
+	}
+	printk("SSP Device2 Initialised\n");
+
+	printk("Sent: 0x3ff\n");
+	ssp_write_word(&hx2750_ssp_dev2,0x3ff);
+
+	return;
+}
+
+void hx2750_ssp2_reset(void)
+{
+	ssp_write_word(&hx2750_ssp_dev2,0x000);
+	ssp_write_word(&hx2750_ssp_dev2,0x000);
+
+}
+
+unsigned long hx2750_ssp2_read(void)
+{
+	u32 ret = 0;
+	ssp_read_word(&hx2750_ssp_dev2, &ret);
+	return ret;
+}
+
+void hx2750_ssp2_write(unsigned long data)
+{
+	ssp_write_word(&hx2750_ssp_dev2, data);
+}
+
+
+/*
+ * Extra hx2750 Specific GPIOs
+ */
+void hx2750_send_egpio(unsigned int val)
+{
+	int i;
+
+	GPCR0 = GPIO_bit(HX2750_GPIO_SR_STROBE);
+	GPCR1 = GPIO_bit(HX2750_GPIO_SR_CLK1);
+
+	for (i=0;i<12;i++) {
+		if (val & 0x01)
+			GPSR2 = GPIO_bit(HX2750_GPIO_GPIO_DIN);
+		else
+			GPCR2 = GPIO_bit(HX2750_GPIO_GPIO_DIN);
+		val >>= 1;
+		GPSR1 = GPIO_bit(HX2750_GPIO_SR_CLK1);
+		GPCR1 = GPIO_bit(HX2750_GPIO_SR_CLK1);
+	}
+
+	GPSR0 = GPIO_bit(HX2750_GPIO_SR_STROBE);
+	GPCR0 = GPIO_bit(HX2750_GPIO_SR_STROBE);
+}
+
+EXPORT_SYMBOL(hx2750_send_egpio);
+
+unsigned int hx2750_egpio_current;
+
+void hx2750_set_egpio(unsigned int gpio)
+{
+	hx2750_egpio_current|=gpio;
+
+	hx2750_send_egpio(hx2750_egpio_current);
+}
+EXPORT_SYMBOL(hx2750_set_egpio);
+
+void hx2750_clear_egpio(unsigned int gpio)
+{
+	hx2750_egpio_current&=~gpio;
+
+	hx2750_send_egpio(hx2750_egpio_current);
+}
+EXPORT_SYMBOL(hx2750_clear_egpio);
+
+
+/*
+ * Touchscreen/Sound/Battery Status
+ */
+void hx2750_tsc2101_send(int read, int command, int *values, int numval)
+{
+	u32 ret = 0;
+	int i;
+
+	GPCR0 = GPIO_bit(HX2750_GPIO_TSC2101_SS);
+
+	ssp_write_word(&hx2750_ssp_dev1, command | read);
+	/* dummy read */
+	ssp_read_word(&hx2750_ssp_dev1, &ret);
+
+	for (i=0; i < numval; i++) {
+		if (read) {
+			ssp_write_word(&hx2750_ssp_dev1, 0);
+			ssp_read_word(&hx2750_ssp_dev1, &values[i]);
+		} else {
+			ssp_write_word(&hx2750_ssp_dev1, values[i]);
+			ssp_read_word(&hx2750_ssp_dev1, &ret);
+		}
+	}
+
+	GPSR0 = GPIO_bit(HX2750_GPIO_TSC2101_SS);
+}
+
+static int hx2750_tsc2101_pendown(void)
+{
+	if ((GPLR(HX2750_GPIO_PENDOWN) & GPIO_bit(HX2750_GPIO_PENDOWN)) == 0)
+		return 1;
+	return 0;
+}
+
+static struct tsc2101_platform_info hx2750_tsc2101_info = {
+	.send     = hx2750_tsc2101_send,
+	.suspend  = hx2750_ssp_suspend,
+	.resume   = hx2750_ssp_resume,
+	.irq      = HX2750_IRQ_GPIO_PENDOWN,
+	.pendown  = hx2750_tsc2101_pendown,
+};
+
+struct platform_device tsc2101_device = {
+	.name 		= "tsc2101",
+	.dev		= {
+ 		.platform_data	= &hx2750_tsc2101_info,
+ 		//.parent = &corgissp_device.dev,
+	},
+	.id 		= -1,
+};
+
+
+/*
+ * MMC/SD Device
+ *
+ * The card detect interrupt isn't debounced so we delay it by 250ms
+ * to give the card a chance to fully insert/eject.
+ */
+static struct pxamci_platform_data hx2750_mci_platform_data;
+
+static int hx2750_mci_init(struct device *dev, irq_handler_t hx2750_detect_int, void *data)
+{
+	int err;
+
+	/*
+	 * setup GPIO for PXA27x MMC controller
+	 */
+	pxa_gpio_mode(GPIO32_MMCCLK_MD);
+	pxa_gpio_mode(GPIO112_MMCCMD_MD);
+	pxa_gpio_mode(GPIO92_MMCDAT0_MD);
+	pxa_gpio_mode(GPIO109_MMCDAT1_MD);
+	pxa_gpio_mode(GPIO110_MMCDAT2_MD);
+	pxa_gpio_mode(GPIO111_MMCDAT3_MD);
+	pxa_gpio_mode(HX2750_GPIO_SD_DETECT | GPIO_IN);
+	pxa_gpio_mode(HX2750_GPIO_SD_READONLY | GPIO_IN);
+
+	hx2750_mci_platform_data.detect_delay = msecs_to_jiffies(250);
+
+	err = request_irq(HX2750_IRQ_GPIO_SD_DETECT, hx2750_detect_int,
+			IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+			"MMC card detect", data);
+	if (err) {
+		printk(KERN_ERR "hx2750_mci_init: MMC/SD: can't request MMC card detect IRQ\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static void hx2750_mci_setpower(struct device *dev, unsigned int vdd)
+{
+	struct pxamci_platform_data* p_d = dev->platform_data;
+
+	if (( 1 << vdd) & p_d->ocr_mask)
+		hx2750_set_egpio(HX2750_EGPIO_SD_PWR);
+	else
+		hx2750_clear_egpio(HX2750_EGPIO_SD_PWR);
+}
+
+static void hx2750_mci_exit(struct device *dev, void *data)
+{
+	free_irq(HX2750_IRQ_GPIO_SD_DETECT, data);
+}
+
+static struct pxamci_platform_data hx2750_mci_platform_data = {
+	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,
+	.init 		= hx2750_mci_init,
+	.setpower 	= hx2750_mci_setpower,
+	.exit		= hx2750_mci_exit,
+};
+
+
+/*
+ * FrameBuffer
+ */
+static struct pxafb_mode_info hx2750_pxafb_modes = {
+	.pixclock       = 288462,
+	.xres           = 240,
+	.yres           = 320,
+	.bpp            = 16,
+	.hsync_len      = 20,
+	.left_margin    = 42,
+	.right_margin   = 18,
+	.vsync_len	= 4,
+	.upper_margin   = 3,
+	.lower_margin   = 4,
+	.sync           = 0,
+};
+
+static struct pxafb_mach_info hx2750_pxafb_info = {
+	.modes          = &hx2750_pxafb_modes,
+	.num_modes      = 1,
+	.fixed_modes    = 1,
+	.lccr0          = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+	.lccr3          = LCCR3_PixFlEdg | LCCR3_OutEnH,
+	.pxafb_backlight_power	= NULL,
+};
+
+
+/*
+ * Test Device
+ */
+static struct platform_device hx2750_test_device = {
+	.name		= "hx2750-test",
+	.id		= -1,
+};
+
+
+/* Initialization code */
+static struct platform_device *devices[] __initdata = {
+	&hx2750_bl_device,
+	&hx2750_test_device,
+	&hx2750_pxa_keys,
+	&tsc2101_device,
+};
+
+static void __init hx2750_init( void )
+{
+	PWER = 0xC0000003;// | PWER_RTC;
+	PFER = 0x00000003;
+	PRER = 0x00000003;
+
+	PGSR0=0x00000018;
+	PGSR1=0x00000380;
+	PGSR2=0x00800000;
+	PGSR3=0x00500400;
+
+	//PCFR |= PCFR_OPDE;
+	PCFR=0x77;
+	PSLR=0xff100000;
+	//PCFR=0x10; - does not return from suspend
+
+	//PCFR=  0x00004040;
+	//PSLR=  0xff400f04;
+
+	/* Setup Extra GPIO Bank access */
+	pxa_gpio_mode(HX2750_GPIO_GPIO_DIN | GPIO_OUT | GPIO_DFLT_HIGH);
+	pxa_gpio_mode(HX2750_GPIO_SR_CLK1 | GPIO_OUT | GPIO_DFLT_LOW);
+	pxa_gpio_mode(HX2750_GPIO_SR_CLK2 | GPIO_IN);
+	pxa_gpio_mode(HX2750_GPIO_SR_STROBE | GPIO_OUT | GPIO_DFLT_LOW);
+
+	/* Init Extra GPIOs - Bootloader reset default is 0x484 */
+	/* This is 0xe84 */
+	hx2750_set_egpio(HX2750_EGPIO_2 | HX2750_EGPIO_7 | HX2750_EGPIO_LCD_PWR | HX2750_EGPIO_BL_PWR | HX2750_EGPIO_WIFI_PWR);
+
+	pxa_set_udc_info(&hx2750_udc_mach_info);
+	pxa_set_mci_info(&hx2750_mci_platform_data);
+	set_pxa_fb_info(&hx2750_pxafb_info);
+	hx2750_ssp_init();
+	platform_add_devices (devices, ARRAY_SIZE (devices));
+}
+
+
+MACHINE_START(HX2750, "HP iPAQ HX2750")
+	.phys_io	= 0x40000000,
+	.io_pg_offst	= (io_p2v(0x40000000) >> 18) & 0xfffc,
+	.boot_params	= 0xa0000100,
+	.map_io		= pxa_map_io,
+        .init_irq 	= pxa_init_irq,
+        .timer		= &pxa_timer,
+	.init_machine 	= hx2750_init,
+MACHINE_END
+
Index: linux-2.6.22/arch/arm/mach-pxa/pm.c
===================================================================
--- linux-2.6.22.orig/arch/arm/mach-pxa/pm.c	2007-08-28 20:33:23.000000000 +0100
+++ linux-2.6.22/arch/arm/mach-pxa/pm.c	2007-08-28 20:37:22.000000000 +0100
@@ -17,6 +17,7 @@
 #include <linux/time.h>
 
 #include <asm/hardware.h>
+#include <asm/mach-types.h>
 #include <asm/memory.h>
 #include <asm/system.h>
 #include <asm/arch/pm.h>
@@ -91,6 +92,9 @@ static struct pm_ops pxa_pm_ops = {
 	.enter		= pxa_pm_enter,
 };
 
+unsigned long pxa_pm_pspr_value;
+extern void pxa_cpu_resume(void);
+
 static int __init pxa_pm_init(void)
 {
 	if (!pxa_cpu_pm_fns) {
@@ -104,6 +108,7 @@ static int __init pxa_pm_init(void)
 		return -ENOMEM;
 	}
 
+	pxa_pm_pspr_value=virt_to_phys(pxa_cpu_resume);
 	pm_set_ops(&pxa_pm_ops);
 	return 0;
 }
Index: linux-2.6.22/arch/arm/mach-pxa/pxa27x.c
===================================================================
--- linux-2.6.22.orig/arch/arm/mach-pxa/pxa27x.c	2007-08-28 20:33:10.000000000 +0100
+++ linux-2.6.22/arch/arm/mach-pxa/pxa27x.c	2007-08-28 20:38:01.000000000 +0100
@@ -220,6 +220,8 @@ void pxa27x_cpu_pm_restore(unsigned long
 	RESTORE(PSTR);
 }
 
+extern unsigned long pxa_pm_pspr_value;
+
 void pxa27x_cpu_pm_enter(suspend_state_t state)
 {
 	extern void pxa_cpu_standby(void);
@@ -242,7 +244,7 @@ void pxa27x_cpu_pm_enter(suspend_state_t
 		break;
 	case PM_SUSPEND_MEM:
 		/* set resume return address */
-		PSPR = virt_to_phys(pxa_cpu_resume);
+		PSPR = pxa_pm_pspr_value;
 		pxa27x_cpu_suspend(PWRMODE_SLEEP);
 		break;
 	}
Index: linux-2.6.22/arch/arm/mach-pxa/pxa25x.c
===================================================================
--- linux-2.6.22.orig/arch/arm/mach-pxa/pxa25x.c	2007-08-28 20:33:10.000000000 +0100
+++ linux-2.6.22/arch/arm/mach-pxa/pxa25x.c	2007-08-28 20:37:14.000000000 +0100
@@ -178,6 +178,8 @@ static void pxa25x_cpu_pm_restore(unsign
 	RESTORE(PSTR);
 }
 
+extern unsigned long pxa_pm_pspr_value;
+
 static void pxa25x_cpu_pm_enter(suspend_state_t state)
 {
 	CKEN = 0;
@@ -185,7 +187,7 @@ static void pxa25x_cpu_pm_enter(suspend_
 	switch (state) {
 	case PM_SUSPEND_MEM:
 		/* set resume return address */
-		PSPR = virt_to_phys(pxa_cpu_resume);
+		PSPR = pxa_pm_pspr_value;
 		pxa25x_cpu_suspend(PWRMODE_SLEEP);
 		break;
 	}
