battery handling

176 views
Skip to first unread message

ffxx68

unread,
Feb 10, 2011, 10:23:47 AM2/10/11
to VT8500/WM8505 Linux Kernel
Hi,

I know it much depends on the actual hardware implementation of the
interface to the battery, but I wonder if any work has been done to
address the deficiencies of the current kernel version with respect to
this subject. In order to make the kernel work, on some devices, the
wmt-battery.ko module must be removed from init.rc.

What I noticed in wmt-battery.c is that wm85xx_read_bat() returns a
constant value of 4000.

My first doubt here: is this return value the one to be compared (if
so, where, how?) with the list of values provided by the battvoltlist
env var by:

setenv battvoltlist
6774,6889,7377,7498,7538,7599,7650,7698,7763,7821,7939

But, I also noticed that wm9712_poll_sample_battery(), which is used
by the wm85xx_read_capacity() "looks like" making a sampling job on
battery, exploiting calls to an A-D converter:

codec_read(AC97_WM97XX_DIGITISER2,...)

Some devices use WM9712 for audio (using AC97 codec) + other functions
(http://www.wolfsonmicro.com/products/codecs/WM9715/) . On my WM8505
smartbook, audio is handled by a VT1613 instead (http://www.via.com.tw/
en/products/audio/codecs/vt1613/index.jsp).

Does anyone have any clue IF and how wmt-battery.c may be adapted to
work on these non-WM9712 devices?

Any reference to previous work is welcome to (I couldn't find anything
with respect to this).

thanks
Fabio

Alexey Charkov

unread,
Feb 12, 2011, 6:44:21 AM2/12/11
to vt8500-wm8505...@googlegroups.com

Hi Fabio!

I'm afraid that there's no straightforward way to determine that. I'd suggest following the circuitry carefully and googling various IC labels. Also, there's a theoretical possibility that the battery gauges are connected via i2c, so you could probably give Tony's latest code a try.

Best,
Alexey

Tony Prisk

unread,
Feb 12, 2011, 1:13:13 PM2/12/11
to vt8500-wm8505...@googlegroups.com
VT1613 support looks a bit incomplete/strange.

There is a small fragment of code in drivers/input/touchscreen/wmt-battery.c (lines 424 through 431) that seems to read the current battery life.
It looks like it sets a GPIO pin low, then switches the same pin to input mode and waits for it to read 'high'. The time it takes to go high again gives the battery voltage.
No idea if it works, but the code is there.

Vitaly Luban

unread,
Feb 12, 2011, 2:10:01 PM2/12/11
to vt8500-wm8505...@googlegroups.com
Looks OK to me given that this GPIO pin must be connected to the battery via resistor with capacitor attached to this very same pin to the ground.
If schematic is done that way, then setting the GPIO pin to low discharges the capacitor, then when switching the pin to input the capacitor start to
charge. It's charging time to the level of logical high depends on values of RC and battery voltage. Given that RC is roughly constant, battery voltage
is measured that way. Precision of such measurement is questionable, but one can get rough idea about what battery voltage is.
--
Vit

Tony Prisk

unread,
Feb 15, 2011, 3:55:46 AM2/15/11
to vt8500-wm8505...@googlegroups.com
Has anyone taken a look at the AC97 source code?

For the life of me, I can't figure out what WMT is doing in their code - there are multiple copies of the same files, and different files that seem to do the same things with different function names.

I tried to write up a basic AC97 driver to get the WM9715 battery code working but with no luck.
During bootup, it seems the AC97 controller is in a not-ready state, but later it becomes ready even though there is no initialization code.

To make it more confusing, I can't even figure out how other AC97 drivers work - it seems that the AC97 bus is directly tied to a sound card instance.

Is anyone familiar with AC97 in linux?

Ed Spiridonov

unread,
Feb 15, 2011, 4:22:27 AM2/15/11
to vt8500-wm8505...@googlegroups.com
2011/2/15 Tony Prisk <sent...@digitalfantasy.co.nz>:

But sound is working now?

ffxx68

unread,
Feb 15, 2011, 12:30:54 PM2/15/11
to VT8500/WM8505 Linux Kernel
Thanks for your experienced feedback.

I will investigate and try to check if any RC-circuit is found between
battery and VT1613 ...

Any idea about how battvoltlist is used?

Tony Prisk

unread,
Feb 15, 2011, 1:41:49 PM2/15/11
to vt8500-wm8505...@googlegroups.com
Audio does not work - I haven't even tried to make it work. I think it is the last thing on most peoples list to get working.

Ed Spiridonov

unread,
Feb 15, 2011, 1:45:03 PM2/15/11
to vt8500-wm8505...@googlegroups.com
2011/2/15 Tony Prisk <sent...@digitalfantasy.co.nz>:

> Audio does not work - I haven't even tried to make it work. I think it is
> the last thing on most peoples list to get working.

But this is the easiest way to test the AC97.

Tony Prisk

unread,
Feb 16, 2011, 4:02:18 AM2/16/11
to vt8500-wm8505...@googlegroups.com
For those that a) can't wait or b) don't care I have pushed some very ugly code for WM9715 battery monitoring.

It works, but only if the wmt-battery is loaded as a module
(It relies on the AC97 bus code and I have figured out how to control the order that the devices initialize, so if you compile AC97 bus support and wmt-battery into the kernel, the battery may start first and crash the kernel). "insmod wmt-battery.ko"/"modprobe wmt-battery" will work fine.

The code needs a lot of tidying up and isn't remotely suitable for mainline so don't be surprised if it changes a lot.
You will need to configure the driver source to suit your battery configuration (min/max voltage).

Tony Prisk

unread,
Feb 17, 2011, 3:28:38 AM2/17/11
to vt8500-wm8505...@googlegroups.com
oops - forgot to push the files that I added :)

I have completed some more updates and pushed the rest of the code, so now it might actually work :)

ffxx68

unread,
Mar 1, 2011, 3:45:27 PM3/1/11
to VT8500/WM8505 Linux Kernel
There's something I don't understand... maybe someone can help.

I noticed that the output while charging should be 50% (standing to
this source code):

else if(POWER_SUPPLY_STATUS_CHARGING == bat_status){
bat_lowalarmcnt = 0;
return capacity_default;//50%

but in my actual device (where the wmt-battery.ko is from version
1.5.2 ...) when status is 'charging' it returns 100% always...

Some other code is around?

thanks

On Feb 12, 8:10 pm, Vitaly Luban <vlu...@gmail.com> wrote:
> Looks OK to me given that this GPIO pin must be connected to the battery via
> resistor with capacitor attached to this very same pin to the ground.
> If schematic is done that way, then setting the GPIO pin to low discharges
> the capacitor, then when switching the pin to input the capacitor start to
> charge. It's charging time to the level of logical high depends on values of
> RC and battery voltage. Given that RC is roughly constant, battery voltage
> is measured that way. Precision of such measurement is questionable, but one
> can get rough idea about what battery voltage is.
>
> On Sat, Feb 12, 2011 at 10:13 AM, Tony Prisk
> <senti...@digitalfantasy.co.nz>wrote:

ffxx68

unread,
Mar 2, 2011, 5:53:37 AM3/2/11
to VT8500/WM8505 Linux Kernel
Since this evidently (as it appears to me) is a mismatch between the
source code and the .ko which is installed on my machine, I wonder if
someone could help me with building the wmt-battery.ko using exactly
the available source code.

I have no expertise with Kernel building and I totally miss the ARM
toolchain to make the build... so if someone is so kind to help
here...
Even step-by-step guidance is welcome. For example, to start with,
where can I download the toolchain from? A Windows (cygwin) version is
welcome, but I also have a RHEL5 x86 or x86_64 (on VMWare).

Something I don't understand as well is that I can't find the printk()
messages from that module, neither from 'dmesg' nor in /var/log/
syslog. Anything else I should check?

thanks a lot in advance!
Fabio

ffxx68

unread,
Mar 9, 2011, 9:20:04 AM3/9/11
to VT8500/WM8505 Linux Kernel
Let me report the results I got until now about this subject.

I rebuilt the wmt_battery.ko (from Angus' kernel:
https://github.com/projectgus/kernel_wm8505), after adding a few
printk messages, to try to understand "a bit" what's happening in
there.

Current wmt_battery.c code logic in wm85xx_read_status() is:

static int charg_stat = 1;
static int charg_gpio = 0;
...
charging=gpio_in_get(charg_gpio);
chargstatus=gpio_in_get(charg_status);
...
if(batt_gpiostate & BIT0){
if(charging & BIT0){
status = POWER_SUPPLY_STATUS_CHARGING;
printk("wmt-battery - 1 charging...\n");
}
else{
status = POWER_SUPPLY_STATUS_DISCHARGING;
printk("wmt-battery - 1 battery...\n");
}
}
else{
if(!(charging & BIT0)){
status = POWER_SUPPLY_STATUS_CHARGING;
printk("wmt-battery - 2 charging...\n ");
}
else{
status = POWER_SUPPLY_STATUS_DISCHARGING;
printk("wmt-battery - 2 battery...\n");
}
}

if(batt_gpiostate & BIT1){
if(status == POWER_SUPPLY_STATUS_CHARGING)
if(chargstatus & BIT1){
status = POWER_SUPPLY_STATUS_FULL;
printk("wmt-battery - 3 charge full....\n");
}
}
else{
if(status == POWER_SUPPLY_STATUS_CHARGING)
if(!(chargstatus & BIT1)){
status = POWER_SUPPLY_STATUS_FULL;
printk("wmt-battery - 4 charge full...\n");
}
}
return status;


- - - - -

Testing the GPIO bits under different conditions gave:

C=value of "charging"
S=value of "chargstatus"

C S Status
----------------------------------------------------------
1 2 1 - Boot. Battery is FULL (after one night charging, charging
red led if off) and external power is plugged.
0 2 2 - Unplugged power
1 0 3 - Power plugged again (after about 10-15 minutes; red led
lit)
1 2 4 - Unplugged (this one above is the same combination of Plugged
and Full)
1 0 5 - Plugged once again (after about more 10-15 minutes; red led
lit)
1 2 6 - Unplugged (after about 30 minutes, but while still charging,
before the led turned off)
1 0 7 - Plugged again (red led on)
1 2 8 - Still plugged but now charge is full (after about 15 more
minutes; red led off)
1 2 9 - Unplugged (mmhh - it's not that reliable.... nothing
changed!)
1 0 10 - After full discharge (autoshutdown), reboot and plugged
again
1 2 11 - Unplugged (just a few minutes chargic passed)
1 0 12 - Plugged once again

C & S are expected to tell if it's plugged/on-battery and full/not-
full, respectively.

S (bit 2) looks like sensing correctly for full charge (or plugged-in
power), while for C I got a "0" only once in this test cycle, I'm not
even sure why... It may well be that the wrong GPIO is being used in
this code for C.

Tony Prisk

unread,
Mar 9, 2011, 1:17:35 PM3/9/11
to vt8500-wm8505...@googlegroups.com
I noticed when I wrote my original 'hacky' battery driver that neither GPIO0
or GPIO1 seemed to be sense the battery on my netbook.

I wondered if this wasn't something that changed between CE6 units and
Android units (the original wmt_battery code seems to be for an android
unit).

Either way - I haven't found a way to detect charge status.

Tony

ffxx68

unread,
Apr 18, 2011, 1:05:27 PM4/18/11
to VT8500/WM8505 Linux Kernel
I'm trying to carry on some experiments" on this subject.

I faked status check, forcing it to return
POWER_SUPPLY_STATUS_DISCHARGING, and set "chargetest" to
"true" (setenv chargetest true), so to allow triggering the actual
battery charge sampling function.

From the code fragment:

--------
gpio_outlow(BAT_GPIO);//gpio out_low for c d-charge
msleep(1000);

for(i=0;i<1000;i++){
if(gpio_in_get(BAT_GPIO))
break;
udelay(1000);
}
--------

The return value of 'i' is:

About 93-94 with the power plug in (very slowly decreasing, maybe)
About 105 (increasing, about 1 unit in 5 seconds) with power plug off,
and increasing (I can't say what the actual power level was... around
50% I'd say).

I have to make some more accurate and sistematic measurements now...

ffxx68

unread,
Apr 19, 2011, 12:23:27 PM4/19/11
to VT8500/WM8505 Linux Kernel
Another bug I found (on my device - I suspect it's a hardware bug
here):

charging = gpio_in_get(charg_gpio);

This is ALWAYS reporting charging=1, if device is boot with power
plugged in, even after unplugging it.
If device is boot with power unplugged the reading is correct and like
this:

power unplugged: charging=0
power plugged: charging=1

ffxx68

unread,
Apr 19, 2011, 12:36:07 PM4/19/11
to VT8500/WM8505 Linux Kernel
For the timebeing, I forced status to always return
POWER_SUPPLY_STATUS_DISCHARGING, in wm85xx_read_status().

After all, a hardware-controlled led is present to tell if it's
actually charging, and tuning battmax and battmin allows to get an
(almost) correct charge level.

Ed Spiridonov

unread,
Apr 19, 2011, 1:34:23 PM4/19/11
to vt8500-wm8505...@googlegroups.com
2011/4/19 ffxx68 <ffu...@googlemail.com>:

> Another bug I found (on my device - I suspect it's a hardware bug
> here):
>
>  charging = gpio_in_get(charg_gpio);
>
> This is ALWAYS reporting charging=1, if device is boot with power
> plugged in, even after unplugging it.
> If device is boot with power unplugged the reading is correct and like
> this:
>
>      power unplugged: charging=0
>      power plugged: charging=1

Hmm... Android show charge status correctly, regardless is power plug
in or not on boot time.

ffxx68

unread,
Apr 20, 2011, 4:45:51 AM4/20/11
to VT8500/WM8505 Linux Kernel
On Apr 19, 7:34 pm, Ed Spiridonov <edo....@gmail.com> wrote:
> 2011/4/19 ffxx68 <ffum...@googlemail.com>:

>
> Hmm... Android show charge status correctly, regardless is power plug
> in or not on boot time.

Unfortunately, not in my case. That is why I had to hack the module....
Reply all
Reply to author
Forward
0 new messages