1/* 2 * Power supply driver for testing. 3 * 4 * Copyright 2010 Anton Vorontsov <cbouatmailru@gmail.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 */ 10 11#include <linux/kernel.h> 12#include <linux/module.h> 13#include <linux/power_supply.h> 14#include <linux/errno.h> 15#include <linux/delay.h> 16#include <linux/vermagic.h> 17 18static int test_power_ac_online = 1; 19static int test_power_battery_status = POWER_SUPPLY_STATUS_CHARGING; 20 21static int test_power_get_ac_property(struct power_supply *psy, 22 enum power_supply_property psp, 23 union power_supply_propval *val) 24{ 25 switch (psp) { 26 case POWER_SUPPLY_PROP_ONLINE: 27 val->intval = test_power_ac_online; 28 break; 29 default: 30 return -EINVAL; 31 } 32 return 0; 33} 34 35static int test_power_get_battery_property(struct power_supply *psy, 36 enum power_supply_property psp, 37 union power_supply_propval *val) 38{ 39 switch (psp) { 40 case POWER_SUPPLY_PROP_MODEL_NAME: 41 val->strval = "Test battery"; 42 break; 43 case POWER_SUPPLY_PROP_MANUFACTURER: 44 val->strval = "Linux"; 45 break; 46 case POWER_SUPPLY_PROP_SERIAL_NUMBER: 47 val->strval = UTS_RELEASE; 48 break; 49 case POWER_SUPPLY_PROP_STATUS: 50 val->intval = test_power_battery_status; 51 break; 52 case POWER_SUPPLY_PROP_CHARGE_TYPE: 53 val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST; 54 break; 55 case POWER_SUPPLY_PROP_HEALTH: 56 val->intval = POWER_SUPPLY_HEALTH_GOOD; 57 break; 58 case POWER_SUPPLY_PROP_TECHNOLOGY: 59 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 60 break; 61 case POWER_SUPPLY_PROP_CAPACITY_LEVEL: 62 val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL; 63 break; 64 case POWER_SUPPLY_PROP_CAPACITY: 65 val->intval = 50; 66 break; 67 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG: 68 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW: 69 val->intval = 3600; 70 break; 71 default: 72 pr_info("%s: some properties deliberately report errors.\n", 73 __func__); 74 return -EINVAL; 75 } 76 return 0; 77} 78 79static enum power_supply_property test_power_ac_props[] = { 80 POWER_SUPPLY_PROP_ONLINE, 81}; 82 83static enum power_supply_property test_power_battery_props[] = { 84 POWER_SUPPLY_PROP_STATUS, 85 POWER_SUPPLY_PROP_CHARGE_TYPE, 86 POWER_SUPPLY_PROP_HEALTH, 87 POWER_SUPPLY_PROP_TECHNOLOGY, 88 POWER_SUPPLY_PROP_CHARGE_FULL, 89 POWER_SUPPLY_PROP_CHARGE_EMPTY, 90 POWER_SUPPLY_PROP_CAPACITY, 91 POWER_SUPPLY_PROP_CAPACITY_LEVEL, 92 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 93 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, 94 POWER_SUPPLY_PROP_MODEL_NAME, 95 POWER_SUPPLY_PROP_MANUFACTURER, 96 POWER_SUPPLY_PROP_SERIAL_NUMBER, 97}; 98 99static char *test_power_ac_supplied_to[] = { 100 "test_battery", 101}; 102 103static struct power_supply test_power_supplies[] = { 104 { 105 .name = "test_ac", 106 .type = POWER_SUPPLY_TYPE_MAINS, 107 .supplied_to = test_power_ac_supplied_to, 108 .num_supplicants = ARRAY_SIZE(test_power_ac_supplied_to), 109 .properties = test_power_ac_props, 110 .num_properties = ARRAY_SIZE(test_power_ac_props), 111 .get_property = test_power_get_ac_property, 112 }, { 113 .name = "test_battery", 114 .type = POWER_SUPPLY_TYPE_BATTERY, 115 .properties = test_power_battery_props, 116 .num_properties = ARRAY_SIZE(test_power_battery_props), 117 .get_property = test_power_get_battery_property, 118 }, 119}; 120 121static int __init test_power_init(void) 122{ 123 int i; 124 int ret; 125 126 for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) { 127 ret = power_supply_register(NULL, &test_power_supplies[i]); 128 if (ret) { 129 pr_err("%s: failed to register %s\n", __func__, 130 test_power_supplies[i].name); 131 goto failed; 132 } 133 } 134 135 return 0; 136failed: 137 while (--i >= 0) 138 power_supply_unregister(&test_power_supplies[i]); 139 return ret; 140} 141module_init(test_power_init); 142 143static void __exit test_power_exit(void) 144{ 145 int i; 146 147 /* Let's see how we handle changes... */ 148 test_power_ac_online = 0; 149 test_power_battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 150 for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) 151 power_supply_changed(&test_power_supplies[i]); 152 pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n", 153 __func__); 154 ssleep(10); 155 156 for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) 157 power_supply_unregister(&test_power_supplies[i]); 158} 159module_exit(test_power_exit); 160 161MODULE_DESCRIPTION("Power supply driver for testing"); 162MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>"); 163MODULE_LICENSE("GPL"); 164