diff options
Diffstat (limited to 'firmware/target/hosted/sonynwz/power-nwz.c')
-rw-r--r-- | firmware/target/hosted/sonynwz/power-nwz.c | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/firmware/target/hosted/sonynwz/power-nwz.c b/firmware/target/hosted/sonynwz/power-nwz.c new file mode 100644 index 0000000000..a5b19d6ead --- /dev/null +++ b/firmware/target/hosted/sonynwz/power-nwz.c @@ -0,0 +1,208 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2016 Amaury Pouly + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "system.h" +#include "power-nwz.h" +#include "button-target.h" +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <string.h> +#include <sys/reboot.h> + +static int power_fd = -1; /* file descriptor */ + +void power_init(void) +{ + power_fd = open(NWZ_POWER_DEV, O_RDWR); +} + +void power_close(void) +{ + close(power_fd); +} + +int nwz_power_get_status(void) +{ + int status; + if(ioctl(power_fd, NWZ_POWER_GET_STATUS, &status) < 0) + return -1; + return status; +} + +static int nwz_power_adval_to_mv(int adval, int ad_base) +{ + if(adval == -1) + return -1; + /* the AD base corresponds to the millivolt value if adval was 255 */ + return (adval * ad_base) / 255; +} + +int nwz_power_get_vbus_adval(void) +{ + int status; + if(ioctl(power_fd, NWZ_POWER_GET_VBUS_ADVAL, &status) < 0) + return -1; + return status; +} + +int nwz_power_get_vbus_voltage(void) +{ + return nwz_power_adval_to_mv(nwz_power_get_vbus_adval(), NWZ_POWER_AD_BASE_VBUS); +} + +int nwz_power_get_vbus_limit(void) +{ + int status; + if(ioctl(power_fd, NWZ_POWER_GET_VBUS_LIMIT, &status) < 0) + return -1; + return status; +} + +int nwz_power_get_charge_switch(void) +{ + int status; + if(ioctl(power_fd, NWZ_POWER_GET_CHARGE_SWITCH, &status) < 0) + return -1; + return status; +} + +int nwz_power_get_charge_current(void) +{ + int status; + if(ioctl(power_fd, NWZ_POWER_GET_CHARGE_CURRENT, &status) < 0) + return -1; + return status; +} + +int nwz_power_get_battery_gauge(void) +{ + int status; + if(ioctl(power_fd, NWZ_POWER_GET_BAT_GAUGE, &status) < 0) + return -1; + return status; +} + +int nwz_power_get_battery_adval(void) +{ + int status; + if(ioctl(power_fd, NWZ_POWER_GET_BAT_ADVAL, &status) < 0) + return -1; + return status; +} + +int nwz_power_get_battery_voltage(void) +{ + return nwz_power_adval_to_mv(nwz_power_get_battery_adval(), NWZ_POWER_AD_BASE_VBAT); +} + +int nwz_power_get_vbat_adval(void) +{ + int status; + if(ioctl(power_fd, NWZ_POWER_GET_VBAT_ADVAL, &status) < 0) + return -1; + return status; +} + +int nwz_power_get_vbat_voltage(void) +{ + return nwz_power_adval_to_mv(nwz_power_get_vbat_adval(), NWZ_POWER_AD_BASE_VBAT); +} + +int nwz_power_get_sample_count(void) +{ + int status; + if(ioctl(power_fd, NWZ_POWER_GET_SAMPLE_COUNT, &status) < 0) + return -1; + return status; +} + +int nwz_power_get_vsys_adval(void) +{ + int status; + if(ioctl(power_fd, NWZ_POWER_GET_VSYS_ADVAL, &status) < 0) + return -1; + return status; +} + +int nwz_power_get_vsys_voltage(void) +{ + return nwz_power_adval_to_mv(nwz_power_get_vsys_adval(), NWZ_POWER_AD_BASE_VSYS); +} + +int nwz_power_get_acc_charge_mode(void) +{ + int status; + if(ioctl(power_fd, NWZ_POWER_GET_ACCESSARY_CHARGE_MODE, &status) < 0) + return -1; + return status; +} + +int nwz_power_is_fully_charged(void) +{ + int status; + if(ioctl(power_fd, NWZ_POWER_IS_FULLY_CHARGED, &status) < 0) + return -1; + return status; +} + +static int write_string_to_file(const char *file, const char *msg) +{ + int fd = open(file, O_WRONLY); + if(fd < 0) + return -1; + const int len = strlen(msg); + int res = write(fd, msg, len); + close(fd); + return res == len ? 0 : -1; +} + +int do_nwz_power_suspend(void) +{ + /* older devices use /proc/pm, while the new one use the standard sys file */ + if(write_string_to_file("/proc/pm", "S3") == 0) + return 0; + return write_string_to_file("/sys/power/state", "mem"); +} + +int nwz_power_suspend(void) +{ + int ret = do_nwz_power_suspend(); + /* the button driver tracks button status using events, but the kernel does + * not generate an event if a key is changed during suspend, so make sure we + * reload as much information as possible */ + nwz_button_reload_after_suspend(); + return ret; +} + +int nwz_power_shutdown(void) +{ + sync(); /* man page advises to sync to avoid data loss */ + return reboot(RB_POWER_OFF); +} + +int nwz_power_restart(void) +{ + sync(); /* man page advises to sync to avoid data loss */ + return reboot(RB_AUTOBOOT); +} |