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