18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Power supply driver for testing. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright 2010 Anton Vorontsov <cbouatmailru@gmail.com> 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Dynamic module parameter code from the Virtual Battery Driver 88c2ecf20Sopenharmony_ci * Copyright (C) 2008 Pylone, Inc. 98c2ecf20Sopenharmony_ci * By: Masashi YOKOTA <yokota@pylone.jp> 108c2ecf20Sopenharmony_ci * Originally found here: 118c2ecf20Sopenharmony_ci * http://downloads.pylone.jp/src/virtual_battery/virtual_battery-0.0.1.tar.bz2 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include <linux/kernel.h> 158c2ecf20Sopenharmony_ci#include <linux/module.h> 168c2ecf20Sopenharmony_ci#include <linux/power_supply.h> 178c2ecf20Sopenharmony_ci#include <linux/errno.h> 188c2ecf20Sopenharmony_ci#include <linux/delay.h> 198c2ecf20Sopenharmony_ci#include <generated/utsrelease.h> 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_cienum test_power_id { 228c2ecf20Sopenharmony_ci TEST_AC, 238c2ecf20Sopenharmony_ci TEST_BATTERY, 248c2ecf20Sopenharmony_ci TEST_USB, 258c2ecf20Sopenharmony_ci TEST_POWER_NUM, 268c2ecf20Sopenharmony_ci}; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_cistatic int ac_online = 1; 298c2ecf20Sopenharmony_cistatic int usb_online = 1; 308c2ecf20Sopenharmony_cistatic int battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 318c2ecf20Sopenharmony_cistatic int battery_health = POWER_SUPPLY_HEALTH_GOOD; 328c2ecf20Sopenharmony_cistatic int battery_present = 1; /* true */ 338c2ecf20Sopenharmony_cistatic int battery_technology = POWER_SUPPLY_TECHNOLOGY_LION; 348c2ecf20Sopenharmony_cistatic int battery_capacity = 50; 358c2ecf20Sopenharmony_cistatic int battery_voltage = 3300; 368c2ecf20Sopenharmony_cistatic int battery_charge_counter = -1000; 378c2ecf20Sopenharmony_cistatic int battery_current = -1600; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cistatic bool module_initialized; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic int test_power_get_ac_property(struct power_supply *psy, 428c2ecf20Sopenharmony_ci enum power_supply_property psp, 438c2ecf20Sopenharmony_ci union power_supply_propval *val) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci switch (psp) { 468c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_ONLINE: 478c2ecf20Sopenharmony_ci val->intval = ac_online; 488c2ecf20Sopenharmony_ci break; 498c2ecf20Sopenharmony_ci default: 508c2ecf20Sopenharmony_ci return -EINVAL; 518c2ecf20Sopenharmony_ci } 528c2ecf20Sopenharmony_ci return 0; 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistatic int test_power_get_usb_property(struct power_supply *psy, 568c2ecf20Sopenharmony_ci enum power_supply_property psp, 578c2ecf20Sopenharmony_ci union power_supply_propval *val) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci switch (psp) { 608c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_ONLINE: 618c2ecf20Sopenharmony_ci val->intval = usb_online; 628c2ecf20Sopenharmony_ci break; 638c2ecf20Sopenharmony_ci default: 648c2ecf20Sopenharmony_ci return -EINVAL; 658c2ecf20Sopenharmony_ci } 668c2ecf20Sopenharmony_ci return 0; 678c2ecf20Sopenharmony_ci} 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistatic int test_power_get_battery_property(struct power_supply *psy, 708c2ecf20Sopenharmony_ci enum power_supply_property psp, 718c2ecf20Sopenharmony_ci union power_supply_propval *val) 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci switch (psp) { 748c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_MODEL_NAME: 758c2ecf20Sopenharmony_ci val->strval = "Test battery"; 768c2ecf20Sopenharmony_ci break; 778c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_MANUFACTURER: 788c2ecf20Sopenharmony_ci val->strval = "Linux"; 798c2ecf20Sopenharmony_ci break; 808c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_SERIAL_NUMBER: 818c2ecf20Sopenharmony_ci val->strval = UTS_RELEASE; 828c2ecf20Sopenharmony_ci break; 838c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_STATUS: 848c2ecf20Sopenharmony_ci val->intval = battery_status; 858c2ecf20Sopenharmony_ci break; 868c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CHARGE_TYPE: 878c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; 888c2ecf20Sopenharmony_ci break; 898c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_HEALTH: 908c2ecf20Sopenharmony_ci val->intval = battery_health; 918c2ecf20Sopenharmony_ci break; 928c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_PRESENT: 938c2ecf20Sopenharmony_ci val->intval = battery_present; 948c2ecf20Sopenharmony_ci break; 958c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_TECHNOLOGY: 968c2ecf20Sopenharmony_ci val->intval = battery_technology; 978c2ecf20Sopenharmony_ci break; 988c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CAPACITY_LEVEL: 998c2ecf20Sopenharmony_ci val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; 1008c2ecf20Sopenharmony_ci break; 1018c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CAPACITY: 1028c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CHARGE_NOW: 1038c2ecf20Sopenharmony_ci val->intval = battery_capacity; 1048c2ecf20Sopenharmony_ci break; 1058c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CHARGE_COUNTER: 1068c2ecf20Sopenharmony_ci val->intval = battery_charge_counter; 1078c2ecf20Sopenharmony_ci break; 1088c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 1098c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CHARGE_FULL: 1108c2ecf20Sopenharmony_ci val->intval = 100; 1118c2ecf20Sopenharmony_ci break; 1128c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 1138c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: 1148c2ecf20Sopenharmony_ci val->intval = 3600; 1158c2ecf20Sopenharmony_ci break; 1168c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_TEMP: 1178c2ecf20Sopenharmony_ci val->intval = 26; 1188c2ecf20Sopenharmony_ci break; 1198c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_VOLTAGE_NOW: 1208c2ecf20Sopenharmony_ci val->intval = battery_voltage; 1218c2ecf20Sopenharmony_ci break; 1228c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CURRENT_AVG: 1238c2ecf20Sopenharmony_ci case POWER_SUPPLY_PROP_CURRENT_NOW: 1248c2ecf20Sopenharmony_ci val->intval = battery_current; 1258c2ecf20Sopenharmony_ci break; 1268c2ecf20Sopenharmony_ci default: 1278c2ecf20Sopenharmony_ci pr_info("%s: some properties deliberately report errors.\n", 1288c2ecf20Sopenharmony_ci __func__); 1298c2ecf20Sopenharmony_ci return -EINVAL; 1308c2ecf20Sopenharmony_ci } 1318c2ecf20Sopenharmony_ci return 0; 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic enum power_supply_property test_power_ac_props[] = { 1358c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_ONLINE, 1368c2ecf20Sopenharmony_ci}; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_cistatic enum power_supply_property test_power_battery_props[] = { 1398c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_STATUS, 1408c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CHARGE_TYPE, 1418c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_HEALTH, 1428c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_PRESENT, 1438c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_TECHNOLOGY, 1448c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 1458c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CHARGE_FULL, 1468c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CHARGE_NOW, 1478c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CHARGE_COUNTER, 1488c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CAPACITY, 1498c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CAPACITY_LEVEL, 1508c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 1518c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, 1528c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_MODEL_NAME, 1538c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_MANUFACTURER, 1548c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_SERIAL_NUMBER, 1558c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_TEMP, 1568c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_VOLTAGE_NOW, 1578c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CURRENT_AVG, 1588c2ecf20Sopenharmony_ci POWER_SUPPLY_PROP_CURRENT_NOW, 1598c2ecf20Sopenharmony_ci}; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_cistatic char *test_power_ac_supplied_to[] = { 1628c2ecf20Sopenharmony_ci "test_battery", 1638c2ecf20Sopenharmony_ci}; 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_cistatic struct power_supply *test_power_supplies[TEST_POWER_NUM]; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_cistatic const struct power_supply_desc test_power_desc[] = { 1688c2ecf20Sopenharmony_ci [TEST_AC] = { 1698c2ecf20Sopenharmony_ci .name = "test_ac", 1708c2ecf20Sopenharmony_ci .type = POWER_SUPPLY_TYPE_MAINS, 1718c2ecf20Sopenharmony_ci .properties = test_power_ac_props, 1728c2ecf20Sopenharmony_ci .num_properties = ARRAY_SIZE(test_power_ac_props), 1738c2ecf20Sopenharmony_ci .get_property = test_power_get_ac_property, 1748c2ecf20Sopenharmony_ci }, 1758c2ecf20Sopenharmony_ci [TEST_BATTERY] = { 1768c2ecf20Sopenharmony_ci .name = "test_battery", 1778c2ecf20Sopenharmony_ci .type = POWER_SUPPLY_TYPE_BATTERY, 1788c2ecf20Sopenharmony_ci .properties = test_power_battery_props, 1798c2ecf20Sopenharmony_ci .num_properties = ARRAY_SIZE(test_power_battery_props), 1808c2ecf20Sopenharmony_ci .get_property = test_power_get_battery_property, 1818c2ecf20Sopenharmony_ci }, 1828c2ecf20Sopenharmony_ci [TEST_USB] = { 1838c2ecf20Sopenharmony_ci .name = "test_usb", 1848c2ecf20Sopenharmony_ci .type = POWER_SUPPLY_TYPE_USB, 1858c2ecf20Sopenharmony_ci .properties = test_power_ac_props, 1868c2ecf20Sopenharmony_ci .num_properties = ARRAY_SIZE(test_power_ac_props), 1878c2ecf20Sopenharmony_ci .get_property = test_power_get_usb_property, 1888c2ecf20Sopenharmony_ci }, 1898c2ecf20Sopenharmony_ci}; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_cistatic const struct power_supply_config test_power_configs[] = { 1928c2ecf20Sopenharmony_ci { 1938c2ecf20Sopenharmony_ci /* test_ac */ 1948c2ecf20Sopenharmony_ci .supplied_to = test_power_ac_supplied_to, 1958c2ecf20Sopenharmony_ci .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to), 1968c2ecf20Sopenharmony_ci }, { 1978c2ecf20Sopenharmony_ci /* test_battery */ 1988c2ecf20Sopenharmony_ci }, { 1998c2ecf20Sopenharmony_ci /* test_usb */ 2008c2ecf20Sopenharmony_ci .supplied_to = test_power_ac_supplied_to, 2018c2ecf20Sopenharmony_ci .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to), 2028c2ecf20Sopenharmony_ci }, 2038c2ecf20Sopenharmony_ci}; 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_cistatic int __init test_power_init(void) 2068c2ecf20Sopenharmony_ci{ 2078c2ecf20Sopenharmony_ci int i; 2088c2ecf20Sopenharmony_ci int ret; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci BUILD_BUG_ON(TEST_POWER_NUM != ARRAY_SIZE(test_power_supplies)); 2118c2ecf20Sopenharmony_ci BUILD_BUG_ON(TEST_POWER_NUM != ARRAY_SIZE(test_power_configs)); 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) { 2148c2ecf20Sopenharmony_ci test_power_supplies[i] = power_supply_register(NULL, 2158c2ecf20Sopenharmony_ci &test_power_desc[i], 2168c2ecf20Sopenharmony_ci &test_power_configs[i]); 2178c2ecf20Sopenharmony_ci if (IS_ERR(test_power_supplies[i])) { 2188c2ecf20Sopenharmony_ci pr_err("%s: failed to register %s\n", __func__, 2198c2ecf20Sopenharmony_ci test_power_desc[i].name); 2208c2ecf20Sopenharmony_ci ret = PTR_ERR(test_power_supplies[i]); 2218c2ecf20Sopenharmony_ci goto failed; 2228c2ecf20Sopenharmony_ci } 2238c2ecf20Sopenharmony_ci } 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci module_initialized = true; 2268c2ecf20Sopenharmony_ci return 0; 2278c2ecf20Sopenharmony_cifailed: 2288c2ecf20Sopenharmony_ci while (--i >= 0) 2298c2ecf20Sopenharmony_ci power_supply_unregister(test_power_supplies[i]); 2308c2ecf20Sopenharmony_ci return ret; 2318c2ecf20Sopenharmony_ci} 2328c2ecf20Sopenharmony_cimodule_init(test_power_init); 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_cistatic void __exit test_power_exit(void) 2358c2ecf20Sopenharmony_ci{ 2368c2ecf20Sopenharmony_ci int i; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci /* Let's see how we handle changes... */ 2398c2ecf20Sopenharmony_ci ac_online = 0; 2408c2ecf20Sopenharmony_ci usb_online = 0; 2418c2ecf20Sopenharmony_ci battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 2428c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) 2438c2ecf20Sopenharmony_ci power_supply_changed(test_power_supplies[i]); 2448c2ecf20Sopenharmony_ci pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n", 2458c2ecf20Sopenharmony_ci __func__); 2468c2ecf20Sopenharmony_ci ssleep(10); 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) 2498c2ecf20Sopenharmony_ci power_supply_unregister(test_power_supplies[i]); 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci module_initialized = false; 2528c2ecf20Sopenharmony_ci} 2538c2ecf20Sopenharmony_cimodule_exit(test_power_exit); 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci#define MAX_KEYLENGTH 256 2588c2ecf20Sopenharmony_cistruct battery_property_map { 2598c2ecf20Sopenharmony_ci int value; 2608c2ecf20Sopenharmony_ci char const *key; 2618c2ecf20Sopenharmony_ci}; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_cistatic struct battery_property_map map_ac_online[] = { 2648c2ecf20Sopenharmony_ci { 0, "off" }, 2658c2ecf20Sopenharmony_ci { 1, "on" }, 2668c2ecf20Sopenharmony_ci { -1, NULL }, 2678c2ecf20Sopenharmony_ci}; 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_cistatic struct battery_property_map map_status[] = { 2708c2ecf20Sopenharmony_ci { POWER_SUPPLY_STATUS_CHARGING, "charging" }, 2718c2ecf20Sopenharmony_ci { POWER_SUPPLY_STATUS_DISCHARGING, "discharging" }, 2728c2ecf20Sopenharmony_ci { POWER_SUPPLY_STATUS_NOT_CHARGING, "not-charging" }, 2738c2ecf20Sopenharmony_ci { POWER_SUPPLY_STATUS_FULL, "full" }, 2748c2ecf20Sopenharmony_ci { -1, NULL }, 2758c2ecf20Sopenharmony_ci}; 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_cistatic struct battery_property_map map_health[] = { 2788c2ecf20Sopenharmony_ci { POWER_SUPPLY_HEALTH_GOOD, "good" }, 2798c2ecf20Sopenharmony_ci { POWER_SUPPLY_HEALTH_OVERHEAT, "overheat" }, 2808c2ecf20Sopenharmony_ci { POWER_SUPPLY_HEALTH_DEAD, "dead" }, 2818c2ecf20Sopenharmony_ci { POWER_SUPPLY_HEALTH_OVERVOLTAGE, "overvoltage" }, 2828c2ecf20Sopenharmony_ci { POWER_SUPPLY_HEALTH_UNSPEC_FAILURE, "failure" }, 2838c2ecf20Sopenharmony_ci { -1, NULL }, 2848c2ecf20Sopenharmony_ci}; 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_cistatic struct battery_property_map map_present[] = { 2878c2ecf20Sopenharmony_ci { 0, "false" }, 2888c2ecf20Sopenharmony_ci { 1, "true" }, 2898c2ecf20Sopenharmony_ci { -1, NULL }, 2908c2ecf20Sopenharmony_ci}; 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_cistatic struct battery_property_map map_technology[] = { 2938c2ecf20Sopenharmony_ci { POWER_SUPPLY_TECHNOLOGY_NiMH, "NiMH" }, 2948c2ecf20Sopenharmony_ci { POWER_SUPPLY_TECHNOLOGY_LION, "LION" }, 2958c2ecf20Sopenharmony_ci { POWER_SUPPLY_TECHNOLOGY_LIPO, "LIPO" }, 2968c2ecf20Sopenharmony_ci { POWER_SUPPLY_TECHNOLOGY_LiFe, "LiFe" }, 2978c2ecf20Sopenharmony_ci { POWER_SUPPLY_TECHNOLOGY_NiCd, "NiCd" }, 2988c2ecf20Sopenharmony_ci { POWER_SUPPLY_TECHNOLOGY_LiMn, "LiMn" }, 2998c2ecf20Sopenharmony_ci { -1, NULL }, 3008c2ecf20Sopenharmony_ci}; 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_cistatic int map_get_value(struct battery_property_map *map, const char *key, 3048c2ecf20Sopenharmony_ci int def_val) 3058c2ecf20Sopenharmony_ci{ 3068c2ecf20Sopenharmony_ci char buf[MAX_KEYLENGTH]; 3078c2ecf20Sopenharmony_ci int cr; 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci strncpy(buf, key, MAX_KEYLENGTH); 3108c2ecf20Sopenharmony_ci buf[MAX_KEYLENGTH-1] = '\0'; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci cr = strnlen(buf, MAX_KEYLENGTH) - 1; 3138c2ecf20Sopenharmony_ci if (cr < 0) 3148c2ecf20Sopenharmony_ci return def_val; 3158c2ecf20Sopenharmony_ci if (buf[cr] == '\n') 3168c2ecf20Sopenharmony_ci buf[cr] = '\0'; 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci while (map->key) { 3198c2ecf20Sopenharmony_ci if (strncasecmp(map->key, buf, MAX_KEYLENGTH) == 0) 3208c2ecf20Sopenharmony_ci return map->value; 3218c2ecf20Sopenharmony_ci map++; 3228c2ecf20Sopenharmony_ci } 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci return def_val; 3258c2ecf20Sopenharmony_ci} 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_cistatic const char *map_get_key(struct battery_property_map *map, int value, 3298c2ecf20Sopenharmony_ci const char *def_key) 3308c2ecf20Sopenharmony_ci{ 3318c2ecf20Sopenharmony_ci while (map->key) { 3328c2ecf20Sopenharmony_ci if (map->value == value) 3338c2ecf20Sopenharmony_ci return map->key; 3348c2ecf20Sopenharmony_ci map++; 3358c2ecf20Sopenharmony_ci } 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci return def_key; 3388c2ecf20Sopenharmony_ci} 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_cistatic inline void signal_power_supply_changed(struct power_supply *psy) 3418c2ecf20Sopenharmony_ci{ 3428c2ecf20Sopenharmony_ci if (module_initialized) 3438c2ecf20Sopenharmony_ci power_supply_changed(psy); 3448c2ecf20Sopenharmony_ci} 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_cistatic int param_set_ac_online(const char *key, const struct kernel_param *kp) 3478c2ecf20Sopenharmony_ci{ 3488c2ecf20Sopenharmony_ci ac_online = map_get_value(map_ac_online, key, ac_online); 3498c2ecf20Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_AC]); 3508c2ecf20Sopenharmony_ci return 0; 3518c2ecf20Sopenharmony_ci} 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_cistatic int param_get_ac_online(char *buffer, const struct kernel_param *kp) 3548c2ecf20Sopenharmony_ci{ 3558c2ecf20Sopenharmony_ci return sprintf(buffer, "%s\n", 3568c2ecf20Sopenharmony_ci map_get_key(map_ac_online, ac_online, "unknown")); 3578c2ecf20Sopenharmony_ci} 3588c2ecf20Sopenharmony_ci 3598c2ecf20Sopenharmony_cistatic int param_set_usb_online(const char *key, const struct kernel_param *kp) 3608c2ecf20Sopenharmony_ci{ 3618c2ecf20Sopenharmony_ci usb_online = map_get_value(map_ac_online, key, usb_online); 3628c2ecf20Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_USB]); 3638c2ecf20Sopenharmony_ci return 0; 3648c2ecf20Sopenharmony_ci} 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_cistatic int param_get_usb_online(char *buffer, const struct kernel_param *kp) 3678c2ecf20Sopenharmony_ci{ 3688c2ecf20Sopenharmony_ci return sprintf(buffer, "%s\n", 3698c2ecf20Sopenharmony_ci map_get_key(map_ac_online, usb_online, "unknown")); 3708c2ecf20Sopenharmony_ci} 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_cistatic int param_set_battery_status(const char *key, 3738c2ecf20Sopenharmony_ci const struct kernel_param *kp) 3748c2ecf20Sopenharmony_ci{ 3758c2ecf20Sopenharmony_ci battery_status = map_get_value(map_status, key, battery_status); 3768c2ecf20Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 3778c2ecf20Sopenharmony_ci return 0; 3788c2ecf20Sopenharmony_ci} 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_cistatic int param_get_battery_status(char *buffer, const struct kernel_param *kp) 3818c2ecf20Sopenharmony_ci{ 3828c2ecf20Sopenharmony_ci return sprintf(buffer, "%s\n", 3838c2ecf20Sopenharmony_ci map_get_key(map_ac_online, battery_status, "unknown")); 3848c2ecf20Sopenharmony_ci} 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_cistatic int param_set_battery_health(const char *key, 3878c2ecf20Sopenharmony_ci const struct kernel_param *kp) 3888c2ecf20Sopenharmony_ci{ 3898c2ecf20Sopenharmony_ci battery_health = map_get_value(map_health, key, battery_health); 3908c2ecf20Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 3918c2ecf20Sopenharmony_ci return 0; 3928c2ecf20Sopenharmony_ci} 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_cistatic int param_get_battery_health(char *buffer, const struct kernel_param *kp) 3958c2ecf20Sopenharmony_ci{ 3968c2ecf20Sopenharmony_ci return sprintf(buffer, "%s\n", 3978c2ecf20Sopenharmony_ci map_get_key(map_ac_online, battery_health, "unknown")); 3988c2ecf20Sopenharmony_ci} 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_cistatic int param_set_battery_present(const char *key, 4018c2ecf20Sopenharmony_ci const struct kernel_param *kp) 4028c2ecf20Sopenharmony_ci{ 4038c2ecf20Sopenharmony_ci battery_present = map_get_value(map_present, key, battery_present); 4048c2ecf20Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_AC]); 4058c2ecf20Sopenharmony_ci return 0; 4068c2ecf20Sopenharmony_ci} 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_cistatic int param_get_battery_present(char *buffer, 4098c2ecf20Sopenharmony_ci const struct kernel_param *kp) 4108c2ecf20Sopenharmony_ci{ 4118c2ecf20Sopenharmony_ci return sprintf(buffer, "%s\n", 4128c2ecf20Sopenharmony_ci map_get_key(map_ac_online, battery_present, "unknown")); 4138c2ecf20Sopenharmony_ci} 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_cistatic int param_set_battery_technology(const char *key, 4168c2ecf20Sopenharmony_ci const struct kernel_param *kp) 4178c2ecf20Sopenharmony_ci{ 4188c2ecf20Sopenharmony_ci battery_technology = map_get_value(map_technology, key, 4198c2ecf20Sopenharmony_ci battery_technology); 4208c2ecf20Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 4218c2ecf20Sopenharmony_ci return 0; 4228c2ecf20Sopenharmony_ci} 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_cistatic int param_get_battery_technology(char *buffer, 4258c2ecf20Sopenharmony_ci const struct kernel_param *kp) 4268c2ecf20Sopenharmony_ci{ 4278c2ecf20Sopenharmony_ci return sprintf(buffer, "%s\n", 4288c2ecf20Sopenharmony_ci map_get_key(map_ac_online, battery_technology, 4298c2ecf20Sopenharmony_ci "unknown")); 4308c2ecf20Sopenharmony_ci} 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_cistatic int param_set_battery_capacity(const char *key, 4338c2ecf20Sopenharmony_ci const struct kernel_param *kp) 4348c2ecf20Sopenharmony_ci{ 4358c2ecf20Sopenharmony_ci int tmp; 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ci if (1 != sscanf(key, "%d", &tmp)) 4388c2ecf20Sopenharmony_ci return -EINVAL; 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci battery_capacity = tmp; 4418c2ecf20Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 4428c2ecf20Sopenharmony_ci return 0; 4438c2ecf20Sopenharmony_ci} 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_ci#define param_get_battery_capacity param_get_int 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_cistatic int param_set_battery_voltage(const char *key, 4488c2ecf20Sopenharmony_ci const struct kernel_param *kp) 4498c2ecf20Sopenharmony_ci{ 4508c2ecf20Sopenharmony_ci int tmp; 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_ci if (1 != sscanf(key, "%d", &tmp)) 4538c2ecf20Sopenharmony_ci return -EINVAL; 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci battery_voltage = tmp; 4568c2ecf20Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 4578c2ecf20Sopenharmony_ci return 0; 4588c2ecf20Sopenharmony_ci} 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci#define param_get_battery_voltage param_get_int 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_cistatic int param_set_battery_charge_counter(const char *key, 4638c2ecf20Sopenharmony_ci const struct kernel_param *kp) 4648c2ecf20Sopenharmony_ci{ 4658c2ecf20Sopenharmony_ci int tmp; 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_ci if (1 != sscanf(key, "%d", &tmp)) 4688c2ecf20Sopenharmony_ci return -EINVAL; 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci battery_charge_counter = tmp; 4718c2ecf20Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 4728c2ecf20Sopenharmony_ci return 0; 4738c2ecf20Sopenharmony_ci} 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci#define param_get_battery_charge_counter param_get_int 4768c2ecf20Sopenharmony_ci 4778c2ecf20Sopenharmony_cistatic int param_set_battery_current(const char *key, 4788c2ecf20Sopenharmony_ci const struct kernel_param *kp) 4798c2ecf20Sopenharmony_ci{ 4808c2ecf20Sopenharmony_ci int tmp; 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_ci if (1 != sscanf(key, "%d", &tmp)) 4838c2ecf20Sopenharmony_ci return -EINVAL; 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci battery_current = tmp; 4868c2ecf20Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 4878c2ecf20Sopenharmony_ci return 0; 4888c2ecf20Sopenharmony_ci} 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci#define param_get_battery_current param_get_int 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_cistatic const struct kernel_param_ops param_ops_ac_online = { 4938c2ecf20Sopenharmony_ci .set = param_set_ac_online, 4948c2ecf20Sopenharmony_ci .get = param_get_ac_online, 4958c2ecf20Sopenharmony_ci}; 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_cistatic const struct kernel_param_ops param_ops_usb_online = { 4988c2ecf20Sopenharmony_ci .set = param_set_usb_online, 4998c2ecf20Sopenharmony_ci .get = param_get_usb_online, 5008c2ecf20Sopenharmony_ci}; 5018c2ecf20Sopenharmony_ci 5028c2ecf20Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_status = { 5038c2ecf20Sopenharmony_ci .set = param_set_battery_status, 5048c2ecf20Sopenharmony_ci .get = param_get_battery_status, 5058c2ecf20Sopenharmony_ci}; 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_present = { 5088c2ecf20Sopenharmony_ci .set = param_set_battery_present, 5098c2ecf20Sopenharmony_ci .get = param_get_battery_present, 5108c2ecf20Sopenharmony_ci}; 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_technology = { 5138c2ecf20Sopenharmony_ci .set = param_set_battery_technology, 5148c2ecf20Sopenharmony_ci .get = param_get_battery_technology, 5158c2ecf20Sopenharmony_ci}; 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_health = { 5188c2ecf20Sopenharmony_ci .set = param_set_battery_health, 5198c2ecf20Sopenharmony_ci .get = param_get_battery_health, 5208c2ecf20Sopenharmony_ci}; 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_capacity = { 5238c2ecf20Sopenharmony_ci .set = param_set_battery_capacity, 5248c2ecf20Sopenharmony_ci .get = param_get_battery_capacity, 5258c2ecf20Sopenharmony_ci}; 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_voltage = { 5288c2ecf20Sopenharmony_ci .set = param_set_battery_voltage, 5298c2ecf20Sopenharmony_ci .get = param_get_battery_voltage, 5308c2ecf20Sopenharmony_ci}; 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_charge_counter = { 5338c2ecf20Sopenharmony_ci .set = param_set_battery_charge_counter, 5348c2ecf20Sopenharmony_ci .get = param_get_battery_charge_counter, 5358c2ecf20Sopenharmony_ci}; 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_current = { 5388c2ecf20Sopenharmony_ci .set = param_set_battery_current, 5398c2ecf20Sopenharmony_ci .get = param_get_battery_current, 5408c2ecf20Sopenharmony_ci}; 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_ci#define param_check_ac_online(name, p) __param_check(name, p, void); 5438c2ecf20Sopenharmony_ci#define param_check_usb_online(name, p) __param_check(name, p, void); 5448c2ecf20Sopenharmony_ci#define param_check_battery_status(name, p) __param_check(name, p, void); 5458c2ecf20Sopenharmony_ci#define param_check_battery_present(name, p) __param_check(name, p, void); 5468c2ecf20Sopenharmony_ci#define param_check_battery_technology(name, p) __param_check(name, p, void); 5478c2ecf20Sopenharmony_ci#define param_check_battery_health(name, p) __param_check(name, p, void); 5488c2ecf20Sopenharmony_ci#define param_check_battery_capacity(name, p) __param_check(name, p, void); 5498c2ecf20Sopenharmony_ci#define param_check_battery_voltage(name, p) __param_check(name, p, void); 5508c2ecf20Sopenharmony_ci#define param_check_battery_charge_counter(name, p) __param_check(name, p, void); 5518c2ecf20Sopenharmony_ci#define param_check_battery_current(name, p) __param_check(name, p, void); 5528c2ecf20Sopenharmony_ci 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_cimodule_param(ac_online, ac_online, 0644); 5558c2ecf20Sopenharmony_ciMODULE_PARM_DESC(ac_online, "AC charging state <on|off>"); 5568c2ecf20Sopenharmony_ci 5578c2ecf20Sopenharmony_cimodule_param(usb_online, usb_online, 0644); 5588c2ecf20Sopenharmony_ciMODULE_PARM_DESC(usb_online, "USB charging state <on|off>"); 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_cimodule_param(battery_status, battery_status, 0644); 5618c2ecf20Sopenharmony_ciMODULE_PARM_DESC(battery_status, 5628c2ecf20Sopenharmony_ci "battery status <charging|discharging|not-charging|full>"); 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_cimodule_param(battery_present, battery_present, 0644); 5658c2ecf20Sopenharmony_ciMODULE_PARM_DESC(battery_present, 5668c2ecf20Sopenharmony_ci "battery presence state <good|overheat|dead|overvoltage|failure>"); 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_cimodule_param(battery_technology, battery_technology, 0644); 5698c2ecf20Sopenharmony_ciMODULE_PARM_DESC(battery_technology, 5708c2ecf20Sopenharmony_ci "battery technology <NiMH|LION|LIPO|LiFe|NiCd|LiMn>"); 5718c2ecf20Sopenharmony_ci 5728c2ecf20Sopenharmony_cimodule_param(battery_health, battery_health, 0644); 5738c2ecf20Sopenharmony_ciMODULE_PARM_DESC(battery_health, 5748c2ecf20Sopenharmony_ci "battery health state <good|overheat|dead|overvoltage|failure>"); 5758c2ecf20Sopenharmony_ci 5768c2ecf20Sopenharmony_cimodule_param(battery_capacity, battery_capacity, 0644); 5778c2ecf20Sopenharmony_ciMODULE_PARM_DESC(battery_capacity, "battery capacity (percentage)"); 5788c2ecf20Sopenharmony_ci 5798c2ecf20Sopenharmony_cimodule_param(battery_voltage, battery_voltage, 0644); 5808c2ecf20Sopenharmony_ciMODULE_PARM_DESC(battery_voltage, "battery voltage (millivolts)"); 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_cimodule_param(battery_charge_counter, battery_charge_counter, 0644); 5838c2ecf20Sopenharmony_ciMODULE_PARM_DESC(battery_charge_counter, 5848c2ecf20Sopenharmony_ci "battery charge counter (microampere-hours)"); 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_cimodule_param(battery_current, battery_current, 0644); 5878c2ecf20Sopenharmony_ciMODULE_PARM_DESC(battery_current, "battery current (milliampere)"); 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Power supply driver for testing"); 5908c2ecf20Sopenharmony_ciMODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); 5918c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 592