--- linux/arch/arm/mach-sa1100/collie_battery.c Tue Jul 22 02:24:32 2003 +++ linux/arch/arm/mach-sa1100/collie_battery.c Tue Jul 22 03:07:56 2003 @@ -14,10 +14,11 @@ * 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: + * Nov 2002 Dietz Proepper: improved battery status. * 12-Nov-2001 Lineo Japan, Inc. * 30-Jul-2002 Lineo Japan, Inc. for 2.4.18 * 29-Jan-2003 Sharp Corporation modify for new QT I/F * */ @@ -79,10 +80,11 @@ int collie_read_BackBattery(void); int collie_read_Temp(void); int collie_check_temp(void); int collie_check_voltage(void); static void collie_charge_on(void); static void collie_charge_off(void); +static void do_main_battery(void); int set_led_status(int which,int status); int GetMainLevel( int Volt ); int GetBackLevel( int Volt ); int collie_get_main_battery(void); unsigned short GetBackupBatteryAD(void); @@ -91,40 +93,35 @@ int suspend_collie_read_Temp(void); /*** extern ***********************************************************************/ extern u32 apm_wakeup_src_mask; extern int counter_step_contrast; -/*** gloabal variables ************************************************************/ -int charge_status = 0; /* charge status 1 : charge 0: not charge */ - -typedef struct BatteryThresh { - int high; - int low; - int verylow; -} BATTERY_THRESH; +/* defines */ +#define COLLIE_BATTERY_STATUS_HIGH APM_BATTERY_STATUS_HIGH +#define COLLIE_BATTERY_STATUS_LOW APM_BATTERY_STATUS_LOW +#define COLLIE_BATTERY_STATUS_VERYLOW APM_BATTERY_STATUS_VERY_LOW +#define COLLIE_BATTERY_STATUS_CRITICAL APM_BATTERY_STATUS_CRITICAL +/*** gloabal variables ************************************************************/ +int charge_status = 0; /* charge status 1 : charge 0: not charge */ -#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0) || \ - defined(CONFIG_COLLIE_TR1) || defined(CONFIG_COLLIE_DEV) -BATTERY_THRESH collie_main_battery_thresh_fl = { - 368, 358, 356 -}; - -BATTERY_THRESH collie_main_battery_thresh_nofl = { - 378, 364, 362 -}; -#else -BATTERY_THRESH collie_main_battery_thresh_fl = { - 368, 358, 356 -}; - -BATTERY_THRESH collie_main_battery_thresh_nofl = { - 378, 365, 363 +typedef struct { + int voltage_thres[2]; /* 0: nofl 1: fl */ + int percent; + int state; +} main_battery_thres; + +#define MAIN_BATTERY_THRES 4 + +main_battery_thres main_batt_thres[MAIN_BATTERY_THRES+2] = { + {{5000, 5000}, 100, COLLIE_BATTERY_STATUS_HIGH }, /* do not remove! */ + {{412,408}, 100, COLLIE_BATTERY_STATUS_HIGH}, + {{378,368}, 40, COLLIE_BATTERY_STATUS_HIGH}, + {{364,358}, 5, COLLIE_BATTERY_STATUS_LOW}, + {{362,356}, 1, COLLIE_BATTERY_STATUS_CRITICAL}, + {{0, 0}, 1, COLLIE_BATTERY_STATUS_CRITICAL } /* do not remove, too! */ }; -#endif - - typedef struct ChargeThresh { int bar1; int bar2; int bar3; @@ -180,24 +177,18 @@ static struct miscdevice battery_device #define GetBackADCtoPower(x) (( 330 * x * 2 ) / 1024 ) // MAX 3.3V #define ConvRevise(x) ( ( ad_revise * x ) / 652 ) #define MAIN_DIFF 50 // 0.5V #define DIFF_CNT ( 3 - 1 ) -#define COLLIE_BATTERY_STATUS_HIGH APM_BATTERY_STATUS_HIGH -#define COLLIE_BATTERY_STATUS_LOW APM_BATTERY_STATUS_LOW -#define COLLIE_BATTERY_STATUS_VERYLOW APM_BATTERY_STATUS_VERY_LOW -#define COLLIE_BATTERY_STATUS_CRITICAL APM_BATTERY_STATUS_CRITICAL - #define COLLIE_AC_LINE_STATUS (!( GPLR & GPIO_AC_IN ) ? APM_AC_OFFLINE : APM_AC_ONLINE) - #define COLLIE_PM_TICK ( 1000 / 10 ) // 1sec #define COLLIE_APO_TICKTIME ( 5 * COLLIE_PM_TICK ) // 5sec #define COLLIE_LPO_TICKTIME COLLIE_APO_TICKTIME #define COLLIE_APO_DEFAULT ( ( 3 * 60 ) * COLLIE_PM_TICK ) // 3 min #define COLLIE_LPO_DEFAULT ( 20 * COLLIE_PM_TICK ) // 20 sec -#define COLLIE_MAIN_GOOD_COUNT ( 10*60 / ( COLLIE_APO_TICKTIME / COLLIE_PM_TICK ) ) +#define COLLIE_MAIN_GOOD_COUNT ( 1*60 / ( COLLIE_APO_TICKTIME / COLLIE_PM_TICK ) ) #define COLLIE_MAIN_NOGOOD_COUNT ( 1*60 / ( COLLIE_APO_TICKTIME / COLLIE_PM_TICK ) ) #define COLLIE_BACKUP_BATTERY_CK_TIME ( 10*60*1*100 ) // 10min #define COLLIE_BACKUP_BATTERY_LOW ( 190 ) @@ -212,10 +203,11 @@ unsigned int LPOCntWk = 0; static DECLARE_WAIT_QUEUE_HEAD(queue); static int msglevel; int collie_backup_battery = COLLIE_BATTERY_STATUS_HIGH; int collie_main_battery = COLLIE_BATTERY_STATUS_HIGH; +int collie_main_battery_percent = 100; int collie_main_charge_battery = 100; int collie_ac_status = APM_AC_OFFLINE; int ad_revise = 0; static int MainCntWk = COLLIE_MAIN_GOOD_COUNT; @@ -229,10 +221,11 @@ static struct pm_dev *battery_pm_dev; / static int battery_off_flag = 0; /* charge : suspend while get adc */ static int collie_charge_temp = 973; static int collie_charge_volt = 465; /* charge : check charge 3.0V */ static int charge_off_mode = 0; /* charge : check volt or non */ +static int collie_main_battery_voltage = 400; static DECLARE_WAIT_QUEUE_HEAD(wq_on); static DECLARE_WAIT_QUEUE_HEAD(wq_off); #if 1 // 2003.1.29 static DECLARE_WAIT_QUEUE_HEAD(battery_waitqueue); @@ -276,28 +269,11 @@ int collie_apm_get_power_status(u_char * } collie_battery_status = *battery_status; #endif // main battery status to percentage - switch (*battery_status) - { - case COLLIE_BATTERY_STATUS_HIGH: - *battery_percentage = 100; - break; - case COLLIE_BATTERY_STATUS_LOW: - *battery_percentage = 40; - break; - case COLLIE_BATTERY_STATUS_VERYLOW: - *battery_percentage = 5; - break; - case COLLIE_BATTERY_STATUS_CRITICAL: - *battery_percentage = 1; - break; - default: - *battery_percentage = 100; - break; - } + *battery_percentage = collie_main_battery_percent; if ( *ac_line_status == APM_AC_ONLINE ) *battery_percentage = 100; // good or ac in --> GOOD_COUNT @@ -529,12 +505,13 @@ int collie_get_main_battery(void) voltage = collie_read_MainBattery(); if ( voltage > 0 ) break; if ( i++ > 5 ) { voltage = 380; break; } } - collie_main_battery = GetMainLevel(GetMainADCtoPower(voltage)); - collie_main_charge_battery = GetMainChargePercent(GetMainADCtoPower(voltage)); + collie_main_battery_voltage = GetMainADCtoPower(voltage); + do_main_battery(); + collie_main_charge_battery = GetMainChargePercent(collie_main_battery_voltage); DPRINTK2("charge percent = %d ( at %d ) \n",collie_main_charge_battery,jiffies); DPRINTK(" get Main battery status %d\n",collie_main_battery); @@ -562,36 +539,36 @@ int GetMainChargePercent( int Volt ) } else { return 5; } } -int GetMainLevel( int Volt ) +static void do_main_battery() { - - DPRINTK(" volt = %d \n",Volt); - - - if ( counter_step_contrast ) { - if ( Volt > collie_main_battery_thresh_fl.high ) - return COLLIE_BATTERY_STATUS_HIGH; - else if ( Volt > collie_main_battery_thresh_fl.low ) - return COLLIE_BATTERY_STATUS_LOW; - else if ( Volt > collie_main_battery_thresh_fl.verylow ) - return COLLIE_BATTERY_STATUS_VERYLOW; - else - return COLLIE_BATTERY_STATUS_CRITICAL; - } else { - if ( Volt > collie_main_battery_thresh_nofl.high ) - return COLLIE_BATTERY_STATUS_HIGH; - else if ( Volt > collie_main_battery_thresh_nofl.low ) - return COLLIE_BATTERY_STATUS_LOW; - else if ( Volt > collie_main_battery_thresh_nofl.verylow ) - return COLLIE_BATTERY_STATUS_VERYLOW; - else - return COLLIE_BATTERY_STATUS_CRITICAL; - } - + int i = MAIN_BATTERY_THRES; + int fl = (counter_step_contrast)? 1 : 0; + + while ( i > 0 && + ( collie_main_battery_voltage > main_batt_thres[i].voltage_thres[fl] ) ) + i--; + /* 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] */ + + collie_main_battery = main_batt_thres[i].state; + { /* perhaps we should put that deltas to our table, too? */ + long deltav = main_batt_thres[i].voltage_thres[fl] - + main_batt_thres[i+1].voltage_thres[fl]; + long deltap = main_batt_thres[i].percent - + main_batt_thres[i+1].percent; + + collie_main_battery_percent = /* (1) */ + main_batt_thres[i+1].percent + + deltap * (collie_main_battery_voltage - + main_batt_thres[i+1].voltage_thres[fl]) / + deltav; + DPRINTK("Battery stuff: v=%i i=%i , dv=%li , dp=%li , p=%i",collie_main_battery_voltage , i, deltav, deltap, collie_main_battery_percent ); + } } int GetBackLevel( int Volt ) { @@ -834,20 +811,18 @@ unsigned short chkFatalBatt(void) GEDR = GPIO_CO; // printk("CO = %x\n",GEDR&GPIO_CO); } - if ( volt < collie_main_battery_thresh_nofl.verylow ) + if ( volt < main_batt_thres[MAIN_BATTERY_THRES].voltage_thres[0] ) return 0; else return 1; #endif } - - int suspend_collie_check_temp(void) { unsigned short temp , i = 0; while(1) { @@ -1032,10 +1007,11 @@ struct proc_dir_entry *proc_batt; typedef struct collie_battery_entry { int* addr; int def_value; char* name; char* description; + char readonly; unsigned short low_ino; } collie_battery_entry_t; #if 1 // 2003.1.29 static collie_battery_entry_t collie_battery_params[] = { @@ -1044,11 +1020,13 @@ static collie_battery_entry_t collie_bat { &collie_change_battery_status , 0 , "chg_status", "Change status" } }; #else static collie_battery_entry_t collie_battery_params[] = { /* { addr, def_value, name, description }*/ - { &msglevel, 0, "msglevel", "debug message output level" } +/* { &msglevel, 0, "msglevel", "debug message output level" } */ + { &msglevel, 0, "msglevel", "debug message output level", 0 }, + { &collie_main_battery_voltage, -1, "main_voltage", "main battery voltage", 1 } }; #endif #define NUM_OF_BATTERY_ENTRY (sizeof(collie_battery_params)/sizeof(collie_battery_entry_t)) static ssize_t collie_battery_read_params(struct file *file, char *buf, @@ -1069,11 +1047,12 @@ static ssize_t collie_battery_read_param } } if (current_param==NULL) { return -EINVAL; } - count = sprintf(outputbuf, "0x%08X\n", +// count = sprintf(outputbuf, "0x%08X\n", + count = sprintf(outputbuf, "%04i\n", *((volatile Word *) 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)) @@ -1094,11 +1073,12 @@ static ssize_t collie_battery_write_para if(collie_battery_params[i].low_ino==i_ino) { current_param = &collie_battery_params[i]; break; } } - if (current_param==NULL) { +// if (current_param==NULL) { + if (current_param==NULL || current_param->readonly) { return -EINVAL; } param = simple_strtoul(buf,&endp,0); if (param == -1) {