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_TIME_TO_EMPTY_NOW, 263 POWER_SUPPLY_PROP_MANUFACTURE_YEAR, 264 POWER_SUPPLY_PROP_TEMP_MAX, 265 }; 266 267 static int test_power_battery_extget_property(struct power_supply *psy, 268 const struct power_supply_ext *ext, 269 void *ext_data, 270 enum power_supply_property psp, 271 union power_supply_propval *val) 272 { 273 switch (psp) { 274 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: 275 return power_supply_get_property_direct(psy, POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 276 val); 277 case POWER_SUPPLY_PROP_MANUFACTURE_YEAR: 278 val->intval = test_power_battery_extmanufacture_year; 279 break; 280 case POWER_SUPPLY_PROP_TEMP_MAX: 281 val->intval = test_power_battery_exttemp_max; 282 break; 283 default: 284 return -EINVAL; 285 } 286 return 0; 287 } 288 289 static int test_power_battery_extset_property(struct power_supply *psy, 290 const struct power_supply_ext *ext, 291 void *ext_data, 292 enum power_supply_property psp, 293 const union power_supply_propval *val) 294 { 295 switch (psp) { 296 case POWER_SUPPLY_PROP_MANUFACTURE_YEAR: 297 test_power_battery_extmanufacture_year = val->intval; 298 break; 299 case POWER_SUPPLY_PROP_TEMP_MAX: 300 test_power_battery_exttemp_max = val->intval; 301 break; 302 default: 303 return -EINVAL; 304 } 305 return 0; 306 } 307 308 static int test_power_battery_extproperty_is_writeable(struct power_supply *psy, 309 const struct power_supply_ext *ext, 310 void *ext_data, 311 enum power_supply_property psp) 312 { 313 return true; 314 } 315 316 static const struct power_supply_ext test_power_battery_ext = { 317 .name = "test_power", 318 .properties = test_power_battery_extprops, 319 .num_properties = ARRAY_SIZE(test_power_battery_extprops), 320 .get_property = test_power_battery_extget_property, 321 .set_property = test_power_battery_extset_property, 322 .property_is_writeable = test_power_battery_extproperty_is_writeable, 323 }; 324 325 static void test_power_configure_battery_extension(bool enable) 326 { 327 struct power_supply *psy; 328 329 psy = test_power_supplies[TEST_BATTERY]; 330 331 if (enable) { 332 if (power_supply_register_extension(psy, &test_power_battery_ext, &psy->dev, 333 NULL)) { 334 pr_err("registering battery extension failed\n"); 335 return; 336 } 337 } else { 338 power_supply_unregister_extension(psy, &test_power_battery_ext); 339 } 340 341 battery_extension = enable; 342 } 343 344 static int __init test_power_init(void) 345 { 346 int i; 347 int ret; 348 349 BUILD_BUG_ON(TEST_POWER_NUM != ARRAY_SIZE(test_power_supplies)); 350 BUILD_BUG_ON(TEST_POWER_NUM != ARRAY_SIZE(test_power_configs)); 351 352 for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) { 353 test_power_supplies[i] = power_supply_register(NULL, 354 &test_power_desc[i], 355 &test_power_configs[i]); 356 if (IS_ERR(test_power_supplies[i])) { 357 pr_err("%s: failed to register %s\n", __func__, 358 test_power_desc[i].name); 359 ret = PTR_ERR(test_power_supplies[i]); 360 goto failed; 361 } 362 } 363 364 test_power_configure_battery_extension(true); 365 366 module_initialized = true; 367 return 0; 368 failed: 369 while (--i >= 0) 370 power_supply_unregister(test_power_supplies[i]); 371 return ret; 372 } 373 module_init(test_power_init); 374 375 static void __exit test_power_exit(void) 376 { 377 int i; 378 379 /* Let's see how we handle changes... */ 380 ac_online = 0; 381 usb_online = 0; 382 battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 383 for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) 384 power_supply_changed(test_power_supplies[i]); 385 pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n", 386 __func__); 387 ssleep(10); 388 389 for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) 390 power_supply_unregister(test_power_supplies[i]); 391 392 module_initialized = false; 393 } 394 module_exit(test_power_exit); 395 396 397 398 #define MAX_KEYLENGTH 256 399 struct battery_property_map { 400 int value; 401 char const *key; 402 }; 403 404 static struct battery_property_map map_ac_online[] = { 405 { 0, "off" }, 406 { 1, "on" }, 407 { -1, NULL }, 408 }; 409 410 static struct battery_property_map map_status[] = { 411 { POWER_SUPPLY_STATUS_CHARGING, "charging" }, 412 { POWER_SUPPLY_STATUS_DISCHARGING, "discharging" }, 413 { POWER_SUPPLY_STATUS_NOT_CHARGING, "not-charging" }, 414 { POWER_SUPPLY_STATUS_FULL, "full" }, 415 { -1, NULL }, 416 }; 417 418 static struct battery_property_map map_health[] = { 419 { POWER_SUPPLY_HEALTH_GOOD, "good" }, 420 { POWER_SUPPLY_HEALTH_OVERHEAT, "overheat" }, 421 { POWER_SUPPLY_HEALTH_DEAD, "dead" }, 422 { POWER_SUPPLY_HEALTH_OVERVOLTAGE, "overvoltage" }, 423 { POWER_SUPPLY_HEALTH_UNSPEC_FAILURE, "failure" }, 424 { -1, NULL }, 425 }; 426 427 static struct battery_property_map map_present[] = { 428 { 0, "false" }, 429 { 1, "true" }, 430 { -1, NULL }, 431 }; 432 433 static struct battery_property_map map_technology[] = { 434 { POWER_SUPPLY_TECHNOLOGY_NiMH, "NiMH" }, 435 { POWER_SUPPLY_TECHNOLOGY_LION, "LION" }, 436 { POWER_SUPPLY_TECHNOLOGY_LIPO, "LIPO" }, 437 { POWER_SUPPLY_TECHNOLOGY_LiFe, "LiFe" }, 438 { POWER_SUPPLY_TECHNOLOGY_NiCd, "NiCd" }, 439 { POWER_SUPPLY_TECHNOLOGY_LiMn, "LiMn" }, 440 { -1, NULL }, 441 }; 442 443 444 static int map_get_value(struct battery_property_map *map, const char *key, 445 int def_val) 446 { 447 char buf[MAX_KEYLENGTH]; 448 int cr; 449 450 strscpy(buf, key, MAX_KEYLENGTH); 451 452 cr = strnlen(buf, MAX_KEYLENGTH) - 1; 453 if (cr < 0) 454 return def_val; 455 if (buf[cr] == '\n') 456 buf[cr] = '\0'; 457 458 while (map->key) { 459 if (strncasecmp(map->key, buf, MAX_KEYLENGTH) == 0) 460 return map->value; 461 map++; 462 } 463 464 return def_val; 465 } 466 467 468 static const char *map_get_key(struct battery_property_map *map, int value, 469 const char *def_key) 470 { 471 while (map->key) { 472 if (map->value == value) 473 return map->key; 474 map++; 475 } 476 477 return def_key; 478 } 479 480 static inline void signal_power_supply_changed(struct power_supply *psy) 481 { 482 if (module_initialized) 483 power_supply_changed(psy); 484 } 485 486 static int param_set_ac_online(const char *key, const struct kernel_param *kp) 487 { 488 ac_online = map_get_value(map_ac_online, key, ac_online); 489 signal_power_supply_changed(test_power_supplies[TEST_AC]); 490 return 0; 491 } 492 493 static int param_get_ac_online(char *buffer, const struct kernel_param *kp) 494 { 495 return sprintf(buffer, "%s\n", 496 map_get_key(map_ac_online, ac_online, "unknown")); 497 } 498 499 static int param_set_usb_online(const char *key, const struct kernel_param *kp) 500 { 501 usb_online = map_get_value(map_ac_online, key, usb_online); 502 signal_power_supply_changed(test_power_supplies[TEST_USB]); 503 return 0; 504 } 505 506 static int param_get_usb_online(char *buffer, const struct kernel_param *kp) 507 { 508 return sprintf(buffer, "%s\n", 509 map_get_key(map_ac_online, usb_online, "unknown")); 510 } 511 512 static int param_set_battery_status(const char *key, 513 const struct kernel_param *kp) 514 { 515 battery_status = map_get_value(map_status, key, battery_status); 516 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 517 return 0; 518 } 519 520 static int param_get_battery_status(char *buffer, const struct kernel_param *kp) 521 { 522 return sprintf(buffer, "%s\n", 523 map_get_key(map_ac_online, battery_status, "unknown")); 524 } 525 526 static int param_set_battery_health(const char *key, 527 const struct kernel_param *kp) 528 { 529 battery_health = map_get_value(map_health, key, battery_health); 530 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 531 return 0; 532 } 533 534 static int param_get_battery_health(char *buffer, const struct kernel_param *kp) 535 { 536 return sprintf(buffer, "%s\n", 537 map_get_key(map_ac_online, battery_health, "unknown")); 538 } 539 540 static int param_set_battery_present(const char *key, 541 const struct kernel_param *kp) 542 { 543 battery_present = map_get_value(map_present, key, battery_present); 544 signal_power_supply_changed(test_power_supplies[TEST_AC]); 545 return 0; 546 } 547 548 static int param_get_battery_present(char *buffer, 549 const struct kernel_param *kp) 550 { 551 return sprintf(buffer, "%s\n", 552 map_get_key(map_ac_online, battery_present, "unknown")); 553 } 554 555 static int param_set_battery_technology(const char *key, 556 const struct kernel_param *kp) 557 { 558 battery_technology = map_get_value(map_technology, key, 559 battery_technology); 560 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 561 return 0; 562 } 563 564 static int param_get_battery_technology(char *buffer, 565 const struct kernel_param *kp) 566 { 567 return sprintf(buffer, "%s\n", 568 map_get_key(map_ac_online, battery_technology, 569 "unknown")); 570 } 571 572 static int param_set_battery_capacity(const char *key, 573 const struct kernel_param *kp) 574 { 575 int tmp; 576 577 if (1 != sscanf(key, "%d", &tmp)) 578 return -EINVAL; 579 580 battery_capacity = tmp; 581 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 582 return 0; 583 } 584 585 #define param_get_battery_capacity param_get_int 586 587 static int param_set_battery_voltage(const char *key, 588 const struct kernel_param *kp) 589 { 590 int tmp; 591 592 if (1 != sscanf(key, "%d", &tmp)) 593 return -EINVAL; 594 595 battery_voltage = tmp; 596 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 597 return 0; 598 } 599 600 #define param_get_battery_voltage param_get_int 601 602 static int param_set_battery_charge_counter(const char *key, 603 const struct kernel_param *kp) 604 { 605 int tmp; 606 607 if (1 != sscanf(key, "%d", &tmp)) 608 return -EINVAL; 609 610 battery_charge_counter = tmp; 611 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 612 return 0; 613 } 614 615 #define param_get_battery_charge_counter param_get_int 616 617 static int param_set_battery_current(const char *key, 618 const struct kernel_param *kp) 619 { 620 int tmp; 621 622 if (1 != sscanf(key, "%d", &tmp)) 623 return -EINVAL; 624 625 battery_current = tmp; 626 signal_power_supply_changed(test_power_supplies[TEST_BATTERY]); 627 return 0; 628 } 629 630 #define param_get_battery_current param_get_int 631 632 static int param_set_battery_extension(const char *key, 633 const struct kernel_param *kp) 634 { 635 bool prev_battery_extension; 636 int ret; 637 638 prev_battery_extension = battery_extension; 639 640 ret = param_set_bool(key, kp); 641 if (ret) 642 return ret; 643 644 if (prev_battery_extension != battery_extension) 645 test_power_configure_battery_extension(battery_extension); 646 647 return 0; 648 } 649 650 #define param_get_battery_extension param_get_bool 651 652 static const struct kernel_param_ops param_ops_ac_online = { 653 .set = param_set_ac_online, 654 .get = param_get_ac_online, 655 }; 656 657 static const struct kernel_param_ops param_ops_usb_online = { 658 .set = param_set_usb_online, 659 .get = param_get_usb_online, 660 }; 661 662 static const struct kernel_param_ops param_ops_battery_status = { 663 .set = param_set_battery_status, 664 .get = param_get_battery_status, 665 }; 666 667 static const struct kernel_param_ops param_ops_battery_present = { 668 .set = param_set_battery_present, 669 .get = param_get_battery_present, 670 }; 671 672 static const struct kernel_param_ops param_ops_battery_technology = { 673 .set = param_set_battery_technology, 674 .get = param_get_battery_technology, 675 }; 676 677 static const struct kernel_param_ops param_ops_battery_health = { 678 .set = param_set_battery_health, 679 .get = param_get_battery_health, 680 }; 681 682 static const struct kernel_param_ops param_ops_battery_capacity = { 683 .set = param_set_battery_capacity, 684 .get = param_get_battery_capacity, 685 }; 686 687 static const struct kernel_param_ops param_ops_battery_voltage = { 688 .set = param_set_battery_voltage, 689 .get = param_get_battery_voltage, 690 }; 691 692 static const struct kernel_param_ops param_ops_battery_charge_counter = { 693 .set = param_set_battery_charge_counter, 694 .get = param_get_battery_charge_counter, 695 }; 696 697 static const struct kernel_param_ops param_ops_battery_current = { 698 .set = param_set_battery_current, 699 .get = param_get_battery_current, 700 }; 701 702 static const struct kernel_param_ops param_ops_battery_extension = { 703 .set = param_set_battery_extension, 704 .get = param_get_battery_extension, 705 }; 706 707 #define param_check_ac_online(name, p) __param_check(name, p, void); 708 #define param_check_usb_online(name, p) __param_check(name, p, void); 709 #define param_check_battery_status(name, p) __param_check(name, p, void); 710 #define param_check_battery_present(name, p) __param_check(name, p, void); 711 #define param_check_battery_technology(name, p) __param_check(name, p, void); 712 #define param_check_battery_health(name, p) __param_check(name, p, void); 713 #define param_check_battery_capacity(name, p) __param_check(name, p, void); 714 #define param_check_battery_voltage(name, p) __param_check(name, p, void); 715 #define param_check_battery_charge_counter(name, p) __param_check(name, p, void); 716 #define param_check_battery_current(name, p) __param_check(name, p, void); 717 #define param_check_battery_extension(name, p) __param_check(name, p, void); 718 719 720 module_param(ac_online, ac_online, 0644); 721 MODULE_PARM_DESC(ac_online, "AC charging state <on|off>"); 722 723 module_param(usb_online, usb_online, 0644); 724 MODULE_PARM_DESC(usb_online, "USB charging state <on|off>"); 725 726 module_param(battery_status, battery_status, 0644); 727 MODULE_PARM_DESC(battery_status, 728 "battery status <charging|discharging|not-charging|full>"); 729 730 module_param(battery_present, battery_present, 0644); 731 MODULE_PARM_DESC(battery_present, 732 "battery presence state <good|overheat|dead|overvoltage|failure>"); 733 734 module_param(battery_technology, battery_technology, 0644); 735 MODULE_PARM_DESC(battery_technology, 736 "battery technology <NiMH|LION|LIPO|LiFe|NiCd|LiMn>"); 737 738 module_param(battery_health, battery_health, 0644); 739 MODULE_PARM_DESC(battery_health, 740 "battery health state <good|overheat|dead|overvoltage|failure>"); 741 742 module_param(battery_capacity, battery_capacity, 0644); 743 MODULE_PARM_DESC(battery_capacity, "battery capacity (percentage)"); 744 745 module_param(battery_voltage, battery_voltage, 0644); 746 MODULE_PARM_DESC(battery_voltage, "battery voltage (millivolts)"); 747 748 module_param(battery_charge_counter, battery_charge_counter, 0644); 749 MODULE_PARM_DESC(battery_charge_counter, 750 "battery charge counter (microampere-hours)"); 751 752 module_param(battery_current, battery_current, 0644); 753 MODULE_PARM_DESC(battery_current, "battery current (milliampere)"); 754 755 module_param(battery_extension, battery_extension, 0644); 756 MODULE_PARM_DESC(battery_extension, "battery extension"); 757 758 MODULE_DESCRIPTION("Power supply driver for testing"); 759 MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); 760 MODULE_LICENSE("GPL"); 761