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