// woot for writing code while sick.
// this code begs a rewrite, but should work fine; its just arranged goofily
-// -> I mean, why the racial divide between keys and other events
+// -> I mean, why the racial divide between keys and other events?
+// -> now that I've put together pnd_io_evdev, should leverage that; be much cleaner.
#include <stdio.h> /* for printf, NULL */
#include <stdlib.h> /* for free */
keycode_t keycodes[] = {
{ KEY_A, "a" },
+ { KEY_B, "b" },
{ KEY_MENU, "pandora" },
{ KEY_POWER, "power" },
+ { KEY_DELETE, "del" },
+ { KEY_COMMA, "comma" },
+ { KEY_1, "1" },
+ { KEY_2, "2" },
+ { KEY_3, "3" },
+ { KEY_4, "4" },
+ { KEY_5, "5" },
+ { KEY_6, "6" },
+ { KEY_7, "7" },
+ { KEY_8, "8" },
+ { KEY_9, "9" },
+ { KEY_0, "0" },
+ { KEY_BRIGHTNESSDOWN, "lcdbrightdown" },
+ { KEY_BRIGHTNESSUP, "lcdbrightup" },
+ { KEY_COFFEE, "hold" }, /* coffee? lol */
+ { KEY_F1, "f1" },
+ { KEY_F2, "f2" },
+ { KEY_F3, "f3" },
+ { KEY_F4, "f4" },
+ { KEY_F5, "f5" },
+ { KEY_F6, "f6" },
+ { KEY_F7, "f7" },
+ { KEY_F8, "f8" },
+ { KEY_F9, "f9" },
+ { KEY_F10, "f10" },
+ { KEY_F11, "f11" },
+ { KEY_F12, "f12" },
+ { KEY_F18, "f18" },
+ { KEY_F23, "f23" },
+ { KEY_YEN, "yen" },
{ -1, NULL }
};
{ -1, -1, NULL }
};
+// FAKESCRIPT_ entries are to better handle a virtual script name; if we have to parse
+// "TOGGLE_HOLD" for every key down, it seems a little inefficient; at conf-time, if we
+// see this string for example, why not change it to a magic number .. and if we see that
+// down the road, we can act with just an integer compare, instead of a string compare..
+#define FAKESCRIPT_TOGGLE_HOLD 0001
+
// event-to-sh mapping
//
typedef struct {
void *reqs; // scancode/etc for the event in question
char *script; // script to invoke
- //unsigned int hold_min; // minimum hold-time to trigger
+ unsigned int maxhold; // maximum hold-time before forcing script invocation
/* state
*/
#define MAXEVENTS 255
evmap_t g_evmap [ MAXEVENTS ];
unsigned int g_evmap_max = 0;
+unsigned int g_queued_keyups = 0;
// battery
unsigned char b_threshold = 5; // %battery
unsigned int b_blinkdur = 1000; // blink duration (uSec), 0sec + uSec is assumed
unsigned char b_active = 0; // 0=inactive, 1=active and waiting to blink, 2=blink is on, waiting to turn off
unsigned char b_shutdown = 1; // %age battery to force a shutdown!
+unsigned int b_shutdelay = 30; // delay for shutdown script
+unsigned char b_warned = 0; // Shutdown attempted
char *b_shutdown_script = NULL;
+unsigned char bc_enable = 1; // enable charger control
+unsigned char bc_stopcap = 99; // battery capacity threshold as stop condition 1
+unsigned int bc_stopcur = 80000; // charge current threshold as stop condition 2, in uA
+unsigned char bc_startcap = 95; // battery capacity threshold to resume charging
+char *bc_charge_devices = NULL; // charger /sys/class/power_supply/ devices, changes between kernel versions
+
+// fd's; pulled from main() so I can be lazy
+int fds [ 8 ] = { -1, -1, -1, -1, -1, -1, -1, -1 }; // 0 = keypad, 1 = gpio keys
+int imaxfd = 0;
/* get to it
*/
void sigchld_handler ( int n );
unsigned char set_next_alarm ( unsigned int secs, unsigned int usecs );
void sigalrm_handler ( int n );
+void fakescript_hold_on ( void );
+void fakescript_hold_off ( void );
static void usage ( char *argv[] ) {
printf ( "%s [-d]\n", argv [ 0 ] );
// umask
umask ( 022 ); // emitted files can be rwxr-xr-x
-
+
} // set up daemon
/* hmm, seems to not like working right after boot.. do we depend on another daemon or
if ( p -> keycode != -1 ) {
g_evmap [ g_evmap_max ].key_p = 1; // its a key, not an event
g_evmap [ g_evmap_max ].reqs = p; // note the keycode
- g_evmap [ g_evmap_max ].script = n; // note the script to activate in response
- pnd_log ( pndn_rem, "Registered key %s [%d] to script %s\n", p -> keyname, p -> keycode, (char*) n );
+
+ // note the script to activate in response
+ if ( strchr ( n, ' ' ) ) {
+ char *foo = strdup ( n );
+ char *t = strchr ( foo, ' ' );
+ *t = '\0';
+ g_evmap [ g_evmap_max ].script = foo;
+ g_evmap [ g_evmap_max ].maxhold = atoi ( t + 1 );
+ } else {
+ g_evmap [ g_evmap_max ].script = n;
+ g_evmap [ g_evmap_max ].maxhold = 0;
+
+ if ( strcmp ( n, "TOGGLE_HOLD" ) == 0 ) {
+ g_evmap [ g_evmap_max ].script = (char*)FAKESCRIPT_TOGGLE_HOLD;
+ }
+
+ }
+
+ pnd_log ( pndn_rem, "Registered key %s [%d] to script %s with maxhold %d\n",
+ p -> keyname, p -> keycode, (char*) n, g_evmap [ g_evmap_max ].maxhold );
+
g_evmap_max++;
} else {
pnd_log ( pndn_warning, "WARNING! Key '%s' is not handled by pndevmapperd yet! Skipping.", k );
} else if ( strncmp ( k, "battery.", 8 ) == 0 ) {
// not consumed here, skip silently
+ } else if ( strncmp ( k, "battery_charge.", 15 ) == 0 ) {
+ // not consumed here, skip silently
+
} else {
// uhhh
pnd_log ( pndn_warning, "Unknown config key '%s'; skipping.\n", k );
b_shutdown = pnd_conf_get_as_int ( evmaph, "battery.shutdown_threshold" );
pnd_log ( pndn_rem, "Battery shutdown threshold set to %u", b_shutdown );
}
+ if ( pnd_conf_get_as_int ( evmaph, "battery.shutdown_delay" ) != PND_CONF_BADNUM ) {
+ b_shutdelay = pnd_conf_get_as_int ( evmaph, "battery.shutdown_delay" );
+ pnd_log ( pndn_rem, "Battery shutdown delay set to %u", b_shutdelay );
+ }
if ( pnd_conf_get_as_char ( evmaph, "battery.shutdown_script" ) != NULL ) {
b_shutdown_script = strdup ( pnd_conf_get_as_char ( evmaph, "battery.shutdown_script" ) );
pnd_log ( pndn_rem, "Battery shutdown script set to %s", b_shutdown_script );
}
+ if ( pnd_conf_get_as_int ( evmaph, "battery_charge.enable" ) != PND_CONF_BADNUM ) {
+ bc_enable = pnd_conf_get_as_int ( evmaph, "battery_charge.enable" );
+ pnd_log ( pndn_rem, "Battery charge enable set to %u", bc_enable );
+ }
+ if ( pnd_conf_get_as_int ( evmaph, "battery_charge.stop_capacity" ) != PND_CONF_BADNUM ) {
+ bc_stopcap = pnd_conf_get_as_int ( evmaph, "battery_charge.stop_capacity" );
+ pnd_log ( pndn_rem, "Battery charge stop capacity set to %u", bc_stopcap );
+ }
+ if ( pnd_conf_get_as_int ( evmaph, "battery_charge.stop_current" ) != PND_CONF_BADNUM ) {
+ bc_stopcur = pnd_conf_get_as_int ( evmaph, "battery_charge.stop_current" );
+ pnd_log ( pndn_rem, "Battery charge stop current set to %u", bc_stopcur );
+ }
+ if ( pnd_conf_get_as_int ( evmaph, "battery_charge.start_capacity" ) != PND_CONF_BADNUM ) {
+ bc_startcap = pnd_conf_get_as_int ( evmaph, "battery_charge.start_capacity" );
+ pnd_log ( pndn_rem, "Battery charge start capacity set to %u", bc_startcap );
+ }
+ if ( pnd_conf_get_as_char ( evmaph, "battery_charge.devices" ) != NULL ) {
+ bc_charge_devices = strdup ( pnd_conf_get_as_char ( evmaph, "battery_charge.devices" ) );
+ pnd_log ( pndn_rem, "Battery charge devices set to %s", bc_charge_devices );
+ }
/* do we have anything to do?
*/
// try to locate the appropriate devices
int id;
- int fds [ 8 ] = { -1, -1, -1, -1, -1, -1, -1, -1 }; // 0 = keypad, 1 = gpio keys
- int imaxfd = 0;
for ( id = 0; ; id++ ) {
char fname[64];
pnd_log ( pndn_rem, "%s maps to %s\n", fname, name );
- if ( strcmp ( name, "omap_twl4030keypad" ) == 0 ) {
+ if ( strcmp ( name, PND_EVDEV_KEYPAD/*"omap_twl4030keypad"*/ ) == 0 ) {
fds [ 0 ] = fd;
} else if ( strcmp ( name, "gpio-keys" ) == 0) {
fds [ 1 ] = fd;
} else if ( strcmp ( name, "AT Translated Set 2 keyboard" ) == 0) { // for vmware, my dev environment
fds [ 0 ] = fd;
- } else if ( strcmp ( name, "triton2-pwrbutton" ) == 0) {
+ } else if ( strcmp ( name, PND_EVDEV_POWER/*"triton2-pwrbutton"*/ ) == 0) {
fds [ 2 ] = fd;
- } else if ( strcmp ( name, "ADS784x Touchscreen" ) == 0) {
+ } else if ( strcmp ( name, PND_EVDEV_TS/*"ADS784x Touchscreen"*/ ) == 0) {
fds [ 3 ] = fd;
- } else if ( strcmp ( name, "vsense66" ) == 0) {
+ } else if ( strcmp ( name, PND_EVDEV_NUB1/*"vsense66"*/ ) == 0) {
fds [ 4 ] = fd;
- } else if ( strcmp ( name, "vsense67" ) == 0) {
+ } else if ( strcmp ( name, PND_EVDEV_NUB1/*"vsense67"*/ ) == 0) {
fds [ 5 ] = fd;
} else {
pnd_log ( pndn_rem, "Ignoring unknown device '%s'\n", name );
int fd = -1, rd, ret;
fd_set fdset;
+ // set up fd list
FD_ZERO ( &fdset );
imaxfd = 0;
}
}
- ret = select ( imaxfd + 1, &fdset, NULL, NULL, NULL );
+ // figure out if we can block forever, or not
+ unsigned char do_block = 1;
+ struct timeval tv;
+ tv.tv_usec = 0;
+ tv.tv_sec = 1;
+
+ for ( i = i; i < g_evmap_max; i++ ) {
+ if ( g_evmap [ i ].keydown_time && g_evmap [ i ].maxhold ) {
+ do_block = 0;
+ break;
+ }
+ }
+
+ // wait for fd's or timeout
+ ret = select ( imaxfd + 1, &fdset, NULL, NULL, do_block ? NULL /* no timeout */ : &tv );
if ( ret == -1 ) {
pnd_log ( pndn_error, "ERROR! select(2) failed with: %s\n", strerror ( errno ) );
continue; // retry!
- }
- for ( i = 0; i < max_fd; i++ ) {
- if ( fds [ i ] != -1 && FD_ISSET ( fds [ i ], &fdset ) ) {
- fd = fds [ i ];
- } // fd is set?
- } // for
+ } else if ( ret == 0 ) { // select returned with timeout (no fd)
- /* buttons or keypad */
- rd = read ( fd, ev, sizeof(struct input_event) * 64 );
- if ( rd < (int) sizeof(struct input_event) ) {
- pnd_log ( pndn_error, "ERROR! read(2) input_event failed with: %s\n", strerror ( errno ) );
- break;
- }
+ // timeout occurred; should only happen when 1 or more keys are being held down and
+ // they're "maxhold" keys, so we have to see if their timer has passed
+ unsigned int now = time ( NULL );
+
+ for ( i = i; i < g_evmap_max; i++ ) {
+
+ if ( g_evmap [ i ].keydown_time &&
+ g_evmap [ i ].maxhold &&
+ now - g_evmap [ i ].keydown_time >= g_evmap [ i ].maxhold )
+ {
+ keycode_t *k = (keycode_t*) g_evmap [ i ].reqs;
+ dispatch_key ( k -> keycode, 0 /* key up */ );
+ }
+
+ } // for
+
+ } else { // an fd was fiddled with
- for (i = 0; i < rd / sizeof(struct input_event); i++ ) {
+ for ( i = 0; i < max_fd; i++ ) {
+ if ( fds [ i ] != -1 && FD_ISSET ( fds [ i ], &fdset ) ) {
+ fd = fds [ i ];
+ } // fd is set?
+ } // for
- if ( ev[i].type == EV_SYN ) {
- continue;
- } else if ( ev[i].type == EV_KEY ) {
+ /* buttons or keypad */
+ rd = read ( fd, ev, sizeof(struct input_event) * 64 );
+ if ( rd < (int) sizeof(struct input_event) ) {
+ pnd_log ( pndn_error, "ERROR! read(2) input_event failed with: %s\n", strerror ( errno ) );
+ break;
+ }
+
+ for (i = 0; i < rd / sizeof(struct input_event); i++ ) {
+
+ if ( ev[i].type == EV_SYN ) {
+ continue;
+ } else if ( ev[i].type == EV_KEY ) {
- // do we even know about this key at all?
- keycode_t *p = keycodes;
- while ( p -> keycode != -1 ) {
- if ( p -> keycode == ev [ i ].code ) {
- break;
+ // do we even know about this key at all?
+ keycode_t *p = keycodes;
+ while ( p -> keycode != -1 ) {
+ if ( p -> keycode == ev [ i ].code ) {
+ break;
+ }
+ p++;
}
- p++;
- }
- // if we do, hand it off to dispatcher to look up if we actually do something with it
- if ( p -> keycode != -1 ) {
- pnd_log ( pndn_debug, "Key Event: key %s [%d] value %d\n", p -> keyname, p -> keycode, ev [ i ].value );
- dispatch_key ( p -> keycode, ev [ i ].value );
- } else {
- pnd_log ( pndn_warning, "Unknown Key Event: keycode %d value %d\n", ev [ i ].code, ev [ i ].value );
- }
+ // if we do, hand it off to dispatcher to look up if we actually do something with it
+ if ( p -> keycode != -1 ) {
+ if ( logall >= 0 ) {
+ pnd_log ( pndn_debug, "Key Event: key %s [%d] value %d\n", p -> keyname, p -> keycode, ev [ i ].value );
+ }
+ dispatch_key ( p -> keycode, ev [ i ].value );
+ } else {
+ if ( logall >= 0 ) {
+ pnd_log ( pndn_warning, "Unknown Key Event: keycode %d value %d\n", ev [ i ].code, ev [ i ].value );
+ }
+ }
- } else if ( ev[i].type == EV_SW ) {
+ } else if ( ev[i].type == EV_SW ) {
- // do we even know about this event at all?
- generic_event_t *p = generics;
- while ( p -> code != -1 ) {
- if ( p -> code == ev [ i ].code ) {
- break;
+ // do we even know about this event at all?
+ generic_event_t *p = generics;
+ while ( p -> code != -1 ) {
+ if ( p -> code == ev [ i ].code ) {
+ break;
+ }
+ p++;
+ }
+
+ // if we do, hand it off to dispatcher to look up if we actually do something with it
+ if ( p -> code != -1 ) {
+ if ( logall >= 0 ) {
+ pnd_log ( pndn_debug, "Generic Event: event %s [%d] value %d\n", p -> name, p -> code, ev [ i ].value );
+ }
+ dispatch_event ( p -> code, ev [ i ].value );
+ } else {
+ if ( logall >= 0 ) {
+ pnd_log ( pndn_warning, "Unknown Generic Event: code %d value %d\n", ev [ i ].code, ev [ i ].value );
+ }
}
- p++;
- }
- // if we do, hand it off to dispatcher to look up if we actually do something with it
- if ( p -> code != -1 ) {
- pnd_log ( pndn_debug, "Generic Event: event %s [%d] value %d\n", p -> name, p -> code, ev [ i ].value );
- dispatch_event ( p -> code, ev [ i ].value );
} else {
- pnd_log ( pndn_warning, "Unknown Generic Event: code %d value %d\n", ev [ i ].code, ev [ i ].value );
- }
+ pnd_log ( pndn_debug, "DEBUG: Unexpected event type %i received\n", ev[i].type );
+ continue;
+ } // type?
- } else {
- pnd_log ( pndn_debug, "DEBUG: Unexpected event type %i received\n", ev[i].type );
- continue;
- } // type?
+ } // for
- } // for
+ } // an fd was touched
} // while
// 2 - down again (hold)
// 0 - up (released)
- pnd_log ( pndn_rem, "Dispatching Key..\n" );
-
for ( i = 0; i < g_evmap_max; i++ ) {
if ( ( g_evmap [ i ].key_p ) &&
( ((keycode_t*) (g_evmap [ i ].reqs)) -> keycode == keycode ) &&
( g_evmap [ i ].script ) )
{
+ unsigned char invoke_it = 0;
// is this a keydown or a keyup?
if ( val == 1 ) {
// keydown
- g_evmap [ i ].keydown_time = time ( NULL );
- } else if ( val == 0 ) {
- // keyup
+ if ( g_evmap [ i ].maxhold == 0 ) {
- char holdtime [ 128 ];
- sprintf ( holdtime, "%d", (int)( time(NULL) - g_evmap [ i ].keydown_time ) );
+ // is this a special internally handled key, or normal key?
+ if ( g_evmap [ i ].script == (char*)FAKESCRIPT_TOGGLE_HOLD ) {
+ // handle this specially
+ fakescript_hold_on();
+ } else {
+ // normal key, with script to run
+ g_evmap [ i ].keydown_time = 0;
+ invoke_it = 1;
+ }
+
+ } else {
+ g_evmap [ i ].keydown_time = time ( NULL );
+ }
- if ( time ( NULL ) - g_evmap [ i ].last_trigger_time >= g_minimum_separation ) {
- int x;
+ } else if ( val == 2 && g_evmap [ i ].keydown_time ) {
+ // key is being held; we should check if max-hold is set
- g_evmap [ i ].last_trigger_time = time ( NULL );
+ if ( g_evmap [ i ].maxhold &&
+ time ( NULL ) - g_evmap [ i ].keydown_time >= g_evmap [ i ].maxhold )
+ {
+ invoke_it = 1;
+ }
- pnd_log ( pndn_rem, "Will attempt to invoke: %s %s\n", g_evmap [ i ].script, holdtime );
+ } else if ( val == 0 ) {
- if ( ( x = fork() ) < 0 ) {
- pnd_log ( pndn_error, "ERROR: Couldn't fork()\n" );
- exit ( -3 );
- }
+ if ( g_evmap [ i ].script == (char*)FAKESCRIPT_TOGGLE_HOLD ) {
+ // handle this specially
+ fakescript_hold_off();
+
+ } else if ( g_evmap [ i ].keydown_time ) {
+ // keyup (while key is down)
- if ( x == 0 ) {
- execl ( g_evmap [ i ].script, g_evmap [ i ].script, holdtime, (char*)NULL );
- pnd_log ( pndn_error, "ERROR: Couldn't exec(%s)\n", g_evmap [ i ].script );
- exit ( -4 );
+ if ( time ( NULL ) - g_evmap [ i ].last_trigger_time >= g_minimum_separation ) {
+ invoke_it = 1;
+ } else {
+ pnd_log ( pndn_rem, "Skipping invokation.. falls within minimum_separation threshold\n" );
}
- } else {
- pnd_log ( pndn_rem, "Skipping invokation.. falls within minimum_separation threshold\n" );
}
} // key up or down?
+ if ( invoke_it ) {
+
+ char holdtime [ 128 ];
+ sprintf ( holdtime, "%d", (int)( time(NULL) - g_evmap [ i ].keydown_time ) );
+ pnd_log ( pndn_rem, "Will attempt to invoke: %s %s\n", g_evmap [ i ].script, holdtime );
+
+ // state
+ g_evmap [ i ].keydown_time = 0; // clear the keydown-ness
+ g_evmap [ i ].last_trigger_time = time ( NULL );
+
+ // invocation
+ int x;
+
+ if ( ( x = fork() ) < 0 ) {
+ pnd_log ( pndn_error, "ERROR: Couldn't fork()\n" );
+ exit ( -3 );
+ }
+
+ if ( x == 0 ) {
+ execl ( g_evmap [ i ].script, g_evmap [ i ].script, holdtime, (char*)NULL );
+ pnd_log ( pndn_error, "ERROR: Couldn't exec(%s)\n", g_evmap [ i ].script );
+ exit ( -4 );
+ }
+
+ } // invoke the script!
+
return;
} // found matching event for keycode
// sucks
return ( 0 );
}
-
+
return ( 1 );
}
pnd_log ( pndn_debug, "---[ SIGALRM ]---\n" );
+ static time_t last_charge_check, last_charge_worka;
int batlevel = pnd_device_get_battery_gauge_perc();
+ int uamps = 0;
+ time_t now;
+
+ pnd_device_get_charge_current ( &uamps );
if ( batlevel < 0 ) {
+#if 0
// couldn't read the battery level, so just assume low and make blinks?
batlevel = 4; // low, but not cause a shutdown
+#else
+ // couldn't read the battery level, so just assume ok!
+ batlevel = 50;
+#endif
}
// first -- are we critical yet? if so, shut down!
- if ( batlevel <= b_shutdown && b_shutdown_script ) {
- int x;
+ if ( batlevel <= b_shutdown && b_shutdown_script) {
- pnd_log ( pndn_error, "CRITICAL BATTERY LEVEL -- shutdown the system down! Invoke: %s\n", b_shutdown_script );
+ if ( uamps > 100 ) {
+ // critical battery, but charging, so relax.
+ b_warned = 0;
+ } else {
+ if (b_warned == 0) {
+ // Avoid warning again till re-powered
+ b_warned = 1;
+ int x;
+ pnd_log ( pndn_error, "Battery Current: %d\n", uamps );
+ pnd_log ( pndn_error, "CRITICAL BATTERY LEVEL -- shutdown the system down! Invoke: %s\n",
+ b_shutdown_script );
+
+ if ( ( x = fork() ) < 0 ) {
+ pnd_log ( pndn_error, "ERROR: Couldn't fork()\n" );
+ exit ( -3 );
+ }
+
+ if ( x == 0 ) {
+ char value [ 100 ];
+ sprintf ( value, "%d", b_shutdelay );
+ execl ( b_shutdown_script, b_shutdown_script, value, (char*)NULL );
+ pnd_log ( pndn_error, "ERROR: Couldn't exec(%s)\n", b_shutdown_script );
+ exit ( -4 );
+ }
+ }
+ } // charging
- if ( ( x = fork() ) < 0 ) {
- pnd_log ( pndn_error, "ERROR: Couldn't fork()\n" );
- exit ( -3 );
- }
+ }
- if ( x == 0 ) {
- execl ( b_shutdown_script, b_shutdown_script, (char*)NULL );
- pnd_log ( pndn_error, "ERROR: Couldn't exec(%s)\n", b_shutdown_script );
- exit ( -4 );
- }
+ // charge monitoring
+ now = time(NULL);
+ if ( bc_enable && bc_charge_devices != NULL && (unsigned int)(now - last_charge_check) > 60 ) {
+ int charge_enabled = pnd_device_get_charger_enable ( bc_charge_devices );
+ if ( charge_enabled < 0 )
+ pnd_log ( pndn_error, "ERROR: Couldn't read charger enable control\n" );
+ else {
+
+ if ( charge_enabled && batlevel >= bc_stopcap && 0 < uamps && uamps < bc_stopcur ) {
+ pnd_log ( pndn_debug, "Charge stop conditions reached, disabling charging\n" );
+ pnd_device_set_charger_enable ( bc_charge_devices, 0 );
+ }
+ else if ( !charge_enabled && batlevel <= bc_startcap ) {
+ pnd_log ( pndn_debug, "Charge start conditions reached, enabling charging\n" );
+ pnd_device_set_charger_enable ( bc_charge_devices, 1 );
+ }
+
+ // for some unknown reason it just stops charging randomly (happens once per week or so),
+ // and does not restart, resulting in a flat battery if machine is unattended.
+ // What seems to help here is writing to chip registers, we can do it here indirectly
+ // by writing to enable. Doing it occasionally should do no harm even with missing charger.
+ if ( batlevel <= bc_startcap && (unsigned int)(now - last_charge_worka) > 20*60 ) {
+ pnd_log ( pndn_debug, "Charge workaround trigger\n" );
+ pnd_device_set_charger_enable ( bc_charge_devices, 1 );
+ last_charge_worka = now;
+ }
+ }
+ last_charge_check = now;
}
// is battery warning already active?
// is user charging up? if so, stop blinking.
// perhaps we shoudl check if charger is connected, and not blink at all in that case..
- if ( batlevel > b_threshold + 1 /* allow for error in read */ ) {
+ if ( uamps > 0 ) {
+ //Re-arm warning
+ b_warned = 0;
pnd_log ( pndn_debug, "Battery is high again, flipping to non-blinker mode\n" );
b_active = 0;
set_next_alarm ( b_frequency, 0 );
- pnd_device_set_led_power_brightness ( 250 );
+ pnd_device_set_led_charger_brightness ( 250 );
return;
}
if ( b_active == 1 ) {
// turn LED on
pnd_log ( pndn_debug, "Blink on\n" );
- pnd_device_set_led_power_brightness ( 200 );
+ pnd_device_set_led_charger_brightness ( 200 );
// set timer to short duration
b_active = 2;
set_next_alarm ( 0, b_blinkdur );
} else if ( b_active == 2 ) {
// turn LED off
pnd_log ( pndn_debug, "Blink off\n" );
- pnd_device_set_led_power_brightness ( 10 );
+ pnd_device_set_led_charger_brightness ( 10 );
// back to longer duration
b_active = 1;
set_next_alarm ( b_blinkfreq, 0 );
}
// warning is off..
- if ( batlevel <= b_threshold ) {
+ if ( batlevel <= b_threshold && uamps < 0 ) {
// battery seems low, go to active mode
pnd_log ( pndn_debug, "Battery is low, flipping to blinker mode\n" );
b_active = 1;
return;
}
+
+void fakescript_hold_on ( void ) {
+ pnd_log ( pndn_rem, "HOLD is being enabled.\n" );
+
+ int i;
+ for ( i = 0; i < imaxfd; i++ ) {
+ ioctl ( fds [ i ], EVIOCGRAB, 1 /* enable */ );
+ }
+
+ return;
+}
+
+void fakescript_hold_off ( void ) {
+ pnd_log ( pndn_rem, "HOLD is being disabled.\n" );
+
+ int i;
+ for ( i = 0; i < imaxfd; i++ ) {
+ ioctl ( fds [ i ], EVIOCGRAB, 0 /* disable */ );
+ }
+
+ return;
+}