.. | .. |
---|
138 | 138 | |
---|
139 | 139 | return ret ? : size; |
---|
140 | 140 | } |
---|
| 141 | + |
---|
| 142 | +static ssize_t oneshot_repeat_show(struct device *child, |
---|
| 143 | + struct device_attribute *attr, |
---|
| 144 | + char *buf) |
---|
| 145 | +{ |
---|
| 146 | + const struct pwm_device *pwm = child_to_pwm_device(child); |
---|
| 147 | + struct pwm_state state; |
---|
| 148 | + |
---|
| 149 | + pwm_get_state(pwm, &state); |
---|
| 150 | + |
---|
| 151 | + return sprintf(buf, "%u\n", state.oneshot_repeat); |
---|
| 152 | +} |
---|
| 153 | + |
---|
| 154 | +static ssize_t oneshot_repeat_store(struct device *child, |
---|
| 155 | + struct device_attribute *attr, |
---|
| 156 | + const char *buf, size_t size) |
---|
| 157 | +{ |
---|
| 158 | + struct pwm_export *export = child_to_pwm_export(child); |
---|
| 159 | + struct pwm_device *pwm = export->pwm; |
---|
| 160 | + struct pwm_state state; |
---|
| 161 | + unsigned int val; |
---|
| 162 | + int ret; |
---|
| 163 | + |
---|
| 164 | + ret = kstrtouint(buf, 0, &val); |
---|
| 165 | + if (ret) |
---|
| 166 | + return ret; |
---|
| 167 | + |
---|
| 168 | + mutex_lock(&export->lock); |
---|
| 169 | + pwm_get_state(pwm, &state); |
---|
| 170 | + state.oneshot_repeat = val; |
---|
| 171 | + ret = pwm_apply_state(pwm, &state); |
---|
| 172 | + mutex_unlock(&export->lock); |
---|
| 173 | + |
---|
| 174 | + return ret ? : size; |
---|
| 175 | +} |
---|
| 176 | + |
---|
| 177 | +static ssize_t duty_offset_show(struct device *child, |
---|
| 178 | + struct device_attribute *attr, |
---|
| 179 | + char *buf) |
---|
| 180 | +{ |
---|
| 181 | + const struct pwm_device *pwm = child_to_pwm_device(child); |
---|
| 182 | + struct pwm_state state; |
---|
| 183 | + |
---|
| 184 | + pwm_get_state(pwm, &state); |
---|
| 185 | + |
---|
| 186 | + return sprintf(buf, "%llu\n", state.duty_offset); |
---|
| 187 | +} |
---|
| 188 | + |
---|
| 189 | +static ssize_t duty_offset_store(struct device *child, |
---|
| 190 | + struct device_attribute *attr, |
---|
| 191 | + const char *buf, size_t size) |
---|
| 192 | +{ |
---|
| 193 | + struct pwm_export *export = child_to_pwm_export(child); |
---|
| 194 | + struct pwm_device *pwm = export->pwm; |
---|
| 195 | + struct pwm_state state; |
---|
| 196 | + u64 val; |
---|
| 197 | + int ret; |
---|
| 198 | + |
---|
| 199 | + ret = kstrtou64(buf, 0, &val); |
---|
| 200 | + if (ret) |
---|
| 201 | + return ret; |
---|
| 202 | + |
---|
| 203 | + mutex_lock(&export->lock); |
---|
| 204 | + pwm_get_state(pwm, &state); |
---|
| 205 | + state.duty_offset = val; |
---|
| 206 | + ret = pwm_apply_state(pwm, &state); |
---|
| 207 | + mutex_unlock(&export->lock); |
---|
| 208 | + |
---|
| 209 | + return ret ? : size; |
---|
| 210 | +} |
---|
141 | 211 | #endif |
---|
142 | 212 | |
---|
143 | 213 | static ssize_t enable_show(struct device *child, |
---|
.. | .. |
---|
279 | 349 | static DEVICE_ATTR_RW(duty_cycle); |
---|
280 | 350 | #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT |
---|
281 | 351 | static DEVICE_ATTR_RW(oneshot_count); |
---|
| 352 | +static DEVICE_ATTR_RW(oneshot_repeat); |
---|
| 353 | +static DEVICE_ATTR_RW(duty_offset); |
---|
282 | 354 | #endif |
---|
283 | 355 | static DEVICE_ATTR_RW(enable); |
---|
284 | 356 | static DEVICE_ATTR_RW(polarity); |
---|
.. | .. |
---|
290 | 362 | &dev_attr_duty_cycle.attr, |
---|
291 | 363 | #ifdef CONFIG_PWM_ROCKCHIP_ONESHOT |
---|
292 | 364 | &dev_attr_oneshot_count.attr, |
---|
| 365 | + &dev_attr_oneshot_repeat.attr, |
---|
| 366 | + &dev_attr_duty_offset.attr, |
---|
293 | 367 | #endif |
---|
294 | 368 | &dev_attr_enable.attr, |
---|
295 | 369 | &dev_attr_polarity.attr, |
---|
.. | .. |
---|
492 | 566 | if (!export) |
---|
493 | 567 | continue; |
---|
494 | 568 | |
---|
| 569 | + /* If pwmchip was not enabled before suspend, do nothing. */ |
---|
| 570 | + if (!export->suspend.enabled) { |
---|
| 571 | + /* release lock taken in pwm_class_get_state */ |
---|
| 572 | + mutex_unlock(&export->lock); |
---|
| 573 | + continue; |
---|
| 574 | + } |
---|
| 575 | + |
---|
495 | 576 | state.enabled = export->suspend.enabled; |
---|
496 | 577 | ret = pwm_class_apply_state(export, pwm, &state); |
---|
497 | 578 | if (ret < 0) |
---|
.. | .. |
---|
516 | 597 | if (!export) |
---|
517 | 598 | continue; |
---|
518 | 599 | |
---|
| 600 | + /* |
---|
| 601 | + * If pwmchip was not enabled before suspend, save |
---|
| 602 | + * state for resume time and do nothing else. |
---|
| 603 | + */ |
---|
519 | 604 | export->suspend = state; |
---|
| 605 | + if (!state.enabled) { |
---|
| 606 | + /* release lock taken in pwm_class_get_state */ |
---|
| 607 | + mutex_unlock(&export->lock); |
---|
| 608 | + continue; |
---|
| 609 | + } |
---|
| 610 | + |
---|
520 | 611 | state.enabled = false; |
---|
521 | 612 | ret = pwm_class_apply_state(export, pwm, &state); |
---|
522 | 613 | if (ret < 0) { |
---|