 arch/arm/common/locomo.c          |    6 
 arch/arm/common/sharpsl_pm.c      |    9 
 arch/arm/mach-pxa/Kconfig         |    1 
 arch/arm/mach-pxa/Makefile        |    2 
 arch/arm/mach-pxa/poodle_pm.c     |  355 ++++++++++++++++++++++++++++++++++++++
 include/asm-arm/hardware/locomo.h |    5 
 6 files changed, 377 insertions(+), 1 deletion(-)

Index: linux-2.6.26-rc4/arch/arm/common/sharpsl_pm.c
===================================================================
--- linux-2.6.26-rc4.orig/arch/arm/common/sharpsl_pm.c	2008-06-01 18:20:22.000000000 +0100
+++ linux-2.6.26-rc4/arch/arm/common/sharpsl_pm.c	2008-06-01 18:20:23.000000000 +0100
@@ -458,6 +458,10 @@
 {
 	int temp, i, buff[5];
 
+	/* Some devices don't support this */
+	if (!sharpsl_pm.machinfo->charge_acin_high)
+		return 0;
+
 	for (i=0; i<5; i++) {
 		buff[i] = sharpsl_pm.machinfo->read_devdata(SHARPSL_ACIN_VOLT);
 		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_ACIN);
@@ -598,6 +602,9 @@
 
 	dev_dbg(sharpsl_pm.dev, "sharpsl_fatal_check entered\n");
 
+	if (machine_is_poodle())
+		return 0;
+
 	/* Check AC-Adapter */
 	acin = sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN);
 
@@ -664,6 +671,7 @@
 		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 1\n");
 
 		/* AC Check */
+		if (!machine_is_poodle())
 		if ((sharpsl_ac_check() < 0) || (sharpsl_check_battery_temp() < 0))
 			return sharpsl_off_charge_error();
 
@@ -686,6 +694,7 @@
 
 		dev_dbg(sharpsl_pm.dev, "Offline Charger: Step 2\n");
 
+		if (!machine_is_poodle())
 		if ((sharpsl_check_battery_temp() < 0) || (sharpsl_check_battery_voltage() < 0))
 			return sharpsl_off_charge_error();
 
Index: linux-2.6.26-rc4/arch/arm/mach-pxa/Kconfig
===================================================================
--- linux-2.6.26-rc4.orig/arch/arm/mach-pxa/Kconfig	2008-06-01 18:20:22.000000000 +0100
+++ linux-2.6.26-rc4/arch/arm/mach-pxa/Kconfig	2008-06-01 18:20:23.000000000 +0100
@@ -210,6 +210,7 @@
 	bool "Enable Sharp SL-5600 (Poodle) Support"
 	depends on PXA_SHARPSL_25x
 	select SHARP_LOCOMO
+	select SHARPSL_PM
 	select PXA_SSP
 
 config MACH_CORGI
Index: linux-2.6.26-rc4/arch/arm/mach-pxa/Makefile
===================================================================
--- linux-2.6.26-rc4.orig/arch/arm/mach-pxa/Makefile	2008-06-01 18:20:22.000000000 +0100
+++ linux-2.6.26-rc4/arch/arm/mach-pxa/Makefile	2008-06-01 18:21:08.000000000 +0100
@@ -30,7 +30,7 @@
 obj-$(CONFIG_PXA_SHARP_C7xx)	+= corgi.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o corgi_pm.o
 obj-$(CONFIG_PXA_SHARP_Cxx00)	+= spitz.o corgi_ssp.o corgi_lcd.o sharpsl_pm.o spitz_pm.o
 obj-$(CONFIG_MACH_AKITA)	+= akita-ioexp.o
-obj-$(CONFIG_MACH_POODLE)	+= poodle.o corgi_ssp.o
+obj-$(CONFIG_MACH_POODLE)	+= poodle.o corgi_ssp.o sharpsl_pm.o poodle_pm.o 
 obj-$(CONFIG_MACH_HX2750)	+= hx2750.o hx2750_test.o
 obj-$(CONFIG_MACH_PCM027)	+= pcm027.o
 obj-$(CONFIG_MACH_PCM990_BASEBOARD)	+= pcm990-baseboard.o
