
#
# Patch managed by http://www.holgerschurig.de/patcher.html
#

--- /dev/null
+++ linux-2.6.10-rc2/arch/arm/mach-pxa/corgi_battery.c
@@ -0,0 +1,2067 @@
+/*
+ * linux/arch/arm/mach-pxa/sharpsl_battery.c
+ *
+ * Based on
+ *  linux/arch/arm/mach-sa1100/collie_battery.c
+ *
+ * Battery routines for corgi (SHARP)
+ *
+ * Copyright (C) 2001  SHARP
+ *
+ * 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.
+ *
+ * ChangeLog:
+ *	12-Nov-2001 Lineo Japan, Inc.
+ *	21-Aug-2002 Lineo Japan, Inc.  for 2.4.18
+ *	12-Dec-2002 Sharp Corporation for Poodle and Corgi
+ *	16-Jan-2003 SHARP sleep_on -> interruptible_sleep_on
+ *	19-May-2003 SHARP support for Sheperd
+ *
+ */
+
+
+/* this driver support the following functions
+ *      - apm_get_power_status
+ *      - charge proc
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+
+#include <linux/poll.h>
+#include <linux/types.h>
+#include <linux/stddef.h>
+#include <linux/timer.h>
+#include <linux/fcntl.h>
+#include <linux/slab.h>
+#include <linux/stat.h>
+#include <linux/proc_fs.h>
+#include <linux/miscdevice.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/pm.h>
+#include <linux/kernel.h>
+#include <linux/smp_lock.h>
+#include <linux/apm_bios.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/apm.h>
+
+//#include <asm/sharp_char.h>
+//#include <asm/sharp_keycode.h>
+
+#include <asm/arch/pxa-regs.h>
+//#include <asm/arch/keyboard_corgi.h>
+#include <asm/arch/corgi.h>
+//#include <video/corgi_backlight.h>
+
+#include "corgi_battery.h"
+
+static struct {
+	u32 ffier, fflcr, ffmcr, ffspr, ffisr, ffdll, ffdlh;
+} sys_ctx;
+
+
+
+//#define DEBUG	1
+#ifdef DEBUG
+#define DPRINTK(x, args...)  printk(x,##args)
+#define DPRINTK2(x, args...)  printk(x,##args)
+#else
+#define DPRINTK(x, args...)   if ( msglevel > 1 )	printk(x,##args);
+#define DPRINTK2(x, args...)  if ( msglevel > 0 )	printk(x,##args);
+#endif
+
+/*
+ * The battery device is one of the misc char devices.
+ * This is its minor number.
+ */
+#define	BATTERY_MINOR_DEV	215
+
+
+
+#if defined(CONFIG_MACH_CORGI)
+#define CHARGE_ON()	({							\
+				if (corgi_suspended) {	\
+					GPSR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);	\
+					GPCR(GPIO43_BTTXD) = GPIO_bit(GPIO43_BTTXD);	\
+				} else {	\
+					GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);	\
+					GPSR(GPIO43_BTTXD) = GPIO_bit(GPIO43_BTTXD);	\
+				}						\
+			})
+#endif
+#if defined(CONFIG_MACH_SHEPHERD) || defined(CONFIG_MACH_HUSKY) 
+#define CHARGE_ON()	({							\
+					GPSR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);	\
+					GPCR(GPIO43_BTTXD) = GPIO_bit(GPIO43_BTTXD);	\
+			})
+#endif
+#define CHARGE_OFF()	({							\
+				GPCR(CORGI_GPIO_CHRG_ON) = GPIO_bit(CORGI_GPIO_CHRG_ON);	\
+				GPCR(GPIO43_BTTXD) = GPIO_bit(GPIO43_BTTXD);	\
+			})
+
+#define DISCHARGE_ON()	GPSR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON)
+#define DISCHARGE_OFF()	GPCR(CORGI_GPIO_DISCHARGE_ON) = GPIO_bit(CORGI_GPIO_DISCHARGE_ON)
+
+//RPFIXME
+//#define CHARGE_LED_ON()		set_led_status(SHARP_LED_CHARGER,LED_CHARGER_CHARGING)
+//#define CHARGE_LED_OFF()	set_led_status(SHARP_LED_CHARGER,LED_CHARGER_OFF)
+//#define CHARGE_LED_ERR()	set_led_status(SHARP_LED_CHARGER,LED_CHARGER_ERROR)
+//#define CHARGE_LED_ERR_OFF()	sharpsl_charge_err_off()
+
+#define CHARGE_LED_ON()		printk("Charge LED On\n");
+#define CHARGE_LED_OFF()	printk("Charge LED Off\n");
+#define CHARGE_LED_ERR()	printk("Charge LED Error\n");
+#define CHARGE_LED_ERR_OFF() printk("Charge LED Error Off\n");
+
+
+#define SHARPSL_BATTERY_STATUS_HIGH	APM_BATTERY_STATUS_HIGH
+#define SHARPSL_BATTERY_STATUS_LOW	APM_BATTERY_STATUS_LOW
+#define SHARPSL_BATTERY_STATUS_VERYLOW	APM_BATTERY_STATUS_LOW
+#define SHARPSL_BATTERY_STATUS_CRITICAL	APM_BATTERY_STATUS_CRITICAL
+
+#define SHARPSL_AC_LINE_STATUS	(!( GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN) )	? APM_AC_OFFLINE : APM_AC_ONLINE)
+#define SHARPSL_BATTERY_OK	(( GPLR(GPIO_MAIN_BAT_LOW) & GPIO_bit(GPIO_MAIN_BAT_LOW) ) ? 1 : 0)	/* 1: OK / 0: FATAL */
+
+#define SHARPSL_APO_TICKTIME		(  30 * SHARPSL_PM_TICK )		// 30 sec
+#define SHARPSL_LPO_TICKTIME		SHARPSL_APO_TICKTIME
+
+
+#define SHARPSL_PM_TICK         	( HZ )          		        // 1 sec
+#define SHARPSL_BATCHK_TIME		( SHARPSL_PM_TICK )			// 1 sec
+#define SHARPSL_MAIN_GOOD_COUNT		( HZ / SHARPSL_PM_TICK )		// 1 sec
+#define SHARPSL_MAIN_NOGOOD_COUNT	( HZ / SHARPSL_PM_TICK )		// 1 sec
+
+
+#define SHARPSL_CHARGE_ON_TIME_INTERVAL	( 1*60*1000 / 10 )	// 1min
+#define SHARPSL_CHARGE_WAIT_TIME	15			// 15 msec
+#define SHARPSL_CHARGE_FINISH_TIME	( 10*60*1000/10 )	// 10 min
+
+#define SHARPSL_CHARGE_CO_CHECK_TIME		5	// 5 msec
+
+#define SHARPSL_BATTERY_CK_TIME		( 10*60*1*100 )		// 10min ( base jiffies )
+
+
+
+
+#define SHARPSL_CHARGE_ON_VOLT			0x99	// 2.9V
+#define SHARPSL_CHARGE_ON_TEMP			0xe0	// 2.9V
+#define SHARPSL_CHARGE_ON_JKVAD_HIGH		0x9b	// 6V
+#define SHARPSL_CHARGE_ON_JKVAD_LOW		0x34	// 2V
+#define SHARPSL_WAIT_DISCHARGE_ON		10	// 100msec
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP	1	// 10msec
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT	1	// 10msec
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD	1	// 10msec
+#define SHARPSL_CORGI_FATAL_ACIN_VOLT		182	// 3.45V
+#define SHARPSL_CORGI_FATAL_NOACIN_VOLT		170	// 3.40V
+#define SHARPSL_CORGI_WAIT_CO_TIME		15	// 15 Sec
+							//NOTICE !!  you want to change this value , so you must change
+							//           alarm check mirgin time ( +30 ) in the sharpsl_power.c.
+
+
+
+//RPFIXME
+//#define SHARPSL_CAUTION_CONTRAST		CORGI_BL_CAUTION_CONTRAST
+//#define SHARPSL_RESET_CONTRAST			CORGI_BL_RESET_CONTRAST
+//#define SHARPSL_LIMIT_CONTRAST(x)		corgibl_set_limit_contrast(x)
+
+#define SHARPSL_CAUTION_CONTRAST		
+#define SHARPSL_RESET_CONTRAST			
+#define SHARPSL_LIMIT_CONTRAST(x)		
+
+
+#define CHARGE_STEP1		1
+#define CHARGE_STEP2		2
+#define CHARGE_STEP3		3
+#define CHARGE_STEP4		4
+#define CHARGE_STEP5	        5
+#define CHARGE_STEP6	        6
+#define CHARGE_STEP7	        7
+#define CHARGE_STEP_END		10
+#define CHARGE_STEP_EXIT	11
+#define CHARGE_STEP_ERROR	12
+#define SHARPSL_CHARGE_RETRY_CNT	1	// 10 min
+#define SHARPSL_AFTER_CHARGE_CNT	0	// 0
+
+#define SHARPSL_CNV_VALUE_NUM	10
+
+
+
+#define PWER_RTC	0x80000000
+
+
+#ifdef CONFIG_MACH_CORGI
+#define R_WAKEUP_SRC	(GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_AK_INT))
+#else
+#define R_WAKEUP_SRC	(GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_AK_INT) | GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW))
+#endif
+
+#define F_WAKEUP_SRC	(GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) | \
+			 GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW))
+#define WAKEUP_SRC	( R_WAKEUP_SRC | F_WAKEUP_SRC | PWER_RTC )
+#define WAKEUP_DEF_SRC	( WAKEUP_SRC );
+
+
+
+
+typedef struct BatteryThresh {
+    int voltage;
+    int percentage;
+    int status;
+} BATTERY_THRESH;
+
+/*** prototype *********************************************************************/
+static int sharpsl_read_MainBattery(void);
+static int sharpsl_off_charge_battery(void);
+
+static BATTERY_THRESH *GetMainLevel( int Volt );
+static int sharpsl_get_main_battery(void);
+static int GetMainPercent(int);
+static int GetMainChargePercent(int);
+static int Get_DAC_Value(int);
+static int sharpsl_check_battery(int mode);
+
+// remove warnings
+static int sharpsl_battery_thread_main(void);
+static int sharpsl_ac_check(void);
+void sharpsl_charge_err_off(void);
+static unsigned short chkFatalBatt(void);
+static int sharpsl_wakeup_hook(void);
+
+
+/*** extern ***********************************************************************/
+
+
+
+unsigned int apm_wakeup_src_mask = WAKEUP_DEF_SRC;
+int pass_charge_flag = 0;
+
+extern int counter_step_contrast;
+
+
+extern int corgi_ssp_max1111_get(ulong data);
+
+extern int set_led_status(int which,int status);
+
+
+/*** variables ********************************************************************/
+
+#define BATTERY_CHECK_TIME	60*10	// 10 min
+
+BATTERY_THRESH  sharpsl_main_battery_thresh_fl[] = {
+    { 999, 100, SHARPSL_BATTERY_STATUS_HIGH},
+    { 210, 100, SHARPSL_BATTERY_STATUS_HIGH},
+    { 194,  90, SHARPSL_BATTERY_STATUS_HIGH},
+    { 188,  70, SHARPSL_BATTERY_STATUS_HIGH},
+    { 184,  50, SHARPSL_BATTERY_STATUS_HIGH},
+    { 180,  25, SHARPSL_BATTERY_STATUS_LOW},
+    { 174,  10, SHARPSL_BATTERY_STATUS_LOW},
+    { 170,   5, SHARPSL_BATTERY_STATUS_VERYLOW},
+    {   0,   0, SHARPSL_BATTERY_STATUS_CRITICAL},
+};
+
+BATTERY_THRESH  sharpsl_main_battery_thresh_nofl[] = {
+    { 999, 100, SHARPSL_BATTERY_STATUS_HIGH},
+    { 210, 100, SHARPSL_BATTERY_STATUS_HIGH},
+    { 194,  90, SHARPSL_BATTERY_STATUS_HIGH},
+    { 188,  70, SHARPSL_BATTERY_STATUS_HIGH},
+    { 184,  50, SHARPSL_BATTERY_STATUS_HIGH},
+    { 180,  25, SHARPSL_BATTERY_STATUS_LOW},
+    { 174,  10, SHARPSL_BATTERY_STATUS_LOW},
+    { 170,   5, SHARPSL_BATTERY_STATUS_VERYLOW},
+    {   0,   0, SHARPSL_BATTERY_STATUS_CRITICAL},
+};
+
+
+
+BATTERY_THRESH sharpsl_main_battery_thresh_charge_fl[] = {
+    { 999, 100, SHARPSL_BATTERY_STATUS_HIGH},
+    { 210, 100, SHARPSL_BATTERY_STATUS_HIGH},
+    { 200,  95, SHARPSL_BATTERY_STATUS_HIGH},
+    { 196,  75, SHARPSL_BATTERY_STATUS_HIGH},
+    { 192,  50, SHARPSL_BATTERY_STATUS_HIGH},
+    { 187,  25, SHARPSL_BATTERY_STATUS_LOW},
+    { 182,  10, SHARPSL_BATTERY_STATUS_LOW},
+    { 170,   5, SHARPSL_BATTERY_STATUS_VERYLOW},
+    {   0,   0, SHARPSL_BATTERY_STATUS_CRITICAL},
+};
+
+BATTERY_THRESH sharpsl_main_battery_thresh_charge_nofl[] = {
+    { 999, 100, SHARPSL_BATTERY_STATUS_HIGH},
+    { 210, 100, SHARPSL_BATTERY_STATUS_HIGH},
+    { 200,  95, SHARPSL_BATTERY_STATUS_HIGH},
+    { 196,  75, SHARPSL_BATTERY_STATUS_HIGH},
+    { 192,  50, SHARPSL_BATTERY_STATUS_HIGH},
+    { 187,  25, SHARPSL_BATTERY_STATUS_LOW},
+    { 182,  10, SHARPSL_BATTERY_STATUS_LOW},
+    { 170,   5, SHARPSL_BATTERY_STATUS_VERYLOW},
+    {   0,   0, SHARPSL_BATTERY_STATUS_CRITICAL},
+};
+
+
+
+#define MAIN_BATTERY_THRES (sizeof(sharpsl_main_battery_thresh_charge_nofl) / sizeof(BATTERY_THRESH) - 1)
+
+
+
+
+
+
+static int corgi_suspended = 0;
+
+int charge_status = 0;			/* charge status  1 : charge  0: not charge */
+
+unsigned int apm_wakeup_factor = 0;
+
+static DECLARE_WAIT_QUEUE_HEAD(battery_queue);
+static int	msglevel;
+
+int sharpsl_main_battery   = SHARPSL_BATTERY_STATUS_HIGH;
+int sharpsl_main_battery_percentage = 100;
+int sharpsl_main_charge_battery = 100;
+int sharpsl_main_battery_voltage = 200;
+
+int sharpsl_ac_status = APM_AC_OFFLINE;
+
+static int MainCntWk = SHARPSL_MAIN_GOOD_COUNT;
+static int MainCnt   = SHARPSL_MAIN_NOGOOD_COUNT;
+static int FattCnt   = 0;
+static int back_ac_status = -1;
+static int back_battery_status = -1;
+
+static int sharpsl_main_status_bk = SHARPSL_BATTERY_STATUS_HIGH;
+static int sharpsl_main_percent_bk = 100;
+static int sharpsl_check_ac_err = 0;
+int sharpsl_main_bk_flag = 0;
+
+static struct timer_list ac_kick_timer;
+
+
+static int sharpsl_alarm_flag;
+
+
+static int battery_off_flag = 0;	/* charge : suspend while get adc */
+static int charge_off_mode = 0;		/* charge : check volt or non     */
+static int is_ac_adaptor = 0;		/* AC adaptor in/out */
+
+//static DECLARE_WAIT_QUEUE_HEAD(wq_on);
+//static DECLARE_WAIT_QUEUE_HEAD(wq_off);
+static DECLARE_WAIT_QUEUE_HEAD(battery_waitqueue);
+
+static void sharpsl_charge_on(void *private_);
+static void sharpsl_charge_off(void *private_);
+static void sharpsl_battery_thread(void *private_);
+
+DECLARE_WORK(battchrgon, sharpsl_charge_on, NULL);
+DECLARE_WORK(battchrgoff, sharpsl_charge_off, NULL);
+DECLARE_WORK(sharpsl_bat, sharpsl_battery_thread, NULL);
+
+static int sharpsl_fatal_off = 1;
+static unsigned int sharpsl_charge_time = 0;
+
+int sharpsl_charge_state = CHARGE_STEP1;
+int sharpsl_charge_cnt = 0;
+int sharpsl_charge_dummy_cnt = 1;
+
+static unsigned int sharpsl_charge_on_time = 0;
+
+static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1];
+static int sharpsl_ad_index = 0;
+
+static int sharpsl_change_battery_status = 0;
+
+
+// for DEBUG
+static int sharpsl_debug_flag = 0;
+
+
+
+
+#define SHARPSL_IS_BATT		245	/* battery : in/out */
+
+#define MAXCTRL_PD0_SH		0
+#define MAXCTRL_PD1_SH		1
+#define MAXCTRL_SGL_SH		2
+#define MAXCTRL_UNI_SH		3
+#define MAXCTRL_SEL_SH		4
+#define MAXCTRL_STR_SH		7
+#define MAXCTRL_PD1_MSK		2
+
+
+
+
+/*** apm subroutines  ***********************************************************/
+void sharpsl_apm_get_power_status(struct apm_power_info *info)
+{
+        // set ac status
+	info->ac_line_status = sharpsl_ac_status;
+
+	// set battery_status  main
+	info->battery_status = sharpsl_main_battery;
+
+	// set battery percentage
+	info->battery_life = sharpsl_main_battery_percentage;
+
+	if ( info->ac_line_status == APM_AC_ONLINE )
+		info->battery_life = 100;
+
+	// set battery_flag
+	if ( info->battery_flag == SHARPSL_BATTERY_STATUS_VERYLOW )
+		info->battery_flag = (1 << 5);
+	else
+		info->battery_flag = (1 << info->battery_status);
+
+	// chk charge status
+	if ( charge_status ) {
+		info->battery_status = APM_BATTERY_STATUS_CHARGING;
+		info->battery_flag = (1 << 3);
+		// charging now, so can not get battery percentage.
+		//*battery_percentage = sharpsl_main_charge_battery;
+		info->battery_life = -1;
+	}
+
+	// set battery life - RPFIXME
+	//info.battery_life = APM_BATTERY_STATUS_UNKNOWN;
+
+}
+
+
+/*** battery main thread  ***********************************************************/
+// waitms : waitms*10 msec wait
+// flag   : 0 : check battery w/o reflcting battery status.
+//          1 : check battery w/  reflcting battery status.
+//          2 : check battery w/  refresh battery status.
+static void sharpsl_kick_battery_check(int before_waitms,int after_waitms,int flag)
+{
+  //int start;
+
+
+  MainCntWk = MainCnt + 1;
+
+  // before check battery
+  mdelay(before_waitms*10);
+
+
+  switch (flag) {
+  case 0:
+    sharpsl_battery_thread_main();
+    break;
+  case 1:
+    if ( sharpsl_main_bk_flag == 0 ) {
+      sharpsl_main_bk_flag = 1;
+      sharpsl_battery_thread_main();
+      sharpsl_main_bk_flag = 0;
+    } else {
+      sharpsl_battery_thread_main();
+    }
+    break;
+  case 2:
+    back_battery_status = -1;
+    sharpsl_battery_thread_main();
+    break;
+  }
+
+  // after check battery
+  mdelay(after_waitms*10);
+}
+
+
+static void sharpsl_kick_battery_check_queue(void)
+{
+  MainCntWk = MainCnt + 1;
+  wake_up(&battery_queue);
+}
+
+static int sharpsl_battery_thread_main(void)
+{
+
+  // start battery check
+  if ( ( jiffies > SHARPSL_BATTERY_CK_TIME ) && ( sharpsl_main_bk_flag == 0 ) ) {
+    sharpsl_main_bk_flag = 1;
+    printk("start check battery ! \n");
+  }
+
+  // get ac status. if change ac status , chk main battery.
+  sharpsl_ac_status =  SHARPSL_AC_LINE_STATUS;
+  if ( back_ac_status != sharpsl_ac_status ) {
+    MainCntWk = MainCnt + 1;			// chk battery
+    sharpsl_change_battery_status = 1;		// change status
+    schedule_work(&sharpsl_bat);
+  }
+  back_ac_status = sharpsl_ac_status;
+
+  // get main battery
+  sharpsl_get_main_battery();
+
+  // if battery is low , backlight driver become to save power.
+  if ( ( ( sharpsl_main_battery == SHARPSL_BATTERY_STATUS_VERYLOW  ) ||
+       ( sharpsl_main_battery == SHARPSL_BATTERY_STATUS_CRITICAL ) ) &&
+       ( sharpsl_main_battery != back_battery_status ) &&
+       ( sharpsl_main_bk_flag ) ) {
+    SHARPSL_LIMIT_CONTRAST(SHARPSL_CAUTION_CONTRAST);
+  } else if ( sharpsl_main_battery != back_battery_status ) {
+    SHARPSL_LIMIT_CONTRAST(SHARPSL_RESET_CONTRAST);
+  }
+  back_battery_status = sharpsl_main_battery;
+
+  // good or ac in   --> GOOD_COUNT
+  // low or very low --> NOGOOD_COUNT
+  if ( ( sharpsl_main_battery == SHARPSL_BATTERY_STATUS_HIGH ) || ( sharpsl_ac_status == APM_AC_ONLINE ) )
+    MainCnt = SHARPSL_MAIN_GOOD_COUNT;
+  else
+    MainCnt = SHARPSL_MAIN_NOGOOD_COUNT;
+  DPRINTK("MainCnt = %d\n",MainCnt);
+
+  // chk critical
+  if ( ( sharpsl_main_battery == SHARPSL_BATTERY_STATUS_CRITICAL ) && sharpsl_fatal_off && sharpsl_main_bk_flag ) {
+		sharpsl_fatal_off = 0;
+		printk("Fatal Off\n");
+		apm_queue_event(APM_CRITICAL_SUSPEND);
+  } else {
+      FattCnt = 0;
+  }
+
+
+  if ( sharpsl_check_ac_err && sharpsl_main_bk_flag && sharpsl_fatal_off ) {
+    	sharpsl_fatal_off = 0;
+    	printk("ac error\n");
+		apm_queue_event(APM_CRITICAL_SUSPEND);
+  }
+
+
+    return 0;
+}
+
+static void sharpsl_battery_thread(void *private_)
+{
+
+#if defined(CONFIG_MACH_CORGI) 
+		// AC adapter is inserted , but charging not start.
+		// SW can not confirm inserted AC adapter, so kick !
+		if ( ( charge_status == 0 ) && ( sharpsl_ac_status == APM_AC_ONLINE )) {
+		  is_ac_adaptor = 1;
+		  schedule_work(&battchrgon);
+		} else if ( ( charge_status == 1 ) && ( sharpsl_ac_status == APM_AC_OFFLINE )) {
+		  is_ac_adaptor = 0;
+		  schedule_work(&battchrgoff);
+		}
+
+		// re-kick charging
+		if ( sharpsl_charge_on_time > 0 ) {
+		  if ( ( jiffies - sharpsl_charge_on_time ) > SHARPSL_CHARGE_ON_TIME_INTERVAL ) {
+		    sharpsl_charge_on_time = jiffies;
+		    CHARGE_OFF();
+		    mdelay(SHARPSL_CHARGE_WAIT_TIME);
+		    CHARGE_ON();
+		  }
+		}
+#endif
+
+		// check battery !
+		sharpsl_battery_thread_main();
+		wake_up (&battery_waitqueue);
+		schedule_delayed_work(&sharpsl_bat, SHARPSL_BATCHK_TIME);
+}
+
+
+/*** battery charge thread  ***********************************************************/
+static void sharpsl_charge_start(void)
+{
+
+#if defined(CONFIG_MACH_CORGI) 
+		sharpsl_charge_on_time = jiffies;
+#endif
+
+
+		if ( sharpsl_check_battery(1) ) {
+		  /* error led on */
+		  CHARGE_LED_ERR();
+		  CHARGE_OFF();
+		  /* charge status flag reset */
+		  charge_status = 0;
+
+#if defined(CONFIG_MACH_CORGI)
+		  sharpsl_charge_on_time = 0;
+#endif
+
+		} else {
+		  /* led on */
+		  CHARGE_LED_OFF();
+		  CHARGE_LED_ON();
+		  /* Charge ON */
+		  CHARGE_OFF();
+		  mdelay(SHARPSL_CHARGE_WAIT_TIME);
+		  CHARGE_ON();
+		  /* charge status flag set */
+		  charge_status = 1;
+		}
+
+		sharpsl_change_battery_status = 1;
+		schedule_work(&sharpsl_bat);
+}
+
+static void sharpsl_charge_on(void *private_)
+{
+
+       // if ac is not insert, so stop charge start proc.
+    if ( ( GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN) ) == 0 ) return;
+
+		// flag clear
+		sharpsl_main_status_bk = SHARPSL_BATTERY_STATUS_HIGH;
+		sharpsl_main_percent_bk = 100;
+
+
+		/* AC Check */
+		if ( sharpsl_ac_check() ) {
+		  DPRINTK("err\n");
+		  CHARGE_LED_ERR();
+		  CHARGE_OFF();
+		} else {
+		  DPRINTK("call charge on \n");
+		  sharpsl_charge_start();
+		}
+}
+
+
+
+static void sharpsl_charge_off(void *private_)
+{
+
+
+		DPRINTK("charge off\n");
+		DPRINTK("charge off mode = %d\n",charge_off_mode);
+
+#if defined(CONFIG_MACH_CORGI) 
+		sharpsl_charge_on_time = 0;
+#endif
+
+		/* Charge OFF */
+		CHARGE_OFF();
+
+		/* led off */
+		CHARGE_LED_OFF();
+
+		if ( sharpsl_check_battery(charge_off_mode) ) {
+			/* error led on */
+			CHARGE_LED_ERR();
+		}
+
+		/* charge status flag reset */
+		charge_status = 0;
+		sharpsl_charge_time = 0;
+
+		sharpsl_change_battery_status = 1;
+		schedule_work(&sharpsl_bat);
+
+}
+
+/*** Int ***********************************************************************/
+static void sharpsl_ac_kick_timer(unsigned long data)
+{
+  int level = (GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN));
+  int match = 0;
+  int err = 0;
+
+  while(1) {
+    if ( level == (GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) ) {
+      match++;
+    } else {
+      level = (GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN));
+      match = 0;
+      err++;
+    }
+    if ( match > 1 ) break;
+    if ( err > 50 ) {
+      // if ac port is not stable , so use last port data.
+      level = (GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN));
+      printk("err : ac port\n");
+      break;
+    }
+  }
+
+  if ( level == 0 ) {
+    /* High->Low  : desert */
+    is_ac_adaptor = 0;
+    sharpsl_ad_index = 0;
+    charge_off_mode = 1;
+    schedule_work(&battchrgoff);
+  } else {
+    /* Low->High  : assert */
+    is_ac_adaptor = 1;
+    schedule_work(&battchrgon);
+  }
+  sharpsl_kick_battery_check_queue();
+}
+
+
+static irqreturn_t Sharpsl_ac_interrupt(int irq,  void *dev_id, struct pt_regs *fp)
+{
+  // clear flag
+  sharpsl_check_ac_err = 0;
+  // wait delay
+  mod_timer(&ac_kick_timer, jiffies + HZ / 100);
+  
+  return IRQ_HANDLED;
+}
+
+static irqreturn_t Sharpsl_co_interrupt(int irq,  void *dev_id, struct pt_regs *fp)
+{
+#if defined(CONFIG_MACH_SHEPHERD) || defined(CONFIG_MACH_HUSKY)
+  // SL-5600
+
+  if ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN))==0) {
+    /* High->Low : AC remove */
+    DPRINTK("co ac remove\n");
+    charge_off_mode = 1;
+    schedule_work(&battchrgoff);
+  } else {
+    DPRINTK("co ac insert %ld\n",jiffies);
+    // interrupt has occured , but it is not means finish charging. We have to check it !
+    if ( sharpsl_charge_time == 0 ) {
+      sharpsl_charge_time = jiffies;
+      schedule_work(&battchrgon);
+      DPRINTK("co retry 1  %d\n",sharpsl_charge_time);
+    } else {
+      if ( jiffies - sharpsl_charge_time > SHARPSL_CHARGE_FINISH_TIME ) {
+          // charging has not finished. so we re-try !
+	sharpsl_charge_time = jiffies;
+	schedule_work(&battchrgon);
+	DPRINTK("co retry 2\n");
+      } else {
+         // charging has finished !
+	charge_off_mode = 0;
+	sharpsl_charge_time = 0;
+	schedule_work(&battchrgoff);
+	DPRINTK("co OK\n");
+      }
+    }
+  }
+
+#else
+  // SL-B500/C700
+  if ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN))==0) {
+    /* High->Low  : AC remove */
+    charge_off_mode = 0;
+    schedule_work(&battchrgoff);
+  } else {
+    /* retry... charging is continue ..... */
+    schedule_work(&battchrgon);
+  }
+#endif
+return IRQ_HANDLED;
+}
+
+/*** get adc *********************************************************************/
+static int sharpsl_cnv_value(int ad)
+{
+  int ad_val = 0;
+  int ret,i;
+
+
+  if ( sharpsl_main_battery != SHARPSL_BATTERY_STATUS_HIGH ) {
+    sharpsl_ad_index = 0;
+    return ad;
+  }
+
+  sharpsl_ad[sharpsl_ad_index] = ad;
+  sharpsl_ad_index++;
+  if ( sharpsl_ad_index >= SHARPSL_CNV_VALUE_NUM ) {
+    for(i=0;i<(SHARPSL_CNV_VALUE_NUM-1);i++)
+      sharpsl_ad[i] = sharpsl_ad[i+1];
+    sharpsl_ad_index = SHARPSL_CNV_VALUE_NUM -1;
+  }
+  for(i=0;i<sharpsl_ad_index;i++)
+    ad_val += sharpsl_ad[i];
+  ret = ( ad_val / sharpsl_ad_index );
+
+  return ret;
+}
+
+static int sharpsl_get_main_battery(void)
+{
+	int i = 0;
+	BATTERY_THRESH *thresh;
+
+	MainCntWk++;
+
+	if ( MainCntWk > MainCnt ) {
+		int voltage;
+
+		MainCntWk = 0;
+
+		while(1) {
+			voltage = sharpsl_read_MainBattery();
+			if ( voltage > 0 ) break;
+			if ( i++ > 5 ) {
+			  voltage = sharpsl_main_battery_thresh_fl[0].voltage;
+			  printk("please fix me !  can not read main battery \n");
+			  break;
+			}
+		}
+
+
+
+
+		voltage = sharpsl_cnv_value(voltage);
+		sharpsl_main_battery_voltage = voltage;
+	
+		thresh = GetMainLevel(voltage);
+
+		sharpsl_main_battery = thresh->status;
+		sharpsl_main_battery_percentage = GetMainPercent(voltage);
+		sharpsl_main_charge_battery = GetMainChargePercent(voltage);
+
+		// if battery is low , backlight driver become to save power.
+		if ( ( ( thresh->status == SHARPSL_BATTERY_STATUS_VERYLOW  ) ||
+		       ( thresh->status == SHARPSL_BATTERY_STATUS_CRITICAL )) &&
+		       ( !sharpsl_main_bk_flag ) ) {
+		  SHARPSL_LIMIT_CONTRAST(SHARPSL_CAUTION_CONTRAST);
+		}
+
+		if ( sharpsl_main_bk_flag == 0 ) {
+		  return sharpsl_main_battery;
+		}
+		
+
+		if ( sharpsl_debug_flag != 0 ) {
+		  int i;
+		  printk("debug flag on\n");
+		  sharpsl_main_battery = sharpsl_debug_flag;
+		  for (i = 0; sharpsl_main_battery_thresh_nofl[i].voltage > 0; i++) {
+		    if ( sharpsl_debug_flag == sharpsl_main_battery_thresh_nofl[i].status ) {
+		      //sharpsl_main_battery_percentage = sharpsl_main_battery_thresh_nofl[i].percentage;
+		      sharpsl_main_battery_percentage = GetMainPercent(voltage);
+		      break;
+		    }
+		  }
+		}
+
+		// Value is kept until it will operate OFF and AC, once low AD comes out.
+		if ( sharpsl_main_battery_percentage < sharpsl_main_percent_bk ) {
+		  sharpsl_main_status_bk = sharpsl_main_battery;
+		  sharpsl_main_percent_bk = sharpsl_main_battery_percentage;
+
+		  sharpsl_change_battery_status = 1;
+		  schedule_work(&sharpsl_bat);
+
+		} else {
+		  sharpsl_main_battery = sharpsl_main_status_bk;
+		  sharpsl_main_battery_percentage = sharpsl_main_percent_bk;
+		}
+
+		//DPRINTK2("charge percent = %d ( at %d ) \n",sharpsl_main_charge_battery,(int)jiffies);
+		DPRINTK(" get Main battery status %d\n",sharpsl_main_battery);
+
+	} else {
+		DPRINTK(" not get Main battery \n");
+		DPRINTK("MainCntWk = %d\n",MainCntWk);
+	}
+	return sharpsl_main_battery;
+}
+
+static int GetLevelIndex(BATTERY_THRESH *thresh, int Volt)
+{
+    int i = MAIN_BATTERY_THRES;
+
+    DPRINTK("volt = %d \n", Volt);
+	while (i > 0 && (Volt > thresh[i].voltage))
+		i--;
+		
+	return i;
+}
+
+static int GetPercent(BATTERY_THRESH *thresh, int Volt)
+{
+    int i = GetLevelIndex(thresh, Volt);
+    
+	/* i is now between 0 and MAIN_BATTERY_THRES. That means
+	 * we can safely access main_batt_thres[i] and
+	 * main_batt_thres[i+1] */
+	
+	{
+        long deltav = thresh[i].voltage - thresh[i + 1].voltage;
+        long deltap = thresh[i].percentage - thresh[i + 1].percentage;
+    
+    	long percentage = 
+    	   	   thresh[i + 1].percentage + 
+    	   	   deltap * (Volt - thresh[i + 1].voltage) /
+    	   	   deltav; 
+
+        DPRINTK("percentage = %ld \n", percentage);
+        return percentage;
+	}
+	
+    return thresh[i].percentage;
+}
+
+static int GetMainPercent( int Volt )
+{
+    BATTERY_THRESH *thresh;
+
+    if (counter_step_contrast)
+	    thresh = sharpsl_main_battery_thresh_fl;
+    else
+	    thresh = sharpsl_main_battery_thresh_nofl;
+
+    return GetPercent(thresh, Volt);
+}
+
+static int GetMainChargePercent( int Volt )
+{
+    BATTERY_THRESH *thresh;
+
+    if (counter_step_contrast)
+	    thresh = sharpsl_main_battery_thresh_charge_fl;
+    else
+	    thresh = sharpsl_main_battery_thresh_charge_nofl;
+
+    return GetPercent(thresh, Volt);
+}
+
+static BATTERY_THRESH *GetMainLevel( int Volt )
+{
+    BATTERY_THRESH *thresh;
+
+    DPRINTK("  volt = %d  \n",Volt);
+
+    if (counter_step_contrast)
+	    thresh = sharpsl_main_battery_thresh_fl;
+    else
+	    thresh = sharpsl_main_battery_thresh_nofl;
+	    
+    return &thresh[GetLevelIndex(thresh, Volt)];
+}
+
+
+/* 
+ * Translate Analog signal to Digital data
+ */
+static int Get_DAC_Value(int channel)
+{
+	unsigned long cmd;
+	int voltage;
+
+	cmd = (1u << MAXCTRL_PD0_SH) | (1u << MAXCTRL_PD1_SH) |
+	    (1u << MAXCTRL_SGL_SH) | (1u << MAXCTRL_UNI_SH) |
+	    (channel << MAXCTRL_SEL_SH) | (1u <<MAXCTRL_STR_SH);
+
+	voltage = corgi_ssp_max1111_get(cmd);
+
+	return voltage;
+}
+
+
+static int sharpsl_get_MainBattery(void)
+{
+	int voltage, batt;
+	int chrg_off = 0;
+	
+	GPSR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
+	mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP*10);
+	batt = Get_DAC_Value(BATT_THM);
+	GPCR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
+	if (batt >= SHARPSL_IS_BATT || batt < 0)
+		return -1;
+	
+	if (is_ac_adaptor) {
+		chrg_off = 1;
+		CHARGE_OFF();
+		mdelay(SHARPSL_WAIT_DISCHARGE_ON*10);
+	}
+	voltage = Get_DAC_Value(BATT_AD);
+	if (chrg_off)
+		CHARGE_ON();
+
+	return voltage;
+}
+
+
+static int sharpsl_read_MainBattery(void)
+{
+	int voltage;
+
+	battery_off_flag = 0;
+
+	voltage = Get_DAC_Value(BATT_AD);
+
+	if ( battery_off_flag )
+		voltage = -1;
+
+	return voltage;
+}
+
+static int sharpsl_read_Temp(void)
+{
+	int temp;
+
+	battery_off_flag = 0;
+
+	GPSR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
+	mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP*10);
+	temp = Get_DAC_Value(BATT_THM);
+	GPCR(CORGI_GPIO_ADC_TEMP_ON) = GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
+
+	if ( battery_off_flag )
+		temp = -1;
+
+	return temp;
+}
+
+static int sharpsl_read_jkvad(void)
+{
+  int temp;
+
+  battery_off_flag = 0;
+
+  temp = Get_DAC_Value(JK_VAD);
+  if ( battery_off_flag )
+    temp = -1;
+
+  return temp;
+}
+
+
+
+static int get_select_val(int *val)
+{
+  int i,j,k,temp,sum = 0;
+
+
+  // Get MAX
+  temp = val[0];
+  j=0;
+  for(i=1;i<5;i++) {
+    if ( temp < val[i] ) { temp = val[i]; j = i; }
+  }
+
+  // Get MIN
+  temp = val[4];
+  k=4;
+  for(i=3;i>=0;i--) {
+    if ( temp > val[i] ) { temp = val[i]; k = i; }
+  }
+
+  for(i=0;i<5;i++) {
+    if ( i == j || i == k ) continue;
+    sum += val[i];
+  }
+  DPRINTK("val = %d(%d)\n",sum,sum/3);
+
+  return ( sum / 3 );
+}
+
+/////////////////////////////////////////////////
+// mode 0 : check temp & voltage
+//      1 : check temp
+// return 1: err
+//        0: OK
+static int sharpsl_check_battery(int mode)
+{
+	int temp, i;
+	int buff[5];
+
+	if ( in_interrupt() ) {
+		DPRINTK("charge(temp) : in_interrupt !\n");
+		return 1;
+	}
+
+	// Check Temp : check inserting battery ?
+	for(i=0;i<5;i++) {
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP*10);
+		buff[i] = sharpsl_read_Temp();
+	}
+	DPRINTK("temp\n");
+	temp = get_select_val(buff);
+
+	if ( temp > SHARPSL_CHARGE_ON_TEMP ) return 1;
+	if ( mode == 1 ) return 0;
+
+	// disable charge
+	CHARGE_OFF();
+
+	// enable discharge
+	DISCHARGE_ON();
+
+	mdelay(SHARPSL_WAIT_DISCHARGE_ON*10);
+
+	// Check Voltage : check full charging
+	for(i=0;i<5;i++) {
+		buff[i] = sharpsl_read_MainBattery();
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT*10);
+	}
+
+	// disable discharge
+	DISCHARGE_OFF();
+
+	DPRINTK("volt\n");
+	temp = get_select_val(buff);
+
+	if ( temp < SHARPSL_CHARGE_ON_VOLT ) return 1;
+
+	return 0;
+}
+
+
+/////////////////////////////////////////////////
+// return 1: err
+//        0: OK
+static int sharpsl_ac_check(void)
+{
+	int temp, i; //, volt;
+	int buff[5];
+
+	if ( in_interrupt() ) {
+		DPRINTK("charge(ac_check) : in_interrupt !\n");
+		return 1;
+	}
+
+	// Check JK_VAD
+	for(i=0;i<5;i++) {
+		buff[i] = sharpsl_read_jkvad();
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD*10);	
+	}
+	DPRINTK("jkvad\n");
+	temp = get_select_val(buff);
+
+	// error occured !
+	if ( temp > SHARPSL_CHARGE_ON_JKVAD_HIGH ) {
+	  sharpsl_check_ac_err = 1;
+	  CHARGE_LED_ERR();
+	  return 1;
+	}
+
+	if ( temp < SHARPSL_CHARGE_ON_JKVAD_LOW ) {
+	  sharpsl_check_ac_err = 1;
+	  CHARGE_LED_ERR();
+	  return 1;
+	}
+
+	sharpsl_check_ac_err = 0;
+	return 0;
+}
+
+
+static int sharpsl_wakeup_hook(void)
+{
+	u32 gplr = GPLR0;
+	int is_resume = 0;
+
+	DPRINTK("GPLR0 = %x\n",gplr);
+
+	if ( (apm_wakeup_factor & GPIO_bit(CORGI_GPIO_AC_IN)) ) {
+
+		if ( gplr & GPIO_bit(CORGI_GPIO_AC_IN) ) {
+			/* charge on */
+			sharpsl_charge_state = CHARGE_STEP1;
+	    	charge_status = 0;
+	    	pass_charge_flag = 0;
+		    DPRINTK("ac insert\n");	
+		} else 
+
+		if ( !( gplr & GPIO_bit(CORGI_GPIO_AC_IN) ) ) {
+			/* charge off */
+			DPRINTK("ac remove\n");
+	    	CHARGE_LED_OFF();
+	    	CHARGE_OFF();
+	    	sharpsl_charge_state = CHARGE_STEP1;
+	    	charge_status = 0;
+		}
+	}
+
+	if ( (apm_wakeup_factor & GPIO_bit(CORGI_GPIO_CHRG_FULL)) ) {
+		DPRINTK("co interrupt\n");
+	}
+
+
+	if ( apm_wakeup_factor & GPIO_bit(CORGI_GPIO_KEY_INT) ) {
+//		if (sharppda_kbd_is_wakeup()){
+			is_resume |= GPIO_bit(CORGI_GPIO_KEY_INT);
+//		}
+	}
+	
+#ifdef CONFIG_MACH_CORGI
+	if ( apm_wakeup_factor & GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW) )
+		apm_wakeup_src_mask = 0;	
+#else
+
+	// lock
+	if ((apm_wakeup_factor & GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW)) &&
+	    (GPLR(CORGI_GPIO_MAIN_BAT_LOW) & GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW))) {
+  			/* charge on */
+			sharpsl_charge_state = CHARGE_STEP1;
+	    	charge_status = 0;
+	    	pass_charge_flag = 0;
+		    DPRINTK("ac insert\n");	
+	}
+
+	// unlock
+	if ((apm_wakeup_factor & GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW)) &&
+		!(GPLR(CORGI_GPIO_MAIN_BAT_LOW) & GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW))) {
+			/* charge off */
+			DPRINTK("ac remove\n");
+	    	CHARGE_LED_OFF();
+	    	CHARGE_OFF();
+	    	sharpsl_charge_state = CHARGE_STEP1;
+	    	charge_status = 0;
+	}
+
+#endif
+
+
+	if ( apm_wakeup_factor & GPIO_bit(CORGI_GPIO_WAKEUP) )
+		is_resume |= GPIO_bit(CORGI_GPIO_WAKEUP);
+
+
+
+//	if ( apm_wakeup_factor & GPIO_bit(CORGI_GPIO_AK_INT) ) {
+//		if ( corgi_wakeup_remocon_hook() ){
+//			is_resume |= GPIO_bit(CORGI_GPIO_AK_INT);
+//		}
+//	}
+
+
+	if ( ( apm_wakeup_factor & PWER_RTC ) && !sharpsl_alarm_flag){
+		is_resume |= PWER_RTC;
+	}
+
+	return is_resume;
+}
+
+/*** PM *************************************************************************/
+
+#ifdef CONFIG_PM
+
+static int corgi_batt_suspend(struct device *dev, uint32_t state, uint32_t level)
+{
+	if (level == SUSPEND_POWER_DOWN) {
+	  // flag clear
+	  sharpsl_main_status_bk = SHARPSL_BATTERY_STATUS_HIGH;
+	  sharpsl_main_percent_bk = 100;
+	  sharpsl_check_ac_err = 0;
+
+	  if ( !sharpsl_main_bk_flag )
+	    sharpsl_main_battery = SHARPSL_BATTERY_STATUS_HIGH;
+
+
+	  sharpsl_charge_state = CHARGE_STEP1;
+	  battery_off_flag = 1;
+#if defined(CONFIG_MACH_CORGI)
+	  /* Charge OFF */
+	  CHARGE_OFF();
+	  CHARGE_LED_OFF();
+	  charge_status = 0;
+	  sharpsl_charge_time = 0;
+#else
+	  if ( charge_status ) {
+	    // charging now , so kick.
+	    pass_charge_flag = 0;
+	  } else {
+	    // not charging now, so not kick
+	    pass_charge_flag = 1;
+	  }
+#endif
+	  apm_wakeup_src_mask |= ( GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_CO) );
+
+	  // wake up by key
+	  apm_wakeup_src_mask |=  GPIO_bit(0);
+	}
+	return 0;
+}	
+	  
+static int corgi_batt_resume(struct device *dev, uint32_t level)
+{
+	if (level == RESUME_POWER_ON) {
+
+	  sharpsl_fatal_off = 1;
+	  FattCnt = 0;
+	  sharpsl_charge_state = CHARGE_STEP1;
+	  MainCntWk = MainCnt + 1;	 // chk battery
+	  back_battery_status = -1;
+	  back_ac_status = -1;
+	  sharpsl_ad_index = 0;
+	  sharpsl_check_ac_err = 0;
+
+	  // AC insert , so kick the charging
+	  if ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0 ) {
+	    is_ac_adaptor = 1;
+	    schedule_work(&battchrgon);
+	  } else {
+	    is_ac_adaptor = 0;
+	    charge_off_mode = 1;
+	    schedule_work(&battchrgoff);
+	  }
+	  sharpsl_kick_battery_check_queue();
+	}
+
+	return 0;
+}
+
+
+
+int corgi_enter_suspend(void)
+{
+	int i;
+	u32 gplr;
+	static unsigned long RTAR_buffer;
+	static unsigned long RTAR_buffer2;
+	
+	if (corgi_suspended) {
+		
+        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;
+		
+		DPRINTK("Corgi Enter Suspend1: %d\n",corgi_suspended);
+		
+		gplr = GPLR0;
+
+		apm_wakeup_factor = PEDR & WAKEUP_SRC & apm_wakeup_src_mask;
+
+		apm_wakeup_factor &= ~0x80000000;		/* clear ALARM */
+		if ( ( RTSR & 0x1 ) && ( RTSR & RTSR_ALE ) )
+			apm_wakeup_factor |= 0x80000000;		/* ALARM */
+
+
+		PEDR = WAKEUP_SRC;
+
+		if (apm_wakeup_factor ){
+
+			gplr &= ~GPIO_bit(CORGI_GPIO_KEY_INT);
+
+			/* Faulty operation check */
+			for (i = 0; i <= 15; i++) {
+
+				if( i == CORGI_GPIO_AK_INT ) continue;
+
+				if ( apm_wakeup_factor & GPIO_bit(i) ) {
+					if ( (PRER & apm_wakeup_src_mask & GPIO_bit(i)) 
+			     		&& !(gplr & GPIO_bit(i)) ) {
+						apm_wakeup_factor &= ~GPIO_bit(i);
+					}
+					if ( (PFER & apm_wakeup_src_mask & GPIO_bit(i)) 
+			     		&& (gplr & GPIO_bit(i)) ) {
+						apm_wakeup_factor &= ~GPIO_bit(i);
+					}
+				}
+			}
+		}
+	} else {
+		charge_status = 0;
+	}
+	
+	DPRINTK("Corgi Enter Suspend2: %d\n",corgi_suspended);
+	
+	DPRINTK("pass_charge_flag = %d\n",pass_charge_flag);
+	if ( !pass_charge_flag ) {
+	  // not charging and AC-IN !
+
+
+	  if ( !charge_status && ( GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0){
+
+	    DPRINTK("kick charging\n");
+	    charge_status = 1;
+	    sharpsl_off_charge_battery();
+	  }
+	}
+
+	if ( charge_status ) {
+	  if (  ( ( RTAR - RCNR ) < ( BATTERY_CHECK_TIME + 30 ) ) && ( RTSR & RTSR_ALE )  ) {
+	    // maybe alarm will occur
+	    sharpsl_alarm_flag = 0;
+	    DPRINTK("RTAR alarm = %8x\n",RTAR);
+	    DPRINTK("RTSR = %8x\n",RTSR);
+	    DPRINTK("RCNR = %8x\n",RCNR);
+	  } else {
+	    RTAR_buffer = RTAR;
+	    RTAR = RCNR + BATTERY_CHECK_TIME;
+	    sharpsl_alarm_flag = 1;
+	    DPRINTK("RTAR charge = %8x\n",RTAR);
+	  }
+	} else {
+	  sharpsl_alarm_flag = 0;
+	  DPRINTK("RTAR not charge = %8x\n",RTAR);
+	}
+
+	// charging , so CHARGE_ON bit is HIGH during OFF.
+	if ( GPLR(CORGI_GPIO_CHRG_ON) & GPIO_bit(CORGI_GPIO_CHRG_ON) ) {
+	  PGSR1 |= GPIO_bit(CORGI_GPIO_CHRG_ON);
+	} else {
+	  PGSR1 &= ~GPIO_bit(CORGI_GPIO_CHRG_ON);
+	}
+
+
+	if ( GPLR(CORGI_GPIO_LED_ORANGE) & GPIO_bit(CORGI_GPIO_LED_ORANGE) ) {
+	  PGSR0 |= GPIO_bit(CORGI_GPIO_LED_ORANGE);
+	} else {
+	  PGSR0 &= ~GPIO_bit(CORGI_GPIO_LED_ORANGE);
+	}
+	if ( GPLR(GPIO43_BTTXD) & GPIO_bit(GPIO43_BTTXD) ) {
+	  PGSR1 |= GPIO_bit(GPIO43_BTTXD);
+	} else {
+	  PGSR1 &= ~GPIO_bit(GPIO43_BTTXD);
+	}
+	
+	PWER = WAKEUP_SRC & apm_wakeup_src_mask;	// Wake Up Enable
+	PRER = R_WAKEUP_SRC & apm_wakeup_src_mask; 	// Rising Edge Enable
+	PFER = F_WAKEUP_SRC & apm_wakeup_src_mask; 	// Falling Edge Enable
+
+	PEDR = WAKEUP_SRC & apm_wakeup_src_mask;	// Edge Detect Register
+
+	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); 
+		}
+	}
+	
+	if (!corgi_suspended) {
+		corgi_suspended=1;
+		goto DO_SLEEP;
+	}
+	
+	if ( sharpsl_alarm_flag ) {
+	  RTAR_buffer2 = RTAR;
+	  RTAR = RTAR_buffer;
+	  DPRINTK("back the ALARM Time\n");
+	}
+
+
+	if ( sharpsl_alarm_flag && ( RCNR == RTAR_buffer2 ) ) {
+	  if ( sharpsl_off_charge_battery() ) {
+	    DPRINTK("charge timer \n");
+	    goto DO_SLEEP;
+	  }
+	}
+
+	/* ----- hardware resume ----- */
+	if ( !sharpsl_wakeup_hook() ) {
+	        printk("return to suspend ....\n");
+		goto DO_SLEEP;
+	}
+	
+	if ( ( (GPLR(CORGI_GPIO_MAIN_BAT_LOW) & GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW)) == 0 )
+	     || ( chkFatalBatt() == 0 ) ) {
+	        printk("return to suspend (fatal) ....\n");
+		goto DO_SLEEP;
+	}
+
+	
+	corgi_suspended=0;
+	return 0;
+
+DO_SLEEP:	
+	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;
+	
+	return 1;	
+}
+
+#endif
+
+
+
+
+
+
+/*** check fatal battery ************************************************/
+// Fatal : 0
+// OK    : 1
+static unsigned short chkFatalBatt(void)
+{
+	int buff[5],temp,i;
+
+	DPRINTK("Check fatal batt\n");
+
+
+
+	// Check AC-Adapter
+	if ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN)) != 0 ) {
+	  // insert ac
+	  DPRINTK("in-ac\n");
+
+	  if ( charge_status == 1 ) {
+	    DPRINTK("fatal : charge off\n");
+	    CHARGE_OFF();
+	    udelay(100);
+	    DISCHARGE_ON();	// enable discharge
+	    mdelay(SHARPSL_WAIT_DISCHARGE_ON*10);
+	  }
+
+	  // Check battery : check inserting battery ?
+	  for(i=0;i<5;i++) {
+		buff[i] = sharpsl_read_MainBattery();
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT*10);
+	  }
+
+	  DPRINTK("volt\n");
+	  temp = get_select_val(buff);
+	  DPRINTK("fatal chk = %d\n",temp);
+
+	  if ( charge_status == 1 ) {
+	    udelay(100);
+	    CHARGE_ON();
+	    GEDR(CORGI_GPIO_CO) = GPIO_bit(CORGI_GPIO_CO);  // FIX ME !
+	    //DPRINTK("CO = %x\n",GEDR&CORGI_GPIO_CO);
+	    DISCHARGE_OFF();	// disable discharge
+	  }
+
+	  if ( temp < SHARPSL_CORGI_FATAL_ACIN_VOLT ) 
+	    return 0;
+	  else
+	    return 1;
+
+	} else {
+	  // not insert ac
+	  DPRINTK("no-ac\n");
+
+	  // Check battery : check inserting battery ?
+	  for(i=0;i<5;i++) {
+		buff[i] = sharpsl_read_MainBattery();
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT*10);
+	  }
+	  DPRINTK("volt\n");
+	  temp = get_select_val(buff);
+	  DPRINTK("fatal chk = %d\n",temp);
+
+	  if ( temp < SHARPSL_CORGI_FATAL_NOACIN_VOLT ) 
+	    return 0;
+	  else
+	    return 1;
+
+	}
+
+
+}
+
+static int sharpsl_wakeup_check_charge(void)
+{
+  unsigned int temp;
+
+  temp = ~GPLR0 & ( GPIO_bit(CORGI_GPIO_AC_IN) | GPIO_bit(CORGI_GPIO_KEY_INT) | GPIO_bit(CORGI_GPIO_WAKEUP) );
+// RPFIXME - from corgi_power  
+//  if ( temp != 0 ) {
+//    apm_wakeup_factor = temp;
+//  }
+  return temp;
+}
+
+/*** for suspend hook ***********************************************************/
+static int sharpsl_off_charge_battery(void)
+{
+
+
+  DPRINTK("charge ? %s\n", (GPLR1 & GPIO_bit(CORGI_GPIO_CHRG_ON)) ? "on" : "off" );
+
+  while(1) {
+    switch ( sharpsl_charge_state ) {
+
+    case CHARGE_STEP1:
+      {
+	DPRINTK("STEP 1\n");
+
+#if defined(CONFIG_MACH_SHEPHERD) || defined(CONFIG_MACH_HUSKY)
+	if ( !(GPLR(CORGI_GPIO_MAIN_BAT_LOW) & GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW)) ) {
+	  // unlock
+	  CHARGE_LED_OFF();
+	  CHARGE_OFF();
+	  sharpsl_charge_state = CHARGE_STEP1;
+	  charge_status = 0;
+	  return 0;
+	}
+#endif
+
+
+	/* AC Check */
+	if ( sharpsl_ac_check() ) {
+	  sharpsl_charge_state = CHARGE_STEP_ERROR;
+	  break;
+	}
+
+	if ( sharpsl_check_battery(1) ) {
+	  sharpsl_charge_state = CHARGE_STEP_ERROR;
+	} else {
+	  sharpsl_charge_state = CHARGE_STEP2;
+	}
+	break;
+      }
+
+    case CHARGE_STEP2:
+      {
+	DPRINTK("STEP 2\n");
+
+	/* Charge Start */
+	CHARGE_LED_OFF();
+	CHARGE_LED_ON();	/* led on */
+	CHARGE_OFF();
+	mdelay(SHARPSL_CHARGE_WAIT_TIME);
+	CHARGE_ON();		/* Charge ON */
+	charge_status = 1;	/* charge status flag set */
+
+	/* wait time */
+	sharpsl_charge_state = CHARGE_STEP3;
+	return 1;
+      }
+
+    case CHARGE_STEP3:
+      {
+	DPRINTK("STEP 3\n");
+
+	if ( sharpsl_check_battery(0) ) {
+	  sharpsl_charge_state = CHARGE_STEP_ERROR;
+	} else {
+	  CHARGE_OFF();
+	  mdelay(SHARPSL_CHARGE_WAIT_TIME);
+	  CHARGE_ON();		/* Charge ON */
+	  charge_status = 1;	/* charge status flag set */
+	  sharpsl_charge_state = CHARGE_STEP4;
+	}
+	break;
+      }
+
+    case CHARGE_STEP4:
+      {
+
+	DPRINTK("STEP 4\n");
+
+	mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
+
+
+	{
+	  int time;
+	  unsigned int ret;
+	  extern int sharpsl_wakeup_check_charge(void);
+	  time = RCNR;
+	  while(1) {
+	    ret = sharpsl_wakeup_check_charge();
+	    if ( ( RCNR - time ) > SHARPSL_CORGI_WAIT_CO_TIME ) return 1;
+	    if ( ret != 0 ) return 0;
+	    if ( GPLR(CORGI_GPIO_CO) & GPIO_bit(CORGI_GPIO_CO) ) break;
+	  }
+	}
+
+
+	if ( GPLR(CORGI_GPIO_CO) & GPIO_bit(CORGI_GPIO_CO) ) {
+	  sharpsl_charge_state = CHARGE_STEP5;
+	  DPRINTK("co occured\n");
+	  break;
+	  //return 1;
+	} else {
+	  return 1;
+	}
+      }
+
+    case CHARGE_STEP5:
+      {
+	DPRINTK("STEP 5\n");
+
+	sharpsl_charge_cnt = 0;
+
+	// retry charge
+	CHARGE_OFF();
+	mdelay(SHARPSL_CHARGE_WAIT_TIME);
+	CHARGE_ON();		/* Charge ON */
+	sharpsl_charge_state = CHARGE_STEP6;
+	//break;
+	return 1;
+      }
+
+    case CHARGE_STEP6:
+      {
+	DPRINTK("STEP 6\n");
+
+	mdelay(SHARPSL_CHARGE_CO_CHECK_TIME);
+
+	{
+	  int time;
+	  unsigned int ret;
+	  extern int sharpsl_wakeup_check_charge(void);
+	  time = RCNR;
+	  while(1) {
+	    ret = sharpsl_wakeup_check_charge();
+	    if ( ( RCNR - time ) > SHARPSL_CORGI_WAIT_CO_TIME ) break;
+	    if ( ret != 0 ) return 0;
+	    if ( GPLR(CORGI_GPIO_CO) & GPIO_bit(CORGI_GPIO_CO) ) {
+	      break;
+	    }
+	  }
+	}
+
+
+	sharpsl_charge_cnt++;
+	if ( GPLR(CORGI_GPIO_CO) & GPIO_bit(CORGI_GPIO_CO) ) {
+	  sharpsl_charge_state = CHARGE_STEP7;
+	  sharpsl_charge_cnt = 0;
+	  sharpsl_charge_dummy_cnt = 1;
+	  DPRINTK("co occured\n");
+	  //return 1;
+	  break;
+	}
+
+
+	if ( sharpsl_charge_cnt > SHARPSL_CHARGE_RETRY_CNT ) {
+	  DPRINTK("current co is fake. retry\n");
+	  sharpsl_charge_state = CHARGE_STEP3;
+	  break;
+	} else {
+	  // no counter is not finished.
+	  return 1;
+	}
+	break;
+      }
+
+    case CHARGE_STEP7:
+      {
+	DPRINTK("STEP 7\n");
+
+	sharpsl_charge_dummy_cnt--;
+
+	if ( sharpsl_charge_dummy_cnt == 0 ) {
+	  sharpsl_charge_state = CHARGE_STEP_END;
+	  DPRINTK("chare is finished !\n");
+	  break;
+	} else {
+	  // chaging is not finished.
+	  return 1;
+	}
+      }
+
+    default:
+      break;
+    }
+
+      if ( sharpsl_charge_state == CHARGE_STEP_END ) {
+	DPRINTK("STEP END\n");
+	DPRINTK("charge end \n");
+	CHARGE_LED_OFF();
+	CHARGE_OFF();
+	charge_status = 0;
+	//sharpsl_charge_state = CHARGE_STEP1;
+	return 0;
+      }
+
+      if ( sharpsl_charge_state == CHARGE_STEP_ERROR ) {
+	DPRINTK("STEP ERROR\n");
+	CHARGE_OFF();
+	/* error led on */
+	CHARGE_LED_ERR_OFF();
+	//CHARGE_LED_ERR();
+	charge_status = 0;
+	  // if error is occured , so led is blinking continue...
+	  while(1) {
+	    if ((GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN))==0) break;
+	  }
+	CHARGE_LED_OFF();
+	//sharpsl_charge_state = CHARGE_STEP1;
+	return 0;
+      }
+
+      if ( sharpsl_charge_state == CHARGE_STEP_EXIT ) {
+	DPRINTK("STEP EXIT\n");
+	charge_status = 0;
+	//sharpsl_charge_state = CHARGE_STEP1;
+	return 0;
+      }
+
+  }
+
+}
+
+
+/*** Config & Setup **********************************************************/
+
+
+#ifdef CONFIG_PROC_FS
+struct proc_dir_entry *proc_batt;
+
+typedef struct sharpsl_battery_entry {
+	int*		addr;
+	int		def_value;
+	char*		name;
+	char*		description;
+	char		readonly;	
+	unsigned short	low_ino;
+} sharpsl_battery_entry_t;
+
+static sharpsl_battery_entry_t sharpsl_battery_params[] = {
+/*  { addr,	def_value,	name,	    description }*/
+  { &msglevel,	0,		"msglevel",    "debug message output level", 0 },
+  { &sharpsl_debug_flag , 0 , "dflag", "debug flag", 0 },
+  { &sharpsl_change_battery_status , 0 , "chg_status", "Change status", 1 },
+  { &sharpsl_main_battery_percentage , 0 , "charge_percentage", "Charge percentage", 1 },
+  { &sharpsl_main_battery_voltage , 0 , "main_voltage", "Main voltage", 1 },                // alias
+  { &sharpsl_main_battery_voltage , 0 , "charge_voltage", "Charge voltage", 1 }
+};
+#define NUM_OF_BATTERY_ENTRY	(sizeof(sharpsl_battery_params)/sizeof(sharpsl_battery_entry_t))
+
+static ssize_t sharpsl_battery_read_params(struct file *file, char *buf,
+				      size_t nbytes, loff_t *ppos)
+{
+	int i_ino = (file->f_dentry->d_inode)->i_ino;
+	char outputbuf[15];
+	int count;
+	int i;
+	sharpsl_battery_entry_t	*current_param = NULL;
+
+	if (*ppos>0) /* Assume reading completed in previous read*/
+		return 0;
+	for (i=0; i<NUM_OF_BATTERY_ENTRY; i++) {
+		printk("Read: %d,%d,%d,%d\n",i,&sharpsl_battery_params[i],sharpsl_battery_params[i].low_ino,i_ino);
+	}
+	if (current_param==NULL) {
+		return -EINVAL;
+	}
+	count = sprintf(outputbuf, "%04i\n",
+			*((volatile u16 *) current_param->addr));
+	*ppos += count;
+	if (count>nbytes)	/* Assume output can be read at one time */
+		return -EINVAL;
+	if (copy_to_user(buf, outputbuf, count))
+		return -EFAULT;
+	return count;
+}
+
+
+static int proc_read(char *buf , char **start, off_t offset,
+			int len, int *eof, void *data)
+{
+	int idx = (int)(long)(data);
+	int i;
+	char *p;
+	sharpsl_battery_entry_t	*current_param = NULL;
+
+	for (i=0; i<NUM_OF_BATTERY_ENTRY; i++) {
+		if (i==idx) {
+			current_param = &sharpsl_battery_params[i];
+			break;
+		}
+		printk("Read: %d,%d,%d,%d\n",i,&sharpsl_battery_params[i],sharpsl_battery_params[i].addr,idx,i);
+	}
+		
+	if (current_param==NULL) {
+		return -EINVAL;
+	}
+	
+	p = buf;
+	
+	p += sprintf(p, "%04i\n", *((volatile u16 *) current_param->addr));
+	*eof = 1;
+
+	return p - buf;
+}
+
+static ssize_t sharpsl_battery_write_params(struct file *file, const char *buf,
+				       size_t nbytes, loff_t *ppos)
+{
+	int			i_ino = (file->f_dentry->d_inode)->i_ino;
+	sharpsl_battery_entry_t	*current_param = NULL;
+	int			i;
+	unsigned long		param;
+	char			*endp;
+
+	for (i=0; i<NUM_OF_BATTERY_ENTRY; i++) {
+		if(sharpsl_battery_params[i].low_ino==i_ino) {
+			current_param = &sharpsl_battery_params[i];
+			break;
+		}
+	}
+	if (current_param==NULL || current_param->readonly) {
+		return -EINVAL;
+	}
+
+	param = simple_strtoul(buf,&endp,0);
+	if (param == -1) {
+		*current_param->addr = current_param->def_value;
+	} else {
+		*current_param->addr = param;
+	}
+	return nbytes+endp-buf;
+}
+
+static unsigned int sharpsl_battery_poll(struct file *fp, poll_table * wait)
+{
+  poll_wait(fp, &battery_waitqueue, wait);
+  if ( sharpsl_change_battery_status ) {
+    sharpsl_change_battery_status = 0;
+    return POLLIN | POLLRDNORM;
+  } else {
+    return 0;
+  }
+}
+
+static struct file_operations proc_params_operations = {
+	read:	sharpsl_battery_read_params,
+	write:	sharpsl_battery_write_params,
+	poll:	sharpsl_battery_poll,
+};
+#endif
+
+extern void (*apm_get_power_status)(struct apm_power_info *);
+
+static int __init corgi_batt_probe(struct device *dev)
+{
+
+#ifdef CONFIG_PROC_FS
+	int	i;
+	struct proc_dir_entry *entry;
+#endif
+
+	/* poodle: TEMP_ON / corgi: pullup resistor */
+	GPDR(CORGI_GPIO_ADC_TEMP_ON) |= GPIO_bit(CORGI_GPIO_ADC_TEMP_ON);
+	/* charge on signal */
+	GPDR(CORGI_GPIO_CHRG_ON) |= GPIO_bit(CORGI_GPIO_CHRG_ON);
+
+	GPDR(GPIO43_BTTXD) |= GPIO_bit(GPIO43_BTTXD);
+
+
+	init_timer(&ac_kick_timer);
+	ac_kick_timer.function = sharpsl_ac_kick_timer;
+
+
+	GPDR(CORGI_GPIO_AC_IN) &= ~GPIO_bit(CORGI_GPIO_AC_IN);
+	GPDR(CORGI_GPIO_CO) &= ~GPIO_bit(CORGI_GPIO_CO);
+	GPDR(CORGI_GPIO_MAIN_BAT_LOW) &= ~GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW);
+	GPDR(CORGI_GPIO_KEY_INT) &= ~GPIO_bit(CORGI_GPIO_KEY_INT);
+
+	// Don't request this interrupt as we don't need it. 
+	// Its just a wakeup source...
+	set_irq_type(CORGI_IRQ_GPIO_KEY_INT, IRQT_FALLING);	
+
+	/* Register interrupt handler. */
+	if (request_irq(CORGI_IRQ_GPIO_AC_IN, Sharpsl_ac_interrupt,
+			SA_INTERRUPT, "ACIN", Sharpsl_ac_interrupt)) {
+		printk("Could not get irq %d.\n", CORGI_IRQ_GPIO_AC_IN);
+	}
+	else set_irq_type(CORGI_IRQ_GPIO_AC_IN,IRQT_BOTHEDGE); /* AC IN */
+
+
+#if defined(CONFIG_MACH_SHEPHERD) || defined(CONFIG_MACH_HUSKY)
+	/* Register interrupt handler. */
+	if (request_irq(CORGI_IRQ_GPIO_CO, Sharpsl_co_interrupt, SA_INTERRUPT,
+			 "CO", Sharpsl_co_interrupt)) {
+		free_irq(CORGI_IRQ_GPIO_AC_IN, Sharpsl_ac_interrupt);
+		printk("Could not get irq %d.\n", CORGI_IRQ_GPIO_CO);
+	}
+	else set_irq_type(CORGI_IRQ_GPIO_CO,IRQT_RISING); /* CHRG FULL */
+#endif
+
+	schedule_work(&sharpsl_bat);
+
+#ifdef CONFIG_PROC_FS
+
+	proc_batt = proc_mkdir("driver/battery", NULL);
+	if (proc_batt == NULL) {
+	  free_irq(CORGI_IRQ_GPIO_AC_IN, Sharpsl_ac_interrupt);
+#if defined(CONFIG_MACH_SHEPHERD) || defined(CONFIG_MACH_HUSKY)
+	  free_irq(CORGI_IRQ_GPIO_CO, Sharpsl_co_interrupt);
+#endif
+	  printk(KERN_ERR "can't create /proc/driver/battery\n");
+	  return -ENOMEM;
+	}
+	for (i=0; i<NUM_OF_BATTERY_ENTRY; i++) {
+		entry = create_proc_entry(sharpsl_battery_params[i].name,
+					  S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH,
+					  proc_batt);
+		if (entry) {
+			sharpsl_battery_params[i].low_ino = entry->low_ino;
+			entry->proc_fops = &proc_params_operations;
+			entry->data = (void*)(long)(i);
+			entry->read_proc = proc_read;
+		} else {
+			int	j;
+			for (j=0; j<i; j++) {
+				remove_proc_entry(sharpsl_battery_params[i].name,
+						  proc_batt);
+			}
+			remove_proc_entry("driver/battery", &proc_root);
+			proc_batt = 0;
+			free_irq(CORGI_IRQ_GPIO_AC_IN, Sharpsl_ac_interrupt);
+#if defined(CONFIG_MACH_SHEPHERD) || defined(CONFIG_MACH_HUSKY)
+			free_irq(CORGI_IRQ_GPIO_CO, Sharpsl_co_interrupt);
+#endif
+			printk(KERN_ERR "battery: can't create /proc/driver/battery\n");
+			return -ENOMEM;
+		}
+	}
+#endif
+
+	apm_get_power_status = sharpsl_apm_get_power_status;
+
+	return 0;
+}
+
+
+
+
+static int corgi_batt_remove(struct device *dev)
+{
+	free_irq(CORGI_IRQ_GPIO_AC_IN, Sharpsl_ac_interrupt);
+#if defined(CONFIG_MACH_SHEPHERD) || defined(CONFIG_MACH_HUSKY)
+	free_irq(CORGI_IRQ_GPIO_CO, Sharpsl_co_interrupt);
+#endif
+
+#ifdef CONFIG_PROC_FS
+	{
+	int	i;
+	for (i=0; i<NUM_OF_BATTERY_ENTRY; i++) {
+		remove_proc_entry(sharpsl_battery_params[i].name, proc_batt);
+	}
+	remove_proc_entry("driver/battery", NULL);
+	proc_batt = 0;
+	}
+#endif
+
+	return 0;
+}
+
+static struct device_driver corgi_batt_driver = {
+	.name		= "corgi-battery",
+	.bus		= &platform_bus_type,
+	.probe		= corgi_batt_probe,
+	.remove		= corgi_batt_remove,
+	.suspend	= corgi_batt_suspend,
+	.resume		= corgi_batt_resume,
+};
+
+static int __devinit corgi_batt_init(void)
+{
+	return driver_register(&corgi_batt_driver);
+}
+
+static void corgi_batt_exit(void)
+{
+ 	driver_unregister(&corgi_batt_driver);
+}
+
+module_init(corgi_batt_init);
+module_exit(corgi_batt_exit);
--- linux-2.6.10-rc2/arch/arm/mach-pxa/Makefile~corgi_power
+++ linux-2.6.10-rc2/arch/arm/mach-pxa/Makefile
@@ -14,7 +14,7 @@
 obj-$(CONFIG_MACH_POODLE)	+= poodle.o
 obj-$(CONFIG_MACH_CORGI)	+= corgi.o corgi_ssp.o corgi_backlight.o corgi_param.o ssp.o
 obj-$(CONFIG_MACH_SHEPHERD)	+= corgi.o corgi_ssp.o corgi_backlight.o corgi_param.o ssp.o
