@@ -56,6 +56,7 @@ struct ds2760_device_info {
56
56
struct device * w1_dev ;
57
57
struct workqueue_struct * monitor_wqueue ;
58
58
struct delayed_work monitor_work ;
59
+ struct delayed_work set_charged_work ;
59
60
};
60
61
61
62
static unsigned int cache_time = 1000 ;
@@ -66,6 +67,14 @@ static unsigned int pmod_enabled;
66
67
module_param (pmod_enabled , bool , 0644 );
67
68
MODULE_PARM_DESC (pmod_enabled , "PMOD enable bit" );
68
69
70
+ static unsigned int rated_capacity ;
71
+ module_param (rated_capacity , uint , 0644 );
72
+ MODULE_PARM_DESC (rated_capacity , "rated battery capacity, 10*mAh or index" );
73
+
74
+ static unsigned int current_accum ;
75
+ module_param (current_accum , uint , 0644 );
76
+ MODULE_PARM_DESC (current_accum , "current accumulator value" );
77
+
69
78
/* Some batteries have their rated capacity stored a N * 10 mAh, while
70
79
* others use an index into this table. */
71
80
static int rated_capacities [] = {
@@ -168,8 +177,13 @@ static int ds2760_battery_read_status(struct ds2760_device_info *di)
168
177
di -> full_active_uAh = di -> raw [DS2760_ACTIVE_FULL ] << 8 |
169
178
di -> raw [DS2760_ACTIVE_FULL + 1 ];
170
179
171
- scale [0 ] = di -> raw [DS2760_ACTIVE_FULL ] << 8 |
172
- di -> raw [DS2760_ACTIVE_FULL + 1 ];
180
+ /* If the full_active_uAh value is not given, fall back to the rated
181
+ * capacity. This is likely to happen when chips are not part of the
182
+ * battery pack and is therefore not bootstrapped. */
183
+ if (di -> full_active_uAh == 0 )
184
+ di -> full_active_uAh = di -> rated_capacity / 1000L ;
185
+
186
+ scale [0 ] = di -> full_active_uAh ;
173
187
for (i = 1 ; i < 5 ; i ++ )
174
188
scale [i ] = scale [i - 1 ] + di -> raw [DS2760_ACTIVE_FULL + 2 + i ];
175
189
@@ -197,15 +211,31 @@ static int ds2760_battery_read_status(struct ds2760_device_info *di)
197
211
if (di -> rem_capacity > 100 )
198
212
di -> rem_capacity = 100 ;
199
213
200
- if (di -> current_uA )
201
- di -> life_sec = - ((di -> accum_current_uAh - di -> empty_uAh ) *
202
- 3600L ) / di -> current_uA ;
214
+ if (di -> current_uA >= 100L )
215
+ di -> life_sec = - ((di -> accum_current_uAh - di -> empty_uAh ) * 36L )
216
+ / ( di -> current_uA / 100L ) ;
203
217
else
204
218
di -> life_sec = 0 ;
205
219
206
220
return 0 ;
207
221
}
208
222
223
+ static void ds2760_battery_set_current_accum (struct ds2760_device_info * di ,
224
+ unsigned int acr_val )
225
+ {
226
+ unsigned char acr [2 ];
227
+
228
+ /* acr is in units of 0.25 mAh */
229
+ acr_val *= 4L ;
230
+ acr_val /= 1000 ;
231
+
232
+ acr [0 ] = acr_val >> 8 ;
233
+ acr [1 ] = acr_val & 0xff ;
234
+
235
+ if (w1_ds2760_write (di -> w1_dev , acr , DS2760_CURRENT_ACCUM_MSB , 2 ) < 2 )
236
+ dev_warn (di -> dev , "ACR write failed\n" );
237
+ }
238
+
209
239
static void ds2760_battery_update_status (struct ds2760_device_info * di )
210
240
{
211
241
int old_charge_status = di -> charge_status ;
@@ -237,21 +267,9 @@ static void ds2760_battery_update_status(struct ds2760_device_info *di)
237
267
if (di -> full_counter < 2 ) {
238
268
di -> charge_status = POWER_SUPPLY_STATUS_CHARGING ;
239
269
} else {
240
- unsigned char acr [2 ];
241
- int acr_val ;
242
-
243
- /* acr is in units of 0.25 mAh */
244
- acr_val = di -> full_active_uAh * 4L / 1000 ;
245
-
246
- acr [0 ] = acr_val >> 8 ;
247
- acr [1 ] = acr_val & 0xff ;
248
-
249
- if (w1_ds2760_write (di -> w1_dev , acr ,
250
- DS2760_CURRENT_ACCUM_MSB , 2 ) < 2 )
251
- dev_warn (di -> dev ,
252
- "ACR reset failed\n" );
253
-
254
270
di -> charge_status = POWER_SUPPLY_STATUS_FULL ;
271
+ ds2760_battery_set_current_accum (di ,
272
+ di -> full_active_uAh );
255
273
}
256
274
}
257
275
} else {
@@ -274,6 +292,17 @@ static void ds2760_battery_write_status(struct ds2760_device_info *di,
274
292
w1_ds2760_recall_eeprom (di -> w1_dev , DS2760_EEPROM_BLOCK1 );
275
293
}
276
294
295
+ static void ds2760_battery_write_rated_capacity (struct ds2760_device_info * di ,
296
+ unsigned char rated_capacity )
297
+ {
298
+ if (rated_capacity == di -> raw [DS2760_RATED_CAPACITY ])
299
+ return ;
300
+
301
+ w1_ds2760_write (di -> w1_dev , & rated_capacity , DS2760_RATED_CAPACITY , 1 );
302
+ w1_ds2760_store_eeprom (di -> w1_dev , DS2760_EEPROM_BLOCK1 );
303
+ w1_ds2760_recall_eeprom (di -> w1_dev , DS2760_EEPROM_BLOCK1 );
304
+ }
305
+
277
306
static void ds2760_battery_work (struct work_struct * work )
278
307
{
279
308
struct ds2760_device_info * di = container_of (work ,
@@ -299,6 +328,52 @@ static void ds2760_battery_external_power_changed(struct power_supply *psy)
299
328
queue_delayed_work (di -> monitor_wqueue , & di -> monitor_work , HZ /10 );
300
329
}
301
330
331
+
332
+ static void ds2760_battery_set_charged_work (struct work_struct * work )
333
+ {
334
+ char bias ;
335
+ struct ds2760_device_info * di = container_of (work ,
336
+ struct ds2760_device_info , set_charged_work .work );
337
+
338
+ dev_dbg (di -> dev , "%s\n" , __func__ );
339
+
340
+ ds2760_battery_read_status (di );
341
+
342
+ /* When we get notified by external circuitry that the battery is
343
+ * considered fully charged now, we know that there is no current
344
+ * flow any more. However, the ds2760's internal current meter is
345
+ * too inaccurate to rely on - spec say something ~15% failure.
346
+ * Hence, we use the current offset bias register to compensate
347
+ * that error.
348
+ */
349
+
350
+ if (!power_supply_am_i_supplied (& di -> bat ))
351
+ return ;
352
+
353
+ bias = (signed char ) di -> current_raw +
354
+ (signed char ) di -> raw [DS2760_CURRENT_OFFSET_BIAS ];
355
+
356
+ dev_dbg (di -> dev , "%s: bias = %d\n" , __func__ , bias );
357
+
358
+ w1_ds2760_write (di -> w1_dev , & bias , DS2760_CURRENT_OFFSET_BIAS , 1 );
359
+ w1_ds2760_store_eeprom (di -> w1_dev , DS2760_EEPROM_BLOCK1 );
360
+ w1_ds2760_recall_eeprom (di -> w1_dev , DS2760_EEPROM_BLOCK1 );
361
+
362
+ /* Write to the di->raw[] buffer directly - the CURRENT_OFFSET_BIAS
363
+ * value won't be read back by ds2760_battery_read_status() */
364
+ di -> raw [DS2760_CURRENT_OFFSET_BIAS ] = bias ;
365
+ }
366
+
367
+ static void ds2760_battery_set_charged (struct power_supply * psy )
368
+ {
369
+ struct ds2760_device_info * di = to_ds2760_device_info (psy );
370
+
371
+ /* postpone the actual work by 20 secs. This is for debouncing GPIO
372
+ * signals and to let the current value settle. See AN4188. */
373
+ cancel_delayed_work (& di -> set_charged_work );
374
+ queue_delayed_work (di -> monitor_wqueue , & di -> set_charged_work , HZ * 20 );
375
+ }
376
+
302
377
static int ds2760_battery_get_property (struct power_supply * psy ,
303
378
enum power_supply_property psp ,
304
379
union power_supply_propval * val )
@@ -337,6 +412,12 @@ static int ds2760_battery_get_property(struct power_supply *psy,
337
412
case POWER_SUPPLY_PROP_TEMP :
338
413
val -> intval = di -> temp_C ;
339
414
break ;
415
+ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW :
416
+ val -> intval = di -> life_sec ;
417
+ break ;
418
+ case POWER_SUPPLY_PROP_CAPACITY :
419
+ val -> intval = di -> rem_capacity ;
420
+ break ;
340
421
default :
341
422
return - EINVAL ;
342
423
}
@@ -353,6 +434,8 @@ static enum power_supply_property ds2760_battery_props[] = {
353
434
POWER_SUPPLY_PROP_CHARGE_EMPTY ,
354
435
POWER_SUPPLY_PROP_CHARGE_NOW ,
355
436
POWER_SUPPLY_PROP_TEMP ,
437
+ POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW ,
438
+ POWER_SUPPLY_PROP_CAPACITY ,
356
439
};
357
440
358
441
static int ds2760_battery_probe (struct platform_device * pdev )
@@ -376,17 +459,12 @@ static int ds2760_battery_probe(struct platform_device *pdev)
376
459
di -> bat .properties = ds2760_battery_props ;
377
460
di -> bat .num_properties = ARRAY_SIZE (ds2760_battery_props );
378
461
di -> bat .get_property = ds2760_battery_get_property ;
462
+ di -> bat .set_charged = ds2760_battery_set_charged ;
379
463
di -> bat .external_power_changed =
380
464
ds2760_battery_external_power_changed ;
381
465
382
466
di -> charge_status = POWER_SUPPLY_STATUS_UNKNOWN ;
383
467
384
- retval = power_supply_register (& pdev -> dev , & di -> bat );
385
- if (retval ) {
386
- dev_err (di -> dev , "failed to register battery\n" );
387
- goto batt_failed ;
388
- }
389
-
390
468
/* enable sleep mode feature */
391
469
ds2760_battery_read_status (di );
392
470
status = di -> raw [DS2760_STATUS_REG ];
@@ -397,7 +475,24 @@ static int ds2760_battery_probe(struct platform_device *pdev)
397
475
398
476
ds2760_battery_write_status (di , status );
399
477
478
+ /* set rated capacity from module param */
479
+ if (rated_capacity )
480
+ ds2760_battery_write_rated_capacity (di , rated_capacity );
481
+
482
+ /* set current accumulator if given as parameter.
483
+ * this should only be done for bootstrapping the value */
484
+ if (current_accum )
485
+ ds2760_battery_set_current_accum (di , current_accum );
486
+
487
+ retval = power_supply_register (& pdev -> dev , & di -> bat );
488
+ if (retval ) {
489
+ dev_err (di -> dev , "failed to register battery\n" );
490
+ goto batt_failed ;
491
+ }
492
+
400
493
INIT_DELAYED_WORK (& di -> monitor_work , ds2760_battery_work );
494
+ INIT_DELAYED_WORK (& di -> set_charged_work ,
495
+ ds2760_battery_set_charged_work );
401
496
di -> monitor_wqueue = create_singlethread_workqueue (dev_name (& pdev -> dev ));
402
497
if (!di -> monitor_wqueue ) {
403
498
retval = - ESRCH ;
@@ -422,6 +517,8 @@ static int ds2760_battery_remove(struct platform_device *pdev)
422
517
423
518
cancel_rearming_delayed_workqueue (di -> monitor_wqueue ,
424
519
& di -> monitor_work );
520
+ cancel_rearming_delayed_workqueue (di -> monitor_wqueue ,
521
+ & di -> set_charged_work );
425
522
destroy_workqueue (di -> monitor_wqueue );
426
523
power_supply_unregister (& di -> bat );
427
524
0 commit comments