int apm_handle_event(struct pxa2x0_apm_softc *sc, u_int type) { struct apm_power_info power; int ret = 0; switch (type) { case APM_NOEVENT: ret = 1; break; case APM_CRIT_SUSPEND_REQ: DPRINTF(("suspend required immediately\n")); #if 0 /* XXX apmd would make us suspend again after resume. */ (void)apm_record_event(sc, type); #endif /* * We ignore APM_CRIT_RESUME and just suspend here as usual * to simplify the actual apm_get_event() implementation. */ apm_suspends++; ret = 1; break; case APM_USER_SUSPEND_REQ: case APM_SUSPEND_REQ: DPRINTF(("suspend requested\n")); if (apm_record_event(sc, type)) { DPRINTF(("suspend ourselves\n")); apm_suspends++; } break; case APM_POWER_CHANGE: DPRINTF(("power status change\n")); apm_power_info(sc, &power); if (power.battery_life != APM_BATT_LIFE_UNKNOWN && power.battery_life < cpu_apmwarn && (sc->sc_flags & SCFLAG_PRINT) != SCFLAG_NOPRINT && ((sc->sc_flags & SCFLAG_PRINT) != SCFLAG_PCTPRINT || sc->sc_batt_life != power.battery_life)) { sc->sc_batt_life = power.battery_life; apm_power_print(sc, &power); } apm_record_event(sc, type); break; case APM_BATTERY_LOW: DPRINTF(("Battery low!\n")); apm_battlow++; apm_record_event(sc, type); break; default: DPRINTF(("apm_handle_event: unsupported event, code %d\n", type)); } return (ret); }
static void apm_resume(struct apm_softc *sc, u_int event_type, u_int event_info) { if (sc->sc_power_state == PWR_RESUME) { #ifdef APMDEBUG aprint_debug_dev(sc->sc_dev, "apm_resume: already running?\n"); #endif return; } sc->sc_power_state = PWR_RESUME; #ifdef TIMER_FREQ /* * Some system requires its clock to be initialized after hybernation. */ initrtclock(TIMER_FREQ); #endif inittodr(time_second); if (!(sc->sc_hwflags & APM_F_DONT_RUN_HOOKS)) { splx(apm_spl); pmf_system_resume(PMF_Q_NONE); } apm_record_event(sc, event_type); }
void apm_resume(struct apm_softc *sc, struct apmregs *regs) { apm_resumes = APM_RESUME_HOLDOFF; /* lower bit in cx means pccard was powered down */ apm_record_event(sc, regs->bx); }
void stsec_sensors_update(void *vsc) { struct stsec_softc *sc = (struct stsec_softc *)vsc; int status, control, batl, bath; ulong batuv; struct ksensor *ks; uint i; #if NAPM > 0 struct apm_power_info old; uint cap_pct; #endif for (i = 0; i < nitems(sc->sc_sensors); i++) sc->sc_sensors[i].flags |= SENSOR_FINVALID; if (stsec_read(sc, ST7_STATUS, &status) != 0 || stsec_read(sc, ST7_CONTROL, &control) != 0 || stsec_read(sc, ST7_BATTERY_L, &batl) != 0 || stsec_read(sc, ST7_BATTERY_H, &bath) != 0) return; /* * Battery voltage is in 10/1024V units, in the 0-1023 range. */ batuv = ((ulong)STB_VALUE(bath, batl) * 10 * 1000000) / 1024; ks = &sc->sc_sensors[STSEC_SENSOR_AC_PRESENCE]; ks->value = !!ISSET(status, STS_AC_AVAILABLE); ks->flags &= ~SENSOR_FINVALID; /* * Old mobo design does not have a battery presence bit; the Linux * code decides there is no battery if the reported battery voltage * is too low, we'll do the same. */ ks = &sc->sc_sensors[STSEC_SENSOR_BATTERY_PRESENCE]; switch (gdium_revision) { case 0: if (ISSET(status, STS_AC_AVAILABLE)) ks->value = batuv > 500000; else ks->value = 1; break; default: ks->value = !!ISSET(status, STS_BATTERY_PRESENT); break; } ks->flags &= ~SENSOR_FINVALID; ks = &sc->sc_sensors[STSEC_SENSOR_BATTERY_STATE]; ks->value = !!ISSET(control, STC_CHARGE_ENABLE); ks->flags &= ~SENSOR_FINVALID; ks = &sc->sc_sensors[STSEC_SENSOR_BATTERY_VOLTAGE]; ks->value = (int64_t)batuv; ks->flags &= ~SENSOR_FINVALID; #if NAPM > 0 bcopy(&stsec_apmdata, &old, sizeof(old)); if (batuv < STSEC_BAT_MIN_VOLT) batuv = STSEC_BAT_MIN_VOLT; else if (batuv > STSEC_BAT_MAX_VOLT) batuv = STSEC_BAT_MAX_VOLT; cap_pct = (batuv - STSEC_BAT_MIN_VOLT) * 100 / (STSEC_BAT_MAX_VOLT - STSEC_BAT_MIN_VOLT); stsec_apmdata.battery_life = cap_pct; stsec_apmdata.ac_state = ISSET(status, STS_AC_AVAILABLE) ? APM_AC_ON : APM_AC_OFF; if (!sc->sc_sensors[STSEC_SENSOR_BATTERY_PRESENCE].value) { stsec_apmdata.battery_state = APM_BATTERY_ABSENT; stsec_apmdata.minutes_left = 0; stsec_apmdata.battery_life = 0; } else { if (ISSET(control, STC_CHARGE_ENABLE)) stsec_apmdata.battery_state = APM_BATT_CHARGING; /* XXX arbitrary */ else if (cap_pct < 10) stsec_apmdata.battery_state = APM_BATT_CRITICAL; else if (cap_pct > 60) stsec_apmdata.battery_state = APM_BATT_HIGH; else stsec_apmdata.battery_state = APM_BATT_LOW; stsec_apmdata.minutes_left = -1; /* unknown */ } if (old.ac_state != stsec_apmdata.ac_state) apm_record_event(APM_POWER_CHANGE, "AC power", stsec_apmdata.ac_state ? "restored" : "lost"); if (old.battery_state != stsec_apmdata.battery_state) apm_record_event(APM_POWER_CHANGE, "battery", BATTERY_STRING(stsec_apmdata.battery_state)); #endif }
int apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { struct pxa2x0_apm_softc *sc; struct apm_power_info *power; int error = 0; /* apm0 only */ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || !(sc = apm_cd.cd_devs[APMUNIT(dev)])) return (ENXIO); switch (cmd) { /* some ioctl names from linux */ case APM_IOC_STANDBY: if ((flag & FWRITE) == 0) error = EBADF; else apm_userstandbys++; break; case APM_IOC_SUSPEND: if ((flag & FWRITE) == 0) error = EBADF; else apm_suspends++; /* XXX */ break; case APM_IOC_PRN_CTL: if ((flag & FWRITE) == 0) error = EBADF; else { int flag = *(int *)data; DPRINTF(( "APM_IOC_PRN_CTL: %d\n", flag )); switch (flag) { case APM_PRINT_ON: /* enable printing */ sc->sc_flags &= ~SCFLAG_PRINT; break; case APM_PRINT_OFF: /* disable printing */ sc->sc_flags &= ~SCFLAG_PRINT; sc->sc_flags |= SCFLAG_NOPRINT; break; case APM_PRINT_PCT: /* disable some printing */ sc->sc_flags &= ~SCFLAG_PRINT; sc->sc_flags |= SCFLAG_PCTPRINT; break; default: error = EINVAL; break; } } break; case APM_IOC_DEV_CTL: if ((flag & FWRITE) == 0) error = EBADF; break; case APM_IOC_GETPOWER: power = (struct apm_power_info *)data; apm_power_info(sc, power); break; case APM_IOC_STANDBY_REQ: if ((flag & FWRITE) == 0) error = EBADF; else if (apm_record_event(sc, APM_USER_STANDBY_REQ)) error = EINVAL; /* ? */ break; case APM_IOC_SUSPEND_REQ: if ((flag & FWRITE) == 0) error = EBADF; else if (apm_record_event(sc, APM_USER_SUSPEND_REQ)) error = EINVAL; /* ? */ default: error = ENOTTY; } return (error); }
static void apm_event_handle(struct apm_softc *sc, u_int event_code, u_int event_info) { int error; const char *code; struct apm_power_info pi; switch (event_code) { case APM_USER_STANDBY_REQ: DPRINTF(APMDEBUG_EVENTS, ("apmev: user standby request\n")); if (apm_do_standby) { if (apm_op_inprog == 0 && apm_record_event(sc, event_code)) apm_userstandbys++; apm_op_inprog++; (void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie, APM_DEV_ALLDEVS, APM_LASTREQ_INPROG); } else { (void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie, APM_DEV_ALLDEVS, APM_LASTREQ_REJECTED); /* in case BIOS hates being spurned */ (*sc->sc_ops->aa_enable)(sc->sc_cookie, 1); } break; case APM_STANDBY_REQ: DPRINTF(APMDEBUG_EVENTS, ("apmev: system standby request\n")); if (apm_op_inprog) { DPRINTF(APMDEBUG_EVENTS | APMDEBUG_ANOM, ("damn fool BIOS did not wait for answer\n")); /* just give up the fight */ apm_damn_fool_bios = 1; } if (apm_do_standby) { if (apm_op_inprog == 0 && apm_record_event(sc, event_code)) apm_standbys++; apm_op_inprog++; (void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie, APM_DEV_ALLDEVS, APM_LASTREQ_INPROG); } else { (void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie, APM_DEV_ALLDEVS, APM_LASTREQ_REJECTED); /* in case BIOS hates being spurned */ (*sc->sc_ops->aa_enable)(sc->sc_cookie, 1); } break; case APM_USER_SUSPEND_REQ: DPRINTF(APMDEBUG_EVENTS, ("apmev: user suspend request\n")); if (apm_op_inprog == 0 && apm_record_event(sc, event_code)) apm_suspends++; apm_op_inprog++; (void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie, APM_DEV_ALLDEVS, APM_LASTREQ_INPROG); break; case APM_SUSPEND_REQ: DPRINTF(APMDEBUG_EVENTS, ("apmev: system suspend request\n")); if (apm_op_inprog) { DPRINTF(APMDEBUG_EVENTS | APMDEBUG_ANOM, ("damn fool BIOS did not wait for answer\n")); /* just give up the fight */ apm_damn_fool_bios = 1; } if (apm_op_inprog == 0 && apm_record_event(sc, event_code)) apm_suspends++; apm_op_inprog++; (void)(*sc->sc_ops->aa_set_powstate)(sc->sc_cookie, APM_DEV_ALLDEVS, APM_LASTREQ_INPROG); break; case APM_POWER_CHANGE: DPRINTF(APMDEBUG_EVENTS, ("apmev: power status change\n")); error = (*sc->sc_ops->aa_get_powstat)(sc->sc_cookie, 0, &pi); #ifdef APM_POWER_PRINT /* only print if nobody is catching events. */ if (error == 0 && (sc->sc_flags & (SCFLAG_OREAD|SCFLAG_OWRITE)) == 0) apm_power_print(sc, &pi); #else __USE(error); #endif apm_record_event(sc, event_code); break; case APM_NORMAL_RESUME: DPRINTF(APMDEBUG_EVENTS, ("apmev: resume system\n")); apm_resume(sc, event_code, event_info); break; case APM_CRIT_RESUME: DPRINTF(APMDEBUG_EVENTS, ("apmev: critical resume system")); apm_resume(sc, event_code, event_info); break; case APM_SYS_STANDBY_RESUME: DPRINTF(APMDEBUG_EVENTS, ("apmev: system standby resume\n")); apm_resume(sc, event_code, event_info); break; case APM_UPDATE_TIME: DPRINTF(APMDEBUG_EVENTS, ("apmev: update time\n")); apm_resume(sc, event_code, event_info); break; case APM_CRIT_SUSPEND_REQ: DPRINTF(APMDEBUG_EVENTS, ("apmev: critical system suspend\n")); apm_record_event(sc, event_code); apm_suspend(sc); break; case APM_BATTERY_LOW: DPRINTF(APMDEBUG_EVENTS, ("apmev: battery low\n")); apm_battlow++; apm_record_event(sc, event_code); break; case APM_CAP_CHANGE: DPRINTF(APMDEBUG_EVENTS, ("apmev: capability change\n")); if (apm_minver < 2) { DPRINTF(APMDEBUG_EVENTS, ("apm: unexpected event\n")); } else { u_int numbatts, capflags; (*sc->sc_ops->aa_get_capabilities)(sc->sc_cookie, &numbatts, &capflags); (*sc->sc_ops->aa_get_powstat)(sc->sc_cookie, 0, &pi); } break; default: switch (event_code >> 8) { case 0: code = "reserved system"; break; case 1: code = "reserved device"; break; case 2: code = "OEM defined"; break; default: code = "reserved"; break; } printf("APM: %s event code %x\n", code, event_code); } }
int apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { struct apm_softc *sc; struct apmregs regs; int error = 0; /* apm0 only */ if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 || !(sc = apm_cd.cd_devs[APMUNIT(dev)])) return ENXIO; rw_enter_write(&sc->sc_lock); switch (cmd) { /* some ioctl names from linux */ case APM_IOC_STANDBY: if ((flag & FWRITE) == 0) error = EBADF; else apm_userstandbys++; break; case APM_IOC_SUSPEND: if ((flag & FWRITE) == 0) error = EBADF; else apm_suspends++; break; case APM_IOC_PRN_CTL: if ((flag & FWRITE) == 0) error = EBADF; else { int flag = *(int *)data; DPRINTF(( "APM_IOC_PRN_CTL: %d\n", flag )); switch (flag) { case APM_PRINT_ON: /* enable printing */ sc->sc_flags &= ~SCFLAG_PRINT; break; case APM_PRINT_OFF: /* disable printing */ sc->sc_flags &= ~SCFLAG_PRINT; sc->sc_flags |= SCFLAG_NOPRINT; break; case APM_PRINT_PCT: /* disable some printing */ sc->sc_flags &= ~SCFLAG_PRINT; sc->sc_flags |= SCFLAG_PCTPRINT; break; default: error = EINVAL; break; } } break; case APM_IOC_DEV_CTL: if ((flag & FWRITE) == 0) error = EBADF; else { struct apm_ctl *actl = (struct apm_ctl *)data; bzero(®s, sizeof(regs)); if (!apmcall(APM_GET_POWER_STATE, actl->dev, ®s)) printf("%s: dev %04x state %04x\n", sc->sc_dev.dv_xname, dev, regs.cx); error = apm_set_powstate(actl->dev, actl->mode); } break; case APM_IOC_GETPOWER: if (apm_get_powstat(®s) == 0) { struct apm_power_info *powerp = (struct apm_power_info *)data; bzero(powerp, sizeof(*powerp)); if (BATT_LIFE(®s) != APM_BATT_LIFE_UNKNOWN) powerp->battery_life = BATT_LIFE(®s); powerp->ac_state = AC_STATE(®s); switch (apm_minver) { case 0: if (!(BATT_FLAGS(®s) & APM_BATT_FLAG_NOBATTERY)) powerp->battery_state = BATT_STATE(®s); break; case 1: default: if (BATT_FLAGS(®s) & APM_BATT_FLAG_HIGH) powerp->battery_state = APM_BATT_HIGH; else if (BATT_FLAGS(®s) & APM_BATT_FLAG_LOW) powerp->battery_state = APM_BATT_LOW; else if (BATT_FLAGS(®s) & APM_BATT_FLAG_CRITICAL) powerp->battery_state = APM_BATT_CRITICAL; else if (BATT_FLAGS(®s) & APM_BATT_FLAG_CHARGING) powerp->battery_state = APM_BATT_CHARGING; else if (BATT_FLAGS(®s) & APM_BATT_FLAG_NOBATTERY) powerp->battery_state = APM_BATTERY_ABSENT; else powerp->battery_state = APM_BATT_UNKNOWN; if (BATT_REM_VALID(®s)) { powerp->minutes_left = BATT_REMAINING(®s); if (sc->be_batt) powerp->minutes_left = swap16(powerp->minutes_left); } } } else { apm_perror("ioctl get power status", ®s); error = EIO; } break; case APM_IOC_STANDBY_REQ: if ((flag & FWRITE) == 0) error = EBADF; /* only fails if no one cares. apmd at least should */ else if (apm_record_event(sc, APM_USER_STANDBY_REQ)) error = EINVAL; /* ? */ break; case APM_IOC_SUSPEND_REQ: if ((flag & FWRITE) == 0) error = EBADF; /* only fails if no one cares. apmd at least should */ else if (apm_record_event(sc, APM_USER_SUSPEND_REQ)) error = EINVAL; /* ? */ break; default: error = ENOTTY; } rw_exit_write(&sc->sc_lock); return error; }
int apm_handle_event(struct apm_softc *sc, struct apmregs *regs) { struct apmregs nregs; int ret = 0; switch (regs->bx) { case APM_NOEVENT: ret++; break; case APM_USER_STANDBY_REQ: if (apm_resumes || apm_op_inprog) break; DPRINTF(("user wants STANDBY--fat chance\n")); apm_op_inprog++; if (apm_record_event(sc, regs->bx)) { DPRINTF(("standby ourselves\n")); apm_userstandbys++; } break; case APM_STANDBY_REQ: if (apm_resumes || apm_op_inprog) break; DPRINTF(("standby requested\n")); if (apm_standbys || apm_suspends) { DPRINTF(("premature standby\n")); apm_error++; ret++; } apm_op_inprog++; if (apm_record_event(sc, regs->bx)) { DPRINTF(("standby ourselves\n")); apm_standbys++; } break; case APM_USER_SUSPEND_REQ: if (apm_resumes || apm_op_inprog) break; DPRINTF(("user wants suspend--fat chance!\n")); apm_op_inprog++; if (apm_record_event(sc, regs->bx)) { DPRINTF(("suspend ourselves\n")); apm_suspends++; } break; case APM_SUSPEND_REQ: if (apm_resumes || apm_op_inprog) break; DPRINTF(("suspend requested\n")); if (apm_standbys || apm_suspends) { DPRINTF(("premature suspend\n")); apm_error++; ret++; } apm_op_inprog++; if (apm_record_event(sc, regs->bx)) { DPRINTF(("suspend ourselves\n")); apm_suspends++; } break; case APM_POWER_CHANGE: DPRINTF(("power status change\n")); apm_get_powstat(&nregs); apm_record_event(sc, regs->bx); break; case APM_NORMAL_RESUME: DPRINTF(("system resumed\n")); apm_resume(sc, regs); break; case APM_CRIT_RESUME: DPRINTF(("system resumed without us!\n")); apm_resume(sc, regs); break; case APM_SYS_STANDBY_RESUME: DPRINTF(("system standby resume\n")); apm_resume(sc, regs); break; case APM_UPDATE_TIME: DPRINTF(("update time, please\n")); inittodr(time_second); apm_record_event(sc, regs->bx); break; case APM_CRIT_SUSPEND_REQ: DPRINTF(("suspend required immediately\n")); apm_record_event(sc, regs->bx); apm_suspend(APM_SYS_SUSPEND); break; case APM_BATTERY_LOW: DPRINTF(("Battery low!\n")); apm_battlow++; apm_record_event(sc, regs->bx); break; case APM_CAPABILITY_CHANGE: DPRINTF(("capability change\n")); if (apm_minver < 2) { DPRINTF(("adult event\n")); } else { if (apmcall(APM_GET_CAPABILITIES, APM_DEV_APM_BIOS, &nregs) != 0) { apm_perror("get capabilities", &nregs); } else { apm_get_powstat(&nregs); } } break; default: { #ifdef APMDEBUG char *p; switch (regs->bx >> 8) { case 0: p = "reserved system"; break; case 1: p = "reserved device"; break; case 2: p = "OEM defined"; break; default:p = "reserved"; break; } #endif DPRINTF(("apm_handle_event: %s event, code %d\n", p, regs->bx)); } } return ret; }
void ykbec_refresh(void *arg) { struct ykbec_softc *sc = (struct ykbec_softc *)arg; u_int val, bat_charge, bat_status, charge_status, bat_state, power_flag; u_int cap_pct, fullcap; int current; #if NAPM > 0 struct apm_power_info old; #endif val = ykbec_read16(sc, REG_FAN_SPEED_HIGH) & 0xfffff; if (val != 0) { val = KB3310_FAN_SPEED_DIVIDER / val; sc->sc_sensor[YKBEC_FAN].value = val; CLR(sc->sc_sensor[YKBEC_FAN].flags, SENSOR_FINVALID); } else SET(sc->sc_sensor[YKBEC_FAN].flags, SENSOR_FINVALID); val = ykbec_read(sc, ECTEMP_CURRENT_REG); sc->sc_sensor[YKBEC_ITEMP].value = val * 1000000 + 273150000; fullcap = ykbec_read16(sc, REG_FULLCHG_CAP_HIGH); sc->sc_sensor[YKBEC_FCAP].value = fullcap * 1000; current = ykbec_read16(sc, REG_CURRENT_HIGH); /* sign extend short -> int, int -> int64 will be done next statement */ current |= -(current & 0x8000); sc->sc_sensor[YKBEC_BCURRENT].value = -1000 * current; sc->sc_sensor[YKBEC_BVOLT].value = ykbec_read16(sc, REG_VOLTAGE_HIGH) * 1000; val = ykbec_read16(sc, REG_TEMPERATURE_HIGH); sc->sc_sensor[YKBEC_BTEMP].value = val * 1000000 + 273150000; cap_pct = ykbec_read16(sc, REG_RELATIVE_CAT_HIGH); sc->sc_sensor[YKBEC_CAP].value = cap_pct * 1000; bat_charge = ykbec_read(sc, REG_BAT_CHARGE); bat_status = ykbec_read(sc, REG_BAT_STATUS); charge_status = ykbec_read(sc, REG_CHARGE_STATUS); bat_state = ykbec_read(sc, REG_BAT_STATE); power_flag = ykbec_read(sc, REG_POWER_FLAG); sc->sc_sensor[YKBEC_CHARGING].value = !!ISSET(bat_state, BAT_STATE_CHARGING); sc->sc_sensor[YKBEC_AC].value = !!ISSET(power_flag, POWER_FLAG_ADAPTER_IN); sc->sc_sensor[YKBEC_CAP].status = ISSET(bat_status, BAT_STATUS_BAT_LOW) ? SENSOR_S_CRIT : SENSOR_S_OK; #if NAPM > 0 bcopy(&ykbec_apmdata, &old, sizeof(old)); ykbec_apmdata.battery_life = cap_pct; ykbec_apmdata.ac_state = ISSET(power_flag, POWER_FLAG_ADAPTER_IN) ? APM_AC_ON : APM_AC_OFF; if (!ISSET(bat_status, BAT_STATUS_BAT_EXISTS)) { ykbec_apmdata.battery_state = APM_BATTERY_ABSENT; ykbec_apmdata.minutes_left = 0; ykbec_apmdata.battery_life = 0; } else { if (ISSET(bat_state, BAT_STATE_CHARGING)) ykbec_apmdata.battery_state = APM_BATT_CHARGING; else if (ISSET(bat_status, BAT_STATUS_BAT_LOW)) ykbec_apmdata.battery_state = APM_BATT_CRITICAL; /* XXX arbitrary */ else if (cap_pct > 60) ykbec_apmdata.battery_state = APM_BATT_HIGH; else ykbec_apmdata.battery_state = APM_BATT_LOW; /* if charging, current is positive */ if (ISSET(bat_state, BAT_STATE_CHARGING)) current = 0; else current = -current; /* XXX Yeeloong draw is about 1A */ if (current <= 0) current = 1000; /* XXX at 5?%, the Yeeloong shuts down */ if (cap_pct <= 5) cap_pct = 0; else cap_pct -= 5; fullcap = cap_pct * 60 * fullcap / 100; ykbec_apmdata.minutes_left = fullcap / current; } if (old.ac_state != ykbec_apmdata.ac_state) apm_record_event(APM_POWER_CHANGE, "AC power", ykbec_apmdata.ac_state ? "restored" : "lost"); if (old.battery_state != ykbec_apmdata.battery_state) apm_record_event(APM_POWER_CHANGE, "battery", BATTERY_STRING(ykbec_apmdata.battery_state)); #endif }