cLK/patches/cwm_off_charge_v2.patch
2011-03-25 23:39:33 +02:00

125 lines
4.4 KiB
Diff

diff --git a/extendedcommands.c b/extendedcommands.c
index 30b2f3e..3ec3436 100644
--- a/extendedcommands.c
+++ b/extendedcommands.c
@@ -19,6 +19,7 @@
#include <signal.h>
#include <sys/wait.h>
+#include <pthread.h>
#include "bootloader.h"
#include "common.h"
@@ -1158,22 +1159,95 @@ int volume_main(int argc, char **argv) {
return 0;
}
+static int write_file(char* path, void* data, int data_size)
+{
+ int fd;
+ fd = open(path, O_WRONLY);
+ if (fd >= 0) {
+ int written = write(fd, data, data_size);
+ close(fd);
+ return written;
+ }
+ return -1;
+}
+
+static int read_file(char* path, void* data, int data_size)
+{
+ int fd;
+ fd = open(path, O_RDONLY);
+ if(fd >= 0){
+ int readed = read(fd, data, data_size);
+ close(fd);
+ return readed;
+ }
+ return -1;
+}
+
+static void* battery_thread(void *cookie)
+{
+ char status[40];
+ int state=-1;
+ int dischargeCount=0;
+
+ while(1){
+ memset(status, 0, sizeof(status));
+ read_file("/sys/class/power_supply/battery/status", status, sizeof(status)-1);
+ if(strstr(status, "Full")!=NULL && state!=1){
+ state=1;
+ write_file("/sys/class/leds/amber/brightness", "0\n", sizeof("0\n")-1);
+ write_file("/sys/class/leds/green/brightness", "1\n", sizeof("1\n")-1);
+ }else if(strstr(status, "Charging")!=NULL && state!=2){
+ state=2;
+ write_file("/sys/class/leds/amber/brightness", "1\n", sizeof("1\n")-1);
+ write_file("/sys/class/leds/green/brightness", "0\n", sizeof("0\n")-1);
+ }else if(strstr(status, "Discharging")!=NULL){
+ state=3;
+ if(dischargeCount==0){ //blink every 2 seconds
+ read_file("/sys/class/leds/amber/brightness", status, sizeof(status)-1);
+ if(status[0]=='0') write_file("/sys/class/leds/amber/brightness", "1\n", sizeof("1\n")-1);
+ else write_file("/sys/class/leds/amber/brightness", "0\n", sizeof("0\n")-1);
+ }
+ read_file("/sys/class/power_supply/battery/over_vchg", status, sizeof(status)-1);
+ dischargeCount=(dischargeCount+1)%4;
+ }else if(strstr(status,"Not charging")!=NULL && state!=4){
+ state=4;
+ write_file("/sys/class/leds/amber/brightness", "0\n", sizeof("0\n")-1);
+ write_file("/sys/class/leds/green/brightness", "0\n", sizeof("0\n")-1);
+ sync();
+ reboot(RB_POWER_OFF);
+ for(;;);
+ }
+ usleep(500000); //wait half a second
+ }
+ return NULL;
+}
+
void handle_chargemode() {
- const char* filename = "/proc/cmdline";
- struct stat file_info;
- if (0 != stat(filename, &file_info))
- return;
- int file_len = file_info.st_size;
- char* file_data = (char*)malloc(file_len + 1);
- FILE *file = fopen(filename, "rb");
- if (file == NULL)
- return;
- fread(file_data, file_len, 1, file);
- // supposedly not necessary, but let's be safe.
- file_data[file_len] = '\0';
- fclose(file);
-
- if (strstr(file_data, "androidboot.mode=offmode_charging") != NULL)
- reboot(RB_POWER_OFF);
+ // old code to read /proc/cmdline was broken because file size is always 0 so file_data was always empty string
+ char cmdline[1024];
+ memset(cmdline, 0, sizeof(cmdline));
+ if(read_file("/proc/cmdline", cmdline, sizeof(cmdline)-1) < 0) return;
+
+ if (strstr(cmdline, "androidboot.mode=offmode_charging") != NULL)
+ {
+ write_file("/sys/class/leds/lcd-backlight/brightness", "0\n", sizeof("0\n")-1);
+ write_file("/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", "powersave\n", sizeof("powersave\n")-1);
+ write_file("/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq", "245000\n", sizeof("245000\n")-1);
+ write_file("/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed", "245000\n", sizeof("245000\n")-1);
+
+ pthread_t t;
+ pthread_create(&t, NULL, battery_thread, NULL);
+
+ // let recovery kernel charge the battery, reboot on any key press so Android will start as user would expect
+ ev_init();
+ struct input_event ev;
+ do {
+ ev_get(&ev, 0);
+ if(ev.type==EV_KEY) write_file("/sys/class/leds/lcd-backlight/brightness", "0\n", sizeof("0\n")-1);
+ } while (!(ev.type==EV_KEY && ev.code==KEY_END));
+
+ reboot(RB_AUTOBOOT);
+ for(;;);
+ }
}