test_power.c 13 KB

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