Tuesday, June 24, 2008

rx1950 battery driver

Today I've finished first implementation of rx1950 battery driver. It's based on adc-battery driver from hh.org

Charging now work correctly (I've tested it, it can charge my battery to 100%, and then disables charging and makes red LED to light solid)

Battery level estimated only by battery voltage. It's quite inaqurate and I'm trying to find ways to improve it.

Results of my efforts as usually available on hh.org: http://handhelds.org/moin/moin.cgi/HpIpaqRx1950

P.S. Unfortunately, battery driver conflicts with touchscreen driver. I'm working on solution...

Monday, June 23, 2008

Batteries, lithium, ions, chargers...

At last :)

I've managed to get charging work correctly, red led blinks when charging is in progress, and lights solid when charging finished. (Denis reported that his PDA has yellow led, btw, it does not matter :)) Problem was stupid: GPJ2, GPJ3 and GPJ6 (and not GPJ4 as I've reported before!) are affected in battery charging. I'll post patch after some testing ;)

Here's short description:

when charger connected, GPF2 goes to 0, and EINT2 interrupt occurs. In that case we should:

  • set GPA2 and GPA3 to 1
  • wait for some time, GPF3 should become 0 (not sure that it's necessary)
  • then we need to set GPJ2, GPJ3 and GPJ6 to 1

when charging is finished, GPF3 becomes 1 (GPF2 still 0!), in that case we should:

  • set GPA2 and GPA3 to 0, set GPA6 and GPA7 to 1
  • set GPJ2, GPJ3, GPJ6 to 0 

when charger is disconnected, GPF2 = 1. Each charger connecting/disconnecting event EINT2 occurs. But it doesn't when charging finished - so we should poll GPF3 periodically to prevent battery overcharging ;)

Now I'm working on getting battery level. It seems that rx1950 doesn't have any "smart" chips that estimate battery level. Sad. Very sad. It isn't possible to estimate battery level precisely only with battery voltage and temperature :( h1900 and h4100 has same situation, driver adc_battery exists in hh tree. I'm going  to adapt it for rx1950.

Btw, if anyone who reads this blog knows way to estimate battery level with voltage and temp - please contact me.

P.S. wince doesn't believe that linux can charge battery :)

If I reboot from linux to windows after charging battery in linux, wince has same battery level which it has before booting to linux. Only removing/inserting battery helps it to detect _real_ battery level ;)

Sunday, June 8, 2008

Some notes about s3c24xx suspend/resume (with htc-compatible loader)

Here's some interesting notes about suspend/resume with stock htc-compatible bootloader (rx1950, h1940, rx3000 PDAs)

After waking up from suspend bootloader:

  • checks if we really wake up from suspend (not power-on after power-off, etc)
  • performs quick memory check (it calculates simple checksum), if check was successfull jumps to physical address 0x30081000

But haret loads kernel to address 0x30008000. So resume address overlaps kernel space. To avoid kernel code corruption we should load kernel higher :) So, you'll need to patch your kernel to create offset for .text section, and also you'll need to patch haret.

Here's patch for haret:

diff -Naur haret/src/linboot.cpp haret.offset/src/linboot.cpp
--- haret/src/linboot.cpp 2007-04-15 20:13:41.000000000 +0200
+++ haret.offset/src/linboot.cpp 2007-04-26 19:52:13.000000000 +0200
@@ -87,7 +87,7 @@
// Recommended tags placement = RAM start + 256
#define PHYSOFFSET_TAGS 0x100
// Recommended kernel placement = RAM start + 32K
-#define PHYSOFFSET_KERNEL 0x8000
+#define PHYSOFFSET_KERNEL 0x98000
// Initrd will be put at the address of kernel + 5MB
#define PHYSOFFSET_INITRD (PHYSOFFSET_KERNEL + 0x500000)
// Maximum size of the tags structure.

Patch for kernel can be obtained here:

http://www.fluff.org/ben/linux-26/2620/2620-confgiurable-kernel-offset1.patch

Also we need to reserve 2 pages to prevent using them by kernel or userspace apps. For this you need to add some lines to arch/arm/mm/mmu.c in function reserve_node_zero:

if (machine_is_h1940() || machine_is_rx3715() || machine_is_rx1950()) {
reserve_bootmem_node(pgdat, 0x30003000, 0x1000,
BOOTMEM_DEFAULT);
reserve_bootmem_node(pgdat, 0x30081000, 0x1000,
BOOTMEM_DEFAULT);
}

Thats's all :) Now I have no crashes on my rx1950 with suspend enabled.

rx1950 porting

Sooooo, here we go :)

Here I'll post history of porting linux to rx1950, info about its hardware, etc.

Prehistory:

Port was started by Victor Chukhantsev and Denis Grigoriev in the end of 2006. At the early stage modified version of linux-2.6.17 could be booted into console using modified haret. SD card didn't work, usb didn't work...

At the beggining of 2007 (when I've joined to the development ;)) many drivers for rx1950 were ported (they were taken from other s3c24xx-based devices): s3c2440mci (sd/mmc driver), backlight driver, usb-device driver. Suspend/battery control/sound still didn't work. Also there were some issues with usb-device driver

From may'07 till may'08 development was stalled.

Our days:

In may'08 I've continued porting. Old patches were adapted to 2.6.25.4 kernel, old s3c2440mci driver was removed, and new s3cmci driver took his place. Also some patches were taken from openmoko repository (s3c2440-usbdevice workaround)

I've added usb pullup handling to the mach-rx1950.c - now usb works perfectly.

In the begging of June suspend support was added. rx1950 uses same H1940_SUSPEND_CHECK and H1940_SUSPEND_RESUMEAT as rx3000, and same checksum algorigthm. Also to boot from nand after wakeup we need to configure GPG13, GPG14, GPG15 to input mode. There's still one issue - lcd flickers after resume, and I don't know how to fix it :(

Today I've started to investigate how to control battery state, how to charge it, etc.

It seems that battery state (charge level) is controlled with built-in ADC. AIN0 - battery level, AIN1 - current consumption (not sure), AIN3 - unknown (maybe some sample voltage level?)

GPF2 (input)- ==0 if charger connected, ==1 otherwise

GPF3 (input)- ==1 if battery charged (no charging needed), ==0 otherwise

GPJ2 (output), GPJ3 (output), GPJ6 (output) - should be set to 1 to enable charging, 0 - to disable charging

GPA3 (output), GPA4 (output) ==1 to enable red LED blinking

GPA6 (output), GPA7 (output) ==1 to enable reg LED solid light

I.e. only when GPF2 == 0 and GPF3 == 0 we should enable charging.

Now I'm working on implementing driver that will control rx1950 battery.

Stay tuned for latest news ;) 

P.S. Sorry for my English ;)