Date: Sat, 29 Jun 2019 08:16:06 -0600 From: Ian Lepore <ian@freebsd.org> To: Nicola Mingotti <nmingotti@gmail.com>, Sergey Manucharian <sm@ara-ler.com> Cc: nmingott@gmail.com, freebsd-arm@freebsd.org Subject: Re: How to set PWM tunable name to ehrpwm.1 ? Message-ID: <8237753a486d20599815aa869eb729433c03eb8b.camel@freebsd.org> In-Reply-To: <f1e1609d-beba-1d49-faf0-ba470c00a773@gmail.com> References: <68790975-a5a5-2138-ca89-117878d6cf2d@gmail.com> <20190606220639.GE13546@eldorado> <8126fa4ae0ca650ca12f28dd538e6e8c4e81b432.camel@freebsd.org> <2852b9da-e647-69a7-3218-88cfa500eadc@gmail.com> <ee540fb38eca660a722f561fc91b660560133ed5.camel@freebsd.org> <f1e1609d-beba-1d49-faf0-ba470c00a773@gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 2019-06-07 at 10:23 -0700, Nicola Mingotti wrote: > > On 6/7/19 7:58 AM, Ian Lepore wrote: > > [...] > > > > > > > > > > The dev.* hierarchy is managed by newbus; what I was picturing was > > something like hw.ehrpwm1.freq and so on, settable as either tunable or > > sysctl. But it turns out ehrpwm1 is just a label in the dts, not > > accessible at runtime. The actual node name is just 'pwm' and really, > > nothing prevents upstream from changing that name on a whim next time > > we import new dts files. (And linux sure seems to have a lot of > > arbitrary whims when it comes to changing dts.) > > > > Since an overlay is required to use this stuff anyway, I'm now thinking > > a custom property in the overlay that names the sysctl nodes might be a > > good option. So you'd add a property like: > > > > &ehrpwm0 { > > status = "okay"; > > pinctrl-names = "default"; > > pinctrl-0 = <&ehrpwm0_AB_pins>; > > freebsd,sysctl = "backlight"; > > }; > > > > And that would make it install names like hw.backlight.freq and > > hw.backlight.period and so on. If you don't add that property, it just > > installs the names it uses now (dev.ehrpwm.*) for compatibility. > > > > -- Ian > > > > > > Ian, this |freebsd,sysctl = "foobar"| to me sounds as a very good solution. > > In this way I could name the tunable with the "hardware name" or also > with the functional name, as "pwm-motor-front-left". This would improve > the readability of underlying software structure. That would be beautiful. > > n. > I just realized I never followed up on this thread after doing the work. After talking to Manu on irc about this, we decided the right way to go was to use the pwm(9) kernel api and the pwm(8) userland tool for controlling pwm devices, instead of just extending the ad-hoc sysctl scheme in the TI driver. I reworked the pwm(9) api a bit to support the idea of "named channels", then added support for pwm(9) to the ti_ehrpwm driver. All of that work was done in 13-current and has now been merged to 12-stable; it should be available in the next weekly- build snapshots for beaglebone. To use the new stuff... if you build custom kernels, you can add 'device pwmbus' and 'device pwmc' to your kernel config. Or, you can load those devices as modules. On -current the modules will get auto- loaded by devd as needed; I'm not sure if that works in 12-stable or not. The other thing you need to do is apply a dts overlay to enable the pwm hardware, setup the pinmux, and define the names for the channels. Here's the dtso I used for testing (based on the one you posted earlier in this thread, but with the freebsd,pwmc nodes added): /dts-v1/; /plugin/; / { compatible = "ti,am335x-bone-black", "ti,am335x-bone", "ti,am33xx"; exclusive-use = "P9.21","P9.22","ehrpwm0_AB"; }; &am33xx_pinmux { ehrpwm0_AB_pins: pinmux_ehrpwm0_AB_pins { pinctrl-single,pins = < 0x154 0x03 /* P9.21 */ 0x150 0x03 /* P9.22 */ >; }; }; &ehrpwm0 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&ehrpwm0_AB_pins>; pwmcontrol@0 { compatible = "freebsd,pwmc"; reg = <0>; label = "backlight"; }; pwmcontrol@1 { compatible = "freebsd,pwmc"; reg = <1>; label = "ChannelB"; }; }; &epwmss0 { status = "okay"; }; &ecap0 { status = "okay"; }; The pwmc(4) driver creates nodes in /dev/pwm/ named pwmcX.Y where X is the unit number and Y is the channel number within that unit. As usual the unit number may change depending on which devices are present, so the dts can include a label= property and the driver creates an alias for the pwmcX.Y with that name: ll /dev/pwm [...] root wheel 14 Jun 29 13:54 ChannelB@ -> ../pwm/pwmc0.1 [...] root wheel 14 Jun 29 13:54 backlight@ -> ../pwm/pwmc0.0 [...] root operator 0x5f Jun 29 13:54 pwmc0.0 [...] root operator 0x5d Jun 29 13:54 pwmc0.1 With this in place, you can use the pwm(8) tool for control. It takes period and duty cycle in nanoseconds, or duty as a percentage. For example, to set the 'ChannelB' output to a 100KHz signal with 40% duty cycle and enable it: pwm -f /dev/pwm/ChannelB -E -p 10000 -d 40% To change it to 1ms on, 1ms off (it stays enabled): pwm -f /dev/pwm/ChannelB -p 2000000 -d 1000000 There are manpages for the pwmc(4) device (describes the dts format) and the pwm(8) tool. If you are writing your own custom C code for control, you can use ioctl() calls for pwm control; the pwmc(4) manpage details that stuff too. -- Ian
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?8237753a486d20599815aa869eb729433c03eb8b.camel>