summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c97
1 files changed, 26 insertions, 71 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c b/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c
index fa9c7b045f..b4a6c61fbb 100644
--- a/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/powermgmt-imx31.c
@@ -168,7 +168,7 @@ int battery_adc_temp(void)
168/* All code has a preference for the main charger being connected over 168/* All code has a preference for the main charger being connected over
169 * USB. USB is considered in the algorithm only if it is the sole source. */ 169 * USB. USB is considered in the algorithm only if it is the sole source. */
170static uint32_t int_sense0 = 0; /* Interrupt Sense 0 bits */ 170static uint32_t int_sense0 = 0; /* Interrupt Sense 0 bits */
171static unsigned int power_status = POWER_INPUT_NONE; /* Detect input changes */ 171static unsigned int last_inputs = POWER_INPUT_NONE; /* Detect input changes */
172static int charger_total_timer = 0; /* Total allowed charging time */ 172static int charger_total_timer = 0; /* Total allowed charging time */
173static int icharger_ave = 0; /* Filtered charging current */ 173static int icharger_ave = 0; /* Filtered charging current */
174static bool charger_close = false; /* Shutdown notification */ 174static bool charger_close = false; /* Shutdown notification */
@@ -181,7 +181,7 @@ static int autorecharge_counter = 0 ; /* Battery < threshold debounce */
181static int chgcurr_timer = 0; /* Countdown to CHGCURR error */ 181static int chgcurr_timer = 0; /* Countdown to CHGCURR error */
182#define AUTORECHARGE_COUNTDOWN (10*2) /* 10s debounce */ 182#define AUTORECHARGE_COUNTDOWN (10*2) /* 10s debounce */
183#define WATCHDOG_TIMEOUT (10*2) /* If not serviced, poweroff in 10s */ 183#define WATCHDOG_TIMEOUT (10*2) /* If not serviced, poweroff in 10s */
184#define CHGCURR_TIMEOUT (2*2) /* 2s debounce */ 184#define CHGCURR_TIMEOUT (4*2) /* 4s debounce */
185 185
186/* Temperature monitoring */ 186/* Temperature monitoring */
187static enum 187static enum
@@ -217,7 +217,7 @@ static bool charger_current_filter_step(void)
217/* Return true if the main charger is connected. */ 217/* Return true if the main charger is connected. */
218static bool main_charger_connected(void) 218static bool main_charger_connected(void)
219{ 219{
220 return (power_status & 220 return (last_inputs &
221 POWER_INPUT_MAIN_CHARGER & 221 POWER_INPUT_MAIN_CHARGER &
222 POWER_INPUT_CHARGER) != 0; 222 POWER_INPUT_CHARGER) != 0;
223} 223}
@@ -233,16 +233,14 @@ static unsigned int auto_recharge_voltage(void)
233 return BATT_USB_VAUTO_RECHARGE; 233 return BATT_USB_VAUTO_RECHARGE;
234} 234}
235 235
236#ifndef NO_LOW_BATTERY_SHUTDOWN
237/* Return greater of supply (BP) or filtered battery voltage. */ 236/* Return greater of supply (BP) or filtered battery voltage. */
238static unsigned int input_millivolts(void) 237unsigned int input_millivolts(void)
239{ 238{
240 unsigned int app_millivolts = application_supply_adc_voltage(); 239 unsigned int app_millivolts = application_supply_adc_voltage();
241 unsigned int bat_millivolts = battery_voltage(); 240 unsigned int bat_millivolts = battery_voltage();
242 241
243 return MAX(app_millivolts, bat_millivolts); 242 return MAX(app_millivolts, bat_millivolts);
244} 243}
245#endif
246 244
247/* Get smoothed readings for initializing filtered data. */ 245/* Get smoothed readings for initializing filtered data. */
248static int stat_battery_reading(int type) 246static int stat_battery_reading(int type)
@@ -292,7 +290,7 @@ static bool update_filtered_battery_voltage(void)
292 290
293 if (millivolts != INT_MIN) 291 if (millivolts != INT_MIN)
294 { 292 {
295 set_filtered_battery_voltage(millivolts); 293 reset_battery_filter(millivolts);
296 return true; 294 return true;
297 } 295 }
298 296
@@ -357,13 +355,13 @@ static bool adjust_charger_current(void)
357 int usb_select; 355 int usb_select;
358 uint32_t i; 356 uint32_t i;
359 357
360 usb_select = ((power_status & POWER_INPUT) == POWER_INPUT_USB) 358 usb_select = ((last_inputs & POWER_INPUT) == POWER_INPUT_USB)
361 ? 1 : 0; 359 ? 1 : 0;
362 360
363 if (charge_state == DISCHARGING && usb_select == 1) 361 if (charge_state == DISCHARGING && usb_select == 1)
364 { 362 {
365 /* USB-only, DISCHARGING, = maintaining battery */ 363 /* USB-only, DISCHARGING, = maintaining battery */
366 int select = (power_status & POWER_INPUT_CHARGER) ? 0 : 1; 364 int select = (last_inputs & POWER_INPUT_CHARGER) ? 0 : 1;
367 charger_setting = charger_bits[CHARGING+1][select]; 365 charger_setting = charger_bits[CHARGING+1][select];
368 } 366 }
369 else 367 else
@@ -458,7 +456,7 @@ static bool charging_ok(void)
458 if (ok) 456 if (ok)
459 { 457 {
460 /* Is the battery even connected? */ 458 /* Is the battery even connected? */
461 ok = (power_status & POWER_INPUT_BATTERY) != 0; 459 ok = (last_inputs & POWER_INPUT_BATTERY) != 0;
462 } 460 }
463 461
464 if (ok) 462 if (ok)
@@ -591,20 +589,6 @@ void powermgmt_init_target(void)
591#endif 589#endif
592} 590}
593 591
594/* Returns CHARGING or DISCHARGING since that's all we really do. */
595int powermgmt_filter_charge_state(void)
596{
597 switch(charge_state)
598 {
599 case TRICKLE:
600 case TOPOFF:
601 case CHARGING:
602 return CHARGING;
603 default:
604 return DISCHARGING;
605 }
606}
607
608/* Returns true if the unit is charging the batteries. */ 592/* Returns true if the unit is charging the batteries. */
609bool charging_state(void) 593bool charging_state(void)
610{ 594{
@@ -625,24 +609,6 @@ int battery_charge_current(void)
625 return icharger_ave / ICHARGER_AVE_SAMPLES; 609 return icharger_ave / ICHARGER_AVE_SAMPLES;
626} 610}
627 611
628bool query_force_shutdown(void)
629{
630#ifndef NO_LOW_BATTERY_SHUTDOWN
631 return input_millivolts() < battery_level_shutoff[0];
632#else
633 return false;
634#endif
635}
636
637bool battery_level_safe(void)
638{
639#ifndef NO_LOW_BATTERY_SHUTDOWN
640 return input_millivolts() > battery_level_dangerous[0];
641#else
642 return true;
643#endif
644}
645
646static void charger_plugged(void) 612static void charger_plugged(void)
647{ 613{
648 adc_enable_channel(ADC_BATTERY_TEMP, true); 614 adc_enable_channel(ADC_BATTERY_TEMP, true);
@@ -662,7 +628,7 @@ static void charger_unplugged(void)
662 } 628 }
663 629
664 /* Might need to reevaluate these bits in charger_none. */ 630 /* Might need to reevaluate these bits in charger_none. */
665 power_status &= ~(POWER_INPUT | POWER_INPUT_CHARGER); 631 last_inputs &= ~(POWER_INPUT | POWER_INPUT_CHARGER);
666 temp_state = TEMP_STATE_NORMAL; 632 temp_state = TEMP_STATE_NORMAL;
667 autorecharge_counter = 0; 633 autorecharge_counter = 0;
668 chgcurr_timer = 0; 634 chgcurr_timer = 0;
@@ -672,15 +638,11 @@ static void charger_unplugged(void)
672 638
673static void charger_none(void) 639static void charger_none(void)
674{ 640{
675 unsigned int pwr = power_input_status(); 641 unsigned int pwr = power_thread_inputs;
676 642
677 if (power_status != pwr) 643 if (last_inputs != pwr)
678 { 644 {
679 /* If battery switch state changed, reset filter. */ 645 last_inputs = pwr;
680 if ((power_status ^ pwr) & POWER_INPUT_BATTERY)
681 update_filtered_battery_voltage();
682
683 power_status = pwr;
684 646
685 if (charge_state == CHARGE_STATE_DISABLED) 647 if (charge_state == CHARGE_STATE_DISABLED)
686 return; 648 return;
@@ -696,7 +658,7 @@ static void charger_none(void)
696 else 658 else
697 { 659 {
698 charger_unplugged(); 660 charger_unplugged();
699 power_status = pwr; /* Restore status */ 661 last_inputs = pwr; /* Restore status */
700 } 662 }
701 } 663 }
702 else if (charger_setting != 0) 664 else if (charger_setting != 0)
@@ -716,17 +678,13 @@ static void charger_none(void)
716 678
717static void charger_control(void) 679static void charger_control(void)
718{ 680{
719 unsigned int pwr = power_input_status(); 681 unsigned int pwr = power_thread_inputs;
720 682
721 if (power_status != pwr) 683 if (last_inputs != pwr)
722 { 684 {
723 unsigned int changed = power_status ^ pwr; 685 unsigned int changed = last_inputs ^ pwr;
724 686
725 power_status = pwr; 687 last_inputs = pwr;
726
727 /* If battery switch state changed, reset filter. */
728 if (changed & POWER_INPUT_BATTERY)
729 update_filtered_battery_voltage();
730 688
731 if (charger_setting != 0) 689 if (charger_setting != 0)
732 charger_setting = CHARGER_ADJUST; 690 charger_setting = CHARGER_ADJUST;
@@ -771,12 +729,11 @@ static void charger_control(void)
771 { 729 {
772 /* Battery voltage may have dropped and a charge cycle should 730 /* Battery voltage may have dropped and a charge cycle should
773 * start again. Debounced. */ 731 * start again. Debounced. */
774 if (autorecharge_counter < 0) 732 if (autorecharge_counter < 0 &&
733 battery_adc_voltage() < BATT_FULL_VOLTAGE)
775 { 734 {
776 /* Try starting a cycle now regardless of battery level to 735 /* Try starting a cycle now if battery isn't already topped
777 * allow user to ensure the battery is topped off. It 736 * off to allow user to ensure the battery is full. */
778 * will soon turn off if already full. */
779 autorecharge_counter = 0;
780 } 737 }
781 else if (battery_voltage() > auto_recharge_voltage()) 738 else if (battery_voltage() > auto_recharge_voltage())
782 { 739 {
@@ -791,6 +748,8 @@ static void charger_control(void)
791 break; 748 break;
792 } 749 }
793 750
751 autorecharge_counter = 0;
752
794 charging_set_thread_priority(true); 753 charging_set_thread_priority(true);
795 754
796 if (stat_battery_reading(ADC_BATTERY) < BATT_VTRICKLE_CHARGE) 755 if (stat_battery_reading(ADC_BATTERY) < BATT_VTRICKLE_CHARGE)
@@ -858,10 +817,12 @@ static void charger_control(void)
858} 817}
859 818
860/* Main charging algorithm - called from powermgmt.c */ 819/* Main charging algorithm - called from powermgmt.c */
861void charging_algorithm_small_step(void) 820void charging_algorithm_step(void)
862{ 821{
822#ifdef IMX31_ALLOW_CHARGING
863 if (service_wdt) 823 if (service_wdt)
864 watchdog_service(); 824 watchdog_service();
825#endif
865 826
866 /* Switch by input state */ 827 /* Switch by input state */
867 switch (charger_input_state) 828 switch (charger_input_state)
@@ -909,12 +870,6 @@ void charging_algorithm_small_step(void)
909 } 870 }
910} 871}
911 872
912void charging_algorithm_big_step(void)
913{
914 /* Sleep for one minute */
915 power_thread_sleep(HZ*60);
916}
917
918/* Disable the charger and prepare for poweroff - called off-thread so we 873/* Disable the charger and prepare for poweroff - called off-thread so we
919 * signal the charging thread to prepare to quit. */ 874 * signal the charging thread to prepare to quit. */
920void charging_algorithm_close(void) 875void charging_algorithm_close(void)