summaryrefslogtreecommitdiff
path: root/packages/kexecboot/linux-kexecboot-2.6.23/tosa-power-r18.patch
diff options
context:
space:
mode:
authorKoen Kooi <koen@openembedded.org>2008-12-13 19:44:49 +0100
committerKoen Kooi <koen@openembedded.org>2008-12-13 19:44:49 +0100
commit9ca80369bdb80c62812928ee93817fa327bb051c (patch)
tree3a6343fe3d350e93723508e4910f33378e00ff8a /packages/kexecboot/linux-kexecboot-2.6.23/tosa-power-r18.patch
parentd86dfe2d99406af510e6ff16ba4aa602d90fb664 (diff)
linux-kexecboot: add 2.6.23 for c7x0
Diffstat (limited to 'packages/kexecboot/linux-kexecboot-2.6.23/tosa-power-r18.patch')
-rw-r--r--packages/kexecboot/linux-kexecboot-2.6.23/tosa-power-r18.patch691
1 files changed, 691 insertions, 0 deletions
diff --git a/packages/kexecboot/linux-kexecboot-2.6.23/tosa-power-r18.patch b/packages/kexecboot/linux-kexecboot-2.6.23/tosa-power-r18.patch
new file mode 100644
index 0000000000..ca703cb188
--- /dev/null
+++ b/packages/kexecboot/linux-kexecboot-2.6.23/tosa-power-r18.patch
@@ -0,0 +1,691 @@
+Index: linux-2.6.17/arch/arm/mach-pxa/Makefile
+===================================================================
+--- linux-2.6.17.orig/arch/arm/mach-pxa/Makefile 2006-09-19 20:51:33.984424500 +0200
++++ linux-2.6.17/arch/arm/mach-pxa/Makefile 2006-09-19 21:08:04.922354250 +0200
+@@ -16,7 +16,7 @@ obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.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 sharpsl_pm.o poodle_pm.o
+-obj-$(CONFIG_MACH_TOSA) += tosa.o
++obj-$(CONFIG_MACH_TOSA) += tosa.o sharpsl_pm.o tosa_pm.o
+ obj-$(CONFIG_MACH_EM_X270) += em-x270.o
+ obj-$(CONFIG_MACH_HX2750) += hx2750.o hx2750_test.o
+
+Index: linux-2.6.17/arch/arm/mach-pxa/tosa_pm.c
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ linux-2.6.17/arch/arm/mach-pxa/tosa_pm.c 2006-09-19 21:08:34.476201250 +0200
+@@ -0,0 +1,661 @@
++/*
++ * Battery and Power Management code for the Sharp SL-6000x
++ *
++ * Copyright (c) 2005 Dirk Opfer
++ *
++ * 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/pm.h>
++#include <linux/wm97xx.h>
++
++#include <asm/apm.h>
++#include <asm/irq.h>
++#include <asm/mach-types.h>
++#include <asm/hardware.h>
++#include <asm/hardware/scoop.h>
++#include <asm/hardware/tmio.h>
++
++#include <asm/arch/sharpsl.h>
++#include <asm/arch/tosa.h>
++#include <asm/arch/pxa-regs.h>
++#include <sound/soc.h>
++#include <sound/ac97_codec.h>
++#include "sharpsl.h"
++
++extern int tosa_bl_intensity(void);
++volatile static int ad_polling;
++static int tosa_pm_driver_probe(struct device *dev);
++static int tosa_pm_driver_remove(struct device *dev);
++static struct wm97xx *wm9712;
++
++/************************************************************
++ * AC97 functions
++ ************************************************************/
++#define AC97_TIMEOUT_VAL 0x1000000
++
++#define AC97_MISC_MODEM_STAT 0x0056
++#define AC97_GPIO_CONFIG 0x004C
++
++static u16 tosa_ac97_read(unsigned short reg)
++{
++ volatile u32 *reg_addr;
++ volatile int timeout;
++ unsigned short data;
++
++ if (CAR & CAR_CAIP) {
++ printk(KERN_CRIT ": CAR_CAIP already set\n");
++ return 0;
++ }
++
++ if (reg == AC97_GPIO_STATUS)
++ reg_addr = &PMC_REG_BASE;
++ else
++ reg_addr = &PAC_REG_BASE;
++
++ reg_addr += (reg >> 1);
++
++ data=0;
++ GSR = GSR_CDONE | GSR_SDONE;
++
++ data = *reg_addr;
++ timeout = 0;
++
++ while(((GSR & GSR_SDONE)) == 0 && (timeout++ < AC97_TIMEOUT_VAL));
++
++ if ((timeout >= AC97_TIMEOUT_VAL)) {
++ GSR = GSR;
++ printk(KERN_CRIT ": AC97 is busy1.\n");
++ return data;
++ }
++
++ // actual read
++ GSR = GSR_CDONE | GSR_SDONE;
++ data = *reg_addr;
++
++ timeout = 0;
++ while(((GSR & GSR_SDONE) == 0) && (timeout++<AC97_TIMEOUT_VAL));
++ if ((timeout >= AC97_TIMEOUT_VAL)) {
++ GSR = GSR;
++ printk(KERN_CRIT ": AC97 is busy2.\n");
++ return data;
++ }
++
++ return data;
++}
++
++static void tosa_ac97_write(unsigned short reg, unsigned short val)
++{
++ volatile u32 *reg_addr;
++ volatile int timeout=0;
++
++ if (CAR & CAR_CAIP) {
++ printk(KERN_CRIT ": CAR_CAIP already set\n");
++ return;
++ }
++
++ GSR = GSR_CDONE | GSR_SDONE;
++ if (reg == AC97_GPIO_STATUS)
++ reg_addr = &PMC_REG_BASE;
++ else
++ reg_addr = &PAC_REG_BASE;
++
++ reg_addr += (reg >> 1);
++
++ *reg_addr = val;
++ while(((GSR & GSR_CDONE) == 0) && (timeout++ < AC97_TIMEOUT_VAL));
++ if (timeout >= AC97_TIMEOUT_VAL) {
++ printk(KERN_CRIT ": AC97 is busy.\n");
++ }
++}
++
++static void tosa_ac97_bit_clear(u8 reg, u16 val)
++{
++ unsigned short dat = tosa_ac97_read(reg);
++ dat &= ~val;
++ tosa_ac97_write(reg, dat);
++}
++
++static void tosa_ac97_bit_set(u8 reg, u16 val)
++{
++ unsigned short dat = tosa_ac97_read(reg);
++ dat |= val;
++ tosa_ac97_write(reg, dat);
++}
++
++
++static int tosa_ac97_init(void)
++{
++ int timeo;
++
++ pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
++ pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
++ pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
++ pxa_gpio_mode(GPIO29_SDATA_IN_AC97_MD);
++ pxa_gpio_mode(GPIO20_DREQ0_MD);
++
++ pxa_set_cken(CKEN2_AC97, 1);
++ /* AC97 power on sequense */
++ while ( 1 ) {
++ GCR = 0;
++ udelay(100);
++ GCR |= GCR_COLD_RST;
++ udelay(5);
++ GCR |= GCR_WARM_RST;
++ udelay(5);
++ for ( timeo = 0x10000; timeo > 0; timeo-- ) {
++ if ( GSR & GSR_PCR ) break;
++ mdelay(5);
++ }
++ if( timeo > 0 ) break;
++ printk(KERN_WARNING "AC97 power on retry!!\n");
++ }
++
++ tosa_ac97_write(AC97_EXTENDED_STATUS, 1);
++ /*
++ * Setting AC97 GPIO
++ * i/o function
++ * GPIO1: input EAR_IN signal
++ * GPIO2: output IRQ signal
++ * GPIO3: output PENDOWN signal
++ * GPIO4: input MASK signal
++ * GPIO5: input DETECT MIC signal
++ */
++ // AC97_GPIO_FUNC AC97_MISC_MODEM_STAT
++
++ tosa_ac97_bit_clear(AC97_MISC_MODEM_STAT,
++ ((1<<2)|(1<<3)|(1<<4)|(1<<5)));
++ tosa_ac97_bit_clear(AC97_GPIO_CONFIG,(1<<2)|(1<<3));
++ tosa_ac97_bit_set(AC97_GPIO_CONFIG, (1<<1)|(1<<4)|(1<<5));
++
++ tosa_ac97_write(AC97_WM97XX_DIGITISER2, 0xc009);
++ tosa_ac97_write(AC97_WM97XX_DIGITISER1, 0x0030 | WM97XX_DELAY(4));
++
++ pxa_gpio_mode(GPIO32_SDATA_IN1_AC97_MD);
++ ad_polling = 1;
++ printk("tosa_ac97_init\n");
++}
++
++void tosa_ac97_exit(void)
++{
++ if (!(CKEN & CKEN2_AC97))
++ return;
++
++ // power down the whole chip
++ tosa_ac97_write(AC97_POWERDOWN, 0x7fff);
++
++// GCR &= ~(GCR_CDONE_IE | GCR_SDONE_IE | GCR_SECRDY_IEN | GCR_PRIRDY_IEN | GCR_SECRES_IEN | GCR_PRIRES_IEN);
++// GSR = GSR;
++// GCR = GCR_ACLINK_OFF;
++ pxa_set_cken(CKEN2_AC97, 0);
++ /* switch back to irq driver */
++ ad_polling = 0;
++ printk("tosa_ac97_exit\n");
++}
++
++int ac97_ad_input(u16 adcsel)
++{
++ unsigned short val = 0;
++ unsigned long timeout;
++
++ // prepare
++ tosa_ac97_read(AC97_WM97XX_DIGITISER_RD);
++
++ if (adcsel & 0x8000)
++ adcsel = ((adcsel & 0x7fff) + 3) << 12;
++
++ /* Conversion start */
++ tosa_ac97_write(AC97_WM97XX_DIGITISER1, (adcsel | WM97XX_POLL | WM97XX_DELAY(4)));
++ timeout = 0x1000;
++ /* wait for POLL to go low */
++ while ((tosa_ac97_read(AC97_WM97XX_DIGITISER1) & WM97XX_POLL) && timeout) {
++ udelay(100);
++ timeout--;
++ }
++
++ val = tosa_ac97_read(AC97_WM97XX_DIGITISER_RD);
++
++ val &= 0xFFF ;
++
++ return val;
++}
++
++
++int tosa_read_aux_adc(u16 adcsel)
++{
++ if (ad_polling)
++ return (ac97_ad_input(adcsel));
++ else
++ return (wm97xx_read_aux_adc(wm9712, adcsel));
++}
++
++static struct device_driver tosa_pm_driver = {
++ .name = "wm97xx-battery",
++ .bus = &wm97xx_bus_type,
++ .owner = THIS_MODULE,
++ .probe = tosa_pm_driver_probe,
++ .remove = tosa_pm_driver_remove,
++};
++
++#if 0
++#define TOSA_TEMP_READ_WAIT_TIME (5) // 5msec [Fix]
++int tosa_read_battery(struct wm97xx* wm, int channel)
++{
++ //return sprintf(buf, "%d\n", wm97xx_read_aux_adc(wm, input));
++
++ int wm_aux,i;
++ int value = 0;
++ int clear_mux;
++
++ switch(channel) {
++
++ case 0: // Main
++
++ set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_V_ON);
++ reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT1_V_ON | TOSA_TC6393_BAT_SW_ON);
++ wm_aux = WM97XX_AUX_ID3;
++ break;
++
++ case 1: // Jacket
++
++ set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT1_V_ON);
++ reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_V_ON | TOSA_TC6393_BAT_SW_ON);
++ wm_aux = WM97XX_AUX_ID3;
++ break;
++
++ case 2: // BU
++ set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BU_CHRG_ON);
++ wm_aux = WM97XX_AUX_ID4;
++ break;
++
++ case 3: // Main Temp
++ set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT1_TH_ON);
++ reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_TH_ON);
++ wm_aux = WM97XX_AUX_ID2;
++ break;
++
++ case 4: // Jacket Temp
++ set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_TH_ON);
++ reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT1_TH_ON);
++ wm_aux = WM97XX_AUX_ID2;
++ break;
++
++ default:
++ return -1;
++ }
++
++ mdelay(TOSA_TEMP_READ_WAIT_TIME);
++ for(i=0;i<4;i++)
++ {
++ if (wm9712)
++ value += wm97xx_read_aux_adc(wm, wm_aux);
++ else
++ value += ac97_ad_input(wm, wm_aux);
++ }
++
++ value>>=2;
++ // reset the multiplexer
++ clear_mux = TOSA_TC6393_BAT0_V_ON | TOSA_TC6393_BAT1_V_ON | TOSA_TC6393_BAT_SW_ON | TOSA_TC6393_BAT0_TH_ON | TOSA_TC6393_BAT1_TH_ON | TOSA_TC6393_BU_CHRG_ON;
++
++ return value;
++
++}
++#endif
++
++/* BL 5-3 */
++struct battery_thresh tosa_battery_levels_bl[] = {
++ { 1663, 100 },
++ { 1605, 75 },
++ { 1564, 50 },
++ { 1510, 25 },
++ { 1435, 5 },
++ { 0, 0 },
++};
++
++/* BL 2-0 */
++struct battery_thresh tosa_battery_levels[] = {
++ { 1679, 100 },
++ { 1617, 75 },
++ { 1576, 50 },
++ { 1530, 25 },
++ { 1448, 5 },
++ { 0, 0 },
++};
++
++struct pm_devices {
++ const char * name;
++ struct bus_type *bus;
++ struct device_driver *driver;
++ struct device * dev;
++ int (*resume)(struct device *dev, void * data); // int (*resume)(struct device *dev);
++ int (*suspend)(struct device *dev, void * data);// int (*suspend)(struct device *dev, pm_message_t state);
++};
++
++/* Ugly
++ We need the following devices to measure the battery and control the charger:
++ Also we need access to these before we sleep and immediatly after we resume so we can't
++ control their pm via the kernel device manager. To access their pm functions we will backup
++ the suspend and resume handler and clear these pointers.
++ After that we can suspend and resume these devices.
++
++ Don't change the order of this table!!!!!
++*/
++static struct pm_devices dev_table[] = {
++ [0] = {
++ .name = TMIO_SOC_NAME,
++ .bus = &platform_bus_type,
++ },
++};
++
++static int tosa_pm_driver_probe(struct device *dev)
++{
++ wm9712 = dev->driver_data;
++ ad_polling = 0;
++ return 0;
++}
++
++static int tosa_pm_driver_remove(struct device *dev)
++{
++ wm9712 = NULL;
++ return 0;
++}
++
++
++static void tosa_charger_init(void)
++{
++ int i;
++
++ /* If this driver doesn't register, bad things will happen, Tosa won't boot,
++ and the world will possibly explode */
++ i = driver_register(&tosa_pm_driver);
++ if (i < 0)
++ panic("Cannot register the tosa_pm driver on the wm97xx bus. Halting.");
++
++ for(i=0;i<ARRAY_SIZE(dev_table);i++)
++ {
++ dev_table[i].driver = driver_find(dev_table[i].name, dev_table[i].bus);
++ if (dev_table[i].driver)
++ {
++ dev_table[i].resume = dev_table[i].driver->resume;
++ dev_table[i].suspend = dev_table[i].driver->suspend;
++ dev_table[i].driver->resume = NULL;
++ dev_table[i].driver->suspend = NULL;
++ }
++ }
++
++ pxa_gpio_mode(TOSA_GPIO_AC_IN | GPIO_IN);
++ pxa_gpio_mode(TOSA_GPIO_BAT0_CRG | GPIO_IN);
++ pxa_gpio_mode(TOSA_GPIO_BAT1_CRG | GPIO_IN);
++ pxa_gpio_mode(TOSA_GPIO_BAT0_LOW | GPIO_IN);
++ pxa_gpio_mode(TOSA_GPIO_BAT1_LOW | GPIO_IN);
++
++ pxa_gpio_mode(TOSA_GPIO_JACKET_DETECT | GPIO_IN);
++ pxa_gpio_mode(TOSA_GPIO_POWERON | GPIO_IN);
++ sharpsl_pm_pxa_init();
++}
++
++
++static void tosa_measure_temp(int on)
++{
++ reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_TH_ON | TOSA_TC6393_BAT1_TH_ON);
++
++ if (on)
++ set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT1_TH_ON);
++
++}
++
++static void tosa_charge(int on)
++{
++ if(on)
++ reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_CHARGE_OFF);
++ else
++ set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_CHARGE_OFF);
++}
++
++static void tosa_discharge1(int on)
++{
++}
++
++static void tosa_discharge(int on)
++{
++}
++
++
++static void tosa_presuspend(void)
++{
++ int i;
++ unsigned long wakeup_mask;
++
++ // put remaining devices into sleep
++ for(i=0;i<ARRAY_SIZE(dev_table);i++)
++ {
++ if(dev_table[i].suspend)
++ driver_for_each_device(dev_table[i].driver, NULL,
++ (void*)&PMSG_SUSPEND, dev_table[i].suspend);
++ }
++
++ tosa_ac97_exit();
++
++ wakeup_mask = GPIO_bit(TOSA_GPIO_POWERON) | GPIO_bit(TOSA_GPIO_ON_KEY) | GPIO_bit(TOSA_GPIO_AC_IN);
++
++ wakeup_mask |= GPIO_bit(TOSA_GPIO_BAT0_LOW);
++ 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);
++ }
++ }
++
++ /* Clear reset status */
++ RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
++
++ /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
++ PCFR = PCFR_OPDE;
++
++ /* Resume on keyboard power key */
++ PGSR1 = (PGSR1 & ~TOSA_GPIO_LOW_STROBE_BIT);
++ PGSR2 = (PGSR2 & ~TOSA_GPIO_HIGH_STROBE_BIT);
++
++ GPDR0 = 0xC3810940;
++ GPDR1 = 0xFCFFAB82;
++ GPDR2 = 0x000F501f;
++// write_scoop_reg(&tosascoop_device.dev,SCOOP_GPWR,0);
++// only debug
++reset_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_NOTE_LED);
++}
++
++void tosa_postsuspend(void)
++{
++ int i;
++// only debug
++set_scoop_gpio(&tosascoop_jc_device.dev, TOSA_SCOOP_JC_NOTE_LED);
++
++ for(i=ARRAY_SIZE(dev_table);i;i--)
++ {
++ if(dev_table[i-1].resume)
++ driver_for_each_device(dev_table[i-1].driver, NULL,
++ NULL, dev_table[i-1].resume);
++ }
++ tosa_ac97_init();
++ PMCR = 0x01;
++}
++
++void tosa_postresume(void)
++{
++ tosa_ac97_exit();
++}
++
++/*
++ * Check what brought us out of the suspend.
++ * Return: 0 to sleep, otherwise wake
++ */
++static int tosa_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(TOSA_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(GPIO_bit(TOSA_GPIO_BAT0_CRG))))
++ dev_dbg(sharpsl_pm.dev, "Charge full interrupt\n");
++
++ if (PEDR & GPIO_bit(TOSA_GPIO_POWERON))
++ is_resume |= GPIO_bit(TOSA_GPIO_POWERON);
++
++ if (PEDR & GPIO_bit(TOSA_GPIO_ON_KEY))
++ is_resume |= GPIO_bit(TOSA_GPIO_ON_KEY);
++
++ if (resume_on_alarm && (PEDR & PWER_RTC))
++ is_resume |= PWER_RTC;
++
++ return is_resume;
++}
++
++static unsigned long tosa_charger_wakeup(void)
++{
++// return ~GPLR0 & ( GPIO_bit(TOSA_GPIO_AC_IN) | GPIO_bit(TOSA_GPIO_POWERON) | GPIO_bit(TOSA_GPIO_ON_KEY) );
++ return (~GPLR0 & ( GPIO_bit(TOSA_GPIO_POWERON) | GPIO_bit(TOSA_GPIO_ON_KEY) )) | (GPLR0 & GPIO_bit(TOSA_GPIO_AC_IN));
++}
++
++unsigned long tosa_read_bat(void)
++{
++ unsigned long value;
++ reset_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_V_ON | TOSA_TC6393_BAT1_V_ON | TOSA_TC6393_BAT_SW_ON);
++ mdelay(5);
++ value = tosa_read_aux_adc(WM97XX_AUX_ID3);
++ set_tc6393_gpio(&tc6393_device.dev,TOSA_TC6393_BAT0_V_ON);
++ return value;
++}
++
++unsigned long tosapm_read_devdata(int type)
++{
++ switch(type) {
++ case SHARPSL_STATUS_ACIN:
++ return ((GPLR(TOSA_GPIO_AC_IN) & GPIO_bit(TOSA_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 1000; // not used on tosa
++ case SHARPSL_BATT_TEMP:
++ return tosa_read_aux_adc(WM97XX_AUX_ID2);
++ case SHARPSL_BATT_VOLT:
++ return tosa_read_bat();
++ default:
++ return tosa_read_bat();
++ }
++}
++
++static struct sharpsl_charger_machinfo tosa_pm_machinfo = {
++ .init = tosa_charger_init,
++ .exit = sharpsl_pm_pxa_remove,
++ .gpio_batlock = TOSA_GPIO_BAT_LOCKED,
++ .gpio_acin = TOSA_GPIO_AC_IN,
++ .gpio_batfull = TOSA_GPIO_BAT0_CRG,
++ .batfull_irq = 0,
++ .discharge = tosa_discharge,
++ .discharge1 = tosa_discharge1,
++ .charge = tosa_charge,
++ .measure_temp = tosa_measure_temp,
++ .presuspend = tosa_presuspend,
++ .postsuspend = tosa_postsuspend,
++ .postresume = tosa_postresume,
++ .read_devdata = tosapm_read_devdata,
++ .charger_wakeup = tosa_charger_wakeup,
++ .should_wakeup = tosa_should_wakeup,
++ .backlight_limit = corgibl_limit_intensity,
++ .backlight_get_status= tosa_bl_intensity,
++ .bat_levels = 6,
++ .bat_levels_noac = tosa_battery_levels,
++ .bat_levels_acin = tosa_battery_levels,
++ .bat_levels_noac_bl = tosa_battery_levels_bl,
++ .bat_levels_acin_bl = tosa_battery_levels_bl,
++ .charge_on_volt = 1200, // 2.9V TOSA_MAIN_BATTERY_ERR_THRESH voltage < 1200 -> error
++ .charge_on_temp = 3600, // -- TOSA_MAIN_BATTERY_EXIST_THRESH temp > 3600 -> error, no battery
++ .charge_acin_high = 1500, // not used default value
++ .charge_acin_low = 500, // not used default value
++ .fatal_acin_volt = 1572, // 3.8V
++ .fatal_noacin_volt= 1551, // 3.75V
++ .status_high_acin = 1564, // 3.78V
++ .status_low_acin = 1510, // 3.65V
++ .status_high_noac = 1564, // 3.78V
++ .status_low_noac = 1510, // 3.65V
++};
++
++static struct platform_device *tosapm_device;
++
++static int __devinit tosapm_init(void)
++{
++ int ret;
++
++ tosapm_device = platform_device_alloc("sharpsl-pm", -1);
++ if (!tosapm_device)
++ return -ENOMEM;
++
++ tosapm_device->dev.platform_data = &tosa_pm_machinfo;
++ ret = platform_device_add(tosapm_device);
++
++ if (ret)
++ platform_device_put(tosapm_device);
++
++ return ret;
++}
++
++static void tosapm_exit(void)
++{
++ int i;
++
++ // restore the resume / suspend handler
++ for(i=0;i<ARRAY_SIZE(dev_table);i++)
++ {
++ if (dev_table[i].driver)
++ {
++ dev_table[i].driver->resume = dev_table[i].resume;
++ dev_table[i].driver->suspend = dev_table[i].suspend;
++ dev_table[i].resume = NULL;
++ dev_table[i].suspend = NULL;
++ put_driver(dev_table[i].driver);
++ }
++ }
++
++ if (wm9712)
++ driver_unregister(&tosa_pm_driver);
++
++ platform_device_unregister(tosapm_device);
++}
++
++module_init(tosapm_init);
++module_exit(tosapm_exit);
+Index: linux-2.6.17/arch/arm/mach-pxa/Kconfig
+===================================================================
+--- linux-2.6.17.orig/arch/arm/mach-pxa/Kconfig 2006-09-19 20:51:40.160810500 +0200
++++ linux-2.6.17/arch/arm/mach-pxa/Kconfig 2006-09-19 21:08:04.926354500 +0200
+@@ -110,6 +110,7 @@ config MACH_TOSA
+ bool "Enable Sharp SL-6000x (Tosa) Support"
+ depends PXA_SHARPSL_25x
+ select TOSHIBA_TC6393XB
++ select SHARPSL_PM
+
+ config PXA25x
+ bool