[Nexus One Android Development] theloginwithnoname:
Initial investigation and analysis

OK, so I'm going to try and use the following repositories in github and in this order:

AOSP > pershoot > CyanogenMod > others

as I'd like it as generic as possible and ideally integrate any patches at the highest level.

Not being an expert in github, you'll have to excuse any obvious noobness! I couldn't see any of the 2784 battery stuff in AOSP so I'm guessing the CM team used the Desire kernel source from developer.htc.com to integrate the files. Actual code here:

http://member.america.htc.com/download/RomCode/Source_and_Binaries/bravo_54b7033a.tar.gz

------

At:

http://github.com/CyanogenMod/cm-kernel/blob/android-msm-2.6.34/drivers/power/ds2784_battery.c

we see device info struct as:

char raw[DS2784_DATA_SIZE]; /* raw DS2784 data */

struct battery_status status;

struct power_supply bat;
struct workqueue_struct *monitor_wqueue;
struct work_struct monitor_work;
struct alarm alarm;
struct wake_lock work_wake_lock;

with battery_status struct as:

u8 percentage; /* battery percentage */
u8 charge_source;
u8 status_reg;
u8 battery_full; /* battery full (don't charge) */

i.e. not many properties.

However, from the corresponding include file at:

http://github.com/CyanogenMod/cm-kernel/blob/android-msm-2.6.34/drivers/power/w1_ds2784.h

there are lots of defined registers, including several AGE and FULL_40.

Our 2784 code has both read and write functions (w1_ds2784_read/write), which are used in function ds2784_battery_read_status.

** Objective 1**

title:

to read some additional values such as AGE and FULL_40 and output them.

suggested implementation:

add in some other properties corresponding to AGE and FULL_40 values, populate these in the read function, parse them in the parse_data function, then output them at line 325 of the ds2784_battery.c file. Yes there will be lots of repetition, but the code is easily and quick to modify.

ideal implementation:

write a new app that outputs these but also outputs the status_reg value too. We can then use this to determine if and when our batteries go into "learning" mode. More below.

code-level:

1) modify struct battery_status, adding:

u16 age;
u16 full_40;

etc, with any other interesting ones too. Might as well grab all of them and output so we can hand-pick the ones that are useful.

2) from line 244 in parse_data, add something like:

s->age = raw[DS2784_REG_AGE_SCALAR];
etc

may have to convert from hex.

*****************

THEN I opened the HTC ds2784_battery.c and was amazed at what I saw!

*****************

*their* battery_info struct contains:

u8 level; /* formula */
u8 level_last;
u32 full_bat; /* Full capacity of battery (mAh) */
u32 full_level; /* Full level for battery control */
u8 guage_status_reg;/* guage status*/
u32 acr;
u32 active_empty;

their ds2784_device_info struct:

int guage_status_reg; /* battery status register offset=01h*/
int full_mah; /* battery full mah */
long full_charge_count; /* Full charge counter */
int acr;
int active_empty;
int full_level; /* Full level for battery control */

OK nothing earthshattering so far, BUT their Calculate_Full_mAh function uses the FULL_40 stuff.

** Objective 2 **

title: write values to registers

implementation: to be discussed once we have the values from Objective 1 and we still need it (i.e. learning mode does not exist or work to recalibrate).

Wrap-up:

The HTC charging code (from line 854) uses the following logic:

percent < 95, batt full = false

if status_reg = full and current <= 80 and percent = 100
then *IF IT HAS BEEN ONE HOUR OR MORE ON FULL CHARGE*!!!
then stop charging

WOW.