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 int test_power_get_ac_property(struct power_supply
*psy
,
34 enum power_supply_property psp
,
35 union power_supply_propval
*val
)
38 case POWER_SUPPLY_PROP_ONLINE
:
39 val
->intval
= ac_online
;
47 static int test_power_get_usb_property(struct power_supply
*psy
,
48 enum power_supply_property psp
,
49 union power_supply_propval
*val
)
52 case POWER_SUPPLY_PROP_ONLINE
:
53 val
->intval
= usb_online
;
61 static int test_power_get_battery_property(struct power_supply
*psy
,
62 enum power_supply_property psp
,
63 union power_supply_propval
*val
)
66 case POWER_SUPPLY_PROP_MODEL_NAME
:
67 val
->strval
= "Test battery";
69 case POWER_SUPPLY_PROP_MANUFACTURER
:
70 val
->strval
= "Linux";
72 case POWER_SUPPLY_PROP_SERIAL_NUMBER
:
73 val
->strval
= UTS_RELEASE
;
75 case POWER_SUPPLY_PROP_STATUS
:
76 val
->intval
= battery_status
;
78 case POWER_SUPPLY_PROP_CHARGE_TYPE
:
79 val
->intval
= POWER_SUPPLY_CHARGE_TYPE_FAST
;
81 case POWER_SUPPLY_PROP_HEALTH
:
82 val
->intval
= battery_health
;
84 case POWER_SUPPLY_PROP_PRESENT
:
85 val
->intval
= battery_present
;
87 case POWER_SUPPLY_PROP_TECHNOLOGY
:
88 val
->intval
= battery_technology
;
90 case POWER_SUPPLY_PROP_CAPACITY_LEVEL
:
91 val
->intval
= POWER_SUPPLY_CAPACITY_LEVEL_NORMAL
;
93 case POWER_SUPPLY_PROP_CAPACITY
:
94 case POWER_SUPPLY_PROP_CHARGE_NOW
:
95 val
->intval
= battery_capacity
;
97 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN
:
98 case POWER_SUPPLY_PROP_CHARGE_FULL
:
101 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG
:
102 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW
:
105 case POWER_SUPPLY_PROP_TEMP
:
108 case POWER_SUPPLY_PROP_VOLTAGE_NOW
:
109 val
->intval
= battery_voltage
;
112 pr_info("%s: some properties deliberately report errors.\n",
119 static enum power_supply_property test_power_ac_props
[] = {
120 POWER_SUPPLY_PROP_ONLINE
,
123 static enum power_supply_property test_power_battery_props
[] = {
124 POWER_SUPPLY_PROP_STATUS
,
125 POWER_SUPPLY_PROP_CHARGE_TYPE
,
126 POWER_SUPPLY_PROP_HEALTH
,
127 POWER_SUPPLY_PROP_PRESENT
,
128 POWER_SUPPLY_PROP_TECHNOLOGY
,
129 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN
,
130 POWER_SUPPLY_PROP_CHARGE_FULL
,
131 POWER_SUPPLY_PROP_CHARGE_NOW
,
132 POWER_SUPPLY_PROP_CAPACITY
,
133 POWER_SUPPLY_PROP_CAPACITY_LEVEL
,
134 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG
,
135 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW
,
136 POWER_SUPPLY_PROP_MODEL_NAME
,
137 POWER_SUPPLY_PROP_MANUFACTURER
,
138 POWER_SUPPLY_PROP_SERIAL_NUMBER
,
139 POWER_SUPPLY_PROP_TEMP
,
140 POWER_SUPPLY_PROP_VOLTAGE_NOW
,
143 static char *test_power_ac_supplied_to
[] = {
147 static struct power_supply test_power_supplies
[] = {
150 .type
= POWER_SUPPLY_TYPE_MAINS
,
151 .supplied_to
= test_power_ac_supplied_to
,
152 .num_supplicants
= ARRAY_SIZE(test_power_ac_supplied_to
),
153 .properties
= test_power_ac_props
,
154 .num_properties
= ARRAY_SIZE(test_power_ac_props
),
155 .get_property
= test_power_get_ac_property
,
157 .name
= "test_battery",
158 .type
= POWER_SUPPLY_TYPE_BATTERY
,
159 .properties
= test_power_battery_props
,
160 .num_properties
= ARRAY_SIZE(test_power_battery_props
),
161 .get_property
= test_power_get_battery_property
,
164 .type
= POWER_SUPPLY_TYPE_USB
,
165 .supplied_to
= test_power_ac_supplied_to
,
166 .num_supplicants
= ARRAY_SIZE(test_power_ac_supplied_to
),
167 .properties
= test_power_ac_props
,
168 .num_properties
= ARRAY_SIZE(test_power_ac_props
),
169 .get_property
= test_power_get_usb_property
,
174 static int __init
test_power_init(void)
179 for (i
= 0; i
< ARRAY_SIZE(test_power_supplies
); i
++) {
180 ret
= power_supply_register(NULL
, &test_power_supplies
[i
]);
182 pr_err("%s: failed to register %s\n", __func__
,
183 test_power_supplies
[i
].name
);
191 power_supply_unregister(&test_power_supplies
[i
]);
194 module_init(test_power_init
);
196 static void __exit
test_power_exit(void)
200 /* Let's see how we handle changes... */
203 battery_status
= POWER_SUPPLY_STATUS_DISCHARGING
;
204 for (i
= 0; i
< ARRAY_SIZE(test_power_supplies
); i
++)
205 power_supply_changed(&test_power_supplies
[i
]);
206 pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n",
210 for (i
= 0; i
< ARRAY_SIZE(test_power_supplies
); i
++)
211 power_supply_unregister(&test_power_supplies
[i
]);
213 module_exit(test_power_exit
);
217 #define MAX_KEYLENGTH 256
218 struct battery_property_map
{
223 static struct battery_property_map map_ac_online
[] = {
229 static struct battery_property_map map_status
[] = {
230 { POWER_SUPPLY_STATUS_CHARGING
, "charging" },
231 { POWER_SUPPLY_STATUS_DISCHARGING
, "discharging" },
232 { POWER_SUPPLY_STATUS_NOT_CHARGING
, "not-charging" },
233 { POWER_SUPPLY_STATUS_FULL
, "full" },
237 static struct battery_property_map map_health
[] = {
238 { POWER_SUPPLY_HEALTH_GOOD
, "good" },
239 { POWER_SUPPLY_HEALTH_OVERHEAT
, "overheat" },
240 { POWER_SUPPLY_HEALTH_DEAD
, "dead" },
241 { POWER_SUPPLY_HEALTH_OVERVOLTAGE
, "overvoltage" },
242 { POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
, "failure" },
246 static struct battery_property_map map_present
[] = {
252 static struct battery_property_map map_technology
[] = {
253 { POWER_SUPPLY_TECHNOLOGY_NiMH
, "NiMH" },
254 { POWER_SUPPLY_TECHNOLOGY_LION
, "LION" },
255 { POWER_SUPPLY_TECHNOLOGY_LIPO
, "LIPO" },
256 { POWER_SUPPLY_TECHNOLOGY_LiFe
, "LiFe" },
257 { POWER_SUPPLY_TECHNOLOGY_NiCd
, "NiCd" },
258 { POWER_SUPPLY_TECHNOLOGY_LiMn
, "LiMn" },
263 static int map_get_value(struct battery_property_map
*map
, const char *key
,
266 char buf
[MAX_KEYLENGTH
];
269 strncpy(buf
, key
, MAX_KEYLENGTH
);
270 buf
[MAX_KEYLENGTH
-1] = '\0';
272 cr
= strnlen(buf
, MAX_KEYLENGTH
) - 1;
277 if (strncasecmp(map
->key
, buf
, MAX_KEYLENGTH
) == 0)
286 static const char *map_get_key(struct battery_property_map
*map
, int value
,
290 if (map
->value
== value
)
298 static int param_set_ac_online(const char *key
, const struct kernel_param
*kp
)
300 ac_online
= map_get_value(map_ac_online
, key
, ac_online
);
301 power_supply_changed(&test_power_supplies
[0]);
305 static int param_get_ac_online(char *buffer
, const struct kernel_param
*kp
)
307 strcpy(buffer
, map_get_key(map_ac_online
, ac_online
, "unknown"));
308 return strlen(buffer
);
311 static int param_set_usb_online(const char *key
, const struct kernel_param
*kp
)
313 usb_online
= map_get_value(map_ac_online
, key
, usb_online
);
314 power_supply_changed(&test_power_supplies
[2]);
318 static int param_get_usb_online(char *buffer
, const struct kernel_param
*kp
)
320 strcpy(buffer
, map_get_key(map_ac_online
, usb_online
, "unknown"));
321 return strlen(buffer
);
324 static int param_set_battery_status(const char *key
,
325 const struct kernel_param
*kp
)
327 battery_status
= map_get_value(map_status
, key
, battery_status
);
328 power_supply_changed(&test_power_supplies
[1]);
332 static int param_get_battery_status(char *buffer
, const struct kernel_param
*kp
)
334 strcpy(buffer
, map_get_key(map_status
, battery_status
, "unknown"));
335 return strlen(buffer
);
338 static int param_set_battery_health(const char *key
,
339 const struct kernel_param
*kp
)
341 battery_health
= map_get_value(map_health
, key
, battery_health
);
342 power_supply_changed(&test_power_supplies
[1]);
346 static int param_get_battery_health(char *buffer
, const struct kernel_param
*kp
)
348 strcpy(buffer
, map_get_key(map_health
, battery_health
, "unknown"));
349 return strlen(buffer
);
352 static int param_set_battery_present(const char *key
,
353 const struct kernel_param
*kp
)
355 battery_present
= map_get_value(map_present
, key
, battery_present
);
356 power_supply_changed(&test_power_supplies
[0]);
360 static int param_get_battery_present(char *buffer
,
361 const struct kernel_param
*kp
)
363 strcpy(buffer
, map_get_key(map_present
, battery_present
, "unknown"));
364 return strlen(buffer
);
367 static int param_set_battery_technology(const char *key
,
368 const struct kernel_param
*kp
)
370 battery_technology
= map_get_value(map_technology
, key
,
372 power_supply_changed(&test_power_supplies
[1]);
376 static int param_get_battery_technology(char *buffer
,
377 const struct kernel_param
*kp
)
380 map_get_key(map_technology
, battery_technology
, "unknown"));
381 return strlen(buffer
);
384 static int param_set_battery_capacity(const char *key
,
385 const struct kernel_param
*kp
)
389 if (1 != sscanf(key
, "%d", &tmp
))
392 battery_capacity
= tmp
;
393 power_supply_changed(&test_power_supplies
[1]);
397 #define param_get_battery_capacity param_get_int
399 static int param_set_battery_voltage(const char *key
,
400 const struct kernel_param
*kp
)
404 if (1 != sscanf(key
, "%d", &tmp
))
407 battery_voltage
= tmp
;
408 power_supply_changed(&test_power_supplies
[1]);
412 #define param_get_battery_voltage param_get_int
414 static struct kernel_param_ops param_ops_ac_online
= {
415 .set
= param_set_ac_online
,
416 .get
= param_get_ac_online
,
419 static struct kernel_param_ops param_ops_usb_online
= {
420 .set
= param_set_usb_online
,
421 .get
= param_get_usb_online
,
424 static struct kernel_param_ops param_ops_battery_status
= {
425 .set
= param_set_battery_status
,
426 .get
= param_get_battery_status
,
429 static struct kernel_param_ops param_ops_battery_present
= {
430 .set
= param_set_battery_present
,
431 .get
= param_get_battery_present
,
434 static struct kernel_param_ops param_ops_battery_technology
= {
435 .set
= param_set_battery_technology
,
436 .get
= param_get_battery_technology
,
439 static struct kernel_param_ops param_ops_battery_health
= {
440 .set
= param_set_battery_health
,
441 .get
= param_get_battery_health
,
444 static struct kernel_param_ops param_ops_battery_capacity
= {
445 .set
= param_set_battery_capacity
,
446 .get
= param_get_battery_capacity
,
449 static struct kernel_param_ops param_ops_battery_voltage
= {
450 .set
= param_set_battery_voltage
,
451 .get
= param_get_battery_voltage
,
454 #define param_check_ac_online(name, p) __param_check(name, p, void);
455 #define param_check_usb_online(name, p) __param_check(name, p, void);
456 #define param_check_battery_status(name, p) __param_check(name, p, void);
457 #define param_check_battery_present(name, p) __param_check(name, p, void);
458 #define param_check_battery_technology(name, p) __param_check(name, p, void);
459 #define param_check_battery_health(name, p) __param_check(name, p, void);
460 #define param_check_battery_capacity(name, p) __param_check(name, p, void);
461 #define param_check_battery_voltage(name, p) __param_check(name, p, void);
464 module_param(ac_online
, ac_online
, 0644);
465 MODULE_PARM_DESC(ac_online
, "AC charging state <on|off>");
467 module_param(usb_online
, usb_online
, 0644);
468 MODULE_PARM_DESC(usb_online
, "USB charging state <on|off>");
470 module_param(battery_status
, battery_status
, 0644);
471 MODULE_PARM_DESC(battery_status
,
472 "battery status <charging|discharging|not-charging|full>");
474 module_param(battery_present
, battery_present
, 0644);
475 MODULE_PARM_DESC(battery_present
,
476 "battery presence state <good|overheat|dead|overvoltage|failure>");
478 module_param(battery_technology
, battery_technology
, 0644);
479 MODULE_PARM_DESC(battery_technology
,
480 "battery technology <NiMH|LION|LIPO|LiFe|NiCd|LiMn>");
482 module_param(battery_health
, battery_health
, 0644);
483 MODULE_PARM_DESC(battery_health
,
484 "battery health state <good|overheat|dead|overvoltage|failure>");
486 module_param(battery_capacity
, battery_capacity
, 0644);
487 MODULE_PARM_DESC(battery_capacity
, "battery capacity (percentage)");
489 module_param(battery_voltage
, battery_voltage
, 0644);
490 MODULE_PARM_DESC(battery_voltage
, "battery voltage (millivolts)");
492 MODULE_DESCRIPTION("Power supply driver for testing");
493 MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");
494 MODULE_LICENSE("GPL");