root/drivers/power/supply/test_power.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. test_power_get_ac_property
  2. test_power_get_usb_property
  3. test_power_get_battery_property
  4. test_power_init
  5. test_power_exit
  6. map_get_value
  7. map_get_key
  8. signal_power_supply_changed
  9. param_set_ac_online
  10. param_get_ac_online
  11. param_set_usb_online
  12. param_get_usb_online
  13. param_set_battery_status
  14. param_get_battery_status
  15. param_set_battery_health
  16. param_get_battery_health
  17. param_set_battery_present
  18. param_get_battery_present
  19. param_set_battery_technology
  20. param_get_battery_technology
  21. param_set_battery_capacity
  22. param_set_battery_voltage

   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 <linux/vermagic.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 
  37 static bool module_initialized;
  38 
  39 static int test_power_get_ac_property(struct power_supply *psy,
  40                                       enum power_supply_property psp,
  41                                       union power_supply_propval *val)
  42 {
  43         switch (psp) {
  44         case POWER_SUPPLY_PROP_ONLINE:
  45                 val->intval = ac_online;
  46                 break;
  47         default:
  48                 return -EINVAL;
  49         }
  50         return 0;
  51 }
  52 
  53 static int test_power_get_usb_property(struct power_supply *psy,
  54                                       enum power_supply_property psp,
  55                                       union power_supply_propval *val)
  56 {
  57         switch (psp) {
  58         case POWER_SUPPLY_PROP_ONLINE:
  59                 val->intval = usb_online;
  60                 break;
  61         default:
  62                 return -EINVAL;
  63         }
  64         return 0;
  65 }
  66 
  67 static int test_power_get_battery_property(struct power_supply *psy,
  68                                            enum power_supply_property psp,
  69                                            union power_supply_propval *val)
  70 {
  71         switch (psp) {
  72         case POWER_SUPPLY_PROP_MODEL_NAME:
  73                 val->strval = "Test battery";
  74                 break;
  75         case POWER_SUPPLY_PROP_MANUFACTURER:
  76                 val->strval = "Linux";
  77                 break;
  78         case POWER_SUPPLY_PROP_SERIAL_NUMBER:
  79                 val->strval = UTS_RELEASE;
  80                 break;
  81         case POWER_SUPPLY_PROP_STATUS:
  82                 val->intval = battery_status;
  83                 break;
  84         case POWER_SUPPLY_PROP_CHARGE_TYPE:
  85                 val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
  86                 break;
  87         case POWER_SUPPLY_PROP_HEALTH:
  88                 val->intval = battery_health;
  89                 break;
  90         case POWER_SUPPLY_PROP_PRESENT:
  91                 val->intval = battery_present;
  92                 break;
  93         case POWER_SUPPLY_PROP_TECHNOLOGY:
  94                 val->intval = battery_technology;
  95                 break;
  96         case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
  97                 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
  98                 break;
  99         case POWER_SUPPLY_PROP_CAPACITY:
 100         case POWER_SUPPLY_PROP_CHARGE_NOW:
 101                 val->intval = battery_capacity;
 102                 break;
 103         case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
 104         case POWER_SUPPLY_PROP_CHARGE_FULL:
 105                 val->intval = 100;
 106                 break;
 107         case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
 108         case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
 109                 val->intval = 3600;
 110                 break;
 111         case POWER_SUPPLY_PROP_TEMP:
 112                 val->intval = 26;
 113                 break;
 114         case POWER_SUPPLY_PROP_VOLTAGE_NOW:
 115                 val->intval = battery_voltage;
 116                 break;
 117         default:
 118                 pr_info("%s: some properties deliberately report errors.\n",
 119                         __func__);
 120                 return -EINVAL;
 121         }
 122         return 0;
 123 }
 124 
 125 static enum power_supply_property test_power_ac_props[] = {
 126         POWER_SUPPLY_PROP_ONLINE,
 127 };
 128 
 129 static enum power_supply_property test_power_battery_props[] = {
 130         POWER_SUPPLY_PROP_STATUS,
 131         POWER_SUPPLY_PROP_CHARGE_TYPE,
 132         POWER_SUPPLY_PROP_HEALTH,
 133         POWER_SUPPLY_PROP_PRESENT,
 134         POWER_SUPPLY_PROP_TECHNOLOGY,
 135         POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
 136         POWER_SUPPLY_PROP_CHARGE_FULL,
 137         POWER_SUPPLY_PROP_CHARGE_NOW,
 138         POWER_SUPPLY_PROP_CAPACITY,
 139         POWER_SUPPLY_PROP_CAPACITY_LEVEL,
 140         POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
 141         POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
 142         POWER_SUPPLY_PROP_MODEL_NAME,
 143         POWER_SUPPLY_PROP_MANUFACTURER,
 144         POWER_SUPPLY_PROP_SERIAL_NUMBER,
 145         POWER_SUPPLY_PROP_TEMP,
 146         POWER_SUPPLY_PROP_VOLTAGE_NOW,
 147 };
 148 
 149 static char *test_power_ac_supplied_to[] = {
 150         "test_battery",
 151 };
 152 
 153 static struct power_supply *test_power_supplies[TEST_POWER_NUM];
 154 
 155 static const struct power_supply_desc test_power_desc[] = {
 156         [TEST_AC] = {
 157                 .name = "test_ac",
 158                 .type = POWER_SUPPLY_TYPE_MAINS,
 159                 .properties = test_power_ac_props,
 160                 .num_properties = ARRAY_SIZE(test_power_ac_props),
 161                 .get_property = test_power_get_ac_property,
 162         },
 163         [TEST_BATTERY] = {
 164                 .name = "test_battery",
 165                 .type = POWER_SUPPLY_TYPE_BATTERY,
 166                 .properties = test_power_battery_props,
 167                 .num_properties = ARRAY_SIZE(test_power_battery_props),
 168                 .get_property = test_power_get_battery_property,
 169         },
 170         [TEST_USB] = {
 171                 .name = "test_usb",
 172                 .type = POWER_SUPPLY_TYPE_USB,
 173                 .properties = test_power_ac_props,
 174                 .num_properties = ARRAY_SIZE(test_power_ac_props),
 175                 .get_property = test_power_get_usb_property,
 176         },
 177 };
 178 
 179 static const struct power_supply_config test_power_configs[] = {
 180         {
 181                 /* test_ac */
 182                 .supplied_to = test_power_ac_supplied_to,
 183                 .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to),
 184         }, {
 185                 /* test_battery */
 186         }, {
 187                 /* test_usb */
 188                 .supplied_to = test_power_ac_supplied_to,
 189                 .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to),
 190         },
 191 };
 192 
 193 static int __init test_power_init(void)
 194 {
 195         int i;
 196         int ret;
 197 
 198         BUILD_BUG_ON(TEST_POWER_NUM != ARRAY_SIZE(test_power_supplies));
 199         BUILD_BUG_ON(TEST_POWER_NUM != ARRAY_SIZE(test_power_configs));
 200 
 201         for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) {
 202                 test_power_supplies[i] = power_supply_register(NULL,
 203                                                 &test_power_desc[i],
 204                                                 &test_power_configs[i]);
 205                 if (IS_ERR(test_power_supplies[i])) {
 206                         pr_err("%s: failed to register %s\n", __func__,
 207                                 test_power_desc[i].name);
 208                         ret = PTR_ERR(test_power_supplies[i]);
 209                         goto failed;
 210                 }
 211         }
 212 
 213         module_initialized = true;
 214         return 0;
 215 failed:
 216         while (--i >= 0)
 217                 power_supply_unregister(test_power_supplies[i]);
 218         return ret;
 219 }
 220 module_init(test_power_init);
 221 
 222 static void __exit test_power_exit(void)
 223 {
 224         int i;
 225 
 226         /* Let's see how we handle changes... */
 227         ac_online = 0;
 228         usb_online = 0;
 229         battery_status = POWER_SUPPLY_STATUS_DISCHARGING;
 230         for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++)
 231                 power_supply_changed(test_power_supplies[i]);
 232         pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n",
 233                 __func__);
 234         ssleep(10);
 235 
 236         for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++)
 237                 power_supply_unregister(test_power_supplies[i]);
 238 
 239         module_initialized = false;
 240 }
 241 module_exit(test_power_exit);
 242 
 243 
 244 
 245 #define MAX_KEYLENGTH 256
 246 struct battery_property_map {
 247         int value;
 248         char const *key;
 249 };
 250 
 251 static struct battery_property_map map_ac_online[] = {
 252         { 0,  "off"  },
 253         { 1,  "on" },
 254         { -1, NULL  },
 255 };
 256 
 257 static struct battery_property_map map_status[] = {
 258         { POWER_SUPPLY_STATUS_CHARGING,     "charging"     },
 259         { POWER_SUPPLY_STATUS_DISCHARGING,  "discharging"  },
 260         { POWER_SUPPLY_STATUS_NOT_CHARGING, "not-charging" },
 261         { POWER_SUPPLY_STATUS_FULL,         "full"         },
 262         { -1,                               NULL           },
 263 };
 264 
 265 static struct battery_property_map map_health[] = {
 266         { POWER_SUPPLY_HEALTH_GOOD,           "good"        },
 267         { POWER_SUPPLY_HEALTH_OVERHEAT,       "overheat"    },
 268         { POWER_SUPPLY_HEALTH_DEAD,           "dead"        },
 269         { POWER_SUPPLY_HEALTH_OVERVOLTAGE,    "overvoltage" },
 270         { POWER_SUPPLY_HEALTH_UNSPEC_FAILURE, "failure"     },
 271         { -1,                                 NULL          },
 272 };
 273 
 274 static struct battery_property_map map_present[] = {
 275         { 0,  "false" },
 276         { 1,  "true"  },
 277         { -1, NULL    },
 278 };
 279 
 280 static struct battery_property_map map_technology[] = {
 281         { POWER_SUPPLY_TECHNOLOGY_NiMH, "NiMH" },
 282         { POWER_SUPPLY_TECHNOLOGY_LION, "LION" },
 283         { POWER_SUPPLY_TECHNOLOGY_LIPO, "LIPO" },
 284         { POWER_SUPPLY_TECHNOLOGY_LiFe, "LiFe" },
 285         { POWER_SUPPLY_TECHNOLOGY_NiCd, "NiCd" },
 286         { POWER_SUPPLY_TECHNOLOGY_LiMn, "LiMn" },
 287         { -1,                           NULL   },
 288 };
 289 
 290 
 291 static int map_get_value(struct battery_property_map *map, const char *key,
 292                                 int def_val)
 293 {
 294         char buf[MAX_KEYLENGTH];
 295         int cr;
 296 
 297         strncpy(buf, key, MAX_KEYLENGTH);
 298         buf[MAX_KEYLENGTH-1] = '\0';
 299 
 300         cr = strnlen(buf, MAX_KEYLENGTH) - 1;
 301         if (cr < 0)
 302                 return def_val;
 303         if (buf[cr] == '\n')
 304                 buf[cr] = '\0';
 305 
 306         while (map->key) {
 307                 if (strncasecmp(map->key, buf, MAX_KEYLENGTH) == 0)
 308                         return map->value;
 309                 map++;
 310         }
 311 
 312         return def_val;
 313 }
 314 
 315 
 316 static const char *map_get_key(struct battery_property_map *map, int value,
 317                                 const char *def_key)
 318 {
 319         while (map->key) {
 320                 if (map->value == value)
 321                         return map->key;
 322                 map++;
 323         }
 324 
 325         return def_key;
 326 }
 327 
 328 static inline void signal_power_supply_changed(struct power_supply *psy)
 329 {
 330         if (module_initialized)
 331                 power_supply_changed(psy);
 332 }
 333 
 334 static int param_set_ac_online(const char *key, const struct kernel_param *kp)
 335 {
 336         ac_online = map_get_value(map_ac_online, key, ac_online);
 337         signal_power_supply_changed(test_power_supplies[TEST_AC]);
 338         return 0;
 339 }
 340 
 341 static int param_get_ac_online(char *buffer, const struct kernel_param *kp)
 342 {
 343         strcpy(buffer, map_get_key(map_ac_online, ac_online, "unknown"));
 344         return strlen(buffer);
 345 }
 346 
 347 static int param_set_usb_online(const char *key, const struct kernel_param *kp)
 348 {
 349         usb_online = map_get_value(map_ac_online, key, usb_online);
 350         signal_power_supply_changed(test_power_supplies[TEST_USB]);
 351         return 0;
 352 }
 353 
 354 static int param_get_usb_online(char *buffer, const struct kernel_param *kp)
 355 {
 356         strcpy(buffer, map_get_key(map_ac_online, usb_online, "unknown"));
 357         return strlen(buffer);
 358 }
 359 
 360 static int param_set_battery_status(const char *key,
 361                                         const struct kernel_param *kp)
 362 {
 363         battery_status = map_get_value(map_status, key, battery_status);
 364         signal_power_supply_changed(test_power_supplies[TEST_BATTERY]);
 365         return 0;
 366 }
 367 
 368 static int param_get_battery_status(char *buffer, const struct kernel_param *kp)
 369 {
 370         strcpy(buffer, map_get_key(map_status, battery_status, "unknown"));
 371         return strlen(buffer);
 372 }
 373 
 374 static int param_set_battery_health(const char *key,
 375                                         const struct kernel_param *kp)
 376 {
 377         battery_health = map_get_value(map_health, key, battery_health);
 378         signal_power_supply_changed(test_power_supplies[TEST_BATTERY]);
 379         return 0;
 380 }
 381 
 382 static int param_get_battery_health(char *buffer, const struct kernel_param *kp)
 383 {
 384         strcpy(buffer, map_get_key(map_health, battery_health, "unknown"));
 385         return strlen(buffer);
 386 }
 387 
 388 static int param_set_battery_present(const char *key,
 389                                         const struct kernel_param *kp)
 390 {
 391         battery_present = map_get_value(map_present, key, battery_present);
 392         signal_power_supply_changed(test_power_supplies[TEST_AC]);
 393         return 0;
 394 }
 395 
 396 static int param_get_battery_present(char *buffer,
 397                                         const struct kernel_param *kp)
 398 {
 399         strcpy(buffer, map_get_key(map_present, battery_present, "unknown"));
 400         return strlen(buffer);
 401 }
 402 
 403 static int param_set_battery_technology(const char *key,
 404                                         const struct kernel_param *kp)
 405 {
 406         battery_technology = map_get_value(map_technology, key,
 407                                                 battery_technology);
 408         signal_power_supply_changed(test_power_supplies[TEST_BATTERY]);
 409         return 0;
 410 }
 411 
 412 static int param_get_battery_technology(char *buffer,
 413                                         const struct kernel_param *kp)
 414 {
 415         strcpy(buffer,
 416                 map_get_key(map_technology, battery_technology, "unknown"));
 417         return strlen(buffer);
 418 }
 419 
 420 static int param_set_battery_capacity(const char *key,
 421                                         const struct kernel_param *kp)
 422 {
 423         int tmp;
 424 
 425         if (1 != sscanf(key, "%d", &tmp))
 426                 return -EINVAL;
 427 
 428         battery_capacity = tmp;
 429         signal_power_supply_changed(test_power_supplies[TEST_BATTERY]);
 430         return 0;
 431 }
 432 
 433 #define param_get_battery_capacity param_get_int
 434 
 435 static int param_set_battery_voltage(const char *key,
 436                                         const struct kernel_param *kp)
 437 {
 438         int tmp;
 439 
 440         if (1 != sscanf(key, "%d", &tmp))
 441                 return -EINVAL;
 442 
 443         battery_voltage = tmp;
 444         signal_power_supply_changed(test_power_supplies[TEST_BATTERY]);
 445         return 0;
 446 }
 447 
 448 #define param_get_battery_voltage param_get_int
 449 
 450 static const struct kernel_param_ops param_ops_ac_online = {
 451         .set = param_set_ac_online,
 452         .get = param_get_ac_online,
 453 };
 454 
 455 static const struct kernel_param_ops param_ops_usb_online = {
 456         .set = param_set_usb_online,
 457         .get = param_get_usb_online,
 458 };
 459 
 460 static const struct kernel_param_ops param_ops_battery_status = {
 461         .set = param_set_battery_status,
 462         .get = param_get_battery_status,
 463 };
 464 
 465 static const struct kernel_param_ops param_ops_battery_present = {
 466         .set = param_set_battery_present,
 467         .get = param_get_battery_present,
 468 };
 469 
 470 static const struct kernel_param_ops param_ops_battery_technology = {
 471         .set = param_set_battery_technology,
 472         .get = param_get_battery_technology,
 473 };
 474 
 475 static const struct kernel_param_ops param_ops_battery_health = {
 476         .set = param_set_battery_health,
 477         .get = param_get_battery_health,
 478 };
 479 
 480 static const struct kernel_param_ops param_ops_battery_capacity = {
 481         .set = param_set_battery_capacity,
 482         .get = param_get_battery_capacity,
 483 };
 484 
 485 static const struct kernel_param_ops param_ops_battery_voltage = {
 486         .set = param_set_battery_voltage,
 487         .get = param_get_battery_voltage,
 488 };
 489 
 490 #define param_check_ac_online(name, p) __param_check(name, p, void);
 491 #define param_check_usb_online(name, p) __param_check(name, p, void);
 492 #define param_check_battery_status(name, p) __param_check(name, p, void);
 493 #define param_check_battery_present(name, p) __param_check(name, p, void);
 494 #define param_check_battery_technology(name, p) __param_check(name, p, void);
 495 #define param_check_battery_health(name, p) __param_check(name, p, void);
 496 #define param_check_battery_capacity(name, p) __param_check(name, p, void);
 497 #define param_check_battery_voltage(name, p) __param_check(name, p, void);
 498 
 499 
 500 module_param(ac_online, ac_online, 0644);
 501 MODULE_PARM_DESC(ac_online, "AC charging state <on|off>");
 502 
 503 module_param(usb_online, usb_online, 0644);
 504 MODULE_PARM_DESC(usb_online, "USB charging state <on|off>");
 505 
 506 module_param(battery_status, battery_status, 0644);
 507 MODULE_PARM_DESC(battery_status,
 508         "battery status <charging|discharging|not-charging|full>");
 509 
 510 module_param(battery_present, battery_present, 0644);
 511 MODULE_PARM_DESC(battery_present,
 512         "battery presence state <good|overheat|dead|overvoltage|failure>");
 513 
 514 module_param(battery_technology, battery_technology, 0644);
 515 MODULE_PARM_DESC(battery_technology,
 516         "battery technology <NiMH|LION|LIPO|LiFe|NiCd|LiMn>");
 517 
 518 module_param(battery_health, battery_health, 0644);
 519 MODULE_PARM_DESC(battery_health,
 520         "battery health state <good|overheat|dead|overvoltage|failure>");
 521 
 522 module_param(battery_capacity, battery_capacity, 0644);
 523 MODULE_PARM_DESC(battery_capacity, "battery capacity (percentage)");
 524 
 525 module_param(battery_voltage, battery_voltage, 0644);
 526 MODULE_PARM_DESC(battery_voltage, "battery voltage (millivolts)");
 527 
 528 MODULE_DESCRIPTION("Power supply driver for testing");
 529 MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");
 530 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */