1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  Sysfs interface for the universal power supply monitor class
4  *
5  *  Copyright © 2007  David Woodhouse <dwmw2@infradead.org>
6  *  Copyright © 2007  Anton Vorontsov <cbou@mail.ru>
7  *  Copyright © 2004  Szabolcs Gyurko
8  *  Copyright © 2003  Ian Molton <spyro@f2s.com>
9  *
10  *  Modified: 2004, Oct     Szabolcs Gyurko
11  */
12 
13 #include <linux/ctype.h>
14 #include <linux/device.h>
15 #include <linux/power_supply.h>
16 #include <linux/slab.h>
17 #include <linux/stat.h>
18 
19 #include "power_supply.h"
20 
21 #define MAX_PROP_NAME_LEN 30
22 
23 struct power_supply_attr {
24     const char *prop_name;
25     char attr_name[MAX_PROP_NAME_LEN + 1];
26     struct device_attribute dev_attr;
27     const char *const *text_values;
28     int text_values_len;
29 };
30 
31 #define _POWER_SUPPLY_ATTR(_name, _text, _len)                                                                         \
32     [POWER_SUPPLY_PROP_##_name] = {                                                                                    \
33         .prop_name = #_name,                                                                                           \
34         .attr_name = #_name "\0",                                                                                      \
35         .text_values = (_text),                                                                                        \
36         .text_values_len = (_len),                                                                                     \
37     }
38 
39 #define POWER_SUPPLY_ATTR(_name) _POWER_SUPPLY_ATTR(_name, NULL, 0)
40 #define _POWER_SUPPLY_ENUM_ATTR(_name, _text) _POWER_SUPPLY_ATTR(_name, _text, ARRAY_SIZE(_text))
41 #define POWER_SUPPLY_ENUM_ATTR(_name) _POWER_SUPPLY_ENUM_ATTR(_name, POWER_SUPPLY_##_name##_TEXT)
42 
43 static const char *const POWER_SUPPLY_TYPE_TEXT[] = {
44     [POWER_SUPPLY_TYPE_UNKNOWN] = "Unknown",
45     [POWER_SUPPLY_TYPE_BATTERY] = "Battery",
46     [POWER_SUPPLY_TYPE_UPS] = "UPS",
47     [POWER_SUPPLY_TYPE_MAINS] = "Mains",
48     [POWER_SUPPLY_TYPE_USB] = "USB",
49     [POWER_SUPPLY_TYPE_USB_DCP] = "USB_DCP",
50     [POWER_SUPPLY_TYPE_USB_CDP] = "USB_CDP",
51     [POWER_SUPPLY_TYPE_USB_ACA] = "USB_ACA",
52     [POWER_SUPPLY_TYPE_USB_TYPE_C] = "USB_C",
53     [POWER_SUPPLY_TYPE_USB_PD] = "USB_PD",
54     [POWER_SUPPLY_TYPE_USB_PD_DRP] = "USB_PD_DRP",
55     [POWER_SUPPLY_TYPE_APPLE_BRICK_ID] = "BrickID",
56     [POWER_SUPPLY_TYPE_WIRELESS] = "Wireless",
57 };
58 
59 static const char *const POWER_SUPPLY_USB_TYPE_TEXT[] = {
60     [POWER_SUPPLY_USB_TYPE_UNKNOWN] = "Unknown", [POWER_SUPPLY_USB_TYPE_SDP] = "SDP",
61     [POWER_SUPPLY_USB_TYPE_DCP] = "DCP",         [POWER_SUPPLY_USB_TYPE_CDP] = "CDP",
62     [POWER_SUPPLY_USB_TYPE_ACA] = "ACA",         [POWER_SUPPLY_USB_TYPE_C] = "C",
63     [POWER_SUPPLY_USB_TYPE_PD] = "PD",           [POWER_SUPPLY_USB_TYPE_PD_DRP] = "PD_DRP",
64     [POWER_SUPPLY_USB_TYPE_PD_PPS] = "PD_PPS",   [POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID] = "BrickID",
65 };
66 
67 static const char *const POWER_SUPPLY_STATUS_TEXT[] = {
68     [POWER_SUPPLY_STATUS_UNKNOWN] = "Unknown",
69     [POWER_SUPPLY_STATUS_CHARGING] = "Charging",
70     [POWER_SUPPLY_STATUS_DISCHARGING] = "Discharging",
71     [POWER_SUPPLY_STATUS_NOT_CHARGING] = "Not charging",
72     [POWER_SUPPLY_STATUS_FULL] = "Full",
73 };
74 
75 static const char *const POWER_SUPPLY_CHARGE_TYPE_TEXT[] = {
76     [POWER_SUPPLY_CHARGE_TYPE_UNKNOWN] = "Unknown",   [POWER_SUPPLY_CHARGE_TYPE_NONE] = "N/A",
77     [POWER_SUPPLY_CHARGE_TYPE_TRICKLE] = "Trickle",   [POWER_SUPPLY_CHARGE_TYPE_FAST] = "Fast",
78     [POWER_SUPPLY_CHARGE_TYPE_STANDARD] = "Standard", [POWER_SUPPLY_CHARGE_TYPE_ADAPTIVE] = "Adaptive",
79     [POWER_SUPPLY_CHARGE_TYPE_CUSTOM] = "Custom",     [POWER_SUPPLY_CHARGE_TYPE_LONGLIFE] = "Long Life",
80     [POWER_SUPPLY_CHARGE_TYPE_TAPER] = "Taper",
81 };
82 
83 static const char *const POWER_SUPPLY_HEALTH_TEXT[] = {
84     [POWER_SUPPLY_HEALTH_UNKNOWN] = "Unknown",
85     [POWER_SUPPLY_HEALTH_GOOD] = "Good",
86     [POWER_SUPPLY_HEALTH_OVERHEAT] = "Overheat",
87     [POWER_SUPPLY_HEALTH_DEAD] = "Dead",
88     [POWER_SUPPLY_HEALTH_OVERVOLTAGE] = "Over voltage",
89     [POWER_SUPPLY_HEALTH_UNSPEC_FAILURE] = "Unspecified failure",
90     [POWER_SUPPLY_HEALTH_COLD] = "Cold",
91     [POWER_SUPPLY_HEALTH_WATCHDOG_TIMER_EXPIRE] = "Watchdog timer expire",
92     [POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE] = "Safety timer expire",
93     [POWER_SUPPLY_HEALTH_OVERCURRENT] = "Over current",
94     [POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED] = "Calibration required",
95     [POWER_SUPPLY_HEALTH_WARM] = "Warm",
96     [POWER_SUPPLY_HEALTH_COOL] = "Cool",
97     [POWER_SUPPLY_HEALTH_HOT] = "Hot",
98 };
99 
100 static const char *const POWER_SUPPLY_TECHNOLOGY_TEXT[] = {
101     [POWER_SUPPLY_TECHNOLOGY_UNKNOWN] = "Unknown", [POWER_SUPPLY_TECHNOLOGY_NiMH] = "NiMH",
102     [POWER_SUPPLY_TECHNOLOGY_LION] = "Li-ion",     [POWER_SUPPLY_TECHNOLOGY_LIPO] = "Li-poly",
103     [POWER_SUPPLY_TECHNOLOGY_LiFe] = "LiFe",       [POWER_SUPPLY_TECHNOLOGY_NiCd] = "NiCd",
104     [POWER_SUPPLY_TECHNOLOGY_LiMn] = "LiMn",
105 };
106 
107 static const char *const POWER_SUPPLY_CAPACITY_LEVEL_TEXT[] = {
108     [POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN] = "Unknown", [POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL] = "Critical",
109     [POWER_SUPPLY_CAPACITY_LEVEL_LOW] = "Low",         [POWER_SUPPLY_CAPACITY_LEVEL_NORMAL] = "Normal",
110     [POWER_SUPPLY_CAPACITY_LEVEL_HIGH] = "High",       [POWER_SUPPLY_CAPACITY_LEVEL_FULL] = "Full",
111 };
112 
113 static const char *const POWER_SUPPLY_SCOPE_TEXT[] = {
114     [POWER_SUPPLY_SCOPE_UNKNOWN] = "Unknown",
115     [POWER_SUPPLY_SCOPE_SYSTEM] = "System",
116     [POWER_SUPPLY_SCOPE_DEVICE] = "Device",
117 };
118 
119 static struct power_supply_attr power_supply_attrs[] = {
120     /* Properties of type `int' */
121     POWER_SUPPLY_ENUM_ATTR(STATUS),
122     POWER_SUPPLY_ENUM_ATTR(CHARGE_TYPE),
123     POWER_SUPPLY_ENUM_ATTR(HEALTH),
124     POWER_SUPPLY_ATTR(PRESENT),
125     POWER_SUPPLY_ATTR(ONLINE),
126     POWER_SUPPLY_ATTR(AUTHENTIC),
127     POWER_SUPPLY_ENUM_ATTR(TECHNOLOGY),
128     POWER_SUPPLY_ATTR(CYCLE_COUNT),
129     POWER_SUPPLY_ATTR(VOLTAGE_MAX),
130     POWER_SUPPLY_ATTR(VOLTAGE_MIN),
131     POWER_SUPPLY_ATTR(VOLTAGE_MAX_DESIGN),
132     POWER_SUPPLY_ATTR(VOLTAGE_MIN_DESIGN),
133     POWER_SUPPLY_ATTR(VOLTAGE_NOW),
134     POWER_SUPPLY_ATTR(VOLTAGE_AVG),
135     POWER_SUPPLY_ATTR(VOLTAGE_OCV),
136     POWER_SUPPLY_ATTR(VOLTAGE_BOOT),
137     POWER_SUPPLY_ATTR(CURRENT_MAX),
138     POWER_SUPPLY_ATTR(CURRENT_NOW),
139     POWER_SUPPLY_ATTR(CURRENT_AVG),
140     POWER_SUPPLY_ATTR(CURRENT_BOOT),
141     POWER_SUPPLY_ATTR(POWER_NOW),
142     POWER_SUPPLY_ATTR(POWER_AVG),
143     POWER_SUPPLY_ATTR(CHARGE_FULL_DESIGN),
144     POWER_SUPPLY_ATTR(CHARGE_EMPTY_DESIGN),
145     POWER_SUPPLY_ATTR(CHARGE_FULL),
146     POWER_SUPPLY_ATTR(CHARGE_EMPTY),
147     POWER_SUPPLY_ATTR(CHARGE_NOW),
148     POWER_SUPPLY_ATTR(CHARGE_AVG),
149     POWER_SUPPLY_ATTR(CHARGE_COUNTER),
150     POWER_SUPPLY_ATTR(CONSTANT_CHARGE_CURRENT),
151     POWER_SUPPLY_ATTR(CONSTANT_CHARGE_CURRENT_MAX),
152     POWER_SUPPLY_ATTR(CONSTANT_CHARGE_VOLTAGE),
153     POWER_SUPPLY_ATTR(CONSTANT_CHARGE_VOLTAGE_MAX),
154     POWER_SUPPLY_ATTR(CHARGE_CONTROL_LIMIT),
155     POWER_SUPPLY_ATTR(CHARGE_CONTROL_LIMIT_MAX),
156     POWER_SUPPLY_ATTR(CHARGE_CONTROL_START_THRESHOLD),
157     POWER_SUPPLY_ATTR(CHARGE_CONTROL_END_THRESHOLD),
158     POWER_SUPPLY_ATTR(INPUT_CURRENT_LIMIT),
159     POWER_SUPPLY_ATTR(INPUT_VOLTAGE_LIMIT),
160     POWER_SUPPLY_ATTR(INPUT_POWER_LIMIT),
161     POWER_SUPPLY_ATTR(ENERGY_FULL_DESIGN),
162     POWER_SUPPLY_ATTR(ENERGY_EMPTY_DESIGN),
163     POWER_SUPPLY_ATTR(ENERGY_FULL),
164     POWER_SUPPLY_ATTR(ENERGY_EMPTY),
165     POWER_SUPPLY_ATTR(ENERGY_NOW),
166     POWER_SUPPLY_ATTR(ENERGY_AVG),
167     POWER_SUPPLY_ATTR(CAPACITY),
168     POWER_SUPPLY_ATTR(CAPACITY_ALERT_MIN),
169     POWER_SUPPLY_ATTR(CAPACITY_ALERT_MAX),
170     POWER_SUPPLY_ATTR(CAPACITY_ERROR_MARGIN),
171     POWER_SUPPLY_ENUM_ATTR(CAPACITY_LEVEL),
172     POWER_SUPPLY_ATTR(TEMP),
173     POWER_SUPPLY_ATTR(TEMP_MAX),
174     POWER_SUPPLY_ATTR(TEMP_MIN),
175     POWER_SUPPLY_ATTR(TEMP_ALERT_MIN),
176     POWER_SUPPLY_ATTR(TEMP_ALERT_MAX),
177     POWER_SUPPLY_ATTR(TEMP_AMBIENT),
178     POWER_SUPPLY_ATTR(TEMP_AMBIENT_ALERT_MIN),
179     POWER_SUPPLY_ATTR(TEMP_AMBIENT_ALERT_MAX),
180     POWER_SUPPLY_ATTR(TIME_TO_EMPTY_NOW),
181     POWER_SUPPLY_ATTR(TIME_TO_EMPTY_AVG),
182     POWER_SUPPLY_ATTR(TIME_TO_FULL_NOW),
183     POWER_SUPPLY_ATTR(TIME_TO_FULL_AVG),
184     POWER_SUPPLY_ENUM_ATTR(TYPE),
185     POWER_SUPPLY_ATTR(USB_TYPE),
186     POWER_SUPPLY_ENUM_ATTR(SCOPE),
187     POWER_SUPPLY_ATTR(PRECHARGE_CURRENT),
188     POWER_SUPPLY_ATTR(CHARGE_TERM_CURRENT),
189     POWER_SUPPLY_ATTR(CALIBRATE),
190     POWER_SUPPLY_ATTR(MANUFACTURE_YEAR),
191     POWER_SUPPLY_ATTR(MANUFACTURE_MONTH),
192     POWER_SUPPLY_ATTR(MANUFACTURE_DAY),
193     /* Properties of type `const char *' */
194     POWER_SUPPLY_ATTR(MODEL_NAME),
195     POWER_SUPPLY_ATTR(MANUFACTURER),
196     POWER_SUPPLY_ATTR(SERIAL_NUMBER),
197 };
198 
199 static struct attribute *__power_supply_attrs[ARRAY_SIZE(power_supply_attrs) + 1];
200 
to_ps_attr(struct device_attribute *attr)201 static struct power_supply_attr *to_ps_attr(struct device_attribute *attr)
202 {
203     return container_of(attr, struct power_supply_attr, dev_attr);
204 }
205 
dev_attr_psp(struct device_attribute *attr)206 static enum power_supply_property dev_attr_psp(struct device_attribute *attr)
207 {
208     return to_ps_attr(attr) - power_supply_attrs;
209 }
210 
power_supply_show_usb_type(struct device *dev, const struct power_supply_desc *desc, union power_supply_propval *value, char *buf)211 static ssize_t power_supply_show_usb_type(struct device *dev, const struct power_supply_desc *desc,
212                                           union power_supply_propval *value, char *buf)
213 {
214     enum power_supply_usb_type usb_type;
215     ssize_t count = 0;
216     bool match = false;
217     int i;
218 
219     for (i = 0; i < desc->num_usb_types; ++i) {
220         usb_type = desc->usb_types[i];
221 
222         if (value->intval == usb_type) {
223             count += sprintf(buf + count, "[%s] ", POWER_SUPPLY_USB_TYPE_TEXT[usb_type]);
224             match = true;
225         } else {
226             count += sprintf(buf + count, "%s ", POWER_SUPPLY_USB_TYPE_TEXT[usb_type]);
227         }
228     }
229 
230     if (!match) {
231         dev_warn(dev, "driver reporting unsupported connected type\n");
232         return -EINVAL;
233     }
234 
235     if (count) {
236         buf[count - 1] = '\n';
237     }
238 
239     return count;
240 }
241 
power_supply_show_property(struct device *dev, struct device_attribute *attr, char *buf)242 static ssize_t power_supply_show_property(struct device *dev, struct device_attribute *attr, char *buf)
243 {
244     ssize_t ret;
245     struct power_supply *psy = dev_get_drvdata(dev);
246     struct power_supply_attr *ps_attr = to_ps_attr(attr);
247     enum power_supply_property psp = dev_attr_psp(attr);
248     union power_supply_propval value;
249     if (psp == POWER_SUPPLY_PROP_TYPE) {
250         value.intval = psy->desc->type;
251     } else {
252         ret = power_supply_get_property(psy, psp, &value);
253         if (ret < 0) {
254             if (ret == -ENODATA) {
255                 dev_dbg(dev, "driver has no data for `%s' property\n", attr->attr.name);
256             } else if (ret != -ENODEV && ret != -EAGAIN) {
257                 dev_err_ratelimited(dev, "driver failed to report `%s' property: %zd\n", attr->attr.name, ret);
258             }
259             return ret;
260         }
261     }
262     if (ps_attr->text_values_len > 0 && value.intval < ps_attr->text_values_len && value.intval >= 0) {
263         return sprintf(buf, "%s\n", ps_attr->text_values[value.intval]);
264     }
265     switch (psp) {
266         case POWER_SUPPLY_PROP_USB_TYPE:
267             ret = power_supply_show_usb_type(dev, psy->desc, &value, buf);
268             break;
269         case POWER_SUPPLY_PROP_MODEL_NAME ... POWER_SUPPLY_PROP_SERIAL_NUMBER:
270             ret = sprintf(buf, "%s\n", value.strval);
271             break;
272         default:
273             ret = sprintf(buf, "%d\n", value.intval);
274     }
275     return ret;
276 }
277 
power_supply_store_property(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)278 static ssize_t power_supply_store_property(struct device *dev, struct device_attribute *attr, const char *buf,
279                                            size_t count)
280 {
281     ssize_t ret;
282     struct power_supply *psy = dev_get_drvdata(dev);
283     struct power_supply_attr *ps_attr = to_ps_attr(attr);
284     enum power_supply_property psp = dev_attr_psp(attr);
285     union power_supply_propval value;
286 
287     ret = -EINVAL;
288     if (ps_attr->text_values_len > 0) {
289         ret = __sysfs_match_string(ps_attr->text_values, ps_attr->text_values_len, buf);
290     }
291 
292     /*
293      * If no match was found, then check to see if it is an integer.
294      * Integer values are valid for enums in addition to the text value.
295      */
296     if (ret < 0) {
297         long long_val;
298 
299         ret = kstrtol(buf, 10, &long_val);
300         if (ret < 0) {
301             return ret;
302         }
303 
304         ret = long_val;
305     }
306 
307     value.intval = ret;
308 
309     ret = power_supply_set_property(psy, psp, &value);
310     if (ret < 0) {
311         return ret;
312     }
313 
314     return count;
315 }
316 
power_supply_attr_is_visible(struct kobject *kobj, struct attribute *attr, int attrno)317 static umode_t power_supply_attr_is_visible(struct kobject *kobj, struct attribute *attr, int attrno)
318 {
319     struct device *dev = kobj_to_dev(kobj);
320     struct power_supply *psy = dev_get_drvdata(dev);
321     umode_t mode = S_IRUSR | S_IRGRP | S_IROTH;
322     int i;
323 
324     if (!power_supply_attrs[attrno].prop_name) {
325         return 0;
326     }
327 
328     if (attrno == POWER_SUPPLY_PROP_TYPE) {
329         return mode;
330     }
331 
332     for (i = 0; i < psy->desc->num_properties; i++) {
333         int property = psy->desc->properties[i];
334 
335         if (property == attrno) {
336             if (psy->desc->property_is_writeable && psy->desc->property_is_writeable(psy, property) > 0) {
337                 mode |= S_IWUSR;
338             }
339 
340             return mode;
341         }
342     }
343 
344     return 0;
345 }
346 
347 static struct attribute_group power_supply_attr_group = {
348     .attrs = __power_supply_attrs,
349     .is_visible = power_supply_attr_is_visible,
350 };
351 
352 static const struct attribute_group *power_supply_attr_groups[] = {
353     &power_supply_attr_group,
354     NULL,
355 };
356 
str_to_lower(char *str)357 static void str_to_lower(char *str)
358 {
359     while (*str) {
360         *str = tolower(*str);
361         str++;
362     }
363 }
364 
power_supply_init_attrs(struct device_type *dev_type)365 void power_supply_init_attrs(struct device_type *dev_type)
366 {
367     int i;
368 
369     dev_type->groups = power_supply_attr_groups;
370 
371     for (i = 0; i < ARRAY_SIZE(power_supply_attrs); i++) {
372         struct device_attribute *attr;
373 
374         if (!power_supply_attrs[i].prop_name) {
375             pr_warn("%s: Property %d skipped because is is missing from power_supply_attrs\n", __func__, i);
376             sprintf(power_supply_attrs[i].attr_name, "_err_%d", i);
377         } else {
378             str_to_lower(power_supply_attrs[i].attr_name);
379         }
380 
381         attr = &power_supply_attrs[i].dev_attr;
382 
383         attr->attr.name = power_supply_attrs[i].attr_name;
384         attr->show = power_supply_show_property;
385         attr->store = power_supply_store_property;
386         __power_supply_attrs[i] = &attr->attr;
387     }
388 }
389 
add_prop_uevent(struct device *dev, struct kobj_uevent_env *env, enum power_supply_property prop, char *prop_buf)390 static int add_prop_uevent(struct device *dev, struct kobj_uevent_env *env, enum power_supply_property prop,
391                            char *prop_buf)
392 {
393     int ret = 0;
394     struct power_supply_attr *pwr_attr;
395     struct device_attribute *dev_attr;
396     char *line;
397 
398     pwr_attr = &power_supply_attrs[prop];
399     dev_attr = &pwr_attr->dev_attr;
400 
401     ret = power_supply_show_property(dev, dev_attr, prop_buf);
402     if (ret == -ENODEV || ret == -ENODATA) {
403         /*
404          * When a battery is absent, we expect -ENODEV. Don't abort;
405          * send the uevent with at least the the PRESENT=0 property
406          */
407         return 0;
408     }
409 
410     if (ret < 0) {
411         return ret;
412     }
413 
414     line = strchr(prop_buf, '\n');
415     if (line) {
416         *line = 0;
417     }
418 
419     return add_uevent_var(env, "POWER_SUPPLY_%s=%s", pwr_attr->prop_name, prop_buf);
420 }
421 
power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)422 int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env)
423 {
424     struct power_supply *psy = dev_get_drvdata(dev);
425     int ret = 0, j;
426     char *prop_buf;
427 
428     if (!psy || !psy->desc) {
429         dev_dbg(dev, "No power supply yet\n");
430         return ret;
431     }
432 
433     ret = add_uevent_var(env, "POWER_SUPPLY_NAME=%s", psy->desc->name);
434     if (ret) {
435         return ret;
436     }
437 
438     prop_buf = (char *)get_zeroed_page(GFP_KERNEL);
439     if (!prop_buf) {
440         return -ENOMEM;
441     }
442 
443     ret = add_prop_uevent(dev, env, POWER_SUPPLY_PROP_TYPE, prop_buf);
444     if (ret) {
445         goto out;
446     }
447 
448     for (j = 0; j < psy->desc->num_properties; j++) {
449         ret = add_prop_uevent(dev, env, psy->desc->properties[j], prop_buf);
450         if (ret) {
451             goto out;
452         }
453     }
454 
455 out:
456     free_page((unsigned long)prop_buf);
457 
458     return ret;
459 }
460