Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * A simple sysfs interface for the generic PWM framework
0004  *
0005  * Copyright (C) 2013 H Hartley Sweeten <hsweeten@visionengravers.com>
0006  *
0007  * Based on previous work by Lars Poeschel <poeschel@lemonage.de>
0008  */
0009 
0010 #include <linux/device.h>
0011 #include <linux/mutex.h>
0012 #include <linux/err.h>
0013 #include <linux/slab.h>
0014 #include <linux/kdev_t.h>
0015 #include <linux/pwm.h>
0016 
0017 struct pwm_export {
0018     struct device child;
0019     struct pwm_device *pwm;
0020     struct mutex lock;
0021     struct pwm_state suspend;
0022 };
0023 
0024 static struct pwm_export *child_to_pwm_export(struct device *child)
0025 {
0026     return container_of(child, struct pwm_export, child);
0027 }
0028 
0029 static struct pwm_device *child_to_pwm_device(struct device *child)
0030 {
0031     struct pwm_export *export = child_to_pwm_export(child);
0032 
0033     return export->pwm;
0034 }
0035 
0036 static ssize_t period_show(struct device *child,
0037                struct device_attribute *attr,
0038                char *buf)
0039 {
0040     const struct pwm_device *pwm = child_to_pwm_device(child);
0041     struct pwm_state state;
0042 
0043     pwm_get_state(pwm, &state);
0044 
0045     return sprintf(buf, "%llu\n", state.period);
0046 }
0047 
0048 static ssize_t period_store(struct device *child,
0049                 struct device_attribute *attr,
0050                 const char *buf, size_t size)
0051 {
0052     struct pwm_export *export = child_to_pwm_export(child);
0053     struct pwm_device *pwm = export->pwm;
0054     struct pwm_state state;
0055     u64 val;
0056     int ret;
0057 
0058     ret = kstrtou64(buf, 0, &val);
0059     if (ret)
0060         return ret;
0061 
0062     mutex_lock(&export->lock);
0063     pwm_get_state(pwm, &state);
0064     state.period = val;
0065     ret = pwm_apply_state(pwm, &state);
0066     mutex_unlock(&export->lock);
0067 
0068     return ret ? : size;
0069 }
0070 
0071 static ssize_t duty_cycle_show(struct device *child,
0072                    struct device_attribute *attr,
0073                    char *buf)
0074 {
0075     const struct pwm_device *pwm = child_to_pwm_device(child);
0076     struct pwm_state state;
0077 
0078     pwm_get_state(pwm, &state);
0079 
0080     return sprintf(buf, "%llu\n", state.duty_cycle);
0081 }
0082 
0083 static ssize_t duty_cycle_store(struct device *child,
0084                 struct device_attribute *attr,
0085                 const char *buf, size_t size)
0086 {
0087     struct pwm_export *export = child_to_pwm_export(child);
0088     struct pwm_device *pwm = export->pwm;
0089     struct pwm_state state;
0090     u64 val;
0091     int ret;
0092 
0093     ret = kstrtou64(buf, 0, &val);
0094     if (ret)
0095         return ret;
0096 
0097     mutex_lock(&export->lock);
0098     pwm_get_state(pwm, &state);
0099     state.duty_cycle = val;
0100     ret = pwm_apply_state(pwm, &state);
0101     mutex_unlock(&export->lock);
0102 
0103     return ret ? : size;
0104 }
0105 
0106 static ssize_t enable_show(struct device *child,
0107                struct device_attribute *attr,
0108                char *buf)
0109 {
0110     const struct pwm_device *pwm = child_to_pwm_device(child);
0111     struct pwm_state state;
0112 
0113     pwm_get_state(pwm, &state);
0114 
0115     return sprintf(buf, "%d\n", state.enabled);
0116 }
0117 
0118 static ssize_t enable_store(struct device *child,
0119                 struct device_attribute *attr,
0120                 const char *buf, size_t size)
0121 {
0122     struct pwm_export *export = child_to_pwm_export(child);
0123     struct pwm_device *pwm = export->pwm;
0124     struct pwm_state state;
0125     int val, ret;
0126 
0127     ret = kstrtoint(buf, 0, &val);
0128     if (ret)
0129         return ret;
0130 
0131     mutex_lock(&export->lock);
0132 
0133     pwm_get_state(pwm, &state);
0134 
0135     switch (val) {
0136     case 0:
0137         state.enabled = false;
0138         break;
0139     case 1:
0140         state.enabled = true;
0141         break;
0142     default:
0143         ret = -EINVAL;
0144         goto unlock;
0145     }
0146 
0147     ret = pwm_apply_state(pwm, &state);
0148 
0149 unlock:
0150     mutex_unlock(&export->lock);
0151     return ret ? : size;
0152 }
0153 
0154 static ssize_t polarity_show(struct device *child,
0155                  struct device_attribute *attr,
0156                  char *buf)
0157 {
0158     const struct pwm_device *pwm = child_to_pwm_device(child);
0159     const char *polarity = "unknown";
0160     struct pwm_state state;
0161 
0162     pwm_get_state(pwm, &state);
0163 
0164     switch (state.polarity) {
0165     case PWM_POLARITY_NORMAL:
0166         polarity = "normal";
0167         break;
0168 
0169     case PWM_POLARITY_INVERSED:
0170         polarity = "inversed";
0171         break;
0172     }
0173 
0174     return sprintf(buf, "%s\n", polarity);
0175 }
0176 
0177 static ssize_t polarity_store(struct device *child,
0178                   struct device_attribute *attr,
0179                   const char *buf, size_t size)
0180 {
0181     struct pwm_export *export = child_to_pwm_export(child);
0182     struct pwm_device *pwm = export->pwm;
0183     enum pwm_polarity polarity;
0184     struct pwm_state state;
0185     int ret;
0186 
0187     if (sysfs_streq(buf, "normal"))
0188         polarity = PWM_POLARITY_NORMAL;
0189     else if (sysfs_streq(buf, "inversed"))
0190         polarity = PWM_POLARITY_INVERSED;
0191     else
0192         return -EINVAL;
0193 
0194     mutex_lock(&export->lock);
0195     pwm_get_state(pwm, &state);
0196     state.polarity = polarity;
0197     ret = pwm_apply_state(pwm, &state);
0198     mutex_unlock(&export->lock);
0199 
0200     return ret ? : size;
0201 }
0202 
0203 static ssize_t capture_show(struct device *child,
0204                 struct device_attribute *attr,
0205                 char *buf)
0206 {
0207     struct pwm_device *pwm = child_to_pwm_device(child);
0208     struct pwm_capture result;
0209     int ret;
0210 
0211     ret = pwm_capture(pwm, &result, jiffies_to_msecs(HZ));
0212     if (ret)
0213         return ret;
0214 
0215     return sprintf(buf, "%u %u\n", result.period, result.duty_cycle);
0216 }
0217 
0218 static DEVICE_ATTR_RW(period);
0219 static DEVICE_ATTR_RW(duty_cycle);
0220 static DEVICE_ATTR_RW(enable);
0221 static DEVICE_ATTR_RW(polarity);
0222 static DEVICE_ATTR_RO(capture);
0223 
0224 static struct attribute *pwm_attrs[] = {
0225     &dev_attr_period.attr,
0226     &dev_attr_duty_cycle.attr,
0227     &dev_attr_enable.attr,
0228     &dev_attr_polarity.attr,
0229     &dev_attr_capture.attr,
0230     NULL
0231 };
0232 ATTRIBUTE_GROUPS(pwm);
0233 
0234 static void pwm_export_release(struct device *child)
0235 {
0236     struct pwm_export *export = child_to_pwm_export(child);
0237 
0238     kfree(export);
0239 }
0240 
0241 static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
0242 {
0243     struct pwm_export *export;
0244     char *pwm_prop[2];
0245     int ret;
0246 
0247     if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags))
0248         return -EBUSY;
0249 
0250     export = kzalloc(sizeof(*export), GFP_KERNEL);
0251     if (!export) {
0252         clear_bit(PWMF_EXPORTED, &pwm->flags);
0253         return -ENOMEM;
0254     }
0255 
0256     export->pwm = pwm;
0257     mutex_init(&export->lock);
0258 
0259     export->child.release = pwm_export_release;
0260     export->child.parent = parent;
0261     export->child.devt = MKDEV(0, 0);
0262     export->child.groups = pwm_groups;
0263     dev_set_name(&export->child, "pwm%u", pwm->hwpwm);
0264 
0265     ret = device_register(&export->child);
0266     if (ret) {
0267         clear_bit(PWMF_EXPORTED, &pwm->flags);
0268         put_device(&export->child);
0269         export = NULL;
0270         return ret;
0271     }
0272     pwm_prop[0] = kasprintf(GFP_KERNEL, "EXPORT=pwm%u", pwm->hwpwm);
0273     pwm_prop[1] = NULL;
0274     kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
0275     kfree(pwm_prop[0]);
0276 
0277     return 0;
0278 }
0279 
0280 static int pwm_unexport_match(struct device *child, void *data)
0281 {
0282     return child_to_pwm_device(child) == data;
0283 }
0284 
0285 static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm)
0286 {
0287     struct device *child;
0288     char *pwm_prop[2];
0289 
0290     if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags))
0291         return -ENODEV;
0292 
0293     child = device_find_child(parent, pwm, pwm_unexport_match);
0294     if (!child)
0295         return -ENODEV;
0296 
0297     pwm_prop[0] = kasprintf(GFP_KERNEL, "UNEXPORT=pwm%u", pwm->hwpwm);
0298     pwm_prop[1] = NULL;
0299     kobject_uevent_env(&parent->kobj, KOBJ_CHANGE, pwm_prop);
0300     kfree(pwm_prop[0]);
0301 
0302     /* for device_find_child() */
0303     put_device(child);
0304     device_unregister(child);
0305     pwm_put(pwm);
0306 
0307     return 0;
0308 }
0309 
0310 static ssize_t export_store(struct device *parent,
0311                 struct device_attribute *attr,
0312                 const char *buf, size_t len)
0313 {
0314     struct pwm_chip *chip = dev_get_drvdata(parent);
0315     struct pwm_device *pwm;
0316     unsigned int hwpwm;
0317     int ret;
0318 
0319     ret = kstrtouint(buf, 0, &hwpwm);
0320     if (ret < 0)
0321         return ret;
0322 
0323     if (hwpwm >= chip->npwm)
0324         return -ENODEV;
0325 
0326     pwm = pwm_request_from_chip(chip, hwpwm, "sysfs");
0327     if (IS_ERR(pwm))
0328         return PTR_ERR(pwm);
0329 
0330     ret = pwm_export_child(parent, pwm);
0331     if (ret < 0)
0332         pwm_put(pwm);
0333 
0334     return ret ? : len;
0335 }
0336 static DEVICE_ATTR_WO(export);
0337 
0338 static ssize_t unexport_store(struct device *parent,
0339                   struct device_attribute *attr,
0340                   const char *buf, size_t len)
0341 {
0342     struct pwm_chip *chip = dev_get_drvdata(parent);
0343     unsigned int hwpwm;
0344     int ret;
0345 
0346     ret = kstrtouint(buf, 0, &hwpwm);
0347     if (ret < 0)
0348         return ret;
0349 
0350     if (hwpwm >= chip->npwm)
0351         return -ENODEV;
0352 
0353     ret = pwm_unexport_child(parent, &chip->pwms[hwpwm]);
0354 
0355     return ret ? : len;
0356 }
0357 static DEVICE_ATTR_WO(unexport);
0358 
0359 static ssize_t npwm_show(struct device *parent, struct device_attribute *attr,
0360              char *buf)
0361 {
0362     const struct pwm_chip *chip = dev_get_drvdata(parent);
0363 
0364     return sprintf(buf, "%u\n", chip->npwm);
0365 }
0366 static DEVICE_ATTR_RO(npwm);
0367 
0368 static struct attribute *pwm_chip_attrs[] = {
0369     &dev_attr_export.attr,
0370     &dev_attr_unexport.attr,
0371     &dev_attr_npwm.attr,
0372     NULL,
0373 };
0374 ATTRIBUTE_GROUPS(pwm_chip);
0375 
0376 /* takes export->lock on success */
0377 static struct pwm_export *pwm_class_get_state(struct device *parent,
0378                           struct pwm_device *pwm,
0379                           struct pwm_state *state)
0380 {
0381     struct device *child;
0382     struct pwm_export *export;
0383 
0384     if (!test_bit(PWMF_EXPORTED, &pwm->flags))
0385         return NULL;
0386 
0387     child = device_find_child(parent, pwm, pwm_unexport_match);
0388     if (!child)
0389         return NULL;
0390 
0391     export = child_to_pwm_export(child);
0392     put_device(child);  /* for device_find_child() */
0393 
0394     mutex_lock(&export->lock);
0395     pwm_get_state(pwm, state);
0396 
0397     return export;
0398 }
0399 
0400 static int pwm_class_apply_state(struct pwm_export *export,
0401                  struct pwm_device *pwm,
0402                  struct pwm_state *state)
0403 {
0404     int ret = pwm_apply_state(pwm, state);
0405 
0406     /* release lock taken in pwm_class_get_state */
0407     mutex_unlock(&export->lock);
0408 
0409     return ret;
0410 }
0411 
0412 static int pwm_class_resume_npwm(struct device *parent, unsigned int npwm)
0413 {
0414     struct pwm_chip *chip = dev_get_drvdata(parent);
0415     unsigned int i;
0416     int ret = 0;
0417 
0418     for (i = 0; i < npwm; i++) {
0419         struct pwm_device *pwm = &chip->pwms[i];
0420         struct pwm_state state;
0421         struct pwm_export *export;
0422 
0423         export = pwm_class_get_state(parent, pwm, &state);
0424         if (!export)
0425             continue;
0426 
0427         state.enabled = export->suspend.enabled;
0428         ret = pwm_class_apply_state(export, pwm, &state);
0429         if (ret < 0)
0430             break;
0431     }
0432 
0433     return ret;
0434 }
0435 
0436 static int __maybe_unused pwm_class_suspend(struct device *parent)
0437 {
0438     struct pwm_chip *chip = dev_get_drvdata(parent);
0439     unsigned int i;
0440     int ret = 0;
0441 
0442     for (i = 0; i < chip->npwm; i++) {
0443         struct pwm_device *pwm = &chip->pwms[i];
0444         struct pwm_state state;
0445         struct pwm_export *export;
0446 
0447         export = pwm_class_get_state(parent, pwm, &state);
0448         if (!export)
0449             continue;
0450 
0451         export->suspend = state;
0452         state.enabled = false;
0453         ret = pwm_class_apply_state(export, pwm, &state);
0454         if (ret < 0) {
0455             /*
0456              * roll back the PWM devices that were disabled by
0457              * this suspend function.
0458              */
0459             pwm_class_resume_npwm(parent, i);
0460             break;
0461         }
0462     }
0463 
0464     return ret;
0465 }
0466 
0467 static int __maybe_unused pwm_class_resume(struct device *parent)
0468 {
0469     struct pwm_chip *chip = dev_get_drvdata(parent);
0470 
0471     return pwm_class_resume_npwm(parent, chip->npwm);
0472 }
0473 
0474 static SIMPLE_DEV_PM_OPS(pwm_class_pm_ops, pwm_class_suspend, pwm_class_resume);
0475 
0476 static struct class pwm_class = {
0477     .name = "pwm",
0478     .owner = THIS_MODULE,
0479     .dev_groups = pwm_chip_groups,
0480     .pm = &pwm_class_pm_ops,
0481 };
0482 
0483 static int pwmchip_sysfs_match(struct device *parent, const void *data)
0484 {
0485     return dev_get_drvdata(parent) == data;
0486 }
0487 
0488 void pwmchip_sysfs_export(struct pwm_chip *chip)
0489 {
0490     struct device *parent;
0491 
0492     /*
0493      * If device_create() fails the pwm_chip is still usable by
0494      * the kernel it's just not exported.
0495      */
0496     parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip,
0497                    "pwmchip%d", chip->base);
0498     if (IS_ERR(parent)) {
0499         dev_warn(chip->dev,
0500              "device_create failed for pwm_chip sysfs export\n");
0501     }
0502 }
0503 
0504 void pwmchip_sysfs_unexport(struct pwm_chip *chip)
0505 {
0506     struct device *parent;
0507     unsigned int i;
0508 
0509     parent = class_find_device(&pwm_class, NULL, chip,
0510                    pwmchip_sysfs_match);
0511     if (!parent)
0512         return;
0513 
0514     for (i = 0; i < chip->npwm; i++) {
0515         struct pwm_device *pwm = &chip->pwms[i];
0516 
0517         if (test_bit(PWMF_EXPORTED, &pwm->flags))
0518             pwm_unexport_child(parent, pwm);
0519     }
0520 
0521     put_device(parent);
0522     device_unregister(parent);
0523 }
0524 
0525 static int __init pwm_sysfs_init(void)
0526 {
0527     return class_register(&pwm_class);
0528 }
0529 subsys_initcall(pwm_sysfs_init);