1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2009 by Michael Sevakis
11 * Copyright (C) 2008 by Bertrik Sikken
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ****************************************************************************/
28 #include "powermgmt.h"
30 #include "usb-target.h"
33 /*===========================================================================
34 * These parameters may be defined per target:
36 * BATT_FULL_VOLTAGE - Upon connect a charge cycle begins if the reading is
37 * lower than this value (millivolts).
39 * BATT_VAUTO_RECHARGE - While left plugged after cycle completion, the
40 * charger restarts automatically if the reading drops
41 * below this value (millivolts). Must be less than
44 * ADC_BATTERY - ADC channel from which to read the battery voltage
46 * BATT_CHG_V - Charger voltage regulation setting (as3514 regval)
48 * BATT_CHG_I - Charger current regulation setting (as3514 regval)
50 * CHARGER_TOTAL_TIMER - Maximum allowed charging time (1/2-second steps)
51 *===========================================================================
54 /* This code assumes USB power input is not distinguishable from main
55 * power and charger connect cannot wait for USB configuration before
56 * considering USB charging available. Where they are distinguishable,
57 * things get more complicated. */
58 static bool charger_close
= false; /* Shutting down? */
59 static int charger_total_timer
= 0; /* Timeout in algorithm steps */
61 /* Current battery threshold for (re)charge:
62 * First plugged = BATT_FULL_VOLTAGE
63 * After charge cycle or non-start = BATT_VAUTO_RECHARGE
65 static unsigned int batt_threshold
= 0;
67 /* ADC should read 0x3ff=5.12V */
68 /* full-scale ADC readout (2^10) in millivolt */
70 /* Returns battery voltage from ADC [millivolts] */
71 unsigned int battery_adc_voltage(void)
73 return (adc_read(ADC_BATTERY
) * 5125 + 512) >> 10;
76 /* Returns true if the unit is charging the batteries. */
77 bool charging_state(void)
79 return charge_state
== CHARGING
;
82 /* Reset the battery filter to a new voltage */
83 static void battery_voltage_sync(void)
88 for (i
= 0, mv
= 0; i
< 5; i
++)
89 mv
+= battery_adc_voltage();
91 reset_battery_filter(mv
/ 5);
94 /* Disable charger and minimize all settings. Reset timers, etc. */
95 static void disable_charger(void)
97 ascodec_write_charger(TMPSUP_OFF
| CHG_I_50MA
| CHG_V_3_90V
| CHG_OFF
);
99 if (charge_state
> DISCHARGING
)
100 charge_state
= DISCHARGING
; /* Not an error state already */
102 charger_total_timer
= 0;
103 battery_voltage_sync();
106 /* Enable charger with specified settings. Start timers, etc. */
107 static void enable_charger(void)
109 ascodec_write_charger(BATT_CHG_I
| BATT_CHG_V
);
111 sleep(HZ
/10); /* Allow charger turn-on time (it could be gradual). */
113 #if CONFIG_CPU != AS3525v2
114 /* acknowledge first end of charging interrupt, it seems to happen both
115 * at charger plug and charger unplug
116 * It doesn't happen on newer AS3543
121 charge_state
= CHARGING
;
122 charger_total_timer
= CHARGER_TOTAL_TIMER
;
123 battery_voltage_sync();
126 void powermgmt_init_target(void)
128 /* Everything CHARGER, OFF! */
129 #if CONFIG_CPU == AS3525v2
130 ascodec_write_pmu(AS3543_CHARGER
, 2, 0x01); //EOC current theshold 30%
132 ascodec_monitor_endofch();
133 ascodec_write_charger(TMPSUP_OFF
| CHG_I_50MA
| CHG_V_3_90V
| CHG_OFF
);
136 static inline void charger_plugged(void)
138 batt_threshold
= BATT_FULL_VOLTAGE
; /* Start with topped value. */
139 battery_voltage_sync();
142 static inline void charger_control(void)
144 switch (charge_state
)
148 unsigned int millivolts
;
149 unsigned int thresh
= batt_threshold
;
151 if (BATT_FULL_VOLTAGE
== thresh
)
153 /* Wait for CHG_status to be indicated. */
154 if (!ascodec_chg_status())
157 batt_threshold
= BATT_VAUTO_RECHARGE
;
160 millivolts
= battery_voltage();
162 if (millivolts
<= thresh
)
169 if (!ascodec_endofch())
171 if (--charger_total_timer
> 0)
174 /* Timer ran out - require replug. */
175 charge_state
= CHARGE_STATE_ERROR
;
177 /* else end of charge */
184 /* DISABLED, ERROR */
189 static inline void charger_unplugged(void)
192 if (charge_state
>= CHARGE_STATE_ERROR
)
193 charge_state
= DISCHARGING
; /* Reset error */
196 /* Main charging algorithm - called from powermgmt.c */
197 void charging_algorithm_step(void)
199 switch (charger_input_state
)
205 case CHARGER_PLUGGED
:
213 case CHARGER_UNPLUGGED
:
220 /* Disable further charging and ack. */
221 charge_state
= CHARGE_STATE_DISABLED
;
223 charger_close
= false;
227 /* Disable the charger and prepare for poweroff - called off-thread so we
228 * signal the charging thread to prepare to quit. */
229 void charging_algorithm_close(void)
231 charger_close
= true;
233 /* Power management thread will set it false again. */
234 while (charger_close
)