blob: 3430b1ea7914f71751cbceea62f574d17cbb4e62 [file] [log] [blame]
Michael Sevakis3157e132008-12-24 16:58:41 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
11 * Revisions copyright (C) 2005 by Gerald Van Baren
12 *
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.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include "config.h"
23#include "system.h"
24#include <time.h>
25#include "kernel.h"
26#include "powermgmt.h"
Thomas Martitzc1bd9b02012-01-03 23:44:38 +000027#include "power.h"
Michael Sevakis3157e132008-12-24 16:58:41 +000028
Thomas Martitzc1bd9b02012-01-03 23:44:38 +000029#define BATT_MINMVOLT 3300 /* minimum millivolts of battery */
30#define BATT_MAXMVOLT 4300 /* maximum millivolts of battery */
Michael Sevakis3157e132008-12-24 16:58:41 +000031#define BATT_MAXRUNTIME (10 * 60) /* maximum runtime with full battery in
32 minutes */
Nick Peskett8fdef402012-01-08 12:07:17 +000033/* Number of millivolts to discharge the battery every second */
34#define BATT_DISCHARGE_STEP ((BATT_MAXMVOLT - BATT_MINMVOLT) / 100)
35/* Number of millivolts to charge the battery every second */
36#define BATT_CHARGE_STEP (BATT_DISCHARGE_STEP * 2)
37#if CONFIG_CHARGING >= CHARGING_MONITOR
38/* Number of seconds to externally power before discharging again */
39#define POWER_AFTER_CHARGE_TICKS (8 * HZ)
40#endif
Michael Sevakis3157e132008-12-24 16:58:41 +000041
Michael Sevakis3157e132008-12-24 16:58:41 +000042extern int battery_percent;
Thomas Martitzc1bd9b02012-01-03 23:44:38 +000043static bool charging = false;
Michael Sevakis3157e132008-12-24 16:58:41 +000044static unsigned int battery_millivolts = BATT_MAXMVOLT;
Thomas Martitzc1bd9b02012-01-03 23:44:38 +000045
46void powermgmt_init_target(void) {}
Michael Sevakis3157e132008-12-24 16:58:41 +000047
48static void battery_status_update(void)
49{
Nick Peskett8fdef402012-01-08 12:07:17 +000050 /* Delay next battery update until tick */
51 static long update_after_tick = 0;
52#if CONFIG_CHARGING >= CHARGING_MONITOR
53 /* When greater than 0, the tick to unplug the external power at */
54 static unsigned int ext_power_until_tick = 0;
Nick Peskett7b376862012-01-05 22:25:13 +000055#endif
Michael Sevakis3157e132008-12-24 16:58:41 +000056
Nick Peskett8fdef402012-01-08 12:07:17 +000057 if TIME_BEFORE(current_tick, update_after_tick)
58 return;
Michael Sevakis3157e132008-12-24 16:58:41 +000059
Nick Peskett8fdef402012-01-08 12:07:17 +000060 update_after_tick = current_tick + HZ;
61
62#if CONFIG_CHARGING >= CHARGING_MONITOR
63 /* Handle period of being externally powered */
64 if (ext_power_until_tick > 0) {
65 if (TIME_AFTER(current_tick, ext_power_until_tick)) {
66 /* Pretend the charger was disconnected */
67 charger_input_state = CHARGER_UNPLUGGED;
68 ext_power_until_tick = 0;
69 }
70 return;
Michael Sevakis3157e132008-12-24 16:58:41 +000071 }
Nick Peskett8fdef402012-01-08 12:07:17 +000072#endif
73
74 if (charging) {
75 battery_millivolts += BATT_CHARGE_STEP;
76 if (battery_millivolts >= BATT_MAXMVOLT) {
77 charging = false;
78 battery_percent = 100;
79#if CONFIG_CHARGING >= CHARGING_MONITOR
80 /* Keep external power until tick */
81 ext_power_until_tick = current_tick + POWER_AFTER_CHARGE_TICKS;
82#elif CONFIG_CHARGING
83 /* Pretend the charger was disconnected */
84 charger_input_state = CHARGER_UNPLUGGED;
85#endif
86 return;
87 }
88 } else {
89 battery_millivolts -= BATT_DISCHARGE_STEP;
90 if (battery_millivolts <= BATT_MINMVOLT) {
91 charging = true;
92 battery_percent = 0;
93#if CONFIG_CHARGING
94 /* Pretend the charger was connected */
95 charger_input_state = CHARGER_PLUGGED;
96#endif
97 return;
98 }
99 }
100
101 battery_percent = 100 * (battery_millivolts - BATT_MINMVOLT) /
102 (BATT_MAXMVOLT - BATT_MINMVOLT);
Michael Sevakis3157e132008-12-24 16:58:41 +0000103}
104
Thomas Martitzc1bd9b02012-01-03 23:44:38 +0000105const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = { 3200 };
106const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = { 3200 };
Michael Sevakis3157e132008-12-24 16:58:41 +0000107
Thomas Martitzc1bd9b02012-01-03 23:44:38 +0000108/* make the simulated curve nicely linear */
109const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
110{ { 3300, 3400, 3500, 3600, 3700, 3800, 3900, 4000, 4100, 4200, 4300 } };
111const unsigned short percent_to_volt_charge[11] =
112{ 3300, 3400, 3500, 3600, 3700, 3800, 3900, 4000, 4100, 4200, 4300 };
Michael Sevakis3157e132008-12-24 16:58:41 +0000113
Michael Sevakis3157e132008-12-24 16:58:41 +0000114
Thomas Martitzc1bd9b02012-01-03 23:44:38 +0000115int _battery_voltage(void)
Michael Sevakis3157e132008-12-24 16:58:41 +0000116{
117 battery_status_update();
118 return battery_millivolts;
119}
120
Thomas Martitzc1bd9b02012-01-03 23:44:38 +0000121#if CONFIG_CHARGING
122unsigned int power_input_status(void)
Michael Sevakis3157e132008-12-24 16:58:41 +0000123{
Michael Sevakis7ccd2c92012-01-25 12:02:54 -0500124 unsigned int status = charger_input_state >= CHARGER_PLUGGED
Nick Peskett8fdef402012-01-08 12:07:17 +0000125 ? POWER_INPUT_CHARGER : POWER_INPUT_NONE;
Michael Sevakis7ccd2c92012-01-25 12:02:54 -0500126
127#ifdef HAVE_BATTERY_SWITCH
128 status |= POWER_INPUT_BATTERY;
129#endif
130
131 return status;
Michael Sevakis3157e132008-12-24 16:58:41 +0000132}
133
Thomas Martitzc1bd9b02012-01-03 23:44:38 +0000134bool charging_state(void)
Michael Sevakis3157e132008-12-24 16:58:41 +0000135{
Thomas Martitzc1bd9b02012-01-03 23:44:38 +0000136 return charging;
Michael Sevakis3157e132008-12-24 16:58:41 +0000137}
138#endif
139
140#ifdef HAVE_ACCESSORY_SUPPLY
141void accessory_supply_set(bool enable)
142{
143 (void)enable;
144}
145#endif
146
Andree Buschmannb6c12a12010-03-20 15:02:29 +0000147#ifdef HAVE_LINEOUT_POWEROFF
148void lineout_set(bool enable)
149{
150 (void)enable;
151}
152#endif
Thomas Martitz5d9759a2012-01-04 00:07:27 +0000153
154#ifdef HAVE_REMOTE_LCD
155bool remote_detect(void)
156{
157 return true;
158}
159#endif
160
161#ifdef HAVE_BATTERY_SWITCH
162unsigned int input_millivolts(void)
163{
164 if ((power_input_status() & POWER_INPUT_BATTERY) == 0) {
165 /* Just return a safe value if battery isn't connected */
166 return 4050;
167 }
168 return battery_voltage();;
169}
170#endif