Files
fake-battery-linux/fake-battery.c
T

127 lines
3.7 KiB
C

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/power_supply.h>
#include <linux/init.h>
#define VERSION_STR "0.1.1"
static struct power_supply *fake_battery;
static struct power_supply_desc battery_desc;
static enum power_supply_property fake_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_CHARGE_FULL,
POWER_SUPPLY_PROP_CHARGE_NOW,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_MANUFACTURER,
POWER_SUPPLY_PROP_SERIAL_NUMBER,
};
static int fake_battery_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
{
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
val->intval = POWER_SUPPLY_STATUS_FULL;
break;
case POWER_SUPPLY_PROP_HEALTH:
val->intval = POWER_SUPPLY_HEALTH_GOOD;
break;
case POWER_SUPPLY_PROP_PRESENT:
val->intval = 1;
break;
case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO;
break;
case POWER_SUPPLY_PROP_CAPACITY:
val->intval = 100;
break;
case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
break;
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
val->intval = 5000000; /* 5000 mAh */
break;
case POWER_SUPPLY_PROP_CHARGE_FULL:
val->intval = 5000000; /* 5000 mAh */
break;
case POWER_SUPPLY_PROP_CHARGE_NOW:
val->intval = 5000000; /* 5000 mAh (fully charged) */
break;
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
val->intval = 4200000; /* 4.2V */
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
val->intval = 0; /* Not charging */
break;
case POWER_SUPPLY_PROP_TEMP:
val->intval = 253; /* 25°C in 0.1°C units */
break;
case POWER_SUPPLY_PROP_MODEL_NAME:
val->strval = "Fake Battery v" VERSION_STR;
break;
case POWER_SUPPLY_PROP_MANUFACTURER:
val->strval = "Thin Air";
break;
case POWER_SUPPLY_PROP_SERIAL_NUMBER:
val->strval = "deadbeef";
break;
default:
return -EINVAL;
}
return 0;
}
static int __init fake_battery_init(void)
{
int ret;
pr_debug("loading fake battery module\n");
// Initialize the power supply descriptor
battery_desc.name = "fake-battery";
battery_desc.type = POWER_SUPPLY_TYPE_BATTERY;
battery_desc.properties = fake_battery_props;
battery_desc.num_properties = ARRAY_SIZE(fake_battery_props);
battery_desc.get_property = fake_battery_get_property;
// Register the power supply
fake_battery = power_supply_register(NULL, &battery_desc, NULL);
if (IS_ERR(fake_battery)) {
ret = PTR_ERR(fake_battery);
pr_err("failed to register power supply: %d\n", ret);
return ret;
}
pr_debug("fake battery registered successfully\n");
return 0;
}
static void __exit fake_battery_exit(void)
{
pr_debug("unloading fake battery module\n");
if (fake_battery)
power_supply_unregister(fake_battery);
}
module_init(fake_battery_init);
module_exit(fake_battery_exit);
MODULE_AUTHOR("Vincent Schweiger");
MODULE_DESCRIPTION("Fake battery module that reports a fully charged battery");
MODULE_VERSION(VERSION_STR);
MODULE_LICENSE("GPL");