1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Power supply driver for testing. 4 * 5 * Copyright 2010 Anton Vorontsov <cbouatmailru@gmail.com> 6 * 7 * Dynamic module parameter code from the Virtual Battery Driver 8 * Copyright (C) 2008 Pylone, Inc. 9 * By: Masashi YOKOTA <yokota@pylone.jp> 10 * Originally found here: 11 * http://downloads.pylone.jp/src/virtual_battery/virtual_battery-0.0.1.tar.bz2 12 */ 13 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/power_supply.h> 17 #include <linux/errno.h> 18 #include <linux/delay.h> 19 #include <generated/utsrelease.h> 20 21 enum test_power_id { 22 TEST_AC, 23 TEST_BATTERY, 24 TEST_USB, 25 TEST_POWER_NUM, 26 }; 27 28 static int ac_online = 1; 29 static int usb_online = 1; 30 static int battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 31 static int battery_health = POWER_SUPPLY_HEALTH_GOOD; 32 static int battery_present = 1; /* true */ 33 static int battery_technology = POWER_SUPPLY_TECHNOLOGY_LION; 34 static int battery_capacity = 50; 35 static int battery_voltage = 3300; 36 static int battery_charge_counter = -1000; 37 static int battery_current = -1600; 38 static enum power_supply_charge_behaviour battery_charge_behaviour = 39 POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO; 40 static enum power_supply_charge_type battery_charge_types = 41 POWER_SUPPLY_CHARGE_TYPE_STANDARD; 42 static bool battery_extension; 43 44 static bool module_initialized; 45 46 static int test_power_get_ac_property(struct power_supply *psy, 47 enum power_supply_property psp, 48 union power_supply_propval *val) 49 { 50 switch (psp) { 51 case POWER_SUPPLY_PROP_ONLINE: 52 val->intval = ac_online; 53 break; 54 default: 55 return -EINVAL; 56 } 57 return 0; 58 } 59 60 static int test_power_get_usb_property(struct power_supply *psy, 61 enum power_supply_property psp, 62 union power_supply_propval *val) 63 { 64 switch (psp) { 65 case POWER_SUPPLY_PROP_ONLINE: 66 val->intval = usb_online; 67 break; 68 default: 69 return -EINVAL; 70 } 71 return 0; 72 } 73 74 static int test_power_get_battery_property(struct power_supply *psy, 75 enum power_supply_property psp, 76 union power_supply_propval *val) 77 { 78 switch (psp) { 79 case POWER_SUPPLY_PROP_MODEL_NAME: 80 val->strval = "Test battery"; 81 break; 82 case POWER_SUPPLY_PROP_MANUFACTURER: 83 val->strval = "Linux"; 84 break; 85 case POWER_SUPPLY_PROP_SERIAL_NUMBER: 86 val->strval = UTS_RELEASE; 87 break; 88 case POWER_SUPPLY_PROP_STATUS: 89 val->intval = battery_status; 90 break; 91 case POWER_SUPPLY_PROP_CHARGE_TYPE: 92 val->intval = battery_charge_types; 93 break; 94 case POWER_SUPPLY_PROP_HEALTH: 95 val->intval = battery_health; 96 break; 97 case POWER_SUPPLY_PROP_PRESENT: 98 val->intval = battery_present; 99 break; 100 case POWER_SUPPLY_PROP_TECHNOLOGY: 101 val->intval = battery_technology; 102 break; 103 case POWER_SUPPLY_PROP_CAPACITY_LEVEL: 104 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; 105 break; 106 case POWER_SUPPLY_PROP_CAPACITY: 107 case POWER_SUPPLY_PROP_CHARGE_NOW: 108 val->intval = battery_capacity; 109 break; 110 case POWER_SUPPLY_PROP_CHARGE_COUNTER: 111 val->intval = battery_charge_counter; 112 break; 113 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: 114 case POWER_SUPPLY_PROP_CHARGE_FULL: 115 val->intval = 100; 116 break; 117 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 118 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: 119 val->intval = 3600; 120 break; 121 case POWER_SUPPLY_PROP_TEMP: 122 val->intval = 26; 123 break; 124 case POWER_SUPPLY_PROP_VOLTAGE_NOW: 125 val->intval = battery_voltage; 126 break; 127 case POWER_SUPPLY_PROP_CURRENT_AVG: 128 case POWER_SUPPLY_PROP_CURRENT_NOW: 129 val->intval = battery_current; 130 break; 131 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: 132 val->intval = battery_charge_behaviour; 133 break; 134 case POWER_SUPPLY_PROP_CHARGE_TYPES: 135 val->intval = battery_charge_types; 136 break; 137 default: 138 pr_info("%s: some properties deliberately report errors.\n", 139 __func__); 140 return -EINVAL; 141 } 142 return 0; 143 } 144 145 static int test_power_battery_property_is_writeable(struct power_supply *psy, 146 enum power_supply_property psp) 147 { 148 return psp == POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR || psp == POWER_SUPPLY_PROP_CHARGE_TYPES; 149 } 150 151 static int test_power_set_battery_property(struct power_supply *psy, 152 enum power_supply_property psp, 153 const union power_supply_propval *val) 154 { 155 switch (psp) { 156 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: 157 if (val->intval < 0 || 158 val->intval >= BITS_PER_TYPE(typeof(psy->desc->charge_behaviours)) || 159 !(BIT(val->intval) & psy->desc->charge_behaviours)) { 160 return -EINVAL; 161 } 162 battery_charge_behaviour = val->intval; 163 break; 164 case POWER_SUPPLY_PROP_CHARGE_TYPES: 165 if (val->intval < 0 || 166 val->intval >= BITS_PER_TYPE(typeof(psy->desc->charge_types)) || 167 !(BIT(val->intval) & psy->desc->charge_types)) { 168 return -EINVAL; 169 } 170 battery_charge_types = val->intval; 171 break; 172 default: 173 return -EINVAL; 174 } 175 return 0; 176 } 177 178 static enum power_supply_property test_power_ac_props[] = { 179 POWER_SUPPLY_PROP_ONLINE, 180 }; 181 182 static enum power_supply_property test_power_battery_props[] = { 183 POWER_SUPPLY_PROP_STATUS, 184 POWER_SUPPLY_PROP_CHARGE_TYPE, 185 POWER_SUPPLY_PROP_HEALTH, 186 POWER_SUPPLY_PROP_PRESENT, 187 POWER_SUPPLY_PROP_TECHNOLOGY, 188 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 189 POWER_SUPPLY_PROP_CHARGE_FULL, 190 POWER_SUPPLY_PROP_CHARGE_NOW, 191 POWER_SUPPLY_PROP_CHARGE_COUNTER, 192 POWER_SUPPLY_PROP_CAPACITY, 193 POWER_SUPPLY_PROP_CAPACITY_LEVEL, 194 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 195 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, 196 POWER_SUPPLY_PROP_MODEL_NAME, 197 POWER_SUPPLY_PROP_MANUFACTURER, 198 POWER_SUPPLY_PROP_SERIAL_NUMBER, 199 POWER_SUPPLY_PROP_TEMP, 200 POWER_SUPPLY_PROP_VOLTAGE_NOW, 201 POWER_SUPPLY_PROP_CURRENT_AVG, 202 POWER_SUPPLY_PROP_CURRENT_NOW, 203 POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR, 204 POWER_SUPPLY_PROP_CHARGE_TYPES, 205 }; 206 207 static char *test_power_ac_supplied_to[] = { 208 "test_battery", 209 }; 210 211 static struct power_supply *test_power_supplies[TEST_POWER_NUM]; 212 213 static const struct power_supply_desc test_power_desc[] = { 214 [TEST_AC] = { 215 .name = "test_ac", 216 .type = POWER_SUPPLY_TYPE_MAINS, 217 .properties = test_power_ac_props, 218 .num_properties = ARRAY_SIZE(test_power_ac_props), 219 .get_property = test_power_get_ac_property, 220 }, 221 [TEST_BATTERY] = { 222 .name = "test_battery", 223 .type = POWER_SUPPLY_TYPE_BATTERY, 224 .properties = test_power_battery_props, 225 .num_properties = ARRAY_SIZE(test_power_battery_props), 226 .get_property = test_power_get_battery_property, 227 .set_property = test_power_set_battery_property, 228 .property_is_writeable = test_power_battery_property_is_writeable, 229 .charge_behaviours = BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_AUTO) 230 | BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE) 231 | BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_INHIBIT_CHARGE_AWAKE) 232 | BIT(POWER_SUPPLY_CHARGE_BEHAVIOUR_FORCE_DISCHARGE), 233 .charge_types = BIT(POWER_SUPPLY_CHARGE_TYPE_STANDARD) 234 | BIT(POWER_SUPPLY_CHARGE_TYPE_LONGLIFE) 235 }, 236 [TEST_USB] = { 237 .name = "test_usb", 238 .type = POWER_SUPPLY_TYPE_USB, 239 .properties = test_power_ac_props, 240 .num_properties = ARRAY_SIZE(test_power_ac_props), 241 .get_property = test_power_get_usb_property, 242 }, 243 }; 244 245 static const struct power_supply_config test_power_configs[] = { 246 { 247 /* test_ac */ 248 .supplied_to = test_power_ac_supplied_to, 249 .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to), 250 }, { 251 /* test_battery */ 252 }, { 253 /* test_usb */ 254 .supplied_to = test_power_ac_supplied_to, 255 .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to), 256 }, 257 }; 258 259 static int test_power_battery_extmanufacture_year = 1234; 260 static int test_power_battery_exttemp_max = 1000; 261 static const enum power_supply_property test_power_battery_extprops[] = { 262 POWER_SUPPLY_PROP_MANUFACTURE_YEAR, 263 POWER_SUPPLY_PROP_TEMP_MAX, 264 }; 265 266 static int test_power_battery_extget_property(struct power_supply *psy, 267 const struct power_supply_ext *ext, 268 void *ext_data, 269 enum power_supply_property psp, 270 union power_supply_propval *val) 271 { 272 switch (psp) { 273 case POWER_SUPPLY_PROP_MANUFACTURE_YEAR: 274 val->intval = test_power_battery_extmanufacture_year; 275 break; 276 case POWER_SUPPLY_PROP_TEMP_MAX: 277 val->intval = test_power_battery_exttemp_max; 278 break; 279 default: 280 return -EINVAL; 281 } 282 return 0; 283 } 284 285 static int test_power_battery_extset_property(struct power_supply *psy, 286 const struct power_supply_ext *ext, 287 void *ext_data, 288 enum power_supply_property psp, 289 const union power_supply_propval *val) 290 { 291 switch (psp) { 292 case POWER_SUPPLY_PROP_MANUFACTURE_YEAR: 293 test_power_battery_extmanufacture_year = val->intval; 294 break; 295 case POWER_SUPPLY_PROP_TEMP_MAX: 296 test_power_battery_exttemp_max = val->intval; 297 break; 298 default: 299 return -EINVAL; 300 } 301 return 0; 302 } 303 304 static int test_power_battery_extproperty_is_writeable(struct power_supply *psy, 305 const struct power_supply_ext *ext, 306 void *ext_data, 307 enum power_supply_property psp) 308 { 309 return true; 310 } 311 312 static const struct power_supply_ext test_power_battery_ext = { 313 .name = "test_power", 314 .properties = test_power_battery_extprops, 315 .num_properties = ARRAY_SIZE(test_power_battery_extprops), 316 .get_property = test_power_battery_extget_property, 317 .set_property = test_power_battery_extset_property, 318 .property_is_writeable = test_power_battery_extproperty_is_writeable, 319 }; 320 321 static void test_power_configure_battery_extension(bool enable) 322 { 323 struct power_supply *psy; 324 325 psy = test_power_supplies[TEST_BATTERY]; 326 327 if (enable) { 328 if (power_supply_register_extension(psy, &test_power_battery_ext, &psy->dev, 329 NULL)) { 330 pr_err("registering battery extension failed\n"); 331 return; 332 } 333 } else { 334 power_supply_unregister_extension(psy, &test_power_battery_ext); 335 } 336 337 battery_extension = enable; 338 } 339 340 static int __init test_power_init(void) 341 { 342 int i; 343 int ret; 344 345 BUILD_BUG_ON(TEST_POWER_NUM != ARRAY_SIZE(test_power_supplies)); 346 BUILD_BUG_ON(TEST_POWER_NUM != ARRAY_SIZE(test_power_configs)); 347 348 for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) { 349 test_power_supplies[i] = power_supply_register(NULL, 350 &test_power_desc[i], 351 &test_power_configs[i]); 352 if (IS_ERR(test_power_supplies[i])) { 353 pr_err("%s: failed to register %s\n", __func__, 354 test_power_desc[i].name); 355 ret = PTR_ERR(test_power_supplies[i]); 356 goto failed; 357 } 358 } 359 360 test_power_configure_battery_extension(true); 361 362 module_initialized = true; 363 return 0; 364 failed: 365 while (--i >= 0) 366 power_supply_unregister(test_power_supplies[i]); 367 return ret; 368 } 369 module_init(test_power_init); 370 371 static void __exit test_power_exit(void) 372 { 373 int i; 374 375 /* Let's see how we handle changes... */ 376 ac_online = 0; 377 usb_online = 0; 378 battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 379 for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) 380 power_supply_changed(test_power_supplies[i]); 381 pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n", 382 __func__); 383 ssleep(10); 384 385 for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) 386 power_supply_unregister(test_power_supplies[i]); 387 388 module_initialized = false; 389 } 390 module_exit(test_power_exit); 391 392 393 394 #define MAX_KEYLENGTH 256 395 struct battery_property_map { 396 int value; 397 char const *key; 398 }; 399 400 static struct battery_property_map map_ac_online[] = { 401 { 0, "off" }, 402 { 1, "on" }, 403 { -1, NULL }, 404 }; 405 406 static struct battery_property_map map_status[] = { 407 { POWER_SUPPLY_STATUS_CHARGING, "charging" }, 408 { POWER_SUPPLY_STATUS_DISCHARGING, "discharging" }, 409 { POWER_SUPPLY_STATUS_NOT_CHARGING, "not-charging" }, 410 { POWER_SUPPLY_STATUS_FULL, "full" }, 411 { -1, NULL }, 412 }; 413 414 static struct battery_property_map map_health[] = { 415 { POWER_SUPPLY_HEALTH_GOOD, "good" }, 416 { POWER_SUPPLY_HEALTH_OVERHEAT, "overheat" }, 417 { POWER_SUPPLY_HEALTH_DEAD, "dead" }, 418 { POWER_SUPPLY_HEALTH_OVERVOLTAGE, "overvoltage" }, 419 { POWER_SUPPLY_HEALTH_UNSPEC_FAILURE, "failure" }, 420 { -1, NULL }, 421 }; 422 423 static struct battery_property_map map_present[] = { 424 { 0, "false" }, 425 { 1, "true" }, 426 { -1, NULL }, 427 }; 428 429 static struct battery_property_map map_technology[] = { 430 { POWER_SUPPLY_TECHNOLOGY_NiMH, "NiMH" }, 431 { POWER_SUPPLY_TECHNOLOGY_LION, "LION" }, 432 { POWER_SUPPLY_TECHNOLOGY_LIPO, "LIPO" }, 433 { POWER_SUPPLY_TECHNOLOGY_LiFe, "LiFe" }, 434 { POWER_SUPPLY_TECHNOLOGY_NiCd, "NiCd" }, 435 { POWER_SUPPLY_TECHNOLOGY_LiMn, "LiMn" }, 436 { -1, NULL }, 437 }; 438 439 440 static int map_get_value(struct battery_property_map *map, const char *key, 441 int def_val) 442 { 443 char buf[MAX_KEYLENGTH]; 444 int cr; 445 446 strscpy(buf, key, MAX_KEYLENGTH); 447 448 cr = strnlen(buf, MAX_KEYLENGTH) - 1; 449 if (cr < 0) 450 return def_val; 451 if (buf[cr] == '\n') 452 buf[cr] = '\0'; 453 454 while (map->key) { 455 if (strncasecmp(map->key, buf, MAX_KEYLENGTH) == 0) 456 return map->value; 457 map++; 458 } 459 460 return def_val; 461 } 462 463 464 static const char *map_get_key(struct battery_property_map *map, int value, 465 const char *def_key) 466 { 467 while (map->key) { 468 if (map->value == value) 469 return map->key; 470 map++; 471 } 472 473 return def_key; 474 } 475 476 static inline void signal_power_supply_changed(struct power_supply *psy) 477 { 478 if (module_initialized) 479 power_supply_changed(psy); 480 } 481 482 static int param_set_ac_online(const char *key, const struct kernel_param *kp) 483 { 484 ac_online = map_get_value(map_ac_online, key, ac_online); 485 signal_power_supply_changed(test_power_supplies[TEST_AC]); 486 return 0; 487 } 488 489 static int param_get_ac_online(char *buffer, const struct kernel_param *kp) 490 { 491 return sprintf(buffer, "%s\n", 492 map_get_key(map_ac_online, ac_online, "unknown")); 493 } 494 495 static int param_set_usb_online(const char *key, const struct kernel_param *kp) 496 { 497 usb_online = map_get_value(map_ac_online, key, usb_online); 498 signal_power_supply_changed(test_power_supplies[TEST_USB]); 499 return 0; 500 } 501 502 static int param_get_usb_online(char *buffer, const struct kernel_param *kp) 503 { 504 return sprintf(buffer, "%s\n", 505 map_get_key(map_ac_online, usb_online, "unknown")); 506 } 507 508 static int param_set_battery_status(const char *key, 509 const struct kernel_param *kp) 510 { 511 battery_status = map_get_value(map_status, key, battery_status); 512 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 513 return 0; 514 } 515 516 static int param_get_battery_status(char *buffer, const struct kernel_param *kp) 517 { 518 return sprintf(buffer, "%s\n", 519 map_get_key(map_ac_online, battery_status, "unknown")); 520 } 521 522 static int param_set_battery_health(const char *key, 523 const struct kernel_param *kp) 524 { 525 battery_health = map_get_value(map_health, key, battery_health); 526 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 527 return 0; 528 } 529 530 static int param_get_battery_health(char *buffer, const struct kernel_param *kp) 531 { 532 return sprintf(buffer, "%s\n", 533 map_get_key(map_ac_online, battery_health, "unknown")); 534 } 535 536 static int param_set_battery_present(const char *key, 537 const struct kernel_param *kp) 538 { 539 battery_present = map_get_value(map_present, key, battery_present); 540 signal_power_supply_changed(test_power_supplies[TEST_AC]); 541 return 0; 542 } 543 544 static int param_get_battery_present(char *buffer, 545 const struct kernel_param *kp) 546 { 547 return sprintf(buffer, "%s\n", 548 map_get_key(map_ac_online, battery_present, "unknown")); 549 } 550 551 static int param_set_battery_technology(const char *key, 552 const struct kernel_param *kp) 553 { 554 battery_technology = map_get_value(map_technology, key, 555 battery_technology); 556 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 557 return 0; 558 } 559 560 static int param_get_battery_technology(char *buffer, 561 const struct kernel_param *kp) 562 { 563 return sprintf(buffer, "%s\n", 564 map_get_key(map_ac_online, battery_technology, 565 "unknown")); 566 } 567 568 static int param_set_battery_capacity(const char *key, 569 const struct kernel_param *kp) 570 { 571 int tmp; 572 573 if (1 != sscanf(key, "%d", &tmp)) 574 return -EINVAL; 575 576 battery_capacity = tmp; 577 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 578 return 0; 579 } 580 581 #define param_get_battery_capacity param_get_int 582 583 static int param_set_battery_voltage(const char *key, 584 const struct kernel_param *kp) 585 { 586 int tmp; 587 588 if (1 != sscanf(key, "%d", &tmp)) 589 return -EINVAL; 590 591 battery_voltage = tmp; 592 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 593 return 0; 594 } 595 596 #define param_get_battery_voltage param_get_int 597 598 static int param_set_battery_charge_counter(const char *key, 599 const struct kernel_param *kp) 600 { 601 int tmp; 602 603 if (1 != sscanf(key, "%d", &tmp)) 604 return -EINVAL; 605 606 battery_charge_counter = tmp; 607 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 608 return 0; 609 } 610 611 #define param_get_battery_charge_counter param_get_int 612 613 static int param_set_battery_current(const char *key, 614 const struct kernel_param *kp) 615 { 616 int tmp; 617 618 if (1 != sscanf(key, "%d", &tmp)) 619 return -EINVAL; 620 621 battery_current = tmp; 622 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 623 return 0; 624 } 625 626 #define param_get_battery_current param_get_int 627 628 static int param_set_battery_extension(const char *key, 629 const struct kernel_param *kp) 630 { 631 bool prev_battery_extension; 632 int ret; 633 634 prev_battery_extension = battery_extension; 635 636 ret = param_set_bool(key, kp); 637 if (ret) 638 return ret; 639 640 if (prev_battery_extension != battery_extension) 641 test_power_configure_battery_extension(battery_extension); 642 643 return 0; 644 } 645 646 #define param_get_battery_extension param_get_bool 647 648 static const struct kernel_param_ops param_ops_ac_online = { 649 .set = param_set_ac_online, 650 .get = param_get_ac_online, 651 }; 652 653 static const struct kernel_param_ops param_ops_usb_online = { 654 .set = param_set_usb_online, 655 .get = param_get_usb_online, 656 }; 657 658 static const struct kernel_param_ops param_ops_battery_status = { 659 .set = param_set_battery_status, 660 .get = param_get_battery_status, 661 }; 662 663 static const struct kernel_param_ops param_ops_battery_present = { 664 .set = param_set_battery_present, 665 .get = param_get_battery_present, 666 }; 667 668 static const struct kernel_param_ops param_ops_battery_technology = { 669 .set = param_set_battery_technology, 670 .get = param_get_battery_technology, 671 }; 672 673 static const struct kernel_param_ops param_ops_battery_health = { 674 .set = param_set_battery_health, 675 .get = param_get_battery_health, 676 }; 677 678 static const struct kernel_param_ops param_ops_battery_capacity = { 679 .set = param_set_battery_capacity, 680 .get = param_get_battery_capacity, 681 }; 682 683 static const struct kernel_param_ops param_ops_battery_voltage = { 684 .set = param_set_battery_voltage, 685 .get = param_get_battery_voltage, 686 }; 687 688 static const struct kernel_param_ops param_ops_battery_charge_counter = { 689 .set = param_set_battery_charge_counter, 690 .get = param_get_battery_charge_counter, 691 }; 692 693 static const struct kernel_param_ops param_ops_battery_current = { 694 .set = param_set_battery_current, 695 .get = param_get_battery_current, 696 }; 697 698 static const struct kernel_param_ops param_ops_battery_extension = { 699 .set = param_set_battery_extension, 700 .get = param_get_battery_extension, 701 }; 702 703 #define param_check_ac_online(name, p) __param_check(name, p, void); 704 #define param_check_usb_online(name, p) __param_check(name, p, void); 705 #define param_check_battery_status(name, p) __param_check(name, p, void); 706 #define param_check_battery_present(name, p) __param_check(name, p, void); 707 #define param_check_battery_technology(name, p) __param_check(name, p, void); 708 #define param_check_battery_health(name, p) __param_check(name, p, void); 709 #define param_check_battery_capacity(name, p) __param_check(name, p, void); 710 #define param_check_battery_voltage(name, p) __param_check(name, p, void); 711 #define param_check_battery_charge_counter(name, p) __param_check(name, p, void); 712 #define param_check_battery_current(name, p) __param_check(name, p, void); 713 #define param_check_battery_extension(name, p) __param_check(name, p, void); 714 715 716 module_param(ac_online, ac_online, 0644); 717 MODULE_PARM_DESC(ac_online, "AC charging state <on|off>"); 718 719 module_param(usb_online, usb_online, 0644); 720 MODULE_PARM_DESC(usb_online, "USB charging state <on|off>"); 721 722 module_param(battery_status, battery_status, 0644); 723 MODULE_PARM_DESC(battery_status, 724 "battery status <charging|discharging|not-charging|full>"); 725 726 module_param(battery_present, battery_present, 0644); 727 MODULE_PARM_DESC(battery_present, 728 "battery presence state <good|overheat|dead|overvoltage|failure>"); 729 730 module_param(battery_technology, battery_technology, 0644); 731 MODULE_PARM_DESC(battery_technology, 732 "battery technology <NiMH|LION|LIPO|LiFe|NiCd|LiMn>"); 733 734 module_param(battery_health, battery_health, 0644); 735 MODULE_PARM_DESC(battery_health, 736 "battery health state <good|overheat|dead|overvoltage|failure>"); 737 738 module_param(battery_capacity, battery_capacity, 0644); 739 MODULE_PARM_DESC(battery_capacity, "battery capacity (percentage)"); 740 741 module_param(battery_voltage, battery_voltage, 0644); 742 MODULE_PARM_DESC(battery_voltage, "battery voltage (millivolts)"); 743 744 module_param(battery_charge_counter, battery_charge_counter, 0644); 745 MODULE_PARM_DESC(battery_charge_counter, 746 "battery charge counter (microampere-hours)"); 747 748 module_param(battery_current, battery_current, 0644); 749 MODULE_PARM_DESC(battery_current, "battery current (milliampere)"); 750 751 module_param(battery_extension, battery_extension, 0644); 752 MODULE_PARM_DESC(battery_extension, "battery extension"); 753 754 MODULE_DESCRIPTION("Power supply driver for testing"); 755 MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); 756 MODULE_LICENSE("GPL"); 757