summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenzo Miori <memoryS60@gmail.com>2014-01-04 22:23:34 +0100
committerGerrit Rockbox <gerrit@rockbox.org>2015-01-29 20:28:07 +0100
commit6879dec6ece3c0797c5df16c9dd494b3dc3a1329 (patch)
tree1d8cfd1905468d3b6a6d98b6aea3c00f4c26354c
parentf65baf9b0f385bc479de9ab2eb92aab23167eba8 (diff)
downloadrockbox-6879dec6ece3c0797c5df16c9dd494b3dc3a1329.tar.gz
rockbox-6879dec6ece3c0797c5df16c9dd494b3dc3a1329.zip
yp-r0: improve the charging code
Some people reported strange charging times and strange battery life. Charging by OF: 25 hours; RB: 18 hours It has been found that there are at least two issues here: 1) the way of getting battery charging status wasn't really accurate. This attempts to fix that issue. This patch also simplifies some code (opening a device is no more needed, for example). To technically explain, battery charging implies first a constant current mode (where the voltage increases) and then a constant voltage mode (where, obviously, the voltage reads more or less the same). The old way the End Of Charge was detected was based solely on the voltage, while now it is based on chip's EOC interrupt, which should be more accurate. 2) OF explicitly sets a constant current 350 mA, while we usually had 55 mA (by as3543 default). This wasn't discovered before since there is a caching problem ("an accurate guess") in the Samsung power mgmt Linux module, thus its debugging dumper wasn't really working, reporting a 55 mA current. Strangely this option should have been set by the bootloader but apparently it does not. Some testing is still needed, but I confirm that with this patch I could run a benchmark for 25 hours (vs. 18 hours), by charging within Rockbox of course. Change-Id: I3bd921e86b9018d1cc3c720d15cc46896e8490b3
-rw-r--r--firmware/export/config/samsungypr0.h8
-rw-r--r--firmware/target/hosted/samsungypr/ypr0/powermgmt-ypr0.c54
2 files changed, 44 insertions, 18 deletions
diff --git a/firmware/export/config/samsungypr0.h b/firmware/export/config/samsungypr0.h
index b27a1fa2a6..212eaa8ec2 100644
--- a/firmware/export/config/samsungypr0.h
+++ b/firmware/export/config/samsungypr0.h
@@ -122,11 +122,6 @@
#endif /* SIMULATOR */
-/* FIXME
- * Lot of people reports bad battery life and funny charging times.
- * Check what's going on...
- */
-
#define BATTERY_CAPACITY_DEFAULT 600 /* default battery capacity */
#define BATTERY_CAPACITY_MIN 600 /* min. capacity selectable */
#define BATTERY_CAPACITY_MAX 600 /* max. capacity selectable */
@@ -138,6 +133,9 @@
/* Linux controlls charging, we can monitor */
#define CONFIG_CHARGING CHARGING_MONITOR
+/* We want to be able to reset the averaging filter */
+#define HAVE_RESET_BATTERY_FILTER
+
/* same dimensions as gigabeats */
#define CONFIG_LCD LCD_YPR0
diff --git a/firmware/target/hosted/samsungypr/ypr0/powermgmt-ypr0.c b/firmware/target/hosted/samsungypr/ypr0/powermgmt-ypr0.c
index 6e04d25f58..014a88db7c 100644
--- a/firmware/target/hosted/samsungypr/ypr0/powermgmt-ypr0.c
+++ b/firmware/target/hosted/samsungypr/ypr0/powermgmt-ypr0.c
@@ -16,14 +16,26 @@
*
****************************************************************************/
#include "config.h"
-#include <sys/ioctl.h>
#include "kernel.h"
#include "powermgmt.h"
#include "power.h"
#include "file.h"
#include "adc.h"
-#include "sc900776.h"
#include "radio-ypr.h"
+#include "ascodec.h"
+#include "stdbool.h"
+
+enum
+{
+ BATT_CHARGING,
+ BATT_NOT_CHARGING,
+ CHARGER_CONNECTED,
+ CHARGER_NOT_CONNECTED,
+};
+
+static bool first_readout = true;
+static int power_status = CHARGER_NOT_CONNECTED;
+static int charging_status = BATT_NOT_CHARGING;
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
{
@@ -49,17 +61,36 @@ const unsigned short const percent_to_volt_charge[11] =
3450, 3670, 3721, 3751, 3782, 3821, 3876, 3941, 4034, 4125, 4200
};
+static void read_charger(void)
+{
+ charging_status = ascodec_endofch() ? BATT_NOT_CHARGING : BATT_CHARGING;
+ power_status = ascodec_chg_status() ? CHARGER_CONNECTED : CHARGER_NOT_CONNECTED;
+ /* Sync the filter due to new charging state */
+ reset_battery_filter(_battery_voltage());
+}
+
unsigned int power_input_status(void)
{
- unsigned status = POWER_INPUT_NONE;
- int fd = open("/dev/minivet", O_RDONLY);
- if (fd >= 0)
+ if (first_readout)
{
- if (ioctl(fd, IOCTL_MINIVET_DET_VBUS, NULL) > 0)
- status = POWER_INPUT_MAIN_CHARGER;
- close(fd);
+ /* 350mA, 4.20V */
+ ascodec_write_pmu(AS3543_CHARGER, 0x1, 0x5C);
+ /* Enable interrupt for charging detection */
+ ascodec_write(AS3514_IRQ_ENRD0, CHG_CHANGED);
+ read_charger();
+ first_readout = false;
}
- return status;
+
+ if (ascodec_read(AS3514_IRQ_ENRD0) & CHG_CHANGED)
+ {
+ /* Something has changed... */
+ read_charger();
+ }
+
+ if (power_status == CHARGER_CONNECTED)
+ return POWER_INPUT_MAIN_CHARGER;
+ else
+ return POWER_INPUT_NONE;
}
#endif /* CONFIG_CHARGING */
@@ -74,10 +105,7 @@ int _battery_voltage(void)
bool charging_state(void)
{
- const unsigned short charged_thres = 4170;
- bool ret = (power_input_status() == POWER_INPUT_MAIN_CHARGER);
- /* dont indicate for > ~95% */
- return ret && (_battery_voltage() <= charged_thres);
+ return (power_status == CHARGER_CONNECTED && charging_status == BATT_CHARGING);
}
#if CONFIG_TUNER