1 /* 2 * A simple sysfs interface for the generic PWM framework 3 * 4 * Copyright (C) 2013 H Hartley Sweeten <hsweeten@visionengravers.com> 5 * 6 * Based on previous work by Lars Poeschel <poeschel@lemonage.de> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2, or (at your option) 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 */ 18 19 #include <linux/device.h> 20 #include <linux/mutex.h> 21 #include <linux/err.h> 22 #include <linux/slab.h> 23 #include <linux/kdev_t.h> 24 #include <linux/pwm.h> 25 26 struct pwm_export { 27 struct device child; 28 struct pwm_device *pwm; 29 }; 30 31 static struct pwm_export *child_to_pwm_export(struct device *child) 32 { 33 return container_of(child, struct pwm_export, child); 34 } 35 36 static struct pwm_device *child_to_pwm_device(struct device *child) 37 { 38 struct pwm_export *export = child_to_pwm_export(child); 39 40 return export->pwm; 41 } 42 43 static ssize_t pwm_period_show(struct device *child, 44 struct device_attribute *attr, 45 char *buf) 46 { 47 const struct pwm_device *pwm = child_to_pwm_device(child); 48 49 return sprintf(buf, "%u\n", pwm_get_period(pwm)); 50 } 51 52 static ssize_t pwm_period_store(struct device *child, 53 struct device_attribute *attr, 54 const char *buf, size_t size) 55 { 56 struct pwm_device *pwm = child_to_pwm_device(child); 57 unsigned int val; 58 int ret; 59 60 ret = kstrtouint(buf, 0, &val); 61 if (ret) 62 return ret; 63 64 ret = pwm_config(pwm, pwm_get_duty_cycle(pwm), val); 65 66 return ret ? : size; 67 } 68 69 static ssize_t pwm_duty_cycle_show(struct device *child, 70 struct device_attribute *attr, 71 char *buf) 72 { 73 const struct pwm_device *pwm = child_to_pwm_device(child); 74 75 return sprintf(buf, "%u\n", pwm_get_duty_cycle(pwm)); 76 } 77 78 static ssize_t pwm_duty_cycle_store(struct device *child, 79 struct device_attribute *attr, 80 const char *buf, size_t size) 81 { 82 struct pwm_device *pwm = child_to_pwm_device(child); 83 unsigned int val; 84 int ret; 85 86 ret = kstrtouint(buf, 0, &val); 87 if (ret) 88 return ret; 89 90 ret = pwm_config(pwm, val, pwm_get_period(pwm)); 91 92 return ret ? : size; 93 } 94 95 static ssize_t pwm_enable_show(struct device *child, 96 struct device_attribute *attr, 97 char *buf) 98 { 99 const struct pwm_device *pwm = child_to_pwm_device(child); 100 int enabled = pwm_is_enabled(pwm); 101 102 return sprintf(buf, "%d\n", enabled); 103 } 104 105 static ssize_t pwm_enable_store(struct device *child, 106 struct device_attribute *attr, 107 const char *buf, size_t size) 108 { 109 struct pwm_device *pwm = child_to_pwm_device(child); 110 int val, ret; 111 112 ret = kstrtoint(buf, 0, &val); 113 if (ret) 114 return ret; 115 116 switch (val) { 117 case 0: 118 pwm_disable(pwm); 119 break; 120 case 1: 121 ret = pwm_enable(pwm); 122 break; 123 default: 124 ret = -EINVAL; 125 break; 126 } 127 128 return ret ? : size; 129 } 130 131 static ssize_t pwm_polarity_show(struct device *child, 132 struct device_attribute *attr, 133 char *buf) 134 { 135 const struct pwm_device *pwm = child_to_pwm_device(child); 136 const char *polarity = "unknown"; 137 138 switch (pwm_get_polarity(pwm)) { 139 case PWM_POLARITY_NORMAL: 140 polarity = "normal"; 141 break; 142 143 case PWM_POLARITY_INVERSED: 144 polarity = "inversed"; 145 break; 146 } 147 148 return sprintf(buf, "%s\n", polarity); 149 } 150 151 static ssize_t pwm_polarity_store(struct device *child, 152 struct device_attribute *attr, 153 const char *buf, size_t size) 154 { 155 struct pwm_device *pwm = child_to_pwm_device(child); 156 enum pwm_polarity polarity; 157 int ret; 158 159 if (sysfs_streq(buf, "normal")) 160 polarity = PWM_POLARITY_NORMAL; 161 else if (sysfs_streq(buf, "inversed")) 162 polarity = PWM_POLARITY_INVERSED; 163 else 164 return -EINVAL; 165 166 ret = pwm_set_polarity(pwm, polarity); 167 168 return ret ? : size; 169 } 170 171 static DEVICE_ATTR(period, 0644, pwm_period_show, pwm_period_store); 172 static DEVICE_ATTR(duty_cycle, 0644, pwm_duty_cycle_show, pwm_duty_cycle_store); 173 static DEVICE_ATTR(enable, 0644, pwm_enable_show, pwm_enable_store); 174 static DEVICE_ATTR(polarity, 0644, pwm_polarity_show, pwm_polarity_store); 175 176 static struct attribute *pwm_attrs[] = { 177 &dev_attr_period.attr, 178 &dev_attr_duty_cycle.attr, 179 &dev_attr_enable.attr, 180 &dev_attr_polarity.attr, 181 NULL 182 }; 183 ATTRIBUTE_GROUPS(pwm); 184 185 static void pwm_export_release(struct device *child) 186 { 187 struct pwm_export *export = child_to_pwm_export(child); 188 189 kfree(export); 190 } 191 192 static int pwm_export_child(struct device *parent, struct pwm_device *pwm) 193 { 194 struct pwm_export *export; 195 int ret; 196 197 if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags)) 198 return -EBUSY; 199 200 export = kzalloc(sizeof(*export), GFP_KERNEL); 201 if (!export) { 202 clear_bit(PWMF_EXPORTED, &pwm->flags); 203 return -ENOMEM; 204 } 205 206 export->pwm = pwm; 207 208 export->child.release = pwm_export_release; 209 export->child.parent = parent; 210 export->child.devt = MKDEV(0, 0); 211 export->child.groups = pwm_groups; 212 dev_set_name(&export->child, "pwm%u", pwm->hwpwm); 213 214 ret = device_register(&export->child); 215 if (ret) { 216 clear_bit(PWMF_EXPORTED, &pwm->flags); 217 kfree(export); 218 return ret; 219 } 220 221 return 0; 222 } 223 224 static int pwm_unexport_match(struct device *child, void *data) 225 { 226 return child_to_pwm_device(child) == data; 227 } 228 229 static int pwm_unexport_child(struct device *parent, struct pwm_device *pwm) 230 { 231 struct device *child; 232 233 if (!test_and_clear_bit(PWMF_EXPORTED, &pwm->flags)) 234 return -ENODEV; 235 236 child = device_find_child(parent, pwm, pwm_unexport_match); 237 if (!child) 238 return -ENODEV; 239 240 /* for device_find_child() */ 241 put_device(child); 242 device_unregister(child); 243 pwm_put(pwm); 244 245 return 0; 246 } 247 248 static ssize_t pwm_export_store(struct device *parent, 249 struct device_attribute *attr, 250 const char *buf, size_t len) 251 { 252 struct pwm_chip *chip = dev_get_drvdata(parent); 253 struct pwm_device *pwm; 254 unsigned int hwpwm; 255 int ret; 256 257 ret = kstrtouint(buf, 0, &hwpwm); 258 if (ret < 0) 259 return ret; 260 261 if (hwpwm >= chip->npwm) 262 return -ENODEV; 263 264 pwm = pwm_request_from_chip(chip, hwpwm, "sysfs"); 265 if (IS_ERR(pwm)) 266 return PTR_ERR(pwm); 267 268 ret = pwm_export_child(parent, pwm); 269 if (ret < 0) 270 pwm_put(pwm); 271 272 return ret ? : len; 273 } 274 static DEVICE_ATTR(export, 0200, NULL, pwm_export_store); 275 276 static ssize_t pwm_unexport_store(struct device *parent, 277 struct device_attribute *attr, 278 const char *buf, size_t len) 279 { 280 struct pwm_chip *chip = dev_get_drvdata(parent); 281 unsigned int hwpwm; 282 int ret; 283 284 ret = kstrtouint(buf, 0, &hwpwm); 285 if (ret < 0) 286 return ret; 287 288 if (hwpwm >= chip->npwm) 289 return -ENODEV; 290 291 ret = pwm_unexport_child(parent, &chip->pwms[hwpwm]); 292 293 return ret ? : len; 294 } 295 static DEVICE_ATTR(unexport, 0200, NULL, pwm_unexport_store); 296 297 static ssize_t npwm_show(struct device *parent, struct device_attribute *attr, 298 char *buf) 299 { 300 const struct pwm_chip *chip = dev_get_drvdata(parent); 301 302 return sprintf(buf, "%u\n", chip->npwm); 303 } 304 static DEVICE_ATTR_RO(npwm); 305 306 static struct attribute *pwm_chip_attrs[] = { 307 &dev_attr_export.attr, 308 &dev_attr_unexport.attr, 309 &dev_attr_npwm.attr, 310 NULL, 311 }; 312 ATTRIBUTE_GROUPS(pwm_chip); 313 314 static struct class pwm_class = { 315 .name = "pwm", 316 .owner = THIS_MODULE, 317 .dev_groups = pwm_chip_groups, 318 }; 319 320 static int pwmchip_sysfs_match(struct device *parent, const void *data) 321 { 322 return dev_get_drvdata(parent) == data; 323 } 324 325 void pwmchip_sysfs_export(struct pwm_chip *chip) 326 { 327 struct device *parent; 328 329 /* 330 * If device_create() fails the pwm_chip is still usable by 331 * the kernel its just not exported. 332 */ 333 parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip, 334 "pwmchip%d", chip->base); 335 if (IS_ERR(parent)) { 336 dev_warn(chip->dev, 337 "device_create failed for pwm_chip sysfs export\n"); 338 } 339 } 340 341 void pwmchip_sysfs_unexport(struct pwm_chip *chip) 342 { 343 struct device *parent; 344 345 parent = class_find_device(&pwm_class, NULL, chip, 346 pwmchip_sysfs_match); 347 if (parent) { 348 /* for class_find_device() */ 349 put_device(parent); 350 device_unregister(parent); 351 } 352 } 353 354 static int __init pwm_sysfs_init(void) 355 { 356 return class_register(&pwm_class); 357 } 358 subsys_initcall(pwm_sysfs_init); 359