Index: linux-2.6.26-rc4/arch/arm/mach-pxa/poodle_pm.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.26-rc4/arch/arm/mach-pxa/poodle_pm.c	2008-06-01 18:20:23.000000000 +0100
@@ -0,0 +1,355 @@
+/*
+ * Battery and Power Management code for the Sharp SL-5600
+ *
+ * Copyright (c) 2006 Richard Purdie
+ *
+ * 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/stat.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/apm-emulation.h>
+#include <asm/irq.h>
+#include <asm/mach-types.h>
+#include <asm/hardware.h>
+#include <asm/hardware/scoop.h>
+#include <asm/hardware/locomo.h>
+
+#include <asm/arch/sharpsl.h>
+#include <asm/arch/poodle.h>
+#include <asm/arch/pxa-regs.h>
+#include "sharpsl.h"
+
+#if 0
+#define SHARPSL_CHARGE_ON_VOLT         0x99  /* 2.9V */
+#define SHARPSL_CHARGE_ON_TEMP         0xe0  /* 2.9V */
+#define SHARPSL_CHARGE_ON_ACIN_HIGH    0x9b  /* 6V */
+#define SHARPSL_CHARGE_ON_ACIN_LOW     0x34  /* 2V */
+#define SHARPSL_FATAL_ACIN_VOLT        182   /* 3.45V */
+#define SHARPSL_FATAL_NOACIN_VOLT      170   /* 3.40V */
+#endif
+
+#define SHARPSL_CHARGE_ON_VOLT			1187	// 2.9V
+#define SHARPSL_CHARGE_ON_TEMP			2441
+#define SHARPSL_FATAL_NOACIN_VOLT	1454    // 3.55V
+#define SHARPSL_FATAL_ACIN_VOLT	1474    // 3.60V
+
+
+#if 0
+#define SHARPSL_POWER_MODE_CHECK		1475
+#define SHARPSL_POODLE_FATAL_VOLT		1433
+#define SHARPSL_POODLE_FATAL_NOACIN_FLON_VOLT	1454    // 3.55V
+#define SHARPSL_POODLE_FATAL_NOACIN_FLOFF_VOLT	1433    // 3.50V
+#define SHARPSL_POODLE_FATAL_ACIN_FLON_VOLT	1474    // 3.60V
+#define SHARPSL_POODLE_FATAL_ACIN_FLOFF_VOLT	1454    // 3.55V
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP	5	// 50msec
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT	1	// 10msec
+#define SHARPSL_WAIT_DISCHARGE_ON		5	// 50msec
+#endif
+
+
+struct battery_thresh poodle_battery_levels_fl[] = {
+    {1582, 100},
+    {1527,  75},
+    {1482,  50},
+    {1458,  25},
+    {1404,   5},
+    {   0,   0},
+};
+
+struct battery_thresh poodle_battery_levels_nofl[] = {
+    {1589, 100},
+    {1536,  75},
+    {1490,  50},
+    {1466,  25},
+    {1413,   5},
+    {   0,   0},
+};
+
+struct battery_thresh poodle_battery_levels_acin_fl[] = {
+    {1601, 100},
+    {1536,  75},
+    {1503,  50},
+    {1482,  25},
+    {   0,   5},
+    {   0,   0},
+};
+
+struct battery_thresh poodle_battery_levels_acin_nofl[] = {
+    {1609, 100},
+    {1548,  75},
+    {1527,  50},
+    {1495,  25},
+    {   0,   5},
+    {   0,   0},
+};
+
+static void poodle_charger_init(void)
+{
+	pxa_gpio_mode(POODLE_GPIO_ADC_TEMP_ON | GPIO_OUT);
+	pxa_gpio_mode(POODLE_GPIO_CHRG_ON | GPIO_OUT);
+	pxa_gpio_mode(POODLE_GPIO_BYPASS_ON | GPIO_OUT);
+	pxa_gpio_mode(POODLE_GPIO_ON_KEY | GPIO_IN);
+	sharpsl_pm_pxa_init();
+}
+
+static void poodle_measure_temp(int on)
+{
+	if (on)
+		GPSR(POODLE_GPIO_ADC_TEMP_ON) = GPIO_bit(POODLE_GPIO_ADC_TEMP_ON);
+	else
+		GPCR(POODLE_GPIO_ADC_TEMP_ON) = GPIO_bit(POODLE_GPIO_ADC_TEMP_ON);
+}
+
+extern struct locomo_dev *frontlight_dev;
+
+static void poodle_charge(int on)
+{
+	if (on) {
+		GPSR(POODLE_GPIO_CHRG_ON) = GPIO_bit(POODLE_GPIO_CHRG_ON);
+		locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_JK_B, 1);
+	} else {
+		GPCR(POODLE_GPIO_CHRG_ON) = GPIO_bit(POODLE_GPIO_CHRG_ON);
+		locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_JK_B, 0);
+	}
+}
+
+static void poodle_discharge(int on)
+{
+	if (on)
+		GPSR(POODLE_GPIO_DISCHARGE_ON) = GPIO_bit(POODLE_GPIO_DISCHARGE_ON);
+	else
+		GPCR(POODLE_GPIO_DISCHARGE_ON) = GPIO_bit(POODLE_GPIO_DISCHARGE_ON);
+}
+
+static void poodle_presuspend(void)
+{
+	int i;
+	unsigned long wakeup_mask;
+
+	/* charging , so CHARGE_ON bit is HIGH during OFF. */
+	if (READ_GPIO_BIT(POODLE_GPIO_CHRG_ON))
+		PGSR1 |= GPIO_bit(POODLE_GPIO_CHRG_ON);
+	else
+		PGSR1 &= ~GPIO_bit(POODLE_GPIO_CHRG_ON);
+
+//	if (READ_GPIO_BIT(CORGI_GPIO_CHRG_UKN))
+//		PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_UKN);
+//	else
+//		PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_UKN);
+
+	/* Resume on keyboard power key */
+//	PGSR2 = (PGSR2 & ~CORGI_GPIO_ALL_STROBE_BIT) | CORGI_GPIO_STROBE_BIT(0);
+
+	wakeup_mask = GPIO_bit(POODLE_GPIO_ON_KEY) | GPIO_bit(POODLE_GPIO_WAKEUP);
+	wakeup_mask |= GPIO_bit(POODLE_GPIO_AC_IN) | GPIO_bit(POODLE_GPIO_CHRG_FULL);
+	wakeup_mask |= GPIO_bit(POODLE_GPIO_MAIN_BAT_LOW) | GPIO_bit(POODLE_GPIO_CF_CD);
+	wakeup_mask |= GPIO_bit(POODLE_GPIO_HP_IN) | GPIO_bit(POODLE_GPIO_GA_INT) | GPIO_bit(POODLE_GPIO_nSD_INT);
+
+
+//	if (!machine_is_corgi())
+//		GPDR0 &= ~(GPIO_bit(15) | GPIO_bit(8)); /* Float n_CS1 */
+
+	PWER = wakeup_mask | PWER_RTC;
+	PRER = wakeup_mask;
+	PFER = wakeup_mask;
+
+	for (i = 0; i <=15; i++) {
+		if (PRER & PFER & GPIO_bit(i)) {
+			if (GPLR0 & GPIO_bit(i) )
+				PRER &= ~GPIO_bit(i);
+			else
+				PFER &= ~GPIO_bit(i);
+		}
+	}
+}
+
+static void poodle_postsuspend(void)
+{
+//	if (!machine_is_corgi())
+//		GPDR0 |= GPIO_bit(15) | GPIO_bit(8); /* Un-Float n_CS1 */
+}
+
+/*
+ * Check what brought us out of the suspend.
+ * Return: 0 to sleep, otherwise wake
+ */
+static int poodle_should_wakeup(unsigned int resume_on_alarm)
+{
+	int is_resume = 0;
+
+	dev_dbg(sharpsl_pm.dev, "GPLR0 = %x,%x\n", GPLR0, PEDR);
+
+	if ((PEDR & GPIO_bit(POODLE_GPIO_AC_IN))) {
+		if (sharpsl_pm.machinfo->read_devdata(SHARPSL_STATUS_ACIN)) {
+			/* charge on */
+			dev_dbg(sharpsl_pm.dev, "ac insert\n");
+			sharpsl_pm.flags |= SHARPSL_DO_OFFLINE_CHRG;
+		} else {
+			/* charge off */
+			dev_dbg(sharpsl_pm.dev, "ac remove\n");
+			sharpsl_pm_led(SHARPSL_LED_OFF);
+			sharpsl_pm.machinfo->charge(0);
+			sharpsl_pm.charge_mode = CHRG_OFF;
+		}
+	}
+
+	if ((PEDR & GPIO_bit(POODLE_GPIO_CHRG_FULL)))
+		dev_dbg(sharpsl_pm.dev, "Charge full interrupt\n");
+
+	if (PEDR & GPIO_bit(POODLE_GPIO_ON_KEY))
+		is_resume |= GPIO_bit(POODLE_GPIO_ON_KEY);
+
+	if (PEDR & GPIO_bit(POODLE_GPIO_WAKEUP))
+		is_resume |= GPIO_bit(POODLE_GPIO_WAKEUP);
+
+//	if ( (apm_wakeup_factor & GPIO_bit(GPIO_GA_INT)) && (LCM_KIC & 1) ) {
+//		LCM_KIC &= ~0x100;
+//		LCM_ICR &= ~0x100;
+//		is_resume |= GPIO_bit(GPIO_GA_INT);
+//	}
+
+	if (PEDR & GPIO_bit(POODLE_GPIO_CF_STSCHG))
+		is_resume |= GPIO_bit(POODLE_GPIO_CF_STSCHG);
+
+	if (PEDR & GPIO_bit(POODLE_GPIO_nSD_INT))
+		is_resume |= GPIO_bit(POODLE_GPIO_nSD_INT);
+
+	if (PEDR & GPIO_bit(POODLE_GPIO_HP_IN))
+		is_resume |= GPIO_bit(POODLE_GPIO_HP_IN);
+
+	if (resume_on_alarm && (PEDR & PWER_RTC))
+		is_resume |= PWER_RTC;
+
+	dev_dbg(sharpsl_pm.dev, "is_resume: %x\n",is_resume);
+	return is_resume;
+}
+
+static unsigned long poodle_charger_wakeup(void)
+{
+	return ~GPLR0 & ( GPIO_bit(POODLE_GPIO_AC_IN) | GPIO_bit(POODLE_GPIO_ON_KEY) | GPIO_bit(POODLE_GPIO_WAKEUP) );
+}
+
+#define MUX_CHL    6u
+#define BATT_CHL   2u
+
+/* ADS7846 Touch Screen Controller bit definitions */
+#define ADSCTRL_PD0		(1u << 0)	/* PD0 */
+#define ADSCTRL_PD1		(1u << 1)	/* PD1 */
+#define ADSCTRL_DFR		(1u << 2)	/* SER/DFR */
+#define ADSCTRL_MOD		(1u << 3)	/* Mode */
+#define ADSCTRL_ADR_SH	4	/* Address setting */
+#define ADSCTRL_STS		(1u << 7)	/* Start Bit */
+
+int poodle_pm_read_ads7846(int channel)
+{
+	int voltage;
+	int cmd = ADSCTRL_PD0 | ADSCTRL_PD1 | ADSCTRL_DFR |
+		(channel << ADSCTRL_ADR_SH) | ADSCTRL_STS;
+
+	corgi_ssp_ads7846_lock();
+
+	corgi_ssp_ads7846_put(cmd);
+	corgi_ssp_ads7846_get();
+
+	corgi_ssp_ads7846_put(cmd);
+	voltage = corgi_ssp_ads7846_get();
+
+	/* Power-Down Enable */
+	corgi_ssp_ads7846_put((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
+	corgi_ssp_ads7846_get();
+
+	corgi_ssp_ads7846_unlock();
+
+	return voltage;
+}
+
+unsigned long poodlepm_read_devdata(int type)
+{
+	switch(type) {
+	case SHARPSL_STATUS_ACIN:
+		return ((GPLR(POODLE_GPIO_AC_IN) & GPIO_bit(POODLE_GPIO_AC_IN)) != 0);
+	case SHARPSL_STATUS_LOCK:
+		return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batlock);
+	case SHARPSL_STATUS_CHRGFULL:
+		return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_batfull);
+	case SHARPSL_STATUS_FATAL:
+		return READ_GPIO_BIT(sharpsl_pm.machinfo->gpio_fatal);
+//	case SHARPSL_ACIN_VOLT:
+//		return poodle_pm_read_ads7846(MAX1111_ACIN_VOLT);
+// FIXME
+	case SHARPSL_BATT_TEMP:
+		return poodle_pm_read_ads7846(MUX_CHL);
+	case SHARPSL_BATT_VOLT:
+	default:
+		return poodle_pm_read_ads7846(BATT_CHL);
+	}
+}
+
+static void poodle_limit_intensity(int limit)
+{
+}
+
+static struct sharpsl_charger_machinfo poodle_pm_machinfo = {
+	.init            = poodle_charger_init,
+	.exit            = sharpsl_pm_pxa_remove,
+	.gpio_batlock    = POODLE_GPIO_BAT_COVER,
+	.gpio_acin       = POODLE_GPIO_AC_IN,
+	.gpio_batfull    = POODLE_GPIO_CHRG_FULL,
+	.batfull_irq	  = 1,
+	.discharge       = poodle_discharge,
+	.charge          = poodle_charge,
+	.measure_temp    = poodle_measure_temp,
+	.presuspend      = poodle_presuspend,
+	.postsuspend     = poodle_postsuspend,
+	.read_devdata    = poodlepm_read_devdata,
+	.charger_wakeup  = poodle_charger_wakeup,
+	.should_wakeup   = poodle_should_wakeup,
+	.backlight_limit =  poodle_limit_intensity,
+	.charge_on_volt	  = SHARPSL_CHARGE_ON_VOLT,
+	.charge_on_temp	  = SHARPSL_CHARGE_ON_TEMP,
+	.fatal_acin_volt  = SHARPSL_FATAL_ACIN_VOLT,
+	.fatal_noacin_volt= SHARPSL_FATAL_NOACIN_VOLT,
+	.bat_levels       = 6,
+	.bat_levels_noac  = poodle_battery_levels_fl,
+	.bat_levels_acin  = poodle_battery_levels_nofl,
+	.status_high_acin = 1490,
+	.status_low_acin  = 1466,
+	.status_high_noac = 1482,
+	.status_low_noac  = 1458,
+};
+
+static struct platform_device *poodlepm_device;
+
+static int __devinit poodlepm_init(void)
+{
+	int ret;
+
+	poodlepm_device = platform_device_alloc("sharpsl-pm", -1);
+	if (!poodlepm_device)
+		return -ENOMEM;
+
+	poodlepm_device->dev.platform_data = &poodle_pm_machinfo;
+	ret = platform_device_add(poodlepm_device);
+
+	if (ret)
+		platform_device_put(poodlepm_device);
+
+	return ret;
+}
+
+static void poodlepm_exit(void)
+{
+	platform_device_unregister(poodlepm_device);
+}
+
+module_init(poodlepm_init);
+module_exit(poodlepm_exit);
Index: linux-2.6.26-rc4/arch/arm/common/locomo.c
===================================================================
--- linux-2.6.26-rc4.orig/arch/arm/common/locomo.c	2008-05-26 19:08:11.000000000 +0100
+++ linux-2.6.26-rc4/arch/arm/common/locomo.c	2008-06-01 18:20:23.000000000 +0100
@@ -600,6 +600,7 @@
 	spin_lock_irqsave(&lchip->lock, flags);
 
 	save->LCM_GPO     = locomo_readl(lchip->base + LOCOMO_GPO);	/* GPIO */
+	// FIXME - should save JK_B
 	locomo_writel(0x00, lchip->base + LOCOMO_GPO);
 	save->LCM_SPICT   = locomo_readl(lchip->base + LOCOMO_SPI + LOCOMO_SPICT);	/* SPI */
 	locomo_writel(0x40, lchip->base + LOCOMO_SPICT);
@@ -1101,11 +1102,16 @@
 
 static struct locomo *locomo_chip_driver(struct locomo_dev *ldev);
 
+struct locomo_dev *frontlight_dev;
+EXPORT_SYMBOL(frontlight_dev);
+
 void locomo_frontlight_set(struct locomo_dev *dev, int duty, int vr, int bpwf)
 {
 	unsigned long flags;
 	struct locomo *lchip = locomo_chip_driver(dev);
 
+	frontlight_dev = dev;
+
 	if (vr)
 		locomo_gpio_write(dev->dev.parent, LOCOMO_GPIO_FL_VR, 1);
 	else
