@@ -122,6 +122,43 @@ static struct pwm *pwm_chip_sysfs_get_pwm(struct pwm_chip *chip,
return pwm;
}
+static ssize_t pwm_chip_sysfs_read_prop(const struct pwm_sysfs *pwm_sysfs,
+ char *propname,
+ char *buf, size_t count)
+{
+ int fd;
+ va_list ap;
+ int ret;
+ size_t cntread = 0;
+
+ fd = openat(pwm_sysfs->dirfd, propname, O_RDONLY | O_CLOEXEC);
+ if (fd < 0)
+ return -1;
+
+ while (cntread < count) {
+ ret = read(fd, buf + cntread, count - cntread);
+ if (ret < 0) {
+ int saved_errno = errno;
+
+ close(fd);
+
+ errno = saved_errno;
+
+ return ret;
+ } else if (ret == 0) {
+ break;
+ }
+
+ cntread += ret;
+ }
+
+ ret = close(fd);
+ if (ret)
+ return ret;
+
+ return cntread;
+}
+
static int pwm_chip_sysfs_write_prop(const struct pwm_sysfs *pwm_sysfs,
char *propname,
const char *restrict format, ...)
@@ -173,7 +210,26 @@ static int pwm_chip_sysfs_set_waveform(struct pwm *pwm,
if (!pwm_sysfs->cache_valid ||
(wf->duty_offset_ns >= wf->period_length_ns - wf->duty_length_ns) != pwm_sysfs->inverted_polarity) {
- if (wf->duty_offset_ns < wf->period_length_ns - wf->duty_length_ns) {
+ if (wf->duty_length_ns == wf->period_length_ns || wf->duty_length_ns == 0) {
+ /*
+ * Waveforms with constant inactive output have two
+ * possible representations in sysfs. Either with normal
+ * polarity and duty_cycle = 0, or with inverted
+ * polarity and duty_cycle = period. The analogous
+ * statement is true for constant active waveforms. As
+ * many PWMs only support a single polarity, and also to
+ * minimize sysfs access, keep the current polarity in
+ * this case.
+ */
+ if (!pwm_sysfs->cache_valid) {
+ char buf[20];
+
+ ret = pwm_chip_sysfs_read_prop(pwm_sysfs, "polarity", buf, sizeof(buf));
+ if (ret < 0)
+ return ret;
+ pwm_sysfs->inverted_polarity = buf[0] == 'i';
+ }
+ } else if (wf->duty_offset_ns < wf->period_length_ns - wf->duty_length_ns) {
ret = pwm_chip_sysfs_write_prop(pwm_sysfs, "polarity", "normal\n");
if (ret)
return ret;
Some waveforms have equivalent representations in sysfs with different polarities. As some PWMs only support a single polarity, minimize polarity changes. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com> --- sysfs.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-)