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

--- /dev/null
+++ linux-2.6.10/arch/arm/mach-pxa/corgi_battery.c
@@ -0,0 +1,1733 @@
+/*
+ * 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.
+ *
+ */
+
+#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/mach-types.h>
+#include <asm/irq.h>
+#include <asm/apm.h>
+
+#include <asm/arch/pxa-regs.h>
+#include <asm/arch/corgi.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
+
+
+/*#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 STATUS_AC_IN 	(GPLR(CORGI_GPIO_AC_IN) & GPIO_bit(CORGI_GPIO_AC_IN))
+#define STATUS_BATT_LOW (GPLR(CORGI_GPIO_MAIN_BAT_LOW) & GPIO_bit(CORGI_GPIO_MAIN_BAT_LOW))
+
+#define SHARPSL_BATCHK_TIME			( HZ )			// 1 sec
+#define SHARPSL_MAIN_GOOD_COUNT		( HZ / SHARPSL_BATCHK_TIME )	// 1 sec
+#define SHARPSL_MAIN_NOGOOD_COUNT	( HZ / SHARPSL_BATCHK_TIME )	// 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_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		100	// 100msec
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_TEMP	10	// 10msec
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT	10	// 10msec
+#define SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD	10	// 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
+
+
+//RPFIXME
+//#define SHARPSL_CAUTION_CONTRAST		CORGI_BL_CAUTION_CONTRAST
+//#define SHARPSL_LIMIT_CONTRAST(x)		corgibl_set_limit_contrast(x)
+#define SHARPSL_CAUTION_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 void 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 corgibl_get_status(void);
+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[] = {
+		{ 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[] = {
+		{ 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) / 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 int	msglevel=0;
+
+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 FattCnt	 = 0;
+static int back_ac_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;
+
+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 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;
+
+/*#if defined(CONFIG_MACH_CORGI) 
+static unsigned int sharpsl_charge_on_time = 0;
+#endif*/
+
+static int sharpsl_ad[SHARPSL_CNV_VALUE_NUM+1];
+static int sharpsl_ad_index = 0;
+
+static int sharpsl_change_battery_status = 0;
+
+
+#define SHARPSL_IS_BATT		245	/* battery : in/out */
+
+/* 
+ * MAX1111 Command Definitions
+ */
+
+#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
+
+/* 
+ * MAX1111 Channel Definitions
+ */
+
+#define	BATT_AD		4u
+#define	BATT_THM	2u
+#define	JK_VAD		6u
+
+
+/*** 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)
+{
+	// before check battery
+	mdelay(before_waitms*10);
+
+	switch (flag) {
+	case 0:
+		sharpsl_battery_thread_main();
+		break;
+	case 1:
+		sharpsl_battery_thread_main();
+		break;
+	}
+
+	// after check battery
+	mdelay(after_waitms*10);
+}
+
+
+static void sharpsl_kick_battery_check_queue(void)
+{
+	schedule_work(&sharpsl_bat);
+}
+
+static int sharpsl_battery_thread_main(void)
+{
+	// get ac status. if change ac status , chk main battery.
+	sharpsl_ac_status =	(!( STATUS_AC_IN )	? APM_AC_OFFLINE : APM_AC_ONLINE);
+	if ( back_ac_status != sharpsl_ac_status ) {
+		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_LIMIT_CONTRAST(SHARPSL_CAUTION_CONTRAST);
+	}
+
+	// chk critical
+	if ( ( sharpsl_main_battery == SHARPSL_BATTERY_STATUS_CRITICAL ) && sharpsl_fatal_off ) {
+		sharpsl_fatal_off = 0;
+		printk("Fatal Off\n");
+		apm_queue_event(APM_CRITICAL_SUSPEND);
+	} else {
+		FattCnt = 0;
+	}
+
+
+	if ( sharpsl_check_ac_err && 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();
+	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 ( STATUS_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 = STATUS_AC_IN;
+	int match = 0;
+	int err = 0;
+
+	while(1) {
+		if ( level == STATUS_AC_IN ) {
+			match++;
+		} else {
+			level = STATUS_AC_IN;
+		match = 0;
+		err++;
+			}
+		if ( match > 1 ) break;
+		if ( err > 50 ) {
+			// if ac port is not stable , so use last port data.
+			level = STATUS_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)
+
+	if (STATUS_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 (STATUS_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 void sharpsl_get_main_battery(void)
+{
+	int i = 0;
+	BATTERY_THRESH *thresh;
+	int voltage;
+
+	while(1) {
+		voltage = sharpsl_read_MainBattery();
+		if ( voltage > 0 ) break;
+		if ( i++ > 5 ) {
+			voltage = sharpsl_main_battery_thresh[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);
+
+
+		
+	// 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);
+
+	return;
+}
+
+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;
+}
+
+static int GetMainPercent( int Volt )
+{
+	BATTERY_THRESH *thresh;
+
+	thresh = sharpsl_main_battery_thresh;
+
+	return GetPercent(thresh, Volt);
+}
+
+static int GetMainChargePercent( int Volt )
+{
+	BATTERY_THRESH *thresh;
+
+	thresh = sharpsl_main_battery_thresh_charge;
+
+	return GetPercent(thresh, Volt);
+}
+
+static BATTERY_THRESH *GetMainLevel( int Volt )
+{
+	BATTERY_THRESH *thresh;
+
+	DPRINTK("	volt = %d	\n",Volt);
+
+	thresh = sharpsl_main_battery_thresh;
+			
+	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);
+	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);
+	}
+	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);
+	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);
+		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);
+
+	// Check Voltage : check full charging
+	for(i=0;i<5;i++) {
+		buff[i] = sharpsl_read_MainBattery();
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
+	}
+
+	// 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);	
+	}
+	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)) &&
+			STATUS_BATT_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)) &&
+		!STATUS_BATT_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;
+
+		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;
+		back_ac_status = -1;
+		sharpsl_ad_index = 0;
+		sharpsl_check_ac_err = 0;
+
+		// AC insert , so kick the charging
+		if (STATUS_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();
+		
+		
+		// Clear the reset source indicators as they break the bootloader upon reboot
+		RCSR=0x0f;
+	}
+
+	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 &&  (STATUS_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 ( (STATUS_BATT_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 (STATUS_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);
+		}
+
+		// Check battery : check inserting battery ?
+		for(i=0;i<5;i++) {
+		buff[i] = sharpsl_read_MainBattery();
+		mdelay(SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT);
+		}
+
+		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);
+		}
+		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 (machine_is_shepherd() || machine_is_husky()) {
+					if ( !STATUS_BATT_LOW ) {
+						// unlock
+						CHARGE_LED_OFF();
+						CHARGE_OFF();
+						sharpsl_charge_state = CHARGE_STEP1;
+						charge_status = 0;
+						return 0;
+					}
+				}
+
+				/* 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;
+					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;
+					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 (STATUS_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;
+		}
+	}
+}
+
+/* 
+ * Sysfs functions 
+ */
+
+static ssize_t msglevel_show(struct device *dev, char *buf)
+{
+	return sprintf(buf, "%d\n",msglevel);
+}
+
+static ssize_t msglevel_store(struct device *dev, const char *buf, size_t count)
+{
+	msglevel = simple_strtoul(buf, NULL, 16);
+	return count;
+}
+
+static ssize_t chg_status_show(struct device *dev, char *buf)
+{
+	return sprintf(buf, "%d\n",sharpsl_change_battery_status);
+}
+
+static ssize_t battery_percentage_show(struct device *dev, char *buf)
+{
+	return sprintf(buf, "%d\n",sharpsl_main_battery_percentage);
+}
+
+static ssize_t battery_voltage_show(struct device *dev, char *buf)
+{
+	return sprintf(buf, "%d\n",sharpsl_main_battery_voltage);
+}
+
+static DEVICE_ATTR(msglevel, 0644, msglevel_show, msglevel_store);
+static DEVICE_ATTR(chg_status, 0444, chg_status_show, NULL);
+static DEVICE_ATTR(battery_percentage, 0444, battery_percentage_show, NULL);
+static DEVICE_ATTR(battery_voltage, 0444, battery_voltage_show, NULL);
+
+/*** Config & Setup **********************************************************/
+
+extern void (*apm_get_power_status)(struct apm_power_info *);
+
+static int __init corgi_batt_probe(struct device *dev)
+{
+
+	/* 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 (machine_is_shepherd() || machine_is_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 */
+	}
+
+	schedule_work(&sharpsl_bat);
+
+	device_create_file(dev, &dev_attr_msglevel);
+	device_create_file(dev, &dev_attr_chg_status);
+	device_create_file(dev, &dev_attr_battery_percentage);
+	device_create_file(dev, &dev_attr_battery_voltage);
+
+	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 (machine_is_shepherd() || machine_is_husky()) 
+		free_irq(CORGI_IRQ_GPIO_CO, Sharpsl_co_interrupt);
+
+	device_remove_file(dev, &dev_attr_msglevel);
+	device_remove_file(dev, &dev_attr_chg_status);
+	device_remove_file(dev, &dev_attr_battery_percentage);
+	device_remove_file(dev, &dev_attr_battery_voltage);
+
+	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/arch/arm/mach-pxa/Makefile~corgi_power-r1.patch
+++ linux-2.6.10/arch/arm/mach-pxa/Makefile
@@ -12,9 +12,7 @@
 obj-$(CONFIG_MACH_MAINSTONE) += mainstone.o
 obj-$(CONFIG_ARCH_PXA_IDP)	+= idp.o
 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_PXA_SHARPSL)	+= 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/arch/arm/mach-pxa/corgi_battery.h
@@ -0,0 +1,4 @@
+
+
+
+

