Hello.
Welcome.
First of all, me, I'm with a client clinic.
I'm working for Belibre as a software developer.
I'm also in the PWM sub system maintainer.
If you want to reach me, well, you find my email address in the kernel,
and I'm also available on IRC.
Belibre is a software consultant,
three headquartered in the south of France.
We're approximately 60 engineers there,
and work in various open source,
and also close source projects depending on the customer's needs.
The motivation for this talk is that
review of new PWM drivers takes quite a long time.
This is partly my fault because I take much time to look into these,
and look they are correct.
But also it's always the same thing that I explain that drivers should do,
and I hope to give some insights what I expect
to just reduce the number of iterations
that are needed to get a patch in,
which helps both the submitter and me as a reviewer.
And also this giving a talk here is a good way
to find something to talk about.
If you have ideas that you want from the PWM subsystem,
I'm interesting.
I'm open to hear what you want.
Let's talk after the talk.
I will be available for now.
So quickly, what is the PWM?
It's a piece of hardware that meets pariotic
square-life signal,
the typical use cases to blink or dim LEDs,
and the more difficult cases are trigger ADC readout.
This is something that colleagues of mine have done
to do high-speed readout as data,
and also remote controls have a higher level of needs
for the timing of the waveform.
So in fact, we have a signal that goes up and down.
Pariotically, and it's defined by the period,
that defines the piece of the waveform that is repeated each time,
and we have the time that is called duty cycle
where the signals up,
and we have an offset from an arbitrarily chosen start of the period,
and it repeats just like that.
The corebacks you have to implement changed since version 613,
while the old ways still works,
but the abstraction changed a bit.
And there are essentially four corebacks that you need to implement.
The first is to use the abstract definition of waveform
with these three parameters that I just showed,
and convert it into a hardware representation,
that is the white pointer.
This is just a chunk of memory provided by the core,
but it doesn't do hardware access yet,
and then there's a reverse function that uses this hardware representation
and calculates it back into the generic form with another second resolution,
and we have two functions to write and read this representation
into the hard actually hardware.
This intermediate step of first calculating,
and then writing into hardware is needed to give a consumer,
so a backlight driver or the infrared driver,
the opportunity to know beforehand what happens.
So with the old API, it wasn't possible to say,
if I request the period of say two milliseconds,
do I get 1.8 or 1.7,
and if you want to control a motor that drives a robot,
you want to know more exactly what's the outcome of your request,
and so you can first iterate,
we are the first two functions,
and know what's the outcome.
The general rules are mostly for the first function
that converts or calculates the hardware registers.
It's important that all functions do it
or all drivers do it in the same way
to have some generic way to work with that,
and to give the consumer driver some way
to find out the right parameters,
to find the best match for their wants
and what the hardware can provide,
and then the rule is to first pick a period
and in a down rounding way.
This is arbitrary, but in some drivers in the past,
picked the nearest period that I can do,
so if I request it 1.8,
I prefer now 1.6 over 1.8,
1.9.
This is just to simplify the math involved there,
and then after that pick the duty cycle
that is possible with the period,
and after that pick duty offset,
if something is requested that is too slow,
you need to run up and signal bars by returning one in that function.
The general thing that I want you to do is to test
with that debug symbol enabled in the kernel configuration,
and with the right testing patterns,
it is able to catch most errors in these requirements.
For the second function,
you have to round up.
This is just to have some hidden potency.
If I reach the contents from the hardware and calculate it
into the generic representation,
I want that if I do it the other way with the outcome
that I have the exact same register values,
so I don't change something just by get the parameters
and write it back.
A difficulty in that is that the generic representation
has some ambiguities.
In general, you don't see the start of the period,
so I can represent the same waveform signal,
which is so identical,
but depending on when the period starts,
the duty offset changes.
The outcome is the exactly same,
but it's still,
it starts to get relevant if you have more than one signal
that you want to use in parallel.
The other problem is that if you have a duty cycle of zero,
it's all ambiguous.
So the period is not fixed,
you can pick anything longer or anything smaller,
and also the duty offset again is ambiguous.
The idea is just that you just assume
that the period is relevant,
and if usually represented also in hardware,
so it's easy.
The overall goal is to present something consistent.
It's not always easy to know beforehand what consistent is,
but it's something about it in potency,
and I try to come up with some documentation,
what I expect,
but it's not yet clear.
There are not so many drivers yet converted,
and so this is a bit inflex yet,
and a period of zero in the original,
in the representation means it's off.
This is also a bit different than the old approach,
but it's a nice reuse of the parameter,
because I don't need a special field for this abling the hardware.
Something to improve testing.
There is a great open source project,
a thick rock,
but uses tea part where
and makes it an oscilloscope.
I have one here.
If you want to have a look after the talk,
I will stick around.
It looks like that.
You just connect the output of your hardware,
and it's connected via USB to your host,
and then you can start a measurement,
and you can even say this output is a PWM,
and you get the parameters shown,
and you can play around with the registers,
and how it changes,
and with that it's easy to find things like the hardware,
or you configure a certain,
you configure the registers somehow,
but there's an offset of minus one,
also missing in the specification.
This is quite nice.
And for the, well,
the both of you is for checking the output,
and to control the actual hardware.
There is library with some tools
that uses a new charity device interface
to control the PWM,
where you can easily modify
or where you feed in the waveform description you want,
and you get the hardware programs accordingly.
There is a debug of S of file,
where you can see what the kernel things
your PWM is programmed to,
and I use MAM2L,
essentially this is to access registers
without bothering the driver,
where you can just assign values to the registers directly.
Some of you might know,
Death MAM2,
which has the same purpose,
but MAM2L is a bit nicer,
API wise.
And when you think you're done with the kernel,
I will be a driver,
the important things are testing your,
the corner cases,
so use,
well, min and max period is a bit annoying,
depending what the max period is,
if it's several minutes,
it's not so feasible,
but 0% and 100% relative to the cycle is something
that some hardware failed to do,
and so this is important at least to know
that there is some problem,
and this should be documented.
There is a tool PWM test path.
It was initially done to,
to compare the timing constraints,
or the timing that,
all sorts of S control API,
and the new character device,
but it also does exactly the pattern
that the debug symbol,
the PWM test needs,
so you can effectively test your driver
in a good way.
And also M2L is,
comes into play here.
This is good for,
for testing,
changing one configuration to the other.
So there are PWM's,
where you,
where it can happen,
but if you change your,
the generated waveform,
where you see one period,
where it's still the old cuticycle,
but already the new period.
And this is also,
I want that documented,
there's currently no need to have a smooth transition,
but this is something I want to know during the review.
And in general,
if you,
if you want to have something usable for you,
if you want to see something good,
also if you only have an LED to debug
and not a certain oscilloscope board,
you want a slow input clock,
which simplifies things where you can see things easier.
I think I'll skip to the rest,
because the time is tight.
I just want to hint,
there is another conference in May,
in these,
for embedded,
it's a conference
that has some tradition already,
with interesting people.
And my company also is involved in,
in commit,
which is a venture capital company supporting
European open source startups,
which might be interesting for you.
Thanks for your attention.
Thank you.
So, you've described very simple,
basically single channel PVWMs.
Now, a state of the art,
SOC that is designed for,
for example,
motor control,
actually has a huge state machine,
and batteries of PWMs and safety circuitry,
so how would you best integrate
a driver for these complex applications
into the Linux kernel?
How would you best model that?
I think the question is about,
if you have several PWMs,
let's have to,
but I use in pairs.
Well, for example,
they need to be synchronized and so on,
so forth,
and then there's safety circuitry,
or safety inputs,
so that these things go flat and so on,
and the question is,
what layer in the software of the kernel
would be the best place to put in a module that can do this?
I would like to hear the things you need.
I have a few ideas,
a few use cases in mind,
that I want to work up on the future,
but if you have something that you want to do,
I will be outside after the talk come to me.
Yeah.
All right, thanks a lot.