/* * Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "common/cmd/cmd_util.h" #include "cmd_axp.h" #include "pm/pm.h" #include "driver/component/axp/axp.h" #include "driver/component/axp/axp_common.h" #include "driver/component/axp/axp_power_supply.h" #include "driver/chip/hal_gpio.h" #ifdef CONFIG_AXP_CORE #ifndef ARRAY_SIZE #define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) #endif static enum cmd_status cmd_axp_write_reg_exec(char *cmd) { uint32_t cnt, reg, val; int ret = 0; cnt = cmd_sscanf(cmd, "%x %x", ®, &val); if (cnt != 2) { CMD_AXP_ERR("invalid param number %d\r\n", cnt); return CMD_STATUS_INVALID_ARG; } CMD_AXP_DBG("r=%d v=%d\r\n", reg, val); ret = axp_write_reg(reg, val); if (ret < 0) { CMD_AXP_ERR("axp write reg error\r\n"); return CMD_STATUS_FAIL; } return CMD_STATUS_OK; } static enum cmd_status cmd_axp_read_reg_exec(char *cmd) { uint32_t reg, cnt; uint8_t val; int ret = 0; cnt = cmd_sscanf(cmd, "%x", ®); if (cnt != 1) { CMD_AXP_ERR("invalid param number %d\r\n", cnt); return CMD_STATUS_INVALID_ARG; } ret = axp_read_reg((uint8_t)reg, &val); if (ret < 0) { CMD_AXP_ERR("axp read reg error\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_DBG("val = 0x%x\r\n", val); return CMD_STATUS_OK; } static enum cmd_status cmd_axp_set_voltage_exec(char *cmd) { char name[64]; uint32_t cnt; int ret = 0; int voltage = 0, onoff = 0; cnt = cmd_sscanf(cmd, "%s %d %d", name, &voltage, &onoff); if (cnt != 3) { CMD_AXP_ERR("invalid param number %d\r\n", cnt); return CMD_STATUS_INVALID_ARG; } CMD_AXP_DBG("name %s,voltage %d,onoff %d\r\n", name, voltage, onoff); ret = axp_set_voltage(name, voltage, onoff); if (ret < 0) { CMD_AXP_ERR("axp set voltage error\r\n"); return CMD_STATUS_FAIL; } return CMD_STATUS_OK; } static enum cmd_status cmd_axp_get_voltage_exec(char *cmd) { char name[64]; uint32_t cnt; int voltage = 0; int ret = 0; cnt = cmd_sscanf(cmd, "%s", name); if (cnt != 1) { CMD_AXP_ERR("invalid param number %d\r\n", cnt); return CMD_STATUS_INVALID_ARG; } ret = axp_get_voltage(name, &voltage); if (ret < 0) { CMD_AXP_ERR("axp get voltage error\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_DBG("name %s,voltage %d\r\n", name, voltage); return CMD_STATUS_OK; } static enum cmd_status cmd_axp_close_all_power_exec(char *cmd) { int ret = 0; ret = axp_poweroff(); if (ret < 0) { CMD_AXP_ERR("axp poweroff error\r\n"); return CMD_STATUS_FAIL; } return CMD_STATUS_OK; } static enum cmd_status cmd_axp_open_all_power_exec(char *cmd) { int ret = 0; ret = axp_poweron(false); if (ret < 0) { CMD_AXP_ERR("axp poweron error\r\n"); return CMD_STATUS_FAIL; } return CMD_STATUS_OK; } static enum cmd_status cmd_axp_get_poweron_source_exec(char *cmd) { enum axp_boot_source poweron_source = axp_get_poweron_source(); switch (poweron_source) { case AXP_BOOT_SOURCE_BUTTON: CMD_AXP_DBG("poweron source is button\r\n"); break; case AXP_BOOT_SOURCE_IRQ_LOW: CMD_AXP_DBG("poweron source is irq\r\n"); break; case AXP_BOOT_SOURCE_VBUS_USB: CMD_AXP_DBG("poweron source is vbus\r\n"); break; case AXP_BOOT_SOURCE_CHARGER: CMD_AXP_DBG("poweron source is charger\r\n"); break; case AXP_BOOT_SOURCE_BATTERY: CMD_AXP_DBG("poweron source is battery\r\n"); break; case AXP_BOOT_SOURCE_UNKOWN: CMD_AXP_DBG("poweron source is unknow\r\n"); break; } return CMD_STATUS_OK; } static enum cmd_status cmd_axp_set_vbus_voltage_exec(char *cmd) { uint32_t cnt; int ret = 0; int voltage = 0; cnt = cmd_sscanf(cmd, "%d", &voltage); if (cnt != 1) { CMD_AXP_ERR("invalid param number %d\r\n", cnt); return CMD_STATUS_INVALID_ARG; } ret = axp_set_vbus_vol_limit(voltage); if (ret < 0) { CMD_AXP_ERR("axp set voltage limit error\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_DBG("voltage %d\r\n", voltage); return CMD_STATUS_OK; } static enum cmd_status cmd_axp_get_vbus_voltage_exec(char *cmd) { int ret = 0; int voltage = 0; ret = axp_get_vbus_vol_limit(&voltage); if (ret < 0) { CMD_AXP_ERR("axp get vbus voltage limit error\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_DBG("get vbus voltage limit %d mv\r\n", voltage); return CMD_STATUS_OK; } static enum cmd_status cmd_axp_dump_whole_reg(char *cmd) { axp_dump_whole_reg(); return CMD_STATUS_OK; } static enum cmd_status cmd_axp_get_bat_property(char *cmd) { int ret; union power_supply_propval *val = malloc(128); if (NULL == val) { CMD_AXP_ERR("%s, malloc memory error\r\n", __func__); return -1; } memset(val, 0x00, 128); /* 获取电池状态,返回值:int,1:电池存在,0:电池不存在 */ ret = axp_get_battery_property(POWER_SUPPLY_PROP_PRESENT, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery preset failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery present: %d\r\n", val->intval); /* 获取电池电压,返回值:int: unit uV;*/ ret = axp_get_battery_property(POWER_SUPPLY_PROP_VOLTAGE_NOW, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery voltage failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery voltage: %d\r\n", val->intval); /* 获取电池的容量,返回值:int */ ret = axp_get_battery_property(POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery energy_full_design failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery energy_full_design: %d\r\n", val->intval); /* 获取电池充电状态:返回值:str * charging * discharging * not_charging * charged_full * */ ret = axp_get_battery_property(POWER_SUPPLY_PROP_STATUS, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery charger status failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery charger status: %s\r\n", val->strval); /* 获取电池设置的低电量警告值,返回值:int unit%*/ ret = axp_get_battery_property(POWER_SUPPLY_PROP_CAPACITY_ALERT_MIN, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery capacity_alert min failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery capacity_alert min: %d\r\n", val->intval); /* 获取电池温度,返回值:int --unit degree celsius*/ ret = axp_get_battery_property(POWER_SUPPLY_PROP_TEMP, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery temp failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery temp: %d\r\n", val->intval); /* 获取电池当前剩余容量:返回值:int */ ret = axp_get_battery_property(POWER_SUPPLY_PROP_CAPACITY, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery status failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery capacity: %d\r\n", val->intval); /* 获取设置电池的低温关机:返回值:int --得到的值要除于10 * 和POWER_SUPPLY_PROP_TEMP_AMBIENT_MIN一样 */ ret = axp_get_battery_property(POWER_SUPPLY_PROP_TEMP_ALERT_MIN, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery status failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery TEMP_ALERT_MIN: %d\r\n", val->intval); /* 获取设置电池的高温关机值:返回值:int --除于10为度 * 和POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX一样 */ ret = axp_get_battery_property(POWER_SUPPLY_PROP_TEMP_ALERT_MAX, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery status failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery TEMP_ALERT_MAX: %d\r\n", val->intval); /* 获取设置电池的低温停冲值:返回值:int -- 除于10为度 * 和POWER_SUPPLY_PROP_TEMP_MIN一样 */ ret = axp_get_battery_property(POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MIN, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery TEMP_AMBIENT_ALERT_MIN failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery TEMP_AMBIENT_ALERT_MIN: %d\r\n", val->intval); /* 获取设置电池的高温停冲值:返回值:int --除于10为度 * 和POWER_SUPPLY_PROP_TEMP_ALERT_MAX一样 */ ret = axp_get_battery_property(POWER_SUPPLY_PROP_TEMP_AMBIENT_ALERT_MAX, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery TEMP_AMBIENT_ALERT_MAX failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery TEMP_AMBIENT_ALERT_MAX: %d\r\n", val->intval); /* 获取电池的放电时间,返回int --unit second */ ret = axp_get_battery_property(POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery TIME_TO_EMPTY failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery TIME_TO_EMPTY: %d\r\n", val->intval); /* 获取还有多少时间充满电,返回int --unit second*/ ret = axp_get_battery_property(POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery T2F failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery chargering T2F: %d\r\n", val->intval); /* 获取目前使用哪款BMU的名字,返回str */ ret = axp_get_battery_property(POWER_SUPPLY_PROP_MANUFACTURER, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery nmu name failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery bmu name: %s\r\n", val->strval); /* 获取电池目前的电流电量等级,返回str * 充满为full * 大于80返回high * 大于warning_level1为normal * 大于warning_level2为low * 低于warning_level2为严重返回:critical * */ ret = axp_get_battery_property(POWER_SUPPLY_PROP_CAPACITY_LEVEL, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery capacity_level failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery capacity_level: %s\r\n", val->strval); /* 获取VBUS的状态,返回值:int 1:online 0: not online */ ret = axp_get_battery_property(POWER_SUPPLY_PROP_ONLINE, val); if (ret < 0) { CMD_AXP_ERR("axp get Battery VBUS status failed\r\n"); return CMD_STATUS_FAIL; } CMD_AXP_INF("Battery VBUS STATUS: %d\r\n", val->intval); return CMD_STATUS_OK; } /* axp cmd_axp_set_charger_cur cur_val * cur_val step:25mv or 100mv * */ static enum cmd_status cmd_axp_set_charger_cur(char *cmd) { int val, cnt; int ret = 0; cnt = cmd_sscanf(cmd, "%d", &val); if (cnt != 1) { CMD_AXP_ERR("invalid param number %d\r\n", cnt); return CMD_STATUS_INVALID_ARG; } ret = axp_set_charger_cur(val); if (ret < 0) { CMD_AXP_ERR("set charger current error\r\n"); } return CMD_STATUS_OK; } static enum cmd_status cmd_axp_get_charger_cur(char *cmd) { int val; val = axp_get_charger_cur(); if (val < 0) { CMD_AXP_ERR("get charger current error\r\n"); } else { CMD_AXP_INF("get charger current limit %d\r\n", val); } return CMD_STATUS_OK; } static const struct cmd_data g_axp_cmds[] = { { "poweron", cmd_axp_open_all_power_exec}, { "poweroff", cmd_axp_close_all_power_exec}, { "read_reg", cmd_axp_read_reg_exec}, { "write_reg", cmd_axp_write_reg_exec}, { "set_voltage", cmd_axp_set_voltage_exec}, { "get_voltage", cmd_axp_get_voltage_exec}, { "get_poweron_source", cmd_axp_get_poweron_source_exec}, { "set_vbus_voltage_limit", cmd_axp_set_vbus_voltage_exec}, { "get_vbus_voltage_limit", cmd_axp_get_vbus_voltage_exec}, { "dump_reg", cmd_axp_dump_whole_reg}, { "get_bat_status", cmd_axp_get_bat_property}, { "set_charger_cur", cmd_axp_set_charger_cur}, { "get_charger_cur", cmd_axp_get_charger_cur}, }; enum cmd_status cmd_axp_exec(char *cmd) { return cmd_exec(cmd, g_axp_cmds, cmd_nitems(g_axp_cmds)); } #endif /* CONFIG_AXP_CORE */