mirror of
https://github.com/lretq/fake-battery-linux.git
synced 2026-08-22 13:27:19 +00:00
141 lines
4.1 KiB
C
141 lines
4.1 KiB
C
/*
|
|
* Copyright (c) 2026 Vincent Schweiger
|
|
*
|
|
* Fake Battery driver for Linux.
|
|
*
|
|
* The main purpose is to emulate a battery for battery-less systems like desktops.
|
|
*/
|
|
|
|
/*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*/
|
|
#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");
|