Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.7-rc6 494 lines 14 kB view raw
1/* 2 * Power supply driver for testing. 3 * 4 * Copyright 2010 Anton Vorontsov <cbouatmailru@gmail.com> 5 * 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 11 * 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. 15 */ 16 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> 23 24static int ac_online = 1; 25static int usb_online = 1; 26static int battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 27static int battery_health = POWER_SUPPLY_HEALTH_GOOD; 28static int battery_present = 1; /* true */ 29static int battery_technology = POWER_SUPPLY_TECHNOLOGY_LION; 30static int battery_capacity = 50; 31static int battery_voltage = 3300; 32 33static int test_power_get_ac_property(struct power_supply *psy, 34 enum power_supply_property psp, 35 union power_supply_propval *val) 36{ 37 switch (psp) { 38 case POWER_SUPPLY_PROP_ONLINE: 39 val->intval = ac_online; 40 break; 41 default: 42 return -EINVAL; 43 } 44 return 0; 45} 46 47static int test_power_get_usb_property(struct power_supply *psy, 48 enum power_supply_property psp, 49 union power_supply_propval *val) 50{ 51 switch (psp) { 52 case POWER_SUPPLY_PROP_ONLINE: 53 val->intval = usb_online; 54 break; 55 default: 56 return -EINVAL; 57 } 58 return 0; 59} 60 61static int test_power_get_battery_property(struct power_supply *psy, 62 enum power_supply_property psp, 63 union power_supply_propval *val) 64{ 65 switch (psp) { 66 case POWER_SUPPLY_PROP_MODEL_NAME: 67 val->strval = "Test battery"; 68 break; 69 case POWER_SUPPLY_PROP_MANUFACTURER: 70 val->strval = "Linux"; 71 break; 72 case POWER_SUPPLY_PROP_SERIAL_NUMBER: 73 val->strval = UTS_RELEASE; 74 break; 75 case POWER_SUPPLY_PROP_STATUS: 76 val->intval = battery_status; 77 break; 78 case POWER_SUPPLY_PROP_CHARGE_TYPE: 79 val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; 80 break; 81 case POWER_SUPPLY_PROP_HEALTH: 82 val->intval = battery_health; 83 break; 84 case POWER_SUPPLY_PROP_PRESENT: 85 val->intval = battery_present; 86 break; 87 case POWER_SUPPLY_PROP_TECHNOLOGY: 88 val->intval = battery_technology; 89 break; 90 case POWER_SUPPLY_PROP_CAPACITY_LEVEL: 91 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; 92 break; 93 case POWER_SUPPLY_PROP_CAPACITY: 94 case POWER_SUPPLY_PROP_CHARGE_NOW: 95 val->intval = battery_capacity; 96 break; 97 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 98 case POWER_SUPPLY_PROP_CHARGE_FULL: 99 val->intval = 100; 100 break; 101 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 102 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: 103 val->intval = 3600; 104 break; 105 case POWER_SUPPLY_PROP_TEMP: 106 val->intval = 26; 107 break; 108 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 109 val->intval = battery_voltage; 110 break; 111 default: 112 pr_info("%s: some properties deliberately report errors.\n", 113 __func__); 114 return -EINVAL; 115 } 116 return 0; 117} 118 119static enum power_supply_property test_power_ac_props[] = { 120 POWER_SUPPLY_PROP_ONLINE, 121}; 122 123static 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, 141}; 142 143static char *test_power_ac_supplied_to[] = { 144 "test_battery", 145}; 146 147static struct power_supply test_power_supplies[] = { 148 { 149 .name = "test_ac", 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, 156 }, { 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, 162 }, { 163 .name = "test_usb", 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, 170 }, 171}; 172 173 174static int __init test_power_init(void) 175{ 176 int i; 177 int ret; 178 179 for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) { 180 ret = power_supply_register(NULL, &test_power_supplies[i]); 181 if (ret) { 182 pr_err("%s: failed to register %s\n", __func__, 183 test_power_supplies[i].name); 184 goto failed; 185 } 186 } 187 188 return 0; 189failed: 190 while (--i >= 0) 191 power_supply_unregister(&test_power_supplies[i]); 192 return ret; 193} 194module_init(test_power_init); 195 196static void __exit test_power_exit(void) 197{ 198 int i; 199 200 /* Let's see how we handle changes... */ 201 ac_online = 0; 202 usb_online = 0; 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", 207 __func__); 208 ssleep(10); 209 210 for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) 211 power_supply_unregister(&test_power_supplies[i]); 212} 213module_exit(test_power_exit); 214 215 216 217#define MAX_KEYLENGTH 256 218struct battery_property_map { 219 int value; 220 char const *key; 221}; 222 223static struct battery_property_map map_ac_online[] = { 224 { 0, "on" }, 225 { 1, "off" }, 226 { -1, NULL }, 227}; 228 229static 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" }, 234 { -1, NULL }, 235}; 236 237static 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" }, 243 { -1, NULL }, 244}; 245 246static struct battery_property_map map_present[] = { 247 { 0, "false" }, 248 { 1, "true" }, 249 { -1, NULL }, 250}; 251 252static 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" }, 259 { -1, NULL }, 260}; 261 262 263static int map_get_value(struct battery_property_map *map, const char *key, 264 int def_val) 265{ 266 char buf[MAX_KEYLENGTH]; 267 int cr; 268 269 strncpy(buf, key, MAX_KEYLENGTH); 270 buf[MAX_KEYLENGTH-1] = '\0'; 271 272 cr = strnlen(buf, MAX_KEYLENGTH) - 1; 273 if (buf[cr] == '\n') 274 buf[cr] = '\0'; 275 276 while (map->key) { 277 if (strncasecmp(map->key, buf, MAX_KEYLENGTH) == 0) 278 return map->value; 279 map++; 280 } 281 282 return def_val; 283} 284 285 286static const char *map_get_key(struct battery_property_map *map, int value, 287 const char *def_key) 288{ 289 while (map->key) { 290 if (map->value == value) 291 return map->key; 292 map++; 293 } 294 295 return def_key; 296} 297 298static int param_set_ac_online(const char *key, const struct kernel_param *kp) 299{ 300 ac_online = map_get_value(map_ac_online, key, ac_online); 301 power_supply_changed(&test_power_supplies[0]); 302 return 0; 303} 304 305static int param_get_ac_online(char *buffer, const struct kernel_param *kp) 306{ 307 strcpy(buffer, map_get_key(map_ac_online, ac_online, "unknown")); 308 return strlen(buffer); 309} 310 311static int param_set_usb_online(const char *key, const struct kernel_param *kp) 312{ 313 usb_online = map_get_value(map_ac_online, key, usb_online); 314 power_supply_changed(&test_power_supplies[2]); 315 return 0; 316} 317 318static int param_get_usb_online(char *buffer, const struct kernel_param *kp) 319{ 320 strcpy(buffer, map_get_key(map_ac_online, usb_online, "unknown")); 321 return strlen(buffer); 322} 323 324static int param_set_battery_status(const char *key, 325 const struct kernel_param *kp) 326{ 327 battery_status = map_get_value(map_status, key, battery_status); 328 power_supply_changed(&test_power_supplies[1]); 329 return 0; 330} 331 332static int param_get_battery_status(char *buffer, const struct kernel_param *kp) 333{ 334 strcpy(buffer, map_get_key(map_status, battery_status, "unknown")); 335 return strlen(buffer); 336} 337 338static int param_set_battery_health(const char *key, 339 const struct kernel_param *kp) 340{ 341 battery_health = map_get_value(map_health, key, battery_health); 342 power_supply_changed(&test_power_supplies[1]); 343 return 0; 344} 345 346static int param_get_battery_health(char *buffer, const struct kernel_param *kp) 347{ 348 strcpy(buffer, map_get_key(map_health, battery_health, "unknown")); 349 return strlen(buffer); 350} 351 352static int param_set_battery_present(const char *key, 353 const struct kernel_param *kp) 354{ 355 battery_present = map_get_value(map_present, key, battery_present); 356 power_supply_changed(&test_power_supplies[0]); 357 return 0; 358} 359 360static int param_get_battery_present(char *buffer, 361 const struct kernel_param *kp) 362{ 363 strcpy(buffer, map_get_key(map_present, battery_present, "unknown")); 364 return strlen(buffer); 365} 366 367static int param_set_battery_technology(const char *key, 368 const struct kernel_param *kp) 369{ 370 battery_technology = map_get_value(map_technology, key, 371 battery_technology); 372 power_supply_changed(&test_power_supplies[1]); 373 return 0; 374} 375 376static int param_get_battery_technology(char *buffer, 377 const struct kernel_param *kp) 378{ 379 strcpy(buffer, 380 map_get_key(map_technology, battery_technology, "unknown")); 381 return strlen(buffer); 382} 383 384static int param_set_battery_capacity(const char *key, 385 const struct kernel_param *kp) 386{ 387 int tmp; 388 389 if (1 != sscanf(key, "%d", &tmp)) 390 return -EINVAL; 391 392 battery_capacity = tmp; 393 power_supply_changed(&test_power_supplies[1]); 394 return 0; 395} 396 397#define param_get_battery_capacity param_get_int 398 399static int param_set_battery_voltage(const char *key, 400 const struct kernel_param *kp) 401{ 402 int tmp; 403 404 if (1 != sscanf(key, "%d", &tmp)) 405 return -EINVAL; 406 407 battery_voltage = tmp; 408 power_supply_changed(&test_power_supplies[1]); 409 return 0; 410} 411 412#define param_get_battery_voltage param_get_int 413 414static struct kernel_param_ops param_ops_ac_online = { 415 .set = param_set_ac_online, 416 .get = param_get_ac_online, 417}; 418 419static struct kernel_param_ops param_ops_usb_online = { 420 .set = param_set_usb_online, 421 .get = param_get_usb_online, 422}; 423 424static struct kernel_param_ops param_ops_battery_status = { 425 .set = param_set_battery_status, 426 .get = param_get_battery_status, 427}; 428 429static struct kernel_param_ops param_ops_battery_present = { 430 .set = param_set_battery_present, 431 .get = param_get_battery_present, 432}; 433 434static struct kernel_param_ops param_ops_battery_technology = { 435 .set = param_set_battery_technology, 436 .get = param_get_battery_technology, 437}; 438 439static struct kernel_param_ops param_ops_battery_health = { 440 .set = param_set_battery_health, 441 .get = param_get_battery_health, 442}; 443 444static struct kernel_param_ops param_ops_battery_capacity = { 445 .set = param_set_battery_capacity, 446 .get = param_get_battery_capacity, 447}; 448 449static struct kernel_param_ops param_ops_battery_voltage = { 450 .set = param_set_battery_voltage, 451 .get = param_get_battery_voltage, 452}; 453 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); 462 463 464module_param(ac_online, ac_online, 0644); 465MODULE_PARM_DESC(ac_online, "AC charging state <on|off>"); 466 467module_param(usb_online, usb_online, 0644); 468MODULE_PARM_DESC(usb_online, "USB charging state <on|off>"); 469 470module_param(battery_status, battery_status, 0644); 471MODULE_PARM_DESC(battery_status, 472 "battery status <charging|discharging|not-charging|full>"); 473 474module_param(battery_present, battery_present, 0644); 475MODULE_PARM_DESC(battery_present, 476 "battery presence state <good|overheat|dead|overvoltage|failure>"); 477 478module_param(battery_technology, battery_technology, 0644); 479MODULE_PARM_DESC(battery_technology, 480 "battery technology <NiMH|LION|LIPO|LiFe|NiCd|LiMn>"); 481 482module_param(battery_health, battery_health, 0644); 483MODULE_PARM_DESC(battery_health, 484 "battery health state <good|overheat|dead|overvoltage|failure>"); 485 486module_param(battery_capacity, battery_capacity, 0644); 487MODULE_PARM_DESC(battery_capacity, "battery capacity (percentage)"); 488 489module_param(battery_voltage, battery_voltage, 0644); 490MODULE_PARM_DESC(battery_voltage, "battery voltage (millivolts)"); 491 492MODULE_DESCRIPTION("Power supply driver for testing"); 493MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); 494MODULE_LICENSE("GPL");