Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
[sfrench/cifs-2.6.git] / drivers / pwm / sysfs.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * A simple sysfs interface for the generic PWM framework
4  *
5  * Copyright (C) 2013 H Hartley Sweeten <hsweeten@visionengravers.com>
6  *
7  * Based on previous work by Lars Poeschel <poeschel@lemonage.de>
8  */
9
10 #include <linux/device.h>
11 #include <linux/mutex.h>
12 #include <linux/err.h>
13 #include <linux/slab.h>
14 #include <linux/kdev_t.h>
15 #include <linux/pwm.h>
16
17 struct pwm_export {
18         struct device child;
19         struct pwm_device *pwm;
20         struct mutex lock;
21 };
22
23 static struct pwm_export *child_to_pwm_export(struct device *child)
24 {
25         return container_of(child, struct pwm_export, child);
26 }
27
28 static struct pwm_device *child_to_pwm_device(struct device *child)
29 {
30         struct pwm_export *export = child_to_pwm_export(child);
31
32         return export->pwm;
33 }
34
35 static ssize_t period_show(struct device *child,
36                            struct device_attribute *attr,
37                            char *buf)
38 {
39         const struct pwm_device *pwm = child_to_pwm_device(child);
40         struct pwm_state state;
41
42         pwm_get_state(pwm, &state);
43
44         return sprintf(buf, "%u\n", state.period);
45 }
46
47 static ssize_t period_store(struct device *child,
48                             struct device_attribute *attr,
49                             const char *buf, size_t size)
50 {
51         struct pwm_export *export = child_to_pwm_export(child);
52         struct pwm_device *pwm = export->pwm;
53         struct pwm_state state;
54         unsigned int val;
55         int ret;
56
57         ret = kstrtouint(buf, 0, &val);
58         if (ret)
59                 return ret;
60
61         mutex_lock(&export->lock);
62         pwm_get_state(pwm, &state);
63         state.period = val;
64         ret = pwm_apply_state(pwm, &state);
65         mutex_unlock(&export->lock);
66
67         return ret ? : size;
68 }
69
70 static ssize_t duty_cycle_show(struct device *child,
71                                struct device_attribute *attr,
72                                char *buf)
73 {
74         const struct pwm_device *pwm = child_to_pwm_device(child);
75         struct pwm_state state;
76
77         pwm_get_state(pwm, &state);
78
79         return sprintf(buf, "%u\n", state.duty_cycle);
80 }
81
82 static ssize_t duty_cycle_store(struct device *child,
83                                 struct device_attribute *attr,
84                                 const char *buf, size_t size)
85 {
86         struct pwm_export *export = child_to_pwm_export(child);
87         struct pwm_device *pwm = export->pwm;
88         struct pwm_state state;
89         unsigned int val;
90         int ret;
91
92         ret = kstrtouint(buf, 0, &val);
93         if (ret)
94                 return ret;
95
96         mutex_lock(&export->lock);
97         pwm_get_state(pwm, &state);
98         state.duty_cycle = val;
99         ret = pwm_apply_state(pwm, &state);
100         mutex_unlock(&export->lock);
101
102         return ret ? : size;
103 }
104
105 static ssize_t enable_show(struct device *child,
106                            struct device_attribute *attr,
107                            char *buf)
108 {
109         const struct pwm_device *pwm = child_to_pwm_device(child);
110         struct pwm_state state;
111
112         pwm_get_state(pwm, &state);
113
114         return sprintf(buf, "%d\n", state.enabled);
115 }
116
117 static ssize_t enable_store(struct device *child,
118                             struct device_attribute *attr,
119                             const char *buf, size_t size)
120 {
121         struct pwm_export *export = child_to_pwm_export(child);
122         struct pwm_device *pwm = export->pwm;
123         struct pwm_state state;
124         int val, ret;
125
126         ret = kstrtoint(buf, 0, &val);
127         if (ret)
128                 return ret;
129
130         mutex_lock(&export->lock);
131
132         pwm_get_state(pwm, &state);
133
134         switch (val) {
135         case 0:
136                 state.enabled = false;
137                 break;
138         case 1:
139                 state.enabled = true;
140                 break;
141         default:
142                 ret = -EINVAL;
143                 goto unlock;
144         }
145
146         ret = pwm_apply_state(pwm, &state);
147
148 unlock:
149         mutex_unlock(&export->lock);
150         return ret ? : size;
151 }
152
153 static ssize_t polarity_show(struct device *child,
154                              struct device_attribute *attr,
155                              char *buf)
156 {
157         const struct pwm_device *pwm = child_to_pwm_device(child);
158         const char *polarity = "unknown";
159         struct pwm_state state;
160
161         pwm_get_state(pwm, &state);
162
163         switch (state.polarity) {
164         case PWM_POLARITY_NORMAL:
165                 polarity = "normal";
166                 break;
167
168         case PWM_POLARITY_INVERSED:
169                 polarity = "inversed";
170                 break;
171         }
172
173         return sprintf(buf, "%s\n", polarity);
174 }
175
176 static ssize_t polarity_store(struct device *child,
177                               struct device_attribute *attr,
178                               const char *buf, size_t size)
179 {
180         struct pwm_export *export = child_to_pwm_export(child);
181         struct pwm_device *pwm = export->pwm;
182         enum pwm_polarity polarity;
183         struct pwm_state state;
184         int ret;
185
186         if (sysfs_streq(buf, "normal"))
187                 polarity = PWM_POLARITY_NORMAL;
188         else if (sysfs_streq(buf, "inversed"))
189                 polarity = PWM_POLARITY_INVERSED;
190         else
191                 return -EINVAL;
192
193         mutex_lock(&export->lock);
194         pwm_get_state(pwm, &state);
195         state.polarity = polarity;
196         ret = pwm_apply_state(pwm, &state);
197         mutex_unlock(&export->lock);
198
199         return ret ? : size;
200 }
201
202 static ssize_t capture_show(struct device *child,
203                             struct device_attribute *attr,
204                             char *buf)
205 {
206         struct pwm_device *pwm = child_to_pwm_device(child);
207         struct pwm_capture result;
208         int ret;
209
210         ret = pwm_capture(pwm, &result, jiffies_to_msecs(HZ));
211         if (ret)
212                 return ret;
213
214         return sprintf(buf, "%u %u\n", result.period, result.duty_cycle);
215 }
216
217 static DEVICE_ATTR_RW(period);
218 static DEVICE_ATTR_RW(duty_cycle);
219 static DEVICE_ATTR_RW(enable);
220 static DEVICE_ATTR_RW(polarity);
221 static DEVICE_ATTR_RO(capture);
222
223 static struct attribute *pwm_attrs[] = {
224         &dev_attr_period.attr,
225         &dev_attr_duty_cycle.attr,
226         &dev_attr_enable.attr,
227         &dev_attr_polarity.attr,
228         &dev_attr_capture.attr,
229         NULL
230 };
231 ATTRIBUTE_GROUPS(pwm);
232
233 static void pwm_export_release(struct device *child)
234 {
235         struct pwm_export *export = child_to_pwm_export(child);
236
237         kfree(export);
238 }
239
240 static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
241 {
242         struct pwm_export *export;
243         char *pwm_prop[2];
244         int ret;
245
246         if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags))
247                 return -EBUSY;
248
249         export = kzalloc(sizeof(*export), GFP_KERNEL);
250         if (!export) {
251                 clear_bit(PWMF_EXPORTED, &pwm->flags);
252                 return -ENOMEM;
253         }
254
255         export->pwm = pwm;
256         mutex_init(&export->lock);
257
258         export->child.release = pwm_export_release;
259         export->child.parent = parent;
260         export->child.devt = MKDEV(0, 0);
261         export->child.groups = pwm_groups;
262         dev_set_name(&export->child, "pwm%u", pwm->hwpwm);
263
264         ret = device_register(&export->child);
265         if (ret) {
266                 clear_bit(PWMF_EXPORTED, &pwm->flags);
267                 put_device(&export->child);
268                 export = NULL;
269                 return ret;
270         }
271         pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=pwm%u", pwm->hwpwm);
272         pwm_prop[1] = NULL;
273         kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
274         kfree(pwm_prop[0]);
275
276         return 0;
277 }
278
279 static int pwm_unexport_match(struct device *child, void *data)
280 {
281         return child_to_pwm_device(child) == data;
282 }
283
284 static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
285 {
286         struct device *child;
287         char *pwm_prop[2];
288
289         if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags))
290                 return -ENODEV;
291
292         child = device_find_child(parent, pwm, pwm_unexport_match);
293         if (!child)
294                 return -ENODEV;
295
296         pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=pwm%u", pwm->hwpwm);
297         pwm_prop[1] = NULL;
298         kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
299         kfree(pwm_prop[0]);
300
301         /* for device_find_child() */
302         put_device(child);
303         device_unregister(child);
304         pwm_put(pwm);
305
306         return 0;
307 }
308
309 static ssize_t export_store(struct device *parent,
310                             struct device_attribute *attr,
311                             const char *buf, size_t len)
312 {
313         struct pwm_chip *chip = dev_get_drvdata(parent);
314         struct pwm_device *pwm;
315         unsigned int hwpwm;
316         int ret;
317
318         ret = kstrtouint(buf, 0, &hwpwm);
319         if (ret < 0)
320                 return ret;
321
322         if (hwpwm >= chip->npwm)
323                 return -ENODEV;
324
325         pwm = pwm_request_from_chip(chip, hwpwm, "sysfs");
326         if (IS_ERR(pwm))
327                 return PTR_ERR(pwm);
328
329         ret = pwm_export_child(parent, pwm);
330         if (ret < 0)
331                 pwm_put(pwm);
332
333         return ret ? : len;
334 }
335 static DEVICE_ATTR_WO(export);
336
337 static ssize_t unexport_store(struct device *parent,
338                               struct device_attribute *attr,
339                               const char *buf, size_t len)
340 {
341         struct pwm_chip *chip = dev_get_drvdata(parent);
342         unsigned int hwpwm;
343         int ret;
344
345         ret = kstrtouint(buf, 0, &hwpwm);
346         if (ret < 0)
347                 return ret;
348
349         if (hwpwm >= chip->npwm)
350                 return -ENODEV;
351
352         ret = pwm_unexport_child(parent, &chip->pwms[hwpwm]);
353
354         return ret ? : len;
355 }
356 static DEVICE_ATTR_WO(unexport);
357
358 static ssize_t npwm_show(struct device *parent, struct device_attribute *attr,
359                          char *buf)
360 {
361         const struct pwm_chip *chip = dev_get_drvdata(parent);
362
363         return sprintf(buf, "%u\n", chip->npwm);
364 }
365 static DEVICE_ATTR_RO(npwm);
366
367 static struct attribute *pwm_chip_attrs[] = {
368         &dev_attr_export.attr,
369         &dev_attr_unexport.attr,
370         &dev_attr_npwm.attr,
371         NULL,
372 };
373 ATTRIBUTE_GROUPS(pwm_chip);
374
375 static struct class pwm_class = {
376         .name = "pwm",
377         .owner = THIS_MODULE,
378         .dev_groups = pwm_chip_groups,
379 };
380
381 static int pwmchip_sysfs_match(struct device *parent, const void *data)
382 {
383         return dev_get_drvdata(parent) == data;
384 }
385
386 void pwmchip_sysfs_export(struct pwm_chip *chip)
387 {
388         struct device *parent;
389
390         /*
391          * If device_create() fails the pwm_chip is still usable by
392          * the kernel it's just not exported.
393          */
394         parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip,
395                                "pwmchip%d", chip->base);
396         if (IS_ERR(parent)) {
397                 dev_warn(chip->dev,
398                          "device_create failed for pwm_chip sysfs export\n");
399         }
400 }
401
402 void pwmchip_sysfs_unexport(struct pwm_chip *chip)
403 {
404         struct device *parent;
405         unsigned int i;
406
407         parent = class_find_device(&pwm_class, NULL, chip,
408                                    pwmchip_sysfs_match);
409         if (!parent)
410                 return;
411
412         for (i = 0; i < chip->npwm; i++) {
413                 struct pwm_device *pwm = &chip->pwms[i];
414
415                 if (test_bit(PWMF_EXPORTED, &pwm->flags))
416                         pwm_unexport_child(parent, pwm);
417         }
418
419         put_device(parent);
420         device_unregister(parent);
421 }
422
423 static int __init pwm_sysfs_init(void)
424 {
425         return class_register(&pwm_class);
426 }
427 subsys_initcall(pwm_sysfs_init);