1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (c) 2008 by Michael Sevakis
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
27 #include "powermgmt.h"
29 #include "power-gigabeat-s.h"
31 const unsigned short battery_level_dangerous
[BATTERY_TYPES_COUNT
] =
36 const unsigned short battery_level_shutoff
[BATTERY_TYPES_COUNT
] =
41 /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
42 const unsigned short percent_to_volt_discharge
[BATTERY_TYPES_COUNT
][11] =
44 /* Toshiba Gigabeat S Li Ion 700mAH figured from discharge curve */
45 { 3659, 3719, 3745, 3761, 3785, 3813, 3856, 3926, 3984, 4040, 4121 },
48 /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
49 const unsigned short percent_to_volt_charge
[11] =
51 /* Toshiba Gigabeat S Li Ion 700mAH figured from charge curve */
52 /* TODO - get actual charge curve (this is copy of discharge) */
53 3659, 3719, 3745, 3761, 3785, 3813, 3856, 3926, 3984, 4040, 4121
56 /* Returns battery voltage from ADC [millivolts] */
57 unsigned int battery_adc_voltage(void)
59 /* ADC reading 0-1023 = 2400mV-4700mV */
60 return ((adc_read(ADC_BATTERY
) * 2303) >> 10) + 2400;
63 /* Returns the application supply voltage from ADC [millvolts] */
64 unsigned int application_supply_adc_voltage(void)
66 return ((adc_read(ADC_APPLICATION_SUPPLY
) * 2303) >> 10) + 2400;
69 unsigned int chrgraw_adc_voltage(void)
71 return (adc_read(ADC_CHARGER_VOLTAGE
) * 23023) >> 10;
74 /* Returns battery charge current from ADC [milliamps] */
75 int battery_adc_charge_current(void)
77 /* Positive reading = charger to battery
78 * Negative reading = battery to charger terminal
79 * ADC reading -512-511 = -2875mA-2875mA */
80 unsigned int value
= adc_read(ADC_CHARGER_CURRENT
);
83 if (value
== ADC_READ_ERROR
)
86 I
= ((((int32_t)value
<< 22) >> 22) * 2881) >> 9;
87 return ILEVEL_ADJUST_IN(I
);
90 /* Estimate power dissipation in the charge path regulator in mW. */
91 unsigned int cccv_regulator_dissipation(void)
93 /* BATTISNS is shorted to BATT so we don't need to use the
94 * battery current reading. */
95 int chrgraw
= (adc_read(ADC_CHARGER_VOLTAGE
) * 230225) >> 10;
96 int batt
= ((adc_read(ADC_BATTERY
) * 23023) >> 10) + 24000;
97 int ichrgsn
= adc_read(ADC_CHARGER_CURRENT
);
98 ichrgsn
= ((((int32_t)ichrgsn
<< 22) >> 22) * 2881) >> 9;
99 ichrgsn
= abs(ichrgsn
);
101 return (chrgraw
- ichrgsn
- batt
)*ILEVEL_ADJUST_IN(ichrgsn
) / 10000;
104 /* Returns battery temperature from ADC [deg-C] */
105 int battery_adc_temp(void)
107 /* E[volts] = value * 2.3V / 1023
108 * R[ohms] = E/I = E[volts] / 0.00002[A] (Thermistor bias current source)
110 * Steinhart-Hart thermistor equation:
111 * [A + B*ln(R) + D*ln^3(R)] = 1 / T[°K]
113 * Coeffients that fit experimental data (one thermistor so far, one run):
114 * A = 0.0013002631685462800
115 * B = 0.0002000841932612330
116 * D = 0.0000000640446750919
118 static const unsigned short ntc_table
[] =
120 #if 0 /* These have degree deltas > 1 (except the final two) so leave them
121 * out. 70 deg C upper limit is quite sufficient. */
122 0, /* INF */ 1, /* 171 */ 2, /* 145 */ 3, /* 130 */
123 4, /* 121 */ 5, /* 114 */ 6, /* 108 */ 7, /* 104 */
124 8, /* 100 */ 9, /* 96 */ 10, /* 93 */ 11, /* 91 */
125 12, /* 88 */ 13, /* 86 */ 14, /* 84 */ 15, /* 82 */
126 16, /* 81 */ 17, /* 79 */ 18, /* 78 */ 19, /* 76 */
127 20, /* 75 */ 21, /* 74 */ 22, /* 72 */ 23, /* 71 */
129 24, /* 70 */ 25, /* 69 */ 26, /* 68 */ 27, /* 67 */
130 28, /* 66 */ 30, /* 65 */ 31, /* 64 */ 32, /* 63 */
131 33, /* 62 */ 35, /* 61 */ 36, /* 60 */ 38, /* 59 */
132 39, /* 58 */ 41, /* 57 */ 43, /* 56 */ 45, /* 55 */
133 47, /* 54 */ 49, /* 53 */ 51, /* 52 */ 53, /* 51 */
134 56, /* 50 */ 58, /* 49 */ 61, /* 48 */ 63, /* 47 */
135 66, /* 46 */ 69, /* 45 */ 73, /* 44 */ 76, /* 43 */
136 80, /* 42 */ 83, /* 41 */ 87, /* 40 */ 92, /* 39 */
137 96, /* 38 */ 101, /* 37 */ 106, /* 36 */ 111, /* 35 */
138 116, /* 34 */ 122, /* 33 */ 128, /* 32 */ 135, /* 31 */
139 142, /* 30 */ 149, /* 29 */ 156, /* 28 */ 164, /* 27 */
140 173, /* 26 */ 182, /* 25 */ 192, /* 24 */ 202, /* 23 */
141 212, /* 22 */ 224, /* 21 */ 236, /* 20 */ 249, /* 19 */
142 262, /* 18 */ 277, /* 17 */ 292, /* 16 */ 308, /* 15 */
143 325, /* 14 */ 344, /* 13 */ 363, /* 12 */ 384, /* 11 */
144 406, /* 10 */ 429, /* 9 */ 454, /* 8 */ 480, /* 7 */
145 509, /* 6 */ 539, /* 5 */ 571, /* 4 */ 605, /* 3 */
146 641, /* 2 */ 680, /* 1 */ 722, /* 0 */ 766, /* -1 */
147 813, /* -2 */ 864, /* -3 */ 918, /* -4 */ 976, /* -5 */
150 unsigned int value
= adc_read(ADC_BATTERY_TEMP
);
156 for (i
= 1; i
< ARRAYLEN(ntc_table
); i
++)
158 if (ntc_table
[i
] > value
)
168 /** Charger control **/
170 /* All code has a preference for the main charger being connected over
171 * USB. USB is considered in the algorithm only if it is the sole source. */
172 static uint32_t int_sense0
= 0; /* Interrupt Sense 0 bits */
173 static unsigned int last_inputs
= POWER_INPUT_NONE
; /* Detect input changes */
174 static int charger_total_timer
= 0; /* Total allowed charging time */
175 static int icharger_ave
= 0; /* Filtered charging current */
176 static bool charger_close
= false; /* Shutdown notification */
177 static bool service_wdt
= true; /* Service the watchdog timer, if things
178 go very wrong, cease and shut down. */
179 static uint32_t charger_setting
= 0; /* Current ICHRG and VCHRG regulator
180 * setting (register bits) */
181 #define CHARGER_ADJUST ((uint32_t)-1)/* Force change in regulator setting */
182 static int autorecharge_counter
= 0 ; /* Battery < threshold debounce */
183 static int chgcurr_timer
= 0; /* Countdown to CHGCURR error */
184 #define AUTORECHARGE_COUNTDOWN (10*2) /* 10s debounce */
185 #define WATCHDOG_TIMEOUT (10*2) /* If not serviced, poweroff in 10s */
186 #define CHGCURR_TIMEOUT (4*2) /* 4s debounce */
188 /* Temperature monitoring */
191 TEMP_STATE_NORMAL
= 0, /* Within range */
192 TEMP_STATE_WAIT
= 1, /* Went out of range, wait to come back */
193 TEMP_LOW_LIMIT
= 0, /* Min temp */
194 TEMP_HIGH_LIMIT
= 1, /* Max temp */
195 } temp_state
= TEMP_STATE_NORMAL
;
197 /* Set power thread priority for charging mode or not */
198 static inline void charging_set_thread_priority(bool charging
)
200 #ifdef HAVE_PRIORITY_SCHEDULING
201 thread_set_priority(THREAD_ID_CURRENT
,
202 charging
? PRIORITY_REALTIME
: PRIORITY_SYSTEM
);
207 /* Update filtered charger current - exponential moving average */
208 static bool charger_current_filter_step(void)
210 int value
= battery_adc_charge_current();
212 if (value
== ADC_READ_ERROR
)
215 icharger_ave
+= value
- (icharger_ave
/ ICHARGER_AVE_SAMPLES
);
219 /* Return true if the main charger is connected. */
220 static bool main_charger_connected(void)
222 return (last_inputs
&
223 POWER_INPUT_MAIN_CHARGER
&
224 POWER_INPUT_CHARGER
) != 0;
227 /* Return the voltage level which should automatically trigger
228 * another recharge cycle based upon which power source is available.
229 * Assumes at least one is. */
230 static unsigned int auto_recharge_voltage(void)
232 if (main_charger_connected())
233 return BATT_VAUTO_RECHARGE
;
235 return BATT_USB_VAUTO_RECHARGE
;
238 /* Return greater of supply (BP) or filtered battery voltage. */
239 unsigned int input_millivolts(void)
241 unsigned int app_millivolts
= application_supply_adc_voltage();
242 unsigned int bat_millivolts
= battery_voltage();
244 return MAX(app_millivolts
, bat_millivolts
);
247 /* Get smoothed readings for initializing filtered data. */
248 static int stat_battery_reading(int type
)
250 int high
= INT_MIN
, low
= INT_MAX
;
254 for (i
= 0; i
< 7; i
++)
256 int reading
= ADC_READ_ERROR
;
258 sleep(2); /* Get unique readings */
263 reading
= battery_adc_voltage();
266 case ADC_CHARGER_CURRENT
:
267 reading
= battery_adc_charge_current();
271 if (reading
== ADC_READ_ERROR
)
283 /* Discard extremes */
284 return (value
- high
- low
) / 5;
287 /* Update filtered battery voltage instead of waiting for filter
289 static bool update_filtered_battery_voltage(void)
291 int millivolts
= stat_battery_reading(ADC_BATTERY
);
293 if (millivolts
!= INT_MIN
)
295 reset_battery_filter(millivolts
);
302 /* Sets the charge current limit based upon state. charge_state should be
303 * set before calling. */
304 static bool adjust_charger_current(void)
306 static const uint8_t charger_bits
[][2] =
310 /* These are actually zeros but reflect this setting */
311 MC13783_ICHRG_0MA
| MC13783_VCHRG_4_050V
,
312 MC13783_ICHRG_0MA
| MC13783_VCHRG_4_050V
,
314 /* Main(+USB): Charge slowly from the adapter until voltage is
315 * sufficient for normal charging.
317 * USB: The truth is that things will probably not make it this far.
318 * Cover the case, just in case the disk isn't used and it is
322 BATTERY_ITRICKLE
| BATTERY_VCHARGING
,
323 BATTERY_ITRICKLE_USB
| BATTERY_VCHARGING
327 BATTERY_IFAST
| BATTERY_VCHARGING
,
328 BATTERY_IFAST_USB
| BATTERY_VCHARGING
332 BATTERY_IFAST
| BATTERY_VCHARGING
,
333 BATTERY_IFAST_USB
| BATTERY_VCHARGING
335 /* Must maintain battery when on USB power only - utterly nasty
336 * but true and something retailos does (it will even end up charging
337 * the battery but not reporting that it is doing so).
338 * Float lower than MAX - could end up slightly discharging after
339 * a full charge but this is safer than maxing it out. */
342 BATTERY_IFLOAT_USB
| BATTERY_VFLOAT_USB
,
343 BATTERY_IMAINTAIN_USB
| BATTERY_VMAINTAIN_USB
346 /* Slower settings to so that the linear regulator doesn't dissipate
347 * an excessive amount of power when coming out of precharge state. */
350 BATTERY_ISLOW
| BATTERY_VCHARGING
,
351 BATTERY_ISLOW_USB
| BATTEYR_VCHARGING
356 bool success
= false;
360 usb_select
= ((last_inputs
& POWER_INPUT
) == POWER_INPUT_USB
)
363 if (charge_state
== DISCHARGING
&& usb_select
== 1)
365 /* USB-only, DISCHARGING, = maintaining battery */
366 int select
= (last_inputs
& POWER_INPUT_CHARGER
) ? 0 : 1;
367 charger_setting
= charger_bits
[CHARGING
+1][select
];
371 /* Take very good care not to write garbage. */
372 int state
= charge_state
;
374 if (state
< DISCHARGING
|| state
> CHARGING
)
377 charger_setting
= charger_bits
[state
][usb_select
];
380 if (charger_setting
!= 0)
382 if ((charger_setting
& MC13783_VCHRG
) > BATTERY_VCHARGING
||
383 (charger_setting
& MC13783_ICHRG
) > BATTERY_IFAST
)
385 /* Table is corrupted somehow. We shouldn't run at all.
387 * Explanation: On two occasions, even though this driver monitors
388 * the regulator register settings on each step and
389 * ensures that only valid table indexes are used,
390 * the current and voltage seem to be misregulated,
391 * resulting in excessively high battery voltage that
392 * will trip the battery protection. After careful
393 * review it seems that two possibilities exist:
394 * This code or data got trashed at some point or
395 * there really is a hardware bug of some sort. So
396 * far the cause is unknown. Voltage is also
397 * monitored in the CHARGING case for that reason.
398 * The solution for data or code corruption is to
399 * just panic and refuse to run the device. The
400 * solution for overvoltage due to hardware bug is to
401 * disable the charging. The action taken will reveal
402 * the true cause, thus _who_ is responsible.
403 * "Burning lithium is baaaad", so sayeth The Council
404 * of Seven Ascended Masters. */
405 charge_state
= CHARGE_STATE_DISABLED
;
410 /* Turn on 5K pulldown. */
411 i
= mc13783_set(MC13783_CHARGER
, MC13783_CHRGRAWPDEN
);
413 if (i
!= MC13783_DATA_ERROR
)
415 charging_set_thread_priority(true);
417 /* Turn regulator logically ON. Hardware may still override.
419 i
= mc13783_write_masked(MC13783_CHARGER
, charger_setting
,
420 MC13783_ICHRG
| MC13783_VCHRG
);
422 if (i
!= MC13783_DATA_ERROR
)
426 /* Enable charge current conversion */
427 adc_enable_channel(ADC_CHARGER_CURRENT
, true);
429 /* Charge path regulator turn on takes ~100ms max. */
432 icharger
= stat_battery_reading(ADC_CHARGER_CURRENT
);
434 if (icharger
!= INT_MIN
)
436 icharger_ave
= icharger
* ICHARGER_AVE_SAMPLES
;
438 if (update_filtered_battery_voltage())
444 /* Force regulator OFF. */
445 charge_state
= CHARGE_STATE_ERROR
;
449 /* Turn regulator OFF. */
451 i
= mc13783_write_masked(MC13783_CHARGER
,
452 MC13783_ICHRG_0MA
| MC13783_VCHRG_4_050V
,
453 MC13783_ICHRG
| MC13783_VCHRG
|
454 MC13783_CHRGRAWPDEN
);
456 if (MC13783_DATA_ERROR
== i
)
458 /* Failed. Force poweroff by not servicing the watchdog. */
461 else if (0 == charger_setting
)
463 /* Here because OFF was requested state */
469 adc_enable_channel(ADC_CHARGER_CURRENT
, false);
470 update_filtered_battery_voltage();
471 charging_set_thread_priority(false);
476 /* Stop the charger - if USB only then the regulator will not really be
477 * turned off. ERROR or DISABLED will turn it off however. */
478 static void stop_charger(void)
480 charger_total_timer
= 0;
482 if (charge_state
> DISCHARGING
)
483 charge_state
= DISCHARGING
;
485 adjust_charger_current();
488 /* Return OK if it is acceptable to start the regulator. */
489 static bool charging_ok(void)
491 bool ok
= charge_state
>= DISCHARGING
; /* Not an error condition? */
495 /* Is the battery even connected? */
496 ok
= (last_inputs
& POWER_INPUT_BATTERY
) != 0;
501 /* No tolerance for any over/under temp - wait for it to
502 * come back into safe range. */
503 static const signed char temp_ranges
[2][2] =
505 /* Temperature range before beginning charging */
506 { BATTERY_CHARGE_MIN
,
507 BATTERY_CHARGE_MAX
},
508 /* Temperature range after out-of-range detected -
509 charging will self-resume */
510 { BATTERY_CHARGE_RESTART_MIN
,
511 BATTERY_CHARGE_RESTART_MAX
},
514 int temp
= battery_adc_temp();
515 const signed char *range
= temp_ranges
[temp_state
];
517 ok
= temp
>= range
[TEMP_LOW_LIMIT
] &&
518 temp
<= range
[TEMP_HIGH_LIMIT
];
522 case TEMP_STATE_NORMAL
:
524 temp_state
= TEMP_STATE_WAIT
;
527 case TEMP_STATE_WAIT
:
529 temp_state
= TEMP_STATE_NORMAL
;
539 /* Any events that should stop the regulator? */
541 /* Overvoltage at CHRGRAW? */
542 ok
= (int_sense0
& MC13783_CHGOVS
) == 0;
546 /* CHGCURR sensed? */
547 ok
= (int_sense0
& MC13783_CHGCURRS
) != 0;
551 /* Debounce transient states */
552 if (chgcurr_timer
> 0)
560 chgcurr_timer
= CHGCURR_TIMEOUT
;
564 /* Charger may need to be reinserted */
566 charge_state
= CHARGE_STATE_ERROR
;
569 if (charger_setting
!= 0)
573 /* Protect against any conceivable overcharge/voltage condition
574 * before hardware protection must intervene. Disable charger
576 ok
= battery_voltage() < BATT_TOO_HIGH
;
578 charge_state
= CHARGE_STATE_DISABLED
;
583 /* Watch to not overheat FET (nothing should go over about 1012.7mW).
584 * Trying a higher voltage AC adapter can work (up to 6.90V) but
585 * we'll just reject that. Reducing current for adapters that bring
586 * CHRGRAW to > 4.900V is another possible action. */
587 ok
= cccv_regulator_dissipation() < 1150;
589 charge_state
= CHARGE_STATE_ERROR
;
594 int state
= charge_state
;
596 if (state
> DISCHARGING
)
599 /* Force off for all states including maintaining the battery level
601 charge_state
= CHARGE_STATE_ERROR
;
603 charge_state
= state
;
610 void powermgmt_init_target(void)
612 #ifdef IMX31_ALLOW_CHARGING
613 const uint32_t regval_w
=
614 MC13783_VCHRG_4_050V
| MC13783_ICHRG_0MA
|
615 MC13783_ICHRGTR_0MA
| MC13783_OVCTRL_6_90V
;
617 /* Use watchdog to shut system down if we lose control of the charging
619 watchdog_init(WATCHDOG_TIMEOUT
);
621 mc13783_write(MC13783_CHARGER
, regval_w
);
623 if (mc13783_read(MC13783_CHARGER
) == regval_w
)
625 /* Divide CHRGRAW input by 10 */
626 mc13783_clear(MC13783_ADC0
, MC13783_CHRGRAWDIV
);
627 /* Turn off BATTDETB. It's worthless on MESx0V since the battery
628 * isn't removable (nor the thermistor). */
629 mc13783_clear(MC13783_POWER_CONTROL0
, MC13783_BATTDETEN
);
633 /* Register has the wrong value - set error condition and disable
634 * since something is wrong. */
635 charge_state
= CHARGE_STATE_DISABLED
;
639 /* Disable charger use */
640 charge_state
= CHARGE_STATE_DISABLED
;
644 /* Returns true if the unit is charging the batteries. */
645 bool charging_state(void)
647 switch (charge_state
)
658 /* Filtered battery charge current */
659 int battery_charge_current(void)
661 return icharger_ave
/ ICHARGER_AVE_SAMPLES
;
664 static void charger_plugged(void)
666 adc_enable_channel(ADC_BATTERY_TEMP
, true);
667 autorecharge_counter
= -1;
670 static void charger_unplugged(void)
672 /* Charger pulled - turn off current sources (though hardware
673 * will have done that anyway). */
674 if (charge_state
> CHARGE_STATE_DISABLED
)
676 /* Reset state and clear any error. If disabled, the charger
677 * will not have been started or will have been stopped already. */
679 charge_state
= DISCHARGING
;
682 /* Might need to reevaluate these bits in charger_none. */
683 last_inputs
&= ~(POWER_INPUT
| POWER_INPUT_CHARGER
);
684 temp_state
= TEMP_STATE_NORMAL
;
685 autorecharge_counter
= 0;
688 adc_enable_channel(ADC_BATTERY_TEMP
, false);
691 static void charger_none(void)
693 unsigned int pwr
= power_thread_inputs
;
695 if (last_inputs
!= pwr
)
699 if (charge_state
== CHARGE_STATE_DISABLED
)
702 if ((pwr
& (POWER_INPUT
| POWER_INPUT_CHARGER
)) == POWER_INPUT_USB
)
704 /* USB connected but not configured. Maintain battery to the
705 * greatest degree possible. It probably won't be enough but the
706 * discharge won't be so severe. */
708 charger_setting
= CHARGER_ADJUST
;
713 last_inputs
= pwr
; /* Restore status */
716 else if (charger_setting
!= 0)
718 /* Maintaining - keep filter going and check charge state */
719 int_sense0
= mc13783_read(MC13783_INTERRUPT_SENSE0
);
721 if (!charger_current_filter_step())
723 /* Failed to read current */
724 charge_state
= CHARGE_STATE_ERROR
;
731 static void charger_control(void)
733 unsigned int pwr
= power_thread_inputs
;
735 if (last_inputs
!= pwr
)
737 unsigned int changed
= last_inputs
^ pwr
;
741 if (charger_setting
!= 0)
742 charger_setting
= CHARGER_ADJUST
;
744 if (charge_state
== DISCHARGING
)
746 if (main_charger_connected())
748 /* If main is connected, ignore USB plugs. */
749 if (changed
& POWER_INPUT_MAIN_CHARGER
)
751 /* Main charger plugged - try charge */
752 autorecharge_counter
= -1;
755 else if (pwr
& POWER_INPUT_USB_CHARGER
756 & POWER_INPUT_CHARGER
)
759 if (changed
& POWER_INPUT_USB_CHARGER
)
761 /* USB charger plugged - try charge */
762 autorecharge_counter
= -1;
764 else if (changed
& POWER_INPUT_MAIN_CHARGER
)
766 /* Main charger pulled - go to battery maintenence. */
767 charger_setting
= CHARGER_ADJUST
;
773 if (charger_setting
!= 0 && !charger_current_filter_step())
775 /* Failed to read current */
776 charge_state
= CHARGE_STATE_ERROR
;
779 int_sense0
= mc13783_read(MC13783_INTERRUPT_SENSE0
);
784 switch (charge_state
)
788 /* Battery voltage may have dropped and a charge cycle should
789 * start again. Debounced. */
790 if (autorecharge_counter
< 0 &&
791 battery_adc_voltage() < BATT_FULL_VOLTAGE
)
793 /* Try starting a cycle now if battery isn't already topped
794 * off to allow user to ensure the battery is full. */
796 else if (battery_voltage() > auto_recharge_voltage())
798 /* Still above threshold - reset counter */
799 autorecharge_counter
= AUTORECHARGE_COUNTDOWN
;
802 else if (autorecharge_counter
> 0)
804 /* Coundown to restart */
805 autorecharge_counter
--;
809 autorecharge_counter
= 0;
811 charging_set_thread_priority(true);
813 if (stat_battery_reading(ADC_BATTERY
) < BATT_VTRICKLE_CHARGE
)
815 /* Battery is deeply discharged - precharge at lower current. */
816 charge_state
= TRICKLE
;
820 /* Ok for fast charge */
821 charge_state
= CHARGING
;
824 charger_setting
= CHARGER_ADJUST
;
825 charger_total_timer
= CHARGER_TOTAL_TIMER
*60*2;
829 case TRICKLE
: /* Very low - precharge */
831 if (battery_voltage() <= BATT_VTRICKLE_CHARGE
)
834 /* Switch to normal charge mode. */
835 charge_state
= CHARGING
;
836 charger_setting
= CHARGER_ADJUST
;
840 case CHARGING
: /* Constant-current stage */
841 case TOPOFF
: /* Constant-voltage stage */
843 /* Reg. mode is more informative than an operational necessity. */
844 charge_state
= (int_sense0
& MC13783_CCCVS
) ? TOPOFF
: CHARGING
;
846 if (main_charger_connected())
848 /* Monitor and stop if current drops below threshold. */
849 if (battery_charge_current() > BATTERY_ICHARGE_COMPLETE
)
854 /* Accurate I-level can't be determined since device also
855 * powers through the I sense. This simply stops the reporting
856 * of charging but the regulator remains on. */
857 if (battery_voltage() <= BATT_USB_VSTOP
)
863 } /* CHARGING: TOPOFF: */
869 /* Check if charger timer expired and stop it if so. */
870 if (charger_total_timer
> 0 && --charger_total_timer
== 0)
872 charge_state
= CHARGE_STATE_ERROR
;
873 stop_charger(); /* Time ran out - error */
877 /* Main charging algorithm - called from powermgmt.c */
878 void charging_algorithm_step(void)
880 #ifdef IMX31_ALLOW_CHARGING
885 /* Switch by input state */
886 switch (charger_input_state
)
892 case CHARGER_PLUGGED
:
900 case CHARGER_UNPLUGGED
:
907 if (charge_state
!= CHARGE_STATE_DISABLED
)
909 /* Disable starts while shutting down */
910 charge_state
= CHARGE_STATE_DISABLED
;
914 charger_close
= false;
918 if (charger_setting
!= 0)
920 if ((mc13783_read(MC13783_CHARGER
) & (MC13783_ICHRG
| MC13783_VCHRG
)) !=
923 /* The hardware setting doesn't match. It could have turned the
924 * charger off in a race of plugging/unplugging or the setting
925 * was changed in one of the calls. */
926 adjust_charger_current();
931 /* Disable the charger and prepare for poweroff - called off-thread so we
932 * signal the charging thread to prepare to quit. */
933 void charging_algorithm_close(void)
935 charger_close
= true;
937 /* Power management thread will set it false again */
938 while (charger_close
)