aboutsummaryrefslogtreecommitdiffstats
path: root/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/battery.patch
blob: 1912b333288de19509e0e86a27c49c65b03651ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
--- 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) {