u-boot fix to charge empty battery
Andy Green
andy at openmoko.com
Thu Oct 9 18:28:28 CEST 2008
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Somebody in the thread at some point said:
| Ok, I do now have a patch ready that fixes most low-power issues:
|
| * Always wait until battery is charged enough before continuing the boot
| process
| -> but still allow boot to continue if no battery is present
| * Cancel the shutdown timer during charging
| * Make sure 1A charger charges with 1A
| * Detect if power button has been pressed for long enough at the
| beginning of the startup sequence
| * Only pulse vibrator and LED when startup is initiated
| * Keep CPU @200Mhz until charging is complete
| -> I hope I didn't break USB ;-)
| * Abort charging if no USB power is present
I sent your patch here for ease of review...
I added it to the current tree, it starts up a fresh A6 here OK.
I also put a small patch on top of it to tidy one or two things up
(copied here after yours).
USB wasn't broken at least when I tried it.
Thanks for taking the time to look at these problems.
- -Andy
diff --git a/board/neo1973/gta02/gta02.c b/board/neo1973/gta02/gta02.c
index 6db164e..be39ae0 100644
- --- a/board/neo1973/gta02/gta02.c
+++ b/board/neo1973/gta02/gta02.c
@@ -324,6 +324,9 @@ static void poll_charger(void)
~ {
~ if (pcf50633_read_charger_type() == 1000)
~ pcf50633_usb_maxcurrent(1000);
+ else /* track what the time-critical udc callback allows us */
+ if (pcf50633_usb_last_maxcurrent != udc_usb_maxcurrent)
+ pcf50633_usb_maxcurrent(udc_usb_maxcurrent);
~ }
~ static int have_int(uint8_t mask1, uint8_t mask2);
@@ -376,6 +379,24 @@ static void cpu_idle(void)
~ local_irq_restore(flags);
~ }
+static int charger_is_present(void)
+{
+ /* is charger or power adapter present? */
+ if (pcf50633_reg_read(PCF50633_REG_MBCS1) & 3)
+ return 1;
+
+ return 0;
+}
+
+static int battery_is_present(void)
+{
+ /* battery is absent -> don't boot */
+ if (pcf50633_reg_read(PCF50633_REG_BVMCTL) & 1)
+ return 0;
+
+ return 1;
+}
+
~ static int battery_is_good(void)
~ {
~ /* battery is absent -> don't boot */
@@ -389,20 +410,22 @@ static int battery_is_good(void)
~ return 1;
~ }
- -static void wait_for_power(void)
+static int wait_for_power(void)
~ {
+ /*
+ * TODO: this function should also check if charger is still attached
+ * it makes no sense to wait otherwise.
+ */
+
~ int seconds = 0;
~ int led_cycle = 1;
+ int power = 1;
~ while (1) {
~ poll_charger();
- - /* track what the time-critical udc callback allows us */
- - if (pcf50633_usb_last_maxcurrent != udc_usb_maxcurrent)
- - pcf50633_usb_maxcurrent(udc_usb_maxcurrent);
- -
- - /* we have plenty of external power -> try to boot */
- - if (pcf50633_usb_last_maxcurrent >= 500)
+ /* we have plenty of external power but no battery -> try to boot */
+ if (!battery_is_present() && (pcf50633_usb_last_maxcurrent >= 500))
~ break;
~ /* cpu_idle sits with interrupts off destroying USB operation
@@ -420,6 +443,13 @@ static void wait_for_power(void)
~ */
~ if (led_cycle && battery_is_good())
~ break;
+
+ /* check if charger is present, otherwise stop start up */
+ if (!charger_is_present())
+ {
+ power = 0;
+ break;
+ }
~ seconds++;
~ }
@@ -435,10 +465,16 @@ static void wait_for_power(void)
~ /* alternate LED and charger cycles */
~ pcf50633_reg_set_bit_mask(PCF50633_REG_MBCC1, 1, !led_cycle);
+
+ /* cancel shutdown timer to keep charging */
+ pcf50633_reg_write(PCF50633_REG_OOCSHDWN, 4);
~ }
~ /* switch off the AUX LED */
~ neo1973_led(GTA02_LED_AUX_RED, 0);
+
+ /* do we have power now? */
+ return power;
~ }
~ static void pcf50633_late_init(void)
@@ -480,26 +516,6 @@ int board_late_init(void)
~ int1 = pcf50633_reg_read(PCF50633_REG_INT1);
~ int2 = pcf50633_reg_read(PCF50633_REG_INT2);
- - wait_for_power();
- - pcf50633_late_init();
- - cpu_speed(M_MDIV, M_PDIV, M_SDIV, 5); /* 400MHZ, 1:4:8 */
- -
- - /* issue a short pulse with the vibrator */
- - neo1973_led(GTA02_LED_AUX_RED, 1);
- - neo1973_vibrator(1);
- - udelay(20000);
- - neo1973_led(GTA02_LED_AUX_RED, 0);
- - neo1973_vibrator(0);
- -
- -#if defined(CONFIG_ARCH_GTA02_v1)
- - /* Glamo3362 reset and power cycle */
- - gpio->GPJDAT &= ~0x000000001; /* GTA02v1_GPIO_3D_RESET */
- - pcf50633_reg_write(PCF50633_REG_DOWN2ENA, 0);
- - udelay(50*1000);
- - pcf50633_reg_write(PCF50633_REG_DOWN2ENA, 0x2);
- - gpio->GPJDAT |= 0x000000001; /* GTA02v1_GPIO_3D_RESET */
- -#endif
- -
~ /* if there's no other reason, must be regular reset */
~ neo1973_wakeup_cause = NEO1973_WAKEUP_RESET;
@@ -551,6 +567,29 @@ woken_by_reset:
~ neo1973_poweroff();
~ continue_boot:
+ /* Power off if no battery is present and only 100mA is available */
+ if (!wait_for_power())
+ neo1973_poweroff();
+
+ pcf50633_late_init();
+ cpu_speed(M_MDIV, M_PDIV, M_SDIV, 5); /* 400MHZ, 1:4:8 */
+
+ /* issue a short pulse with the vibrator */
+ neo1973_led(GTA02_LED_AUX_RED, 1);
+ neo1973_vibrator(1);
+ udelay(20000);
+ neo1973_led(GTA02_LED_AUX_RED, 0);
+ neo1973_vibrator(0);
+
+#if defined(CONFIG_ARCH_GTA02_v1)
+ /* Glamo3362 reset and power cycle */
+ gpio->GPJDAT &= ~0x000000001; /* GTA02v1_GPIO_3D_RESET */
+ pcf50633_reg_write(PCF50633_REG_DOWN2ENA, 0);
+ udelay(50*1000);
+ pcf50633_reg_write(PCF50633_REG_DOWN2ENA, 0x2);
+ gpio->GPJDAT |= 0x000000001; /* GTA02v1_GPIO_3D_RESET */
+#endif
+
~ env_stop_in_menu = getenv("stop_in_menu");
~ /* If the stop_in_menu environment variable is set, enter the
~ * boot menu */
u-boot-clean-batt-charge-patch.patch
From: Andy Green <andy at openmoko.com>
Signed-off-by: Andy Green <andy at openmoko.com>
- ---
~ board/neo1973/gta02/gta02.c | 27 ++++++++++++---------------
~ 1 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/board/neo1973/gta02/gta02.c b/board/neo1973/gta02/gta02.c
index be39ae0..a59a513 100644
- --- a/board/neo1973/gta02/gta02.c
+++ b/board/neo1973/gta02/gta02.c
@@ -326,7 +326,7 @@ static void poll_charger(void)
~ pcf50633_usb_maxcurrent(1000);
~ else /* track what the time-critical udc callback allows us */
~ if (pcf50633_usb_last_maxcurrent != udc_usb_maxcurrent)
- - pcf50633_usb_maxcurrent(udc_usb_maxcurrent);
+ pcf50633_usb_maxcurrent(udc_usb_maxcurrent);
~ }
~ static int have_int(uint8_t mask1, uint8_t mask2);
@@ -382,25 +382,19 @@ static void cpu_idle(void)
~ static int charger_is_present(void)
~ {
~ /* is charger or power adapter present? */
- - if (pcf50633_reg_read(PCF50633_REG_MBCS1) & 3)
- - return 1;
- -
- - return 0;
+ return !!(pcf50633_reg_read(PCF50633_REG_MBCS1) & 3);
~ }
~ static int battery_is_present(void)
~ {
- - /* battery is absent -> don't boot */
- - if (pcf50633_reg_read(PCF50633_REG_BVMCTL) & 1)
- - return 0;
- -
- - return 1;
+ /* battery less than bvmlvl -> don't boot */
+ return !(pcf50633_reg_read(PCF50633_REG_BVMCTL) & 1);
~ }
~ static int battery_is_good(void)
~ {
~ /* battery is absent -> don't boot */
- - if (pcf50633_reg_read(PCF50633_REG_BVMCTL) & 1)
+ if (!battery_is_present())
~ return 0;
~ /* we could try to boot, but we'll probably die on the way */
@@ -424,7 +418,8 @@ static int wait_for_power(void)
~ while (1) {
~ poll_charger();
- - /* we have plenty of external power but no battery -> try to boot */
+ /* we have plenty of external power but no visible battery ->
+ * don't hang around trying to charge, try to boot */
~ if (!battery_is_present() && (pcf50633_usb_last_maxcurrent >= 500))
~ break;
@@ -445,8 +440,7 @@ static int wait_for_power(void)
~ break;
~ /* check if charger is present, otherwise stop start up */
- - if (!charger_is_present())
- - {
+ if (!charger_is_present()) {
~ power = 0;
~ break;
~ }
@@ -466,7 +460,10 @@ static int wait_for_power(void)
~ /* alternate LED and charger cycles */
~ pcf50633_reg_set_bit_mask(PCF50633_REG_MBCC1, 1, !led_cycle);
- - /* cancel shutdown timer to keep charging */
+ /* cancel shutdown timer to keep charging
+ * it can get triggered by lowvsys along the way but if it
+ * didn't kill us then don't let it kill us later
+ */
~ pcf50633_reg_write(PCF50633_REG_OOCSHDWN, 4);
~ }
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org
iEYEARECAAYFAkjuMSYACgkQOjLpvpq7dMoN2QCeI0pjlTsyVFIMr590H0u5Cmda
tbYAnii30AX5C+0NJyq3q2WKS30rzHVa
=ptBD
-----END PGP SIGNATURE-----
More information about the devel
mailing list