2 * Power supply driver for testing.
4 * Copyright 2010 Anton Vorontsov <cbouatmailru@gmail.com>
6 * Dynamic module parameter code from the Virtual Battery Driver
7 * Copyright (C) 2008 Pylone, Inc.
8 * By: Masashi YOKOTA <yokota@pylone.jp>
9 * Originally found here:
10 * http://downloads.pylone.jp/src/virtual_battery/virtual_battery-0.0.1.tar.bz2
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/power_supply.h>
20 #include <linux/errno.h>
21 #include <linux/delay.h>
22 #include <linux/vermagic.h>
24 static int ac_online
= 1;
25 static int usb_online
= 1;
26 static int battery_status
= POWER_SUPPLY_STATUS_DISCHARGING
;
27 static int battery_health
= POWER_SUPPLY_HEALTH_GOOD
;
28 static int battery_present
= 1; /* true */
29 static int battery_technology
= POWER_SUPPLY_TECHNOLOGY_LION
;
30 static int battery_capacity
= 50;
31 static int battery_voltage
= 3300;
33 static bool module_initialized
;
35 static int test_power_get_ac_property(struct power_supply
*psy
,
36 enum power_supply_property psp
,
37 union power_supply_propval
*val
)
40 case POWER_SUPPLY_PROP_ONLINE
:
41 val
->intval
= ac_online
;
49 static int test_power_get_usb_property(struct power_supply
*psy
,
50 enum power_supply_property psp
,
51 union power_supply_propval
*val
)
54 case POWER_SUPPLY_PROP_ONLINE
:
55 val
->intval
= usb_online
;
63 static int test_power_get_battery_property(struct power_supply
*psy
,
64 enum power_supply_property psp
,
65 union power_supply_propval
*val
)
68 case POWER_SUPPLY_PROP_MODEL_NAME
:
69 val
->strval
= "Test battery";
71 case POWER_SUPPLY_PROP_MANUFACTURER
:
72 val
->strval
= "Linux";
74 case POWER_SUPPLY_PROP_SERIAL_NUMBER
:
75 val
->strval
= UTS_RELEASE
;
77 case POWER_SUPPLY_PROP_STATUS
:
78 val
->intval
= battery_status
;
80 case POWER_SUPPLY_PROP_CHARGE_TYPE
:
81 val
->intval
= POWER_SUPPLY_CHARGE_TYPE_FAST
;
83 case POWER_SUPPLY_PROP_HEALTH
:
84 val
->intval
= battery_health
;
86 case POWER_SUPPLY_PROP_PRESENT
:
87 val
->intval
= battery_present
;
89 case POWER_SUPPLY_PROP_TECHNOLOGY
:
90 val
->intval
= battery_technology
;
92 case POWER_SUPPLY_PROP_CAPACITY_LEVEL
:
93 val
->intval
= POWER_SUPPLY_CAPACITY_LEVEL_NORMAL
;
95 case POWER_SUPPLY_PROP_CAPACITY
:
96 case POWER_SUPPLY_PROP_CHARGE_NOW
:
97 val
->intval
= battery_capacity
;
99 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN
:
100 case POWER_SUPPLY_PROP_CHARGE_FULL
:
103 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG
:
104 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW
:
107 case POWER_SUPPLY_PROP_TEMP
:
110 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
111 val
->intval
= battery_voltage
;
114 pr_info("%s: some properties deliberately report errors.\n",
121 static enum power_supply_property test_power_ac_props
[] = {
122 POWER_SUPPLY_PROP_ONLINE
,
125 static enum power_supply_property test_power_battery_props
[] = {
126 POWER_SUPPLY_PROP_STATUS
,
127 POWER_SUPPLY_PROP_CHARGE_TYPE
,
128 POWER_SUPPLY_PROP_HEALTH
,
129 POWER_SUPPLY_PROP_PRESENT
,
130 POWER_SUPPLY_PROP_TECHNOLOGY
,
131 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN
,
132 POWER_SUPPLY_PROP_CHARGE_FULL
,
133 POWER_SUPPLY_PROP_CHARGE_NOW
,
134 POWER_SUPPLY_PROP_CAPACITY
,
135 POWER_SUPPLY_PROP_CAPACITY_LEVEL
,
136 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG
,
137 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW
,
138 POWER_SUPPLY_PROP_MODEL_NAME
,
139 POWER_SUPPLY_PROP_MANUFACTURER
,
140 POWER_SUPPLY_PROP_SERIAL_NUMBER
,
141 POWER_SUPPLY_PROP_TEMP
,
142 POWER_SUPPLY_PROP_VOLTAGE_NOW
,
145 static char *test_power_ac_supplied_to
[] = {
149 static struct power_supply test_power_supplies
[] = {
152 .type
= POWER_SUPPLY_TYPE_MAINS
,
153 .supplied_to
= test_power_ac_supplied_to
,
154 .num_supplicants
= ARRAY_SIZE(test_power_ac_supplied_to
),
155 .properties
= test_power_ac_props
,
156 .num_properties
= ARRAY_SIZE(test_power_ac_props
),
157 .get_property
= test_power_get_ac_property
,
159 .name
= "test_battery",
160 .type
= POWER_SUPPLY_TYPE_BATTERY
,
161 .properties
= test_power_battery_props
,
162 .num_properties
= ARRAY_SIZE(test_power_battery_props
),
163 .get_property
= test_power_get_battery_property
,
166 .type
= POWER_SUPPLY_TYPE_USB
,
167 .supplied_to
= test_power_ac_supplied_to
,
168 .num_supplicants
= ARRAY_SIZE(test_power_ac_supplied_to
),
169 .properties
= test_power_ac_props
,
170 .num_properties
= ARRAY_SIZE(test_power_ac_props
),
171 .get_property
= test_power_get_usb_property
,
176 static int __init
test_power_init(void)
181 for (i
= 0; i
< ARRAY_SIZE(test_power_supplies
); i
++) {
182 ret
= power_supply_register(NULL
, &test_power_supplies
[i
]);
184 pr_err("%s: failed to register %s\n", __func__
,
185 test_power_supplies
[i
].name
);
190 module_initialized
= true;
194 power_supply_unregister(&test_power_supplies
[i
]);
197 module_init(test_power_init
);
199 static void __exit
test_power_exit(void)
203 /* Let's see how we handle changes... */
206 battery_status
= POWER_SUPPLY_STATUS_DISCHARGING
;
207 for (i
= 0; i
< ARRAY_SIZE(test_power_supplies
); i
++)
208 power_supply_changed(&test_power_supplies
[i
]);
209 pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n",
213 for (i
= 0; i
< ARRAY_SIZE(test_power_supplies
); i
++)
214 power_supply_unregister(&test_power_supplies
[i
]);
216 module_initialized
= false;
218 module_exit(test_power_exit
);
222 #define MAX_KEYLENGTH 256
223 struct battery_property_map
{
228 static struct battery_property_map map_ac_online
[] = {
234 static struct battery_property_map map_status
[] = {
235 { POWER_SUPPLY_STATUS_CHARGING
, "charging" },
236 { POWER_SUPPLY_STATUS_DISCHARGING
, "discharging" },
237 { POWER_SUPPLY_STATUS_NOT_CHARGING
, "not-charging" },
238 { POWER_SUPPLY_STATUS_FULL
, "full" },
242 static struct battery_property_map map_health
[] = {
243 { POWER_SUPPLY_HEALTH_GOOD
, "good" },
244 { POWER_SUPPLY_HEALTH_OVERHEAT
, "overheat" },
245 { POWER_SUPPLY_HEALTH_DEAD
, "dead" },
246 { POWER_SUPPLY_HEALTH_OVERVOLTAGE
, "overvoltage" },
247 { POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
, "failure" },
251 static struct battery_property_map map_present
[] = {
257 static struct battery_property_map map_technology
[] = {
258 { POWER_SUPPLY_TECHNOLOGY_NiMH
, "NiMH" },
259 { POWER_SUPPLY_TECHNOLOGY_LION
, "LION" },
260 { POWER_SUPPLY_TECHNOLOGY_LIPO
, "LIPO" },
261 { POWER_SUPPLY_TECHNOLOGY_LiFe
, "LiFe" },
262 { POWER_SUPPLY_TECHNOLOGY_NiCd
, "NiCd" },
263 { POWER_SUPPLY_TECHNOLOGY_LiMn
, "LiMn" },
268 static int map_get_value(struct battery_property_map
*map
, const char *key
,
271 char buf
[MAX_KEYLENGTH
];
274 strncpy(buf
, key
, MAX_KEYLENGTH
);
275 buf
[MAX_KEYLENGTH
-1] = '\0';
277 cr
= strnlen(buf
, MAX_KEYLENGTH
) - 1;
282 if (strncasecmp(map
->key
, buf
, MAX_KEYLENGTH
) == 0)
291 static const char *map_get_key(struct battery_property_map
*map
, int value
,
295 if (map
->value
== value
)
303 static inline void signal_power_supply_changed(struct power_supply
*psy
)
305 if (module_initialized
)
306 power_supply_changed(psy
);
309 static int param_set_ac_online(const char *key
, const struct kernel_param
*kp
)
311 ac_online
= map_get_value(map_ac_online
, key
, ac_online
);
312 signal_power_supply_changed(&test_power_supplies
[0]);
316 static int param_get_ac_online(char *buffer
, const struct kernel_param
*kp
)
318 strcpy(buffer
, map_get_key(map_ac_online
, ac_online
, "unknown"));
319 return strlen(buffer
);
322 static int param_set_usb_online(const char *key
, const struct kernel_param
*kp
)
324 usb_online
= map_get_value(map_ac_online
, key
, usb_online
);
325 signal_power_supply_changed(&test_power_supplies
[2]);
329 static int param_get_usb_online(char *buffer
, const struct kernel_param
*kp
)
331 strcpy(buffer
, map_get_key(map_ac_online
, usb_online
, "unknown"));
332 return strlen(buffer
);
335 static int param_set_battery_status(const char *key
,
336 const struct kernel_param
*kp
)
338 battery_status
= map_get_value(map_status
, key
, battery_status
);
339 signal_power_supply_changed(&test_power_supplies
[1]);
343 static int param_get_battery_status(char *buffer
, const struct kernel_param
*kp
)
345 strcpy(buffer
, map_get_key(map_status
, battery_status
, "unknown"));
346 return strlen(buffer
);
349 static int param_set_battery_health(const char *key
,
350 const struct kernel_param
*kp
)
352 battery_health
= map_get_value(map_health
, key
, battery_health
);
353 signal_power_supply_changed(&test_power_supplies
[1]);
357 static int param_get_battery_health(char *buffer
, const struct kernel_param
*kp
)
359 strcpy(buffer
, map_get_key(map_health
, battery_health
, "unknown"));
360 return strlen(buffer
);
363 static int param_set_battery_present(const char *key
,
364 const struct kernel_param
*kp
)
366 battery_present
= map_get_value(map_present
, key
, battery_present
);
367 signal_power_supply_changed(&test_power_supplies
[0]);
371 static int param_get_battery_present(char *buffer
,
372 const struct kernel_param
*kp
)
374 strcpy(buffer
, map_get_key(map_present
, battery_present
, "unknown"));
375 return strlen(buffer
);
378 static int param_set_battery_technology(const char *key
,
379 const struct kernel_param
*kp
)
381 battery_technology
= map_get_value(map_technology
, key
,
383 signal_power_supply_changed(&test_power_supplies
[1]);
387 static int param_get_battery_technology(char *buffer
,
388 const struct kernel_param
*kp
)
391 map_get_key(map_technology
, battery_technology
, "unknown"));
392 return strlen(buffer
);
395 static int param_set_battery_capacity(const char *key
,
396 const struct kernel_param
*kp
)
400 if (1 != sscanf(key
, "%d", &tmp
))
403 battery_capacity
= tmp
;
404 signal_power_supply_changed(&test_power_supplies
[1]);
408 #define param_get_battery_capacity param_get_int
410 static int param_set_battery_voltage(const char *key
,
411 const struct kernel_param
*kp
)
415 if (1 != sscanf(key
, "%d", &tmp
))
418 battery_voltage
= tmp
;
419 signal_power_supply_changed(&test_power_supplies
[1]);
423 #define param_get_battery_voltage param_get_int
425 static struct kernel_param_ops param_ops_ac_online
= {
426 .set
= param_set_ac_online
,
427 .get
= param_get_ac_online
,
430 static struct kernel_param_ops param_ops_usb_online
= {
431 .set
= param_set_usb_online
,
432 .get
= param_get_usb_online
,
435 static struct kernel_param_ops param_ops_battery_status
= {
436 .set
= param_set_battery_status
,
437 .get
= param_get_battery_status
,
440 static struct kernel_param_ops param_ops_battery_present
= {
441 .set
= param_set_battery_present
,
442 .get
= param_get_battery_present
,
445 static struct kernel_param_ops param_ops_battery_technology
= {
446 .set
= param_set_battery_technology
,
447 .get
= param_get_battery_technology
,
450 static struct kernel_param_ops param_ops_battery_health
= {
451 .set
= param_set_battery_health
,
452 .get
= param_get_battery_health
,
455 static struct kernel_param_ops param_ops_battery_capacity
= {
456 .set
= param_set_battery_capacity
,
457 .get
= param_get_battery_capacity
,
460 static struct kernel_param_ops param_ops_battery_voltage
= {
461 .set
= param_set_battery_voltage
,
462 .get
= param_get_battery_voltage
,
465 #define param_check_ac_online(name, p) __param_check(name, p, void);
466 #define param_check_usb_online(name, p) __param_check(name, p, void);
467 #define param_check_battery_status(name, p) __param_check(name, p, void);
468 #define param_check_battery_present(name, p) __param_check(name, p, void);
469 #define param_check_battery_technology(name, p) __param_check(name, p, void);
470 #define param_check_battery_health(name, p) __param_check(name, p, void);
471 #define param_check_battery_capacity(name, p) __param_check(name, p, void);
472 #define param_check_battery_voltage(name, p) __param_check(name, p, void);
475 module_param(ac_online
, ac_online
, 0644);
476 MODULE_PARM_DESC(ac_online
, "AC charging state <on|off>");
478 module_param(usb_online
, usb_online
, 0644);
479 MODULE_PARM_DESC(usb_online
, "USB charging state <on|off>");
481 module_param(battery_status
, battery_status
, 0644);
482 MODULE_PARM_DESC(battery_status
,
483 "battery status <charging|discharging|not-charging|full>");
485 module_param(battery_present
, battery_present
, 0644);
486 MODULE_PARM_DESC(battery_present
,
487 "battery presence state <good|overheat|dead|overvoltage|failure>");
489 module_param(battery_technology
, battery_technology
, 0644);
490 MODULE_PARM_DESC(battery_technology
,
491 "battery technology <NiMH|LION|LIPO|LiFe|NiCd|LiMn>");
493 module_param(battery_health
, battery_health
, 0644);
494 MODULE_PARM_DESC(battery_health
,
495 "battery health state <good|overheat|dead|overvoltage|failure>");
497 module_param(battery_capacity
, battery_capacity
, 0644);
498 MODULE_PARM_DESC(battery_capacity
, "battery capacity (percentage)");
500 module_param(battery_voltage
, battery_voltage
, 0644);
501 MODULE_PARM_DESC(battery_voltage
, "battery voltage (millivolts)");
503 MODULE_DESCRIPTION("Power supply driver for testing");
504 MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");
505 MODULE_LICENSE("GPL");