162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Power supply driver for testing. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2010 Anton Vorontsov <cbouatmailru@gmail.com> 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Dynamic module parameter code from the Virtual Battery Driver 862306a36Sopenharmony_ci * Copyright (C) 2008 Pylone, Inc. 962306a36Sopenharmony_ci * By: Masashi YOKOTA <yokota@pylone.jp> 1062306a36Sopenharmony_ci * Originally found here: 1162306a36Sopenharmony_ci * http://downloads.pylone.jp/src/virtual_battery/virtual_battery-0.0.1.tar.bz2 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/kernel.h> 1562306a36Sopenharmony_ci#include <linux/module.h> 1662306a36Sopenharmony_ci#include <linux/power_supply.h> 1762306a36Sopenharmony_ci#include <linux/errno.h> 1862306a36Sopenharmony_ci#include <linux/delay.h> 1962306a36Sopenharmony_ci#include <generated/utsrelease.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cienum test_power_id { 2262306a36Sopenharmony_ci TEST_AC, 2362306a36Sopenharmony_ci TEST_BATTERY, 2462306a36Sopenharmony_ci TEST_USB, 2562306a36Sopenharmony_ci TEST_POWER_NUM, 2662306a36Sopenharmony_ci}; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistatic int ac_online = 1; 2962306a36Sopenharmony_cistatic int usb_online = 1; 3062306a36Sopenharmony_cistatic int battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 3162306a36Sopenharmony_cistatic int battery_health = POWER_SUPPLY_HEALTH_GOOD; 3262306a36Sopenharmony_cistatic int battery_present = 1; /* true */ 3362306a36Sopenharmony_cistatic int battery_technology = POWER_SUPPLY_TECHNOLOGY_LION; 3462306a36Sopenharmony_cistatic int battery_capacity = 50; 3562306a36Sopenharmony_cistatic int battery_voltage = 3300; 3662306a36Sopenharmony_cistatic int battery_charge_counter = -1000; 3762306a36Sopenharmony_cistatic int battery_current = -1600; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic bool module_initialized; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_cistatic int test_power_get_ac_property(struct power_supply *psy, 4262306a36Sopenharmony_ci enum power_supply_property psp, 4362306a36Sopenharmony_ci union power_supply_propval *val) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci switch (psp) { 4662306a36Sopenharmony_ci case POWER_SUPPLY_PROP_ONLINE: 4762306a36Sopenharmony_ci val->intval = ac_online; 4862306a36Sopenharmony_ci break; 4962306a36Sopenharmony_ci default: 5062306a36Sopenharmony_ci return -EINVAL; 5162306a36Sopenharmony_ci } 5262306a36Sopenharmony_ci return 0; 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistatic int test_power_get_usb_property(struct power_supply *psy, 5662306a36Sopenharmony_ci enum power_supply_property psp, 5762306a36Sopenharmony_ci union power_supply_propval *val) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci switch (psp) { 6062306a36Sopenharmony_ci case POWER_SUPPLY_PROP_ONLINE: 6162306a36Sopenharmony_ci val->intval = usb_online; 6262306a36Sopenharmony_ci break; 6362306a36Sopenharmony_ci default: 6462306a36Sopenharmony_ci return -EINVAL; 6562306a36Sopenharmony_ci } 6662306a36Sopenharmony_ci return 0; 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistatic int test_power_get_battery_property(struct power_supply *psy, 7062306a36Sopenharmony_ci enum power_supply_property psp, 7162306a36Sopenharmony_ci union power_supply_propval *val) 7262306a36Sopenharmony_ci{ 7362306a36Sopenharmony_ci switch (psp) { 7462306a36Sopenharmony_ci case POWER_SUPPLY_PROP_MODEL_NAME: 7562306a36Sopenharmony_ci val->strval = "Test battery"; 7662306a36Sopenharmony_ci break; 7762306a36Sopenharmony_ci case POWER_SUPPLY_PROP_MANUFACTURER: 7862306a36Sopenharmony_ci val->strval = "Linux"; 7962306a36Sopenharmony_ci break; 8062306a36Sopenharmony_ci case POWER_SUPPLY_PROP_SERIAL_NUMBER: 8162306a36Sopenharmony_ci val->strval = UTS_RELEASE; 8262306a36Sopenharmony_ci break; 8362306a36Sopenharmony_ci case POWER_SUPPLY_PROP_STATUS: 8462306a36Sopenharmony_ci val->intval = battery_status; 8562306a36Sopenharmony_ci break; 8662306a36Sopenharmony_ci case POWER_SUPPLY_PROP_CHARGE_TYPE: 8762306a36Sopenharmony_ci val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; 8862306a36Sopenharmony_ci break; 8962306a36Sopenharmony_ci case POWER_SUPPLY_PROP_HEALTH: 9062306a36Sopenharmony_ci val->intval = battery_health; 9162306a36Sopenharmony_ci break; 9262306a36Sopenharmony_ci case POWER_SUPPLY_PROP_PRESENT: 9362306a36Sopenharmony_ci val->intval = battery_present; 9462306a36Sopenharmony_ci break; 9562306a36Sopenharmony_ci case POWER_SUPPLY_PROP_TECHNOLOGY: 9662306a36Sopenharmony_ci val->intval = battery_technology; 9762306a36Sopenharmony_ci break; 9862306a36Sopenharmony_ci case POWER_SUPPLY_PROP_CAPACITY_LEVEL: 9962306a36Sopenharmony_ci val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; 10062306a36Sopenharmony_ci break; 10162306a36Sopenharmony_ci case POWER_SUPPLY_PROP_CAPACITY: 10262306a36Sopenharmony_ci case POWER_SUPPLY_PROP_CHARGE_NOW: 10362306a36Sopenharmony_ci val->intval = battery_capacity; 10462306a36Sopenharmony_ci break; 10562306a36Sopenharmony_ci case POWER_SUPPLY_PROP_CHARGE_COUNTER: 10662306a36Sopenharmony_ci val->intval = battery_charge_counter; 10762306a36Sopenharmony_ci break; 10862306a36Sopenharmony_ci case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 10962306a36Sopenharmony_ci case POWER_SUPPLY_PROP_CHARGE_FULL: 11062306a36Sopenharmony_ci val->intval = 100; 11162306a36Sopenharmony_ci break; 11262306a36Sopenharmony_ci case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 11362306a36Sopenharmony_ci case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: 11462306a36Sopenharmony_ci val->intval = 3600; 11562306a36Sopenharmony_ci break; 11662306a36Sopenharmony_ci case POWER_SUPPLY_PROP_TEMP: 11762306a36Sopenharmony_ci val->intval = 26; 11862306a36Sopenharmony_ci break; 11962306a36Sopenharmony_ci case POWER_SUPPLY_PROP_VOLTAGE_NOW: 12062306a36Sopenharmony_ci val->intval = battery_voltage; 12162306a36Sopenharmony_ci break; 12262306a36Sopenharmony_ci case POWER_SUPPLY_PROP_CURRENT_AVG: 12362306a36Sopenharmony_ci case POWER_SUPPLY_PROP_CURRENT_NOW: 12462306a36Sopenharmony_ci val->intval = battery_current; 12562306a36Sopenharmony_ci break; 12662306a36Sopenharmony_ci default: 12762306a36Sopenharmony_ci pr_info("%s: some properties deliberately report errors.\n", 12862306a36Sopenharmony_ci __func__); 12962306a36Sopenharmony_ci return -EINVAL; 13062306a36Sopenharmony_ci } 13162306a36Sopenharmony_ci return 0; 13262306a36Sopenharmony_ci} 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cistatic enum power_supply_property test_power_ac_props[] = { 13562306a36Sopenharmony_ci POWER_SUPPLY_PROP_ONLINE, 13662306a36Sopenharmony_ci}; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_cistatic enum power_supply_property test_power_battery_props[] = { 13962306a36Sopenharmony_ci POWER_SUPPLY_PROP_STATUS, 14062306a36Sopenharmony_ci POWER_SUPPLY_PROP_CHARGE_TYPE, 14162306a36Sopenharmony_ci POWER_SUPPLY_PROP_HEALTH, 14262306a36Sopenharmony_ci POWER_SUPPLY_PROP_PRESENT, 14362306a36Sopenharmony_ci POWER_SUPPLY_PROP_TECHNOLOGY, 14462306a36Sopenharmony_ci POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 14562306a36Sopenharmony_ci POWER_SUPPLY_PROP_CHARGE_FULL, 14662306a36Sopenharmony_ci POWER_SUPPLY_PROP_CHARGE_NOW, 14762306a36Sopenharmony_ci POWER_SUPPLY_PROP_CHARGE_COUNTER, 14862306a36Sopenharmony_ci POWER_SUPPLY_PROP_CAPACITY, 14962306a36Sopenharmony_ci POWER_SUPPLY_PROP_CAPACITY_LEVEL, 15062306a36Sopenharmony_ci POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 15162306a36Sopenharmony_ci POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, 15262306a36Sopenharmony_ci POWER_SUPPLY_PROP_MODEL_NAME, 15362306a36Sopenharmony_ci POWER_SUPPLY_PROP_MANUFACTURER, 15462306a36Sopenharmony_ci POWER_SUPPLY_PROP_SERIAL_NUMBER, 15562306a36Sopenharmony_ci POWER_SUPPLY_PROP_TEMP, 15662306a36Sopenharmony_ci POWER_SUPPLY_PROP_VOLTAGE_NOW, 15762306a36Sopenharmony_ci POWER_SUPPLY_PROP_CURRENT_AVG, 15862306a36Sopenharmony_ci POWER_SUPPLY_PROP_CURRENT_NOW, 15962306a36Sopenharmony_ci}; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cistatic char *test_power_ac_supplied_to[] = { 16262306a36Sopenharmony_ci "test_battery", 16362306a36Sopenharmony_ci}; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic struct power_supply *test_power_supplies[TEST_POWER_NUM]; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_cistatic const struct power_supply_desc test_power_desc[] = { 16862306a36Sopenharmony_ci [TEST_AC] = { 16962306a36Sopenharmony_ci .name = "test_ac", 17062306a36Sopenharmony_ci .type = POWER_SUPPLY_TYPE_MAINS, 17162306a36Sopenharmony_ci .properties = test_power_ac_props, 17262306a36Sopenharmony_ci .num_properties = ARRAY_SIZE(test_power_ac_props), 17362306a36Sopenharmony_ci .get_property = test_power_get_ac_property, 17462306a36Sopenharmony_ci }, 17562306a36Sopenharmony_ci [TEST_BATTERY] = { 17662306a36Sopenharmony_ci .name = "test_battery", 17762306a36Sopenharmony_ci .type = POWER_SUPPLY_TYPE_BATTERY, 17862306a36Sopenharmony_ci .properties = test_power_battery_props, 17962306a36Sopenharmony_ci .num_properties = ARRAY_SIZE(test_power_battery_props), 18062306a36Sopenharmony_ci .get_property = test_power_get_battery_property, 18162306a36Sopenharmony_ci }, 18262306a36Sopenharmony_ci [TEST_USB] = { 18362306a36Sopenharmony_ci .name = "test_usb", 18462306a36Sopenharmony_ci .type = POWER_SUPPLY_TYPE_USB, 18562306a36Sopenharmony_ci .properties = test_power_ac_props, 18662306a36Sopenharmony_ci .num_properties = ARRAY_SIZE(test_power_ac_props), 18762306a36Sopenharmony_ci .get_property = test_power_get_usb_property, 18862306a36Sopenharmony_ci }, 18962306a36Sopenharmony_ci}; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_cistatic const struct power_supply_config test_power_configs[] = { 19262306a36Sopenharmony_ci { 19362306a36Sopenharmony_ci /* test_ac */ 19462306a36Sopenharmony_ci .supplied_to = test_power_ac_supplied_to, 19562306a36Sopenharmony_ci .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to), 19662306a36Sopenharmony_ci }, { 19762306a36Sopenharmony_ci /* test_battery */ 19862306a36Sopenharmony_ci }, { 19962306a36Sopenharmony_ci /* test_usb */ 20062306a36Sopenharmony_ci .supplied_to = test_power_ac_supplied_to, 20162306a36Sopenharmony_ci .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to), 20262306a36Sopenharmony_ci }, 20362306a36Sopenharmony_ci}; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_cistatic int __init test_power_init(void) 20662306a36Sopenharmony_ci{ 20762306a36Sopenharmony_ci int i; 20862306a36Sopenharmony_ci int ret; 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci BUILD_BUG_ON(TEST_POWER_NUM != ARRAY_SIZE(test_power_supplies)); 21162306a36Sopenharmony_ci BUILD_BUG_ON(TEST_POWER_NUM != ARRAY_SIZE(test_power_configs)); 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) { 21462306a36Sopenharmony_ci test_power_supplies[i] = power_supply_register(NULL, 21562306a36Sopenharmony_ci &test_power_desc[i], 21662306a36Sopenharmony_ci &test_power_configs[i]); 21762306a36Sopenharmony_ci if (IS_ERR(test_power_supplies[i])) { 21862306a36Sopenharmony_ci pr_err("%s: failed to register %s\n", __func__, 21962306a36Sopenharmony_ci test_power_desc[i].name); 22062306a36Sopenharmony_ci ret = PTR_ERR(test_power_supplies[i]); 22162306a36Sopenharmony_ci goto failed; 22262306a36Sopenharmony_ci } 22362306a36Sopenharmony_ci } 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci module_initialized = true; 22662306a36Sopenharmony_ci return 0; 22762306a36Sopenharmony_cifailed: 22862306a36Sopenharmony_ci while (--i >= 0) 22962306a36Sopenharmony_ci power_supply_unregister(test_power_supplies[i]); 23062306a36Sopenharmony_ci return ret; 23162306a36Sopenharmony_ci} 23262306a36Sopenharmony_cimodule_init(test_power_init); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_cistatic void __exit test_power_exit(void) 23562306a36Sopenharmony_ci{ 23662306a36Sopenharmony_ci int i; 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci /* Let's see how we handle changes... */ 23962306a36Sopenharmony_ci ac_online = 0; 24062306a36Sopenharmony_ci usb_online = 0; 24162306a36Sopenharmony_ci battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 24262306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) 24362306a36Sopenharmony_ci power_supply_changed(test_power_supplies[i]); 24462306a36Sopenharmony_ci pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n", 24562306a36Sopenharmony_ci __func__); 24662306a36Sopenharmony_ci ssleep(10); 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) 24962306a36Sopenharmony_ci power_supply_unregister(test_power_supplies[i]); 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci module_initialized = false; 25262306a36Sopenharmony_ci} 25362306a36Sopenharmony_cimodule_exit(test_power_exit); 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci#define MAX_KEYLENGTH 256 25862306a36Sopenharmony_cistruct battery_property_map { 25962306a36Sopenharmony_ci int value; 26062306a36Sopenharmony_ci char const *key; 26162306a36Sopenharmony_ci}; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_cistatic struct battery_property_map map_ac_online[] = { 26462306a36Sopenharmony_ci { 0, "off" }, 26562306a36Sopenharmony_ci { 1, "on" }, 26662306a36Sopenharmony_ci { -1, NULL }, 26762306a36Sopenharmony_ci}; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_cistatic struct battery_property_map map_status[] = { 27062306a36Sopenharmony_ci { POWER_SUPPLY_STATUS_CHARGING, "charging" }, 27162306a36Sopenharmony_ci { POWER_SUPPLY_STATUS_DISCHARGING, "discharging" }, 27262306a36Sopenharmony_ci { POWER_SUPPLY_STATUS_NOT_CHARGING, "not-charging" }, 27362306a36Sopenharmony_ci { POWER_SUPPLY_STATUS_FULL, "full" }, 27462306a36Sopenharmony_ci { -1, NULL }, 27562306a36Sopenharmony_ci}; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_cistatic struct battery_property_map map_health[] = { 27862306a36Sopenharmony_ci { POWER_SUPPLY_HEALTH_GOOD, "good" }, 27962306a36Sopenharmony_ci { POWER_SUPPLY_HEALTH_OVERHEAT, "overheat" }, 28062306a36Sopenharmony_ci { POWER_SUPPLY_HEALTH_DEAD, "dead" }, 28162306a36Sopenharmony_ci { POWER_SUPPLY_HEALTH_OVERVOLTAGE, "overvoltage" }, 28262306a36Sopenharmony_ci { POWER_SUPPLY_HEALTH_UNSPEC_FAILURE, "failure" }, 28362306a36Sopenharmony_ci { -1, NULL }, 28462306a36Sopenharmony_ci}; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_cistatic struct battery_property_map map_present[] = { 28762306a36Sopenharmony_ci { 0, "false" }, 28862306a36Sopenharmony_ci { 1, "true" }, 28962306a36Sopenharmony_ci { -1, NULL }, 29062306a36Sopenharmony_ci}; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_cistatic struct battery_property_map map_technology[] = { 29362306a36Sopenharmony_ci { POWER_SUPPLY_TECHNOLOGY_NiMH, "NiMH" }, 29462306a36Sopenharmony_ci { POWER_SUPPLY_TECHNOLOGY_LION, "LION" }, 29562306a36Sopenharmony_ci { POWER_SUPPLY_TECHNOLOGY_LIPO, "LIPO" }, 29662306a36Sopenharmony_ci { POWER_SUPPLY_TECHNOLOGY_LiFe, "LiFe" }, 29762306a36Sopenharmony_ci { POWER_SUPPLY_TECHNOLOGY_NiCd, "NiCd" }, 29862306a36Sopenharmony_ci { POWER_SUPPLY_TECHNOLOGY_LiMn, "LiMn" }, 29962306a36Sopenharmony_ci { -1, NULL }, 30062306a36Sopenharmony_ci}; 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_cistatic int map_get_value(struct battery_property_map *map, const char *key, 30462306a36Sopenharmony_ci int def_val) 30562306a36Sopenharmony_ci{ 30662306a36Sopenharmony_ci char buf[MAX_KEYLENGTH]; 30762306a36Sopenharmony_ci int cr; 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci strscpy(buf, key, MAX_KEYLENGTH); 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci cr = strnlen(buf, MAX_KEYLENGTH) - 1; 31262306a36Sopenharmony_ci if (cr < 0) 31362306a36Sopenharmony_ci return def_val; 31462306a36Sopenharmony_ci if (buf[cr] == '\n') 31562306a36Sopenharmony_ci buf[cr] = '\0'; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci while (map->key) { 31862306a36Sopenharmony_ci if (strncasecmp(map->key, buf, MAX_KEYLENGTH) == 0) 31962306a36Sopenharmony_ci return map->value; 32062306a36Sopenharmony_ci map++; 32162306a36Sopenharmony_ci } 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci return def_val; 32462306a36Sopenharmony_ci} 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_cistatic const char *map_get_key(struct battery_property_map *map, int value, 32862306a36Sopenharmony_ci const char *def_key) 32962306a36Sopenharmony_ci{ 33062306a36Sopenharmony_ci while (map->key) { 33162306a36Sopenharmony_ci if (map->value == value) 33262306a36Sopenharmony_ci return map->key; 33362306a36Sopenharmony_ci map++; 33462306a36Sopenharmony_ci } 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci return def_key; 33762306a36Sopenharmony_ci} 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_cistatic inline void signal_power_supply_changed(struct power_supply *psy) 34062306a36Sopenharmony_ci{ 34162306a36Sopenharmony_ci if (module_initialized) 34262306a36Sopenharmony_ci power_supply_changed(psy); 34362306a36Sopenharmony_ci} 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_cistatic int param_set_ac_online(const char *key, const struct kernel_param *kp) 34662306a36Sopenharmony_ci{ 34762306a36Sopenharmony_ci ac_online = map_get_value(map_ac_online, key, ac_online); 34862306a36Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_AC]); 34962306a36Sopenharmony_ci return 0; 35062306a36Sopenharmony_ci} 35162306a36Sopenharmony_ci 35262306a36Sopenharmony_cistatic int param_get_ac_online(char *buffer, const struct kernel_param *kp) 35362306a36Sopenharmony_ci{ 35462306a36Sopenharmony_ci return sprintf(buffer, "%s\n", 35562306a36Sopenharmony_ci map_get_key(map_ac_online, ac_online, "unknown")); 35662306a36Sopenharmony_ci} 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_cistatic int param_set_usb_online(const char *key, const struct kernel_param *kp) 35962306a36Sopenharmony_ci{ 36062306a36Sopenharmony_ci usb_online = map_get_value(map_ac_online, key, usb_online); 36162306a36Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_USB]); 36262306a36Sopenharmony_ci return 0; 36362306a36Sopenharmony_ci} 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_cistatic int param_get_usb_online(char *buffer, const struct kernel_param *kp) 36662306a36Sopenharmony_ci{ 36762306a36Sopenharmony_ci return sprintf(buffer, "%s\n", 36862306a36Sopenharmony_ci map_get_key(map_ac_online, usb_online, "unknown")); 36962306a36Sopenharmony_ci} 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_cistatic int param_set_battery_status(const char *key, 37262306a36Sopenharmony_ci const struct kernel_param *kp) 37362306a36Sopenharmony_ci{ 37462306a36Sopenharmony_ci battery_status = map_get_value(map_status, key, battery_status); 37562306a36Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 37662306a36Sopenharmony_ci return 0; 37762306a36Sopenharmony_ci} 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_cistatic int param_get_battery_status(char *buffer, const struct kernel_param *kp) 38062306a36Sopenharmony_ci{ 38162306a36Sopenharmony_ci return sprintf(buffer, "%s\n", 38262306a36Sopenharmony_ci map_get_key(map_ac_online, battery_status, "unknown")); 38362306a36Sopenharmony_ci} 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_cistatic int param_set_battery_health(const char *key, 38662306a36Sopenharmony_ci const struct kernel_param *kp) 38762306a36Sopenharmony_ci{ 38862306a36Sopenharmony_ci battery_health = map_get_value(map_health, key, battery_health); 38962306a36Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 39062306a36Sopenharmony_ci return 0; 39162306a36Sopenharmony_ci} 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_cistatic int param_get_battery_health(char *buffer, const struct kernel_param *kp) 39462306a36Sopenharmony_ci{ 39562306a36Sopenharmony_ci return sprintf(buffer, "%s\n", 39662306a36Sopenharmony_ci map_get_key(map_ac_online, battery_health, "unknown")); 39762306a36Sopenharmony_ci} 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_cistatic int param_set_battery_present(const char *key, 40062306a36Sopenharmony_ci const struct kernel_param *kp) 40162306a36Sopenharmony_ci{ 40262306a36Sopenharmony_ci battery_present = map_get_value(map_present, key, battery_present); 40362306a36Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_AC]); 40462306a36Sopenharmony_ci return 0; 40562306a36Sopenharmony_ci} 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_cistatic int param_get_battery_present(char *buffer, 40862306a36Sopenharmony_ci const struct kernel_param *kp) 40962306a36Sopenharmony_ci{ 41062306a36Sopenharmony_ci return sprintf(buffer, "%s\n", 41162306a36Sopenharmony_ci map_get_key(map_ac_online, battery_present, "unknown")); 41262306a36Sopenharmony_ci} 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_cistatic int param_set_battery_technology(const char *key, 41562306a36Sopenharmony_ci const struct kernel_param *kp) 41662306a36Sopenharmony_ci{ 41762306a36Sopenharmony_ci battery_technology = map_get_value(map_technology, key, 41862306a36Sopenharmony_ci battery_technology); 41962306a36Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 42062306a36Sopenharmony_ci return 0; 42162306a36Sopenharmony_ci} 42262306a36Sopenharmony_ci 42362306a36Sopenharmony_cistatic int param_get_battery_technology(char *buffer, 42462306a36Sopenharmony_ci const struct kernel_param *kp) 42562306a36Sopenharmony_ci{ 42662306a36Sopenharmony_ci return sprintf(buffer, "%s\n", 42762306a36Sopenharmony_ci map_get_key(map_ac_online, battery_technology, 42862306a36Sopenharmony_ci "unknown")); 42962306a36Sopenharmony_ci} 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_cistatic int param_set_battery_capacity(const char *key, 43262306a36Sopenharmony_ci const struct kernel_param *kp) 43362306a36Sopenharmony_ci{ 43462306a36Sopenharmony_ci int tmp; 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci if (1 != sscanf(key, "%d", &tmp)) 43762306a36Sopenharmony_ci return -EINVAL; 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci battery_capacity = tmp; 44062306a36Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 44162306a36Sopenharmony_ci return 0; 44262306a36Sopenharmony_ci} 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci#define param_get_battery_capacity param_get_int 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_cistatic int param_set_battery_voltage(const char *key, 44762306a36Sopenharmony_ci const struct kernel_param *kp) 44862306a36Sopenharmony_ci{ 44962306a36Sopenharmony_ci int tmp; 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci if (1 != sscanf(key, "%d", &tmp)) 45262306a36Sopenharmony_ci return -EINVAL; 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci battery_voltage = tmp; 45562306a36Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 45662306a36Sopenharmony_ci return 0; 45762306a36Sopenharmony_ci} 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci#define param_get_battery_voltage param_get_int 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_cistatic int param_set_battery_charge_counter(const char *key, 46262306a36Sopenharmony_ci const struct kernel_param *kp) 46362306a36Sopenharmony_ci{ 46462306a36Sopenharmony_ci int tmp; 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci if (1 != sscanf(key, "%d", &tmp)) 46762306a36Sopenharmony_ci return -EINVAL; 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci battery_charge_counter = tmp; 47062306a36Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 47162306a36Sopenharmony_ci return 0; 47262306a36Sopenharmony_ci} 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci#define param_get_battery_charge_counter param_get_int 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_cistatic int param_set_battery_current(const char *key, 47762306a36Sopenharmony_ci const struct kernel_param *kp) 47862306a36Sopenharmony_ci{ 47962306a36Sopenharmony_ci int tmp; 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci if (1 != sscanf(key, "%d", &tmp)) 48262306a36Sopenharmony_ci return -EINVAL; 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci battery_current = tmp; 48562306a36Sopenharmony_ci signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 48662306a36Sopenharmony_ci return 0; 48762306a36Sopenharmony_ci} 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci#define param_get_battery_current param_get_int 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_cistatic const struct kernel_param_ops param_ops_ac_online = { 49262306a36Sopenharmony_ci .set = param_set_ac_online, 49362306a36Sopenharmony_ci .get = param_get_ac_online, 49462306a36Sopenharmony_ci}; 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_cistatic const struct kernel_param_ops param_ops_usb_online = { 49762306a36Sopenharmony_ci .set = param_set_usb_online, 49862306a36Sopenharmony_ci .get = param_get_usb_online, 49962306a36Sopenharmony_ci}; 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_status = { 50262306a36Sopenharmony_ci .set = param_set_battery_status, 50362306a36Sopenharmony_ci .get = param_get_battery_status, 50462306a36Sopenharmony_ci}; 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_present = { 50762306a36Sopenharmony_ci .set = param_set_battery_present, 50862306a36Sopenharmony_ci .get = param_get_battery_present, 50962306a36Sopenharmony_ci}; 51062306a36Sopenharmony_ci 51162306a36Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_technology = { 51262306a36Sopenharmony_ci .set = param_set_battery_technology, 51362306a36Sopenharmony_ci .get = param_get_battery_technology, 51462306a36Sopenharmony_ci}; 51562306a36Sopenharmony_ci 51662306a36Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_health = { 51762306a36Sopenharmony_ci .set = param_set_battery_health, 51862306a36Sopenharmony_ci .get = param_get_battery_health, 51962306a36Sopenharmony_ci}; 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_capacity = { 52262306a36Sopenharmony_ci .set = param_set_battery_capacity, 52362306a36Sopenharmony_ci .get = param_get_battery_capacity, 52462306a36Sopenharmony_ci}; 52562306a36Sopenharmony_ci 52662306a36Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_voltage = { 52762306a36Sopenharmony_ci .set = param_set_battery_voltage, 52862306a36Sopenharmony_ci .get = param_get_battery_voltage, 52962306a36Sopenharmony_ci}; 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_charge_counter = { 53262306a36Sopenharmony_ci .set = param_set_battery_charge_counter, 53362306a36Sopenharmony_ci .get = param_get_battery_charge_counter, 53462306a36Sopenharmony_ci}; 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_cistatic const struct kernel_param_ops param_ops_battery_current = { 53762306a36Sopenharmony_ci .set = param_set_battery_current, 53862306a36Sopenharmony_ci .get = param_get_battery_current, 53962306a36Sopenharmony_ci}; 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_ci#define param_check_ac_online(name, p) __param_check(name, p, void); 54262306a36Sopenharmony_ci#define param_check_usb_online(name, p) __param_check(name, p, void); 54362306a36Sopenharmony_ci#define param_check_battery_status(name, p) __param_check(name, p, void); 54462306a36Sopenharmony_ci#define param_check_battery_present(name, p) __param_check(name, p, void); 54562306a36Sopenharmony_ci#define param_check_battery_technology(name, p) __param_check(name, p, void); 54662306a36Sopenharmony_ci#define param_check_battery_health(name, p) __param_check(name, p, void); 54762306a36Sopenharmony_ci#define param_check_battery_capacity(name, p) __param_check(name, p, void); 54862306a36Sopenharmony_ci#define param_check_battery_voltage(name, p) __param_check(name, p, void); 54962306a36Sopenharmony_ci#define param_check_battery_charge_counter(name, p) __param_check(name, p, void); 55062306a36Sopenharmony_ci#define param_check_battery_current(name, p) __param_check(name, p, void); 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_cimodule_param(ac_online, ac_online, 0644); 55462306a36Sopenharmony_ciMODULE_PARM_DESC(ac_online, "AC charging state <on|off>"); 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_cimodule_param(usb_online, usb_online, 0644); 55762306a36Sopenharmony_ciMODULE_PARM_DESC(usb_online, "USB charging state <on|off>"); 55862306a36Sopenharmony_ci 55962306a36Sopenharmony_cimodule_param(battery_status, battery_status, 0644); 56062306a36Sopenharmony_ciMODULE_PARM_DESC(battery_status, 56162306a36Sopenharmony_ci "battery status <charging|discharging|not-charging|full>"); 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_cimodule_param(battery_present, battery_present, 0644); 56462306a36Sopenharmony_ciMODULE_PARM_DESC(battery_present, 56562306a36Sopenharmony_ci "battery presence state <good|overheat|dead|overvoltage|failure>"); 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_cimodule_param(battery_technology, battery_technology, 0644); 56862306a36Sopenharmony_ciMODULE_PARM_DESC(battery_technology, 56962306a36Sopenharmony_ci "battery technology <NiMH|LION|LIPO|LiFe|NiCd|LiMn>"); 57062306a36Sopenharmony_ci 57162306a36Sopenharmony_cimodule_param(battery_health, battery_health, 0644); 57262306a36Sopenharmony_ciMODULE_PARM_DESC(battery_health, 57362306a36Sopenharmony_ci "battery health state <good|overheat|dead|overvoltage|failure>"); 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_cimodule_param(battery_capacity, battery_capacity, 0644); 57662306a36Sopenharmony_ciMODULE_PARM_DESC(battery_capacity, "battery capacity (percentage)"); 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_cimodule_param(battery_voltage, battery_voltage, 0644); 57962306a36Sopenharmony_ciMODULE_PARM_DESC(battery_voltage, "battery voltage (millivolts)"); 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_cimodule_param(battery_charge_counter, battery_charge_counter, 0644); 58262306a36Sopenharmony_ciMODULE_PARM_DESC(battery_charge_counter, 58362306a36Sopenharmony_ci "battery charge counter (microampere-hours)"); 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_cimodule_param(battery_current, battery_current, 0644); 58662306a36Sopenharmony_ciMODULE_PARM_DESC(battery_current, "battery current (milliampere)"); 58762306a36Sopenharmony_ci 58862306a36Sopenharmony_ciMODULE_DESCRIPTION("Power supply driver for testing"); 58962306a36Sopenharmony_ciMODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); 59062306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 591