-obj-$(CONFIG_MACH_HUSKY)	+= corgi.o corgi_ssp.o corgi_backlight.o corgi_param.o ssp.o
+obj-$(CONFIG_MACH_HUSKY)	+= corgi.o corgi_ssp.o corgi_backlight.o corgi_param.o ssp.o corgi_battery.o
 
 # Support for blinky lights
 led-y := leds.o
--- /dev/null
+++ linux-2.6.10-rc2/arch/arm/mach-pxa/corgi_battery.h
@@ -0,0 +1,87 @@
+/*
+ *  linux/include/asm-arm/arch-cotulla/sharpsl_battery.h
+ *  
+ *  (C) Copyright 2002 HTC, Inc.
+ *  
+ *  May be copied or modified under the terms of the GNU General Public
+ *  License.  See linux/COPYING for more information.
+ *
+ * modify: TX/RX I2C for DEMO data is ok.
+ *
+ * ChangeLog:
+ *	21-Aug-2002 Lineo Japan, Inc.  for 2.4.18
+ *	26-Feb-2004 Lineo Solutions, Inc.  for Tosa
+ *
+ */
+
+/* Temperature parameters definition */
+#define		num_0		0
+#define		num_2		2
+#define		num_3		3
+#define		num_4		4
+#define		num_5		5
+#define		num_6		6
+#define		num_10		10
+#define		num_19		19
+#define		num_20		20
+#define		num_30		30
+#define		num_35		35
+#define		num_36		36
+#define		num_38		38
+#define		num_50		50
+#define		num_60		60
+#define		num_80		80
+#define		num_90		90
+#define		num_100		100
+#define		num_175		175
+#define		num_190		190
+#define		num_200		200
+#define		num_900		900
+#define		num_360		360
+#define		num_3600	3600
+#define		num_500		500
+#define		num_5000	5000
+#define		num_k		1000
+#define		num_1000	1000
+#define		num_1900	1900
+#define		num_9000	9000
+#define		num_8100	8100
+#define		num_9100	9100
+#define		num_2293	2293
+#define		num_2500	2500
+#define		num_10000	10000
+#define		num_25000	25000
+#define		num_3600	3600		/* 3600 * 1000 */
+#define		num_4096	4096
+#define		num_190000	190000
+#define		num_810000	810000
+#define		num_910000	910000
+#define		num_x3d		0x3d
+#define		num_x62		0x62
+#define		num_x10		0x42
+#define		num_x49		0x49		/* 0.045v for diff temperature */
+
+
+
+#define		T_P10		1709
+#define		T_P05		1849
+#define		T_P00		1975
+#define		T_N05		2086
+#define		T_N10		2180
+#define		T_NON		65535
+
+#define		Pbase_k		60		/* 0.06 x 1000 */
+#define		Psm_k		50		/* 50 : SD card */
+#define		Pim_k		50		/* 50 : IrDA */
+#define		Plm_k		100		/* 100 : Back-lite */
+#define		Pam_k		200		/* 200 : Audio */
+#define		BATT_AD		4u		/* channel of BATTery */
+#define		BATT_THM	2u		/* channel of BATTery */
+#define		JK_VAD		6u		/* channel of BATTery */
+
+#define		Temper_V47	0x449	/* 0.670v (47"C) */
+#define		Temper_V50	0x3e7	/* 0.610v (50"C) */
+#define		BattBad_V	0x614	/* 0.95v */
+#define		ReCharge_V	0x666	/* 1.0v  */
+#define		Min_120		120		/* 120 minutes */
+#define		hour_8		480		/* 60*8 minutes */

