root/drivers/pwm/sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. child_to_pwm_export
  2. child_to_pwm_device
  3. period_show
  4. period_store
  5. duty_cycle_show
  6. duty_cycle_store
  7. enable_show
  8. enable_store
  9. polarity_show
  10. polarity_store
  11. capture_show
  12. pwm_export_release
  13. pwm_export_child
  14. pwm_unexport_match
  15. pwm_unexport_child
  16. export_store
  17. unexport_store
  18. npwm_show
  19. pwm_class_get_state
  20. pwm_class_apply_state
  21. pwm_class_resume_npwm
  22. pwm_class_suspend
  23. pwm_class_resume
  24. pwmchip_sysfs_match
  25. pwmchip_sysfs_export
  26. pwmchip_sysfs_unexport
  27. pwm_sysfs_init

   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         struct pwm_state suspend;
  22 };
  23 
  24 static struct pwm_export *child_to_pwm_export(struct device *child)
  25 {
  26         return container_of(child, struct pwm_export, child);
  27 }
  28 
  29 static struct pwm_device *child_to_pwm_device(struct device *child)
  30 {
  31         struct pwm_export *export = child_to_pwm_export(child);
  32 
  33         return export->pwm;
  34 }
  35 
  36 static ssize_t period_show(struct device *child,
  37                            struct device_attribute *attr,
  38                            char *buf)
  39 {
  40         const struct pwm_device *pwm = child_to_pwm_device(child);
  41         struct pwm_state state;
  42 
  43         pwm_get_state(pwm, &state);
  44 
  45         return sprintf(buf, "%u\n", state.period);
  46 }
  47 
  48 static ssize_t period_store(struct device *child,
  49                             struct device_attribute *attr,
  50                             const char *buf, size_t size)
  51 {
  52         struct pwm_export *export = child_to_pwm_export(child);
  53         struct pwm_device *pwm = export->pwm;
  54         struct pwm_state state;
  55         unsigned int val;
  56         int ret;
  57 
  58         ret = kstrtouint(buf, 0, &val);
  59         if (ret)
  60                 return ret;
  61 
  62         mutex_lock(&export->lock);
  63         pwm_get_state(pwm, &state);
  64         state.period = val;
  65         ret = pwm_apply_state(pwm, &state);
  66         mutex_unlock(&export->lock);
  67 
  68         return ret ? : size;
  69 }
  70 
  71 static ssize_t duty_cycle_show(struct device *child,
  72                                struct device_attribute *attr,
  73                                char *buf)
  74 {
  75         const struct pwm_device *pwm = child_to_pwm_device(child);
  76         struct pwm_state state;
  77 
  78         pwm_get_state(pwm, &state);
  79 
  80         return sprintf(buf, "%u\n", state.duty_cycle);
  81 }
  82 
  83 static ssize_t duty_cycle_store(struct device *child,
  84                                 struct device_attribute *attr,
  85                                 const char *buf, size_t size)
  86 {
  87         struct pwm_export *export = child_to_pwm_export(child);
  88         struct pwm_device *pwm = export->pwm;
  89         struct pwm_state state;
  90         unsigned int val;
  91         int ret;
  92 
  93         ret = kstrtouint(buf, 0, &val);
  94         if (ret)
  95                 return ret;
  96 
  97         mutex_lock(&export->lock);
  98         pwm_get_state(pwm, &state);
  99         state.duty_cycle = val;
 100         ret = pwm_apply_state(pwm, &state);
 101         mutex_unlock(&export->lock);
 102 
 103         return ret ? : size;
 104 }
 105 
 106 static ssize_t enable_show(struct device *child,
 107                            struct device_attribute *attr,
 108                            char *buf)
 109 {
 110         const struct pwm_device *pwm = child_to_pwm_device(child);
 111         struct pwm_state state;
 112 
 113         pwm_get_state(pwm, &state);
 114 
 115         return sprintf(buf, "%d\n", state.enabled);
 116 }
 117 
 118 static ssize_t enable_store(struct device *child,
 119                             struct device_attribute *attr,
 120                             const char *buf, size_t size)
 121 {
 122         struct pwm_export *export = child_to_pwm_export(child);
 123         struct pwm_device *pwm = export->pwm;
 124         struct pwm_state state;
 125         int val, ret;
 126 
 127         ret = kstrtoint(buf, 0, &val);
 128         if (ret)
 129                 return ret;
 130 
 131         mutex_lock(&export->lock);
 132 
 133         pwm_get_state(pwm, &state);
 134 
 135         switch (val) {
 136         case 0:
 137                 state.enabled = false;
 138                 break;
 139         case 1:
 140                 state.enabled = true;
 141                 break;
 142         default:
 143                 ret = -EINVAL;
 144                 goto unlock;
 145         }
 146 
 147         ret = pwm_apply_state(pwm, &state);
 148 
 149 unlock:
 150         mutex_unlock(&export->lock);
 151         return ret ? : size;
 152 }
 153 
 154 static ssize_t polarity_show(struct device *child,
 155                              struct device_attribute *attr,
 156                              char *buf)
 157 {
 158         const struct pwm_device *pwm = child_to_pwm_device(child);
 159         const char *polarity = "unknown";
 160         struct pwm_state state;
 161 
 162         pwm_get_state(pwm, &state);
 163 
 164         switch (state.polarity) {
 165         case PWM_POLARITY_NORMAL:
 166                 polarity = "normal";
 167                 break;
 168 
 169         case PWM_POLARITY_INVERSED:
 170                 polarity = "inversed";
 171                 break;
 172         }
 173 
 174         return sprintf(buf, "%s\n", polarity);
 175 }
 176 
 177 static ssize_t polarity_store(struct device *child,
 178                               struct device_attribute *attr,
 179                               const char *buf, size_t size)
 180 {
 181         struct pwm_export *export = child_to_pwm_export(child);
 182         struct pwm_device *pwm = export->pwm;
 183         enum pwm_polarity polarity;
 184         struct pwm_state state;
 185         int ret;
 186 
 187         if (sysfs_streq(buf, "normal"))
 188                 polarity = PWM_POLARITY_NORMAL;
 189         else if (sysfs_streq(buf, "inversed"))
 190                 polarity = PWM_POLARITY_INVERSED;
 191         else
 192                 return -EINVAL;
 193 
 194         mutex_lock(&export->lock);
 195         pwm_get_state(pwm, &state);
 196         state.polarity = polarity;
 197         ret = pwm_apply_state(pwm, &state);
 198         mutex_unlock(&export->lock);
 199 
 200         return ret ? : size;
 201 }
 202 
 203 static ssize_t capture_show(struct device *child,
 204                             struct device_attribute *attr,
 205                             char *buf)
 206 {
 207         struct pwm_device *pwm = child_to_pwm_device(child);
 208         struct pwm_capture result;
 209         int ret;
 210 
 211         ret = pwm_capture(pwm, &result, jiffies_to_msecs(HZ));
 212         if (ret)
 213                 return ret;
 214 
 215         return sprintf(buf, "%u %u\n", result.period, result.duty_cycle);
 216 }
 217 
 218 static DEVICE_ATTR_RW(period);
 219 static DEVICE_ATTR_RW(duty_cycle);
 220 static DEVICE_ATTR_RW(enable);
 221 static DEVICE_ATTR_RW(polarity);
 222 static DEVICE_ATTR_RO(capture);
 223 
 224 static struct attribute *pwm_attrs[] = {
 225         &dev_attr_period.attr,
 226         &dev_attr_duty_cycle.attr,
 227         &dev_attr_enable.attr,
 228         &dev_attr_polarity.attr,
 229         &dev_attr_capture.attr,
 230         NULL
 231 };
 232 ATTRIBUTE_GROUPS(pwm);
 233 
 234 static void pwm_export_release(struct device *child)
 235 {
 236         struct pwm_export *export = child_to_pwm_export(child);
 237 
 238         kfree(export);
 239 }
 240 
 241 static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
 242 {
 243         struct pwm_export *export;
 244         char *pwm_prop[2];
 245         int ret;
 246 
 247         if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags))
 248                 return -EBUSY;
 249 
 250         export = kzalloc(sizeof(*export), GFP_KERNEL);
 251         if (!export) {
 252                 clear_bit(PWMF_EXPORTED, &pwm->flags);
 253                 return -ENOMEM;
 254         }
 255 
 256         export->pwm = pwm;
 257         mutex_init(&export->lock);
 258 
 259         export->child.release = pwm_export_release;
 260         export->child.parent = parent;
 261         export->child.devt = MKDEV(0, 0);
 262         export->child.groups = pwm_groups;
 263         dev_set_name(&export->child, "pwm%u", pwm->hwpwm);
 264 
 265         ret = device_register(&export->child);
 266         if (ret) {
 267                 clear_bit(PWMF_EXPORTED, &pwm->flags);
 268                 put_device(&export->child);
 269                 export = NULL;
 270                 return ret;
 271         }
 272         pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=pwm%u", pwm->hwpwm);
 273         pwm_prop[1] = NULL;
 274         kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
 275         kfree(pwm_prop[0]);
 276 
 277         return 0;
 278 }
 279 
 280 static int pwm_unexport_match(struct device *child, void *data)
 281 {
 282         return child_to_pwm_device(child) == data;
 283 }
 284 
 285 static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
 286 {
 287         struct device *child;
 288         char *pwm_prop[2];
 289 
 290         if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags))
 291                 return -ENODEV;
 292 
 293         child = device_find_child(parent, pwm, pwm_unexport_match);
 294         if (!child)
 295                 return -ENODEV;
 296 
 297         pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=pwm%u", pwm->hwpwm);
 298         pwm_prop[1] = NULL;
 299         kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
 300         kfree(pwm_prop[0]);
 301 
 302         /* for device_find_child() */
 303         put_device(child);
 304         device_unregister(child);
 305         pwm_put(pwm);
 306 
 307         return 0;
 308 }
 309 
 310 static ssize_t export_store(struct device *parent,
 311                             struct device_attribute *attr,
 312                             const char *buf, size_t len)
 313 {
 314         struct pwm_chip *chip = dev_get_drvdata(parent);
 315         struct pwm_device *pwm;
 316         unsigned int hwpwm;
 317         int ret;
 318 
 319         ret = kstrtouint(buf, 0, &hwpwm);
 320         if (ret < 0)
 321                 return ret;
 322 
 323         if (hwpwm >= chip->npwm)
 324                 return -ENODEV;
 325 
 326         pwm = pwm_request_from_chip(chip, hwpwm, "sysfs");
 327         if (IS_ERR(pwm))
 328                 return PTR_ERR(pwm);
 329 
 330         ret = pwm_export_child(parent, pwm);
 331         if (ret < 0)
 332                 pwm_put(pwm);
 333 
 334         return ret ? : len;
 335 }
 336 static DEVICE_ATTR_WO(export);
 337 
 338 static ssize_t unexport_store(struct device *parent,
 339                               struct device_attribute *attr,
 340                               const char *buf, size_t len)
 341 {
 342         struct pwm_chip *chip = dev_get_drvdata(parent);
 343         unsigned int hwpwm;
 344         int ret;
 345 
 346         ret = kstrtouint(buf, 0, &hwpwm);
 347         if (ret < 0)
 348                 return ret;
 349 
 350         if (hwpwm >= chip->npwm)
 351                 return -ENODEV;
 352 
 353         ret = pwm_unexport_child(parent, &chip->pwms[hwpwm]);
 354 
 355         return ret ? : len;
 356 }
 357 static DEVICE_ATTR_WO(unexport);
 358 
 359 static ssize_t npwm_show(struct device *parent, struct device_attribute *attr,
 360                          char *buf)
 361 {
 362         const struct pwm_chip *chip = dev_get_drvdata(parent);
 363 
 364         return sprintf(buf, "%u\n", chip->npwm);
 365 }
 366 static DEVICE_ATTR_RO(npwm);
 367 
 368 static struct attribute *pwm_chip_attrs[] = {
 369         &dev_attr_export.attr,
 370         &dev_attr_unexport.attr,
 371         &dev_attr_npwm.attr,
 372         NULL,
 373 };
 374 ATTRIBUTE_GROUPS(pwm_chip);
 375 
 376 /* takes export->lock on success */
 377 static struct pwm_export *pwm_class_get_state(struct device *parent,
 378                                               struct pwm_device *pwm,
 379                                               struct pwm_state *state)
 380 {
 381         struct device *child;
 382         struct pwm_export *export;
 383 
 384         if (!test_bit(PWMF_EXPORTED, &pwm->flags))
 385                 return NULL;
 386 
 387         child = device_find_child(parent, pwm, pwm_unexport_match);
 388         if (!child)
 389                 return NULL;
 390 
 391         export = child_to_pwm_export(child);
 392         put_device(child);      /* for device_find_child() */
 393 
 394         mutex_lock(&export->lock);
 395         pwm_get_state(pwm, state);
 396 
 397         return export;
 398 }
 399 
 400 static int pwm_class_apply_state(struct pwm_export *export,
 401                                  struct pwm_device *pwm,
 402                                  struct pwm_state *state)
 403 {
 404         int ret = pwm_apply_state(pwm, state);
 405 
 406         /* release lock taken in pwm_class_get_state */
 407         mutex_unlock(&export->lock);
 408 
 409         return ret;
 410 }
 411 
 412 static int pwm_class_resume_npwm(struct device *parent, unsigned int npwm)
 413 {
 414         struct pwm_chip *chip = dev_get_drvdata(parent);
 415         unsigned int i;
 416         int ret = 0;
 417 
 418         for (i = 0; i < npwm; i++) {
 419                 struct pwm_device *pwm = &chip->pwms[i];
 420                 struct pwm_state state;
 421                 struct pwm_export *export;
 422 
 423                 export = pwm_class_get_state(parent, pwm, &state);
 424                 if (!export)
 425                         continue;
 426 
 427                 state.enabled = export->suspend.enabled;
 428                 ret = pwm_class_apply_state(export, pwm, &state);
 429                 if (ret < 0)
 430                         break;
 431         }
 432 
 433         return ret;
 434 }
 435 
 436 static int __maybe_unused pwm_class_suspend(struct device *parent)
 437 {
 438         struct pwm_chip *chip = dev_get_drvdata(parent);
 439         unsigned int i;
 440         int ret = 0;
 441 
 442         for (i = 0; i < chip->npwm; i++) {
 443                 struct pwm_device *pwm = &chip->pwms[i];
 444                 struct pwm_state state;
 445                 struct pwm_export *export;
 446 
 447                 export = pwm_class_get_state(parent, pwm, &state);
 448                 if (!export)
 449                         continue;
 450 
 451                 export->suspend = state;
 452                 state.enabled = false;
 453                 ret = pwm_class_apply_state(export, pwm, &state);
 454                 if (ret < 0) {
 455                         /*
 456                          * roll back the PWM devices that were disabled by
 457                          * this suspend function.
 458                          */
 459                         pwm_class_resume_npwm(parent, i);
 460                         break;
 461                 }
 462         }
 463 
 464         return ret;
 465 }
 466 
 467 static int __maybe_unused pwm_class_resume(struct device *parent)
 468 {
 469         struct pwm_chip *chip = dev_get_drvdata(parent);
 470 
 471         return pwm_class_resume_npwm(parent, chip->npwm);
 472 }
 473 
 474 static SIMPLE_DEV_PM_OPS(pwm_class_pm_ops, pwm_class_suspend, pwm_class_resume);
 475 
 476 static struct class pwm_class = {
 477         .name = "pwm",
 478         .owner = THIS_MODULE,
 479         .dev_groups = pwm_chip_groups,
 480         .pm = &pwm_class_pm_ops,
 481 };
 482 
 483 static int pwmchip_sysfs_match(struct device *parent, const void *data)
 484 {
 485         return dev_get_drvdata(parent) == data;
 486 }
 487 
 488 void pwmchip_sysfs_export(struct pwm_chip *chip)
 489 {
 490         struct device *parent;
 491 
 492         /*
 493          * If device_create() fails the pwm_chip is still usable by
 494          * the kernel it's just not exported.
 495          */
 496         parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip,
 497                                "pwmchip%d", chip->base);
 498         if (IS_ERR(parent)) {
 499                 dev_warn(chip->dev,
 500                          "device_create failed for pwm_chip sysfs export\n");
 501         }
 502 }
 503 
 504 void pwmchip_sysfs_unexport(struct pwm_chip *chip)
 505 {
 506         struct device *parent;
 507         unsigned int i;
 508 
 509         parent = class_find_device(&pwm_class, NULL, chip,
 510                                    pwmchip_sysfs_match);
 511         if (!parent)
 512                 return;
 513 
 514         for (i = 0; i < chip->npwm; i++) {
 515                 struct pwm_device *pwm = &chip->pwms[i];
 516 
 517                 if (test_bit(PWMF_EXPORTED, &pwm->flags))
 518                         pwm_unexport_child(parent, pwm);
 519         }
 520 
 521         put_device(parent);
 522         device_unregister(parent);
 523 }
 524 
 525 static int __init pwm_sysfs_init(void)
 526 {
 527         return class_register(&pwm_class);
 528 }
 529 subsys_initcall(pwm_sysfs_init);

/* [<][>][^][v][top][bottom][index][help] */