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 battery_status
= POWER_SUPPLY_STATUS_DISCHARGING
;
26 static int battery_health
= POWER_SUPPLY_HEALTH_GOOD
;
27 static int battery_present
= 1; /* true */
28 static int battery_technology
= POWER_SUPPLY_TECHNOLOGY_LION
;
29 static int battery_capacity
= 50;
31 static int test_power_get_ac_property(struct power_supply
*psy
,
32 enum power_supply_property psp
,
33 union power_supply_propval
*val
)
36 case POWER_SUPPLY_PROP_ONLINE
:
37 val
->intval
= ac_online
;
45 static int test_power_get_battery_property(struct power_supply
*psy
,
46 enum power_supply_property psp
,
47 union power_supply_propval
*val
)
50 case POWER_SUPPLY_PROP_MODEL_NAME
:
51 val
->strval
= "Test battery";
53 case POWER_SUPPLY_PROP_MANUFACTURER
:
54 val
->strval
= "Linux";
56 case POWER_SUPPLY_PROP_SERIAL_NUMBER
:
57 val
->strval
= UTS_RELEASE
;
59 case POWER_SUPPLY_PROP_STATUS
:
60 val
->intval
= battery_status
;
62 case POWER_SUPPLY_PROP_CHARGE_TYPE
:
63 val
->intval
= POWER_SUPPLY_CHARGE_TYPE_FAST
;
65 case POWER_SUPPLY_PROP_HEALTH
:
66 val
->intval
= battery_health
;
68 case POWER_SUPPLY_PROP_PRESENT
:
69 val
->intval
= battery_present
;
71 case POWER_SUPPLY_PROP_TECHNOLOGY
:
72 val
->intval
= battery_technology
;
74 case POWER_SUPPLY_PROP_CAPACITY_LEVEL
:
75 val
->intval
= POWER_SUPPLY_CAPACITY_LEVEL_NORMAL
;
77 case POWER_SUPPLY_PROP_CAPACITY
:
78 case POWER_SUPPLY_PROP_CHARGE_NOW
:
79 val
->intval
= battery_capacity
;
81 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN
:
82 case POWER_SUPPLY_PROP_CHARGE_FULL
:
85 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG
:
86 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW
:
90 pr_info("%s: some properties deliberately report errors.\n",
97 static enum power_supply_property test_power_ac_props
[] = {
98 POWER_SUPPLY_PROP_ONLINE
,
101 static enum power_supply_property test_power_battery_props
[] = {
102 POWER_SUPPLY_PROP_STATUS
,
103 POWER_SUPPLY_PROP_CHARGE_TYPE
,
104 POWER_SUPPLY_PROP_HEALTH
,
105 POWER_SUPPLY_PROP_PRESENT
,
106 POWER_SUPPLY_PROP_TECHNOLOGY
,
107 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN
,
108 POWER_SUPPLY_PROP_CHARGE_FULL
,
109 POWER_SUPPLY_PROP_CHARGE_NOW
,
110 POWER_SUPPLY_PROP_CAPACITY
,
111 POWER_SUPPLY_PROP_CAPACITY_LEVEL
,
112 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG
,
113 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW
,
114 POWER_SUPPLY_PROP_MODEL_NAME
,
115 POWER_SUPPLY_PROP_MANUFACTURER
,
116 POWER_SUPPLY_PROP_SERIAL_NUMBER
,
119 static char *test_power_ac_supplied_to
[] = {
123 static struct power_supply test_power_supplies
[] = {
126 .type
= POWER_SUPPLY_TYPE_MAINS
,
127 .supplied_to
= test_power_ac_supplied_to
,
128 .num_supplicants
= ARRAY_SIZE(test_power_ac_supplied_to
),
129 .properties
= test_power_ac_props
,
130 .num_properties
= ARRAY_SIZE(test_power_ac_props
),
131 .get_property
= test_power_get_ac_property
,
133 .name
= "test_battery",
134 .type
= POWER_SUPPLY_TYPE_BATTERY
,
135 .properties
= test_power_battery_props
,
136 .num_properties
= ARRAY_SIZE(test_power_battery_props
),
137 .get_property
= test_power_get_battery_property
,
142 static int __init
test_power_init(void)
147 for (i
= 0; i
< ARRAY_SIZE(test_power_supplies
); i
++) {
148 ret
= power_supply_register(NULL
, &test_power_supplies
[i
]);
150 pr_err("%s: failed to register %s\n", __func__
,
151 test_power_supplies
[i
].name
);
159 power_supply_unregister(&test_power_supplies
[i
]);
162 module_init(test_power_init
);
164 static void __exit
test_power_exit(void)
168 /* Let's see how we handle changes... */
170 battery_status
= POWER_SUPPLY_STATUS_DISCHARGING
;
171 for (i
= 0; i
< ARRAY_SIZE(test_power_supplies
); i
++)
172 power_supply_changed(&test_power_supplies
[i
]);
173 pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n",
177 for (i
= 0; i
< ARRAY_SIZE(test_power_supplies
); i
++)
178 power_supply_unregister(&test_power_supplies
[i
]);
180 module_exit(test_power_exit
);
184 #define MAX_KEYLENGTH 256
185 struct battery_property_map
{
190 static struct battery_property_map map_ac_online
[] = {
196 static struct battery_property_map map_status
[] = {
197 { POWER_SUPPLY_STATUS_CHARGING
, "charging" },
198 { POWER_SUPPLY_STATUS_DISCHARGING
, "discharging" },
199 { POWER_SUPPLY_STATUS_NOT_CHARGING
, "not-charging" },
200 { POWER_SUPPLY_STATUS_FULL
, "full" },
204 static struct battery_property_map map_health
[] = {
205 { POWER_SUPPLY_HEALTH_GOOD
, "good" },
206 { POWER_SUPPLY_HEALTH_OVERHEAT
, "overheat" },
207 { POWER_SUPPLY_HEALTH_DEAD
, "dead" },
208 { POWER_SUPPLY_HEALTH_OVERVOLTAGE
, "overvoltage" },
209 { POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
, "failure" },
213 static struct battery_property_map map_present
[] = {
219 static struct battery_property_map map_technology
[] = {
220 { POWER_SUPPLY_TECHNOLOGY_NiMH
, "NiMH" },
221 { POWER_SUPPLY_TECHNOLOGY_LION
, "LION" },
222 { POWER_SUPPLY_TECHNOLOGY_LIPO
, "LIPO" },
223 { POWER_SUPPLY_TECHNOLOGY_LiFe
, "LiFe" },
224 { POWER_SUPPLY_TECHNOLOGY_NiCd
, "NiCd" },
225 { POWER_SUPPLY_TECHNOLOGY_LiMn
, "LiMn" },
230 static int map_get_value(struct battery_property_map
*map
, const char *key
,
233 char buf
[MAX_KEYLENGTH
];
236 strncpy(buf
, key
, MAX_KEYLENGTH
);
237 buf
[MAX_KEYLENGTH
-1] = '\0';
239 cr
= strnlen(buf
, MAX_KEYLENGTH
) - 1;
244 if (strncasecmp(map
->key
, buf
, MAX_KEYLENGTH
) == 0)
253 static const char *map_get_key(struct battery_property_map
*map
, int value
,
257 if (map
->value
== value
)
265 static int param_set_ac_online(const char *key
, const struct kernel_param
*kp
)
267 ac_online
= map_get_value(map_ac_online
, key
, ac_online
);
268 power_supply_changed(&test_power_supplies
[0]);
272 static int param_get_ac_online(char *buffer
, const struct kernel_param
*kp
)
274 strcpy(buffer
, map_get_key(map_ac_online
, ac_online
, "unknown"));
275 return strlen(buffer
);
278 static int param_set_battery_status(const char *key
,
279 const struct kernel_param
*kp
)
281 battery_status
= map_get_value(map_status
, key
, battery_status
);
282 power_supply_changed(&test_power_supplies
[1]);
286 static int param_get_battery_status(char *buffer
, const struct kernel_param
*kp
)
288 strcpy(buffer
, map_get_key(map_status
, battery_status
, "unknown"));
289 return strlen(buffer
);
292 static int param_set_battery_health(const char *key
,
293 const struct kernel_param
*kp
)
295 battery_health
= map_get_value(map_health
, key
, battery_health
);
296 power_supply_changed(&test_power_supplies
[1]);
300 static int param_get_battery_health(char *buffer
, const struct kernel_param
*kp
)
302 strcpy(buffer
, map_get_key(map_health
, battery_health
, "unknown"));
303 return strlen(buffer
);
306 static int param_set_battery_present(const char *key
,
307 const struct kernel_param
*kp
)
309 battery_present
= map_get_value(map_present
, key
, battery_present
);
310 power_supply_changed(&test_power_supplies
[0]);
314 static int param_get_battery_present(char *buffer
,
315 const struct kernel_param
*kp
)
317 strcpy(buffer
, map_get_key(map_present
, battery_present
, "unknown"));
318 return strlen(buffer
);
321 static int param_set_battery_technology(const char *key
,
322 const struct kernel_param
*kp
)
324 battery_technology
= map_get_value(map_technology
, key
,
326 power_supply_changed(&test_power_supplies
[1]);
330 static int param_get_battery_technology(char *buffer
,
331 const struct kernel_param
*kp
)
334 map_get_key(map_technology
, battery_technology
, "unknown"));
335 return strlen(buffer
);
338 static int param_set_battery_capacity(const char *key
,
339 const struct kernel_param
*kp
)
343 if (1 != sscanf(key
, "%d", &tmp
))
346 battery_capacity
= tmp
;
347 power_supply_changed(&test_power_supplies
[1]);
351 #define param_get_battery_capacity param_get_int
355 static struct kernel_param_ops param_ops_ac_online
= {
356 .set
= param_set_ac_online
,
357 .get
= param_get_ac_online
,
360 static struct kernel_param_ops param_ops_battery_status
= {
361 .set
= param_set_battery_status
,
362 .get
= param_get_battery_status
,
365 static struct kernel_param_ops param_ops_battery_present
= {
366 .set
= param_set_battery_present
,
367 .get
= param_get_battery_present
,
370 static struct kernel_param_ops param_ops_battery_technology
= {
371 .set
= param_set_battery_technology
,
372 .get
= param_get_battery_technology
,
375 static struct kernel_param_ops param_ops_battery_health
= {
376 .set
= param_set_battery_health
,
377 .get
= param_get_battery_health
,
380 static struct kernel_param_ops param_ops_battery_capacity
= {
381 .set
= param_set_battery_capacity
,
382 .get
= param_get_battery_capacity
,
386 #define param_check_ac_online(name, p) __param_check(name, p, void);
387 #define param_check_battery_status(name, p) __param_check(name, p, void);
388 #define param_check_battery_present(name, p) __param_check(name, p, void);
389 #define param_check_battery_technology(name, p) __param_check(name, p, void);
390 #define param_check_battery_health(name, p) __param_check(name, p, void);
391 #define param_check_battery_capacity(name, p) __param_check(name, p, void);
394 module_param(ac_online
, ac_online
, 0644);
395 MODULE_PARM_DESC(ac_online
, "AC charging state <on|off>");
397 module_param(battery_status
, battery_status
, 0644);
398 MODULE_PARM_DESC(battery_status
,
399 "battery status <charging|discharging|not-charging|full>");
401 module_param(battery_present
, battery_present
, 0644);
402 MODULE_PARM_DESC(battery_present
,
403 "battery presence state <good|overheat|dead|overvoltage|failure>");
405 module_param(battery_technology
, battery_technology
, 0644);
406 MODULE_PARM_DESC(battery_technology
,
407 "battery technology <NiMH|LION|LIPO|LiFe|NiCd|LiMn>");
409 module_param(battery_health
, battery_health
, 0644);
410 MODULE_PARM_DESC(battery_health
,
411 "battery health state <good|overheat|dead|overvoltage|failure>");
413 module_param(battery_capacity
, battery_capacity
, 0644);
414 MODULE_PARM_DESC(battery_capacity
, "battery capacity (percentage)");
417 MODULE_DESCRIPTION("Power supply driver for testing");
418 MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");
419 MODULE_LICENSE("GPL");