usr.sbin/pwm/pwm add support for flags

The pwm utility cant set the only flag defined (PWM_POLARITY_INVERTED) so this
patch add the option -I (capital letter i) to send it to the drivers.

None of existing PWM driver have implemented support for flags.
But soon:ish I will put up an review of a pwm driver using TI OMAP DMTimer.

Differential Revision: https://reviews.freebsd.org/D29137
MFC after:   2 weeks
This commit is contained in:
Oskar Holmund 2021-03-11 09:55:23 +01:00 committed by Emmanuel Vadot
parent 7d4a5de84d
commit 17b14d8f77
3 changed files with 34 additions and 7 deletions

View File

@ -80,9 +80,16 @@ pwm_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
bcopy(data, &state, sizeof(state)); bcopy(data, &state, sizeof(state));
rv = PWMBUS_CHANNEL_CONFIG(bus, sc->chan, rv = PWMBUS_CHANNEL_CONFIG(bus, sc->chan,
state.period, state.duty); state.period, state.duty);
if (rv == 0) if (rv != 0)
rv = PWMBUS_CHANNEL_ENABLE(bus, sc->chan, return (rv);
state.enable);
rv = PWMBUS_CHANNEL_SET_FLAGS(bus,
sc->chan, state.flags);
if (rv != 0 && rv != EOPNOTSUPP)
return (rv);
rv = PWMBUS_CHANNEL_ENABLE(bus, sc->chan,
state.enable);
break; break;
case PWMGETSTATE: case PWMGETSTATE:
bcopy(data, &state, sizeof(state)); bcopy(data, &state, sizeof(state));
@ -90,6 +97,12 @@ pwm_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
&state.period, &state.duty); &state.period, &state.duty);
if (rv != 0) if (rv != 0)
return (rv); return (rv);
rv = PWMBUS_CHANNEL_GET_FLAGS(bus, sc->chan,
&state.flags);
if (rv != 0)
return (rv);
rv = PWMBUS_CHANNEL_IS_ENABLED(bus, sc->chan, rv = PWMBUS_CHANNEL_IS_ENABLED(bus, sc->chan,
&state.enable); &state.enable);
if (rv != 0) if (rv != 0)

View File

@ -35,6 +35,7 @@
.Nm .Nm
.Op Fl f Ar device .Op Fl f Ar device
.Op Fl D | Fl E .Op Fl D | Fl E
.Op Fl I
.Op Fl p Ar period .Op Fl p Ar period
.Op Fl d Ar duty .Op Fl d Ar duty
.Sh DESCRIPTION .Sh DESCRIPTION
@ -82,6 +83,8 @@ during which the signal is asserted.
Enable the PWM channel. Enable the PWM channel.
.It Fl p Ar period .It Fl p Ar period
Configure the period (in nanoseconds) of the PWM channel. Configure the period (in nanoseconds) of the PWM channel.
.It Fl I
Invert PWM signal polarity
.El .El
.Sh EXAMPLES .Sh EXAMPLES
.Bl -bullet .Bl -bullet

View File

@ -48,6 +48,7 @@
#define PWM_SHOW_CONFIG 0x0004 #define PWM_SHOW_CONFIG 0x0004
#define PWM_PERIOD 0x0008 #define PWM_PERIOD 0x0008
#define PWM_DUTY 0x0010 #define PWM_DUTY 0x0010
#define PWM_INVERTED 0x0020
static char device_name[PATH_MAX] = "/dev/pwm/pwmc0.0"; static char device_name[PATH_MAX] = "/dev/pwm/pwmc0.0";
@ -66,7 +67,7 @@ usage(void)
{ {
fprintf(stderr, "Usage:\n"); fprintf(stderr, "Usage:\n");
fprintf(stderr, "\tpwm [-f dev] -C\n"); fprintf(stderr, "\tpwm [-f dev] -C\n");
fprintf(stderr, "\tpwm [-f dev] [-D | -E] [-p period] [-d duty[%%]]\n"); fprintf(stderr, "\tpwm [-f dev] [-D | -E] [-I] [-p period] [-d duty[%%]]\n");
exit(1); exit(1);
} }
@ -87,7 +88,7 @@ main(int argc, char *argv[])
fd = -1; fd = -1;
period = duty = -1; period = duty = -1;
while ((ch = getopt(argc, argv, "f:EDCp:d:")) != -1) { while ((ch = getopt(argc, argv, "f:EDCIp:d:")) != -1) {
switch (ch) { switch (ch) {
case 'E': case 'E':
if (action & (PWM_DISABLE | PWM_SHOW_CONFIG)) if (action & (PWM_DISABLE | PWM_SHOW_CONFIG))
@ -104,6 +105,11 @@ main(int argc, char *argv[])
usage(); usage();
action = PWM_SHOW_CONFIG; action = PWM_SHOW_CONFIG;
break; break;
case 'I':
if (action & PWM_SHOW_CONFIG)
usage();
action |= PWM_INVERTED;
break;
case 'p': case 'p':
if (action & PWM_SHOW_CONFIG) if (action & PWM_SHOW_CONFIG)
usage(); usage();
@ -172,10 +178,11 @@ main(int argc, char *argv[])
} }
if (action == PWM_SHOW_CONFIG) { if (action == PWM_SHOW_CONFIG) {
printf("period: %u\nduty: %u\nenabled:%d\n", printf("period: %u\nduty: %u\nenabled:%d\ninverted:%d\n",
state.period, state.period,
state.duty, state.duty,
state.enable); state.enable,
state.flags & PWM_POLARITY_INVERTED);
} else { } else {
if (action & PWM_ENABLE) if (action & PWM_ENABLE)
state.enable = true; state.enable = true;
@ -183,6 +190,10 @@ main(int argc, char *argv[])
state.enable = false; state.enable = false;
if (action & PWM_PERIOD) if (action & PWM_PERIOD)
state.period = period; state.period = period;
if (action & PWM_INVERTED)
state.flags |= PWM_POLARITY_INVERTED;
else
state.flags &= ~PWM_POLARITY_INVERTED;
if (action & PWM_DUTY) { if (action & PWM_DUTY) {
if (*percent != '\0') if (*percent != '\0')
state.duty = (uint64_t)state.period * duty / 100; state.duty = (uint64_t)state.period * duty / 100;