WEBVTT

00:00.000 --> 00:07.000
Hello.

00:07.000 --> 00:15.000
Welcome.

00:15.000 --> 00:18.000
First of all, me, I'm with a client clinic.

00:18.000 --> 00:23.000
I'm working for Belibre as a software developer.

00:23.000 --> 00:28.000
I'm also in the PWM sub system maintainer.

00:28.000 --> 00:34.000
If you want to reach me, well, you find my email address in the kernel,

00:34.000 --> 00:38.000
and I'm also available on IRC.

00:38.000 --> 00:42.000
Belibre is a software consultant,

00:42.000 --> 00:45.000
three headquartered in the south of France.

00:45.000 --> 00:48.000
We're approximately 60 engineers there,

00:48.000 --> 00:50.000
and work in various open source,

00:50.000 --> 00:55.000
and also close source projects depending on the customer's needs.

00:55.000 --> 00:59.000
The motivation for this talk is that

00:59.000 --> 01:03.000
review of new PWM drivers takes quite a long time.

01:03.000 --> 01:08.000
This is partly my fault because I take much time to look into these,

01:08.000 --> 01:10.000
and look they are correct.

01:10.000 --> 01:15.000
But also it's always the same thing that I explain that drivers should do,

01:15.000 --> 01:19.000
and I hope to give some insights what I expect

01:19.000 --> 01:25.000
to just reduce the number of iterations

01:25.000 --> 01:28.000
that are needed to get a patch in,

01:28.000 --> 01:33.000
which helps both the submitter and me as a reviewer.

01:33.000 --> 01:39.000
And also this giving a talk here is a good way

01:39.000 --> 01:44.000
to find something to talk about.

01:44.000 --> 01:49.000
If you have ideas that you want from the PWM subsystem,

01:49.000 --> 01:50.000
I'm interesting.

01:50.000 --> 01:52.000
I'm open to hear what you want.

01:52.000 --> 01:55.000
Let's talk after the talk.

01:55.000 --> 01:58.000
I will be available for now.

01:58.000 --> 02:02.000
So quickly, what is the PWM?

02:02.000 --> 02:05.000
It's a piece of hardware that meets pariotic

02:05.000 --> 02:08.000
square-life signal,

02:08.000 --> 02:13.000
the typical use cases to blink or dim LEDs,

02:13.000 --> 02:20.000
and the more difficult cases are trigger ADC readout.

02:20.000 --> 02:24.000
This is something that colleagues of mine have done

02:24.000 --> 02:28.000
to do high-speed readout as data,

02:28.000 --> 02:32.000
and also remote controls have a higher level of needs

02:32.000 --> 02:37.000
for the timing of the waveform.

02:37.000 --> 02:42.000
So in fact, we have a signal that goes up and down.

02:42.000 --> 02:45.000
Pariotically, and it's defined by the period,

02:45.000 --> 02:52.000
that defines the piece of the waveform that is repeated each time,

02:52.000 --> 02:56.000
and we have the time that is called duty cycle

02:56.000 --> 02:58.000
where the signals up,

02:58.000 --> 03:03.000
and we have an offset from an arbitrarily chosen start of the period,

03:03.000 --> 03:07.000
and it repeats just like that.

03:08.000 --> 03:15.000
The corebacks you have to implement changed since version 613,

03:15.000 --> 03:18.000
while the old ways still works,

03:18.000 --> 03:21.000
but the abstraction changed a bit.

03:21.000 --> 03:26.000
And there are essentially four corebacks that you need to implement.

03:26.000 --> 03:32.000
The first is to use the abstract definition of waveform

03:32.000 --> 03:35.000
with these three parameters that I just showed,

03:35.000 --> 03:39.000
and convert it into a hardware representation,

03:39.000 --> 03:42.000
that is the white pointer.

03:42.000 --> 03:45.000
This is just a chunk of memory provided by the core,

03:45.000 --> 03:49.000
but it doesn't do hardware access yet,

03:49.000 --> 03:55.000
and then there's a reverse function that uses this hardware representation

03:55.000 --> 04:01.000
and calculates it back into the generic form with another second resolution,

04:01.000 --> 04:06.000
and we have two functions to write and read this representation

04:06.000 --> 04:11.000
into the hard actually hardware.

04:11.000 --> 04:14.000
This intermediate step of first calculating,

04:14.000 --> 04:20.000
and then writing into hardware is needed to give a consumer,

04:20.000 --> 04:26.000
so a backlight driver or the infrared driver,

04:26.000 --> 04:29.000
the opportunity to know beforehand what happens.

04:29.000 --> 04:32.000
So with the old API, it wasn't possible to say,

04:32.000 --> 04:35.000
if I request the period of say two milliseconds,

04:35.000 --> 04:38.000
do I get 1.8 or 1.7,

04:38.000 --> 04:42.000
and if you want to control a motor that drives a robot,

04:42.000 --> 04:48.000
you want to know more exactly what's the outcome of your request,

04:48.000 --> 04:50.000
and so you can first iterate,

04:50.000 --> 04:52.000
we are the first two functions,

04:52.000 --> 04:58.000
and know what's the outcome.

04:58.000 --> 05:05.000
The general rules are mostly for the first function

05:05.000 --> 05:10.000
that converts or calculates the hardware registers.

05:10.000 --> 05:14.000
It's important that all functions do it

05:14.000 --> 05:16.000
or all drivers do it in the same way

05:16.000 --> 05:20.000
to have some generic way to work with that,

05:20.000 --> 05:24.000
and to give the consumer driver some way

05:24.000 --> 05:27.000
to find out the right parameters,

05:27.000 --> 05:31.000
to find the best match for their wants

05:31.000 --> 05:33.000
and what the hardware can provide,

05:33.000 --> 05:36.000
and then the rule is to first pick a period

05:36.000 --> 05:39.000
and in a down rounding way.

05:39.000 --> 05:43.000
This is arbitrary, but in some drivers in the past,

05:43.000 --> 05:47.000
picked the nearest period that I can do,

05:47.000 --> 05:50.000
so if I request it 1.8,

05:50.000 --> 05:54.000
I prefer now 1.6 over 1.8,

05:54.000 --> 05:59.000
1.9.

05:59.000 --> 06:05.000
This is just to simplify the math involved there,

06:05.000 --> 06:09.000
and then after that pick the duty cycle

06:09.000 --> 06:11.000
that is possible with the period,

06:11.000 --> 06:16.000
and after that pick duty offset,

06:17.000 --> 06:22.000
if something is requested that is too slow,

06:22.000 --> 06:28.000
you need to run up and signal bars by returning one in that function.

06:28.000 --> 06:32.000
The general thing that I want you to do is to test

06:32.000 --> 06:37.000
with that debug symbol enabled in the kernel configuration,

06:37.000 --> 06:40.000
and with the right testing patterns,

06:40.000 --> 06:50.000
it is able to catch most errors in these requirements.

06:50.000 --> 06:55.000
For the second function,

06:55.000 --> 06:57.000
you have to round up.

06:57.000 --> 07:00.000
This is just to have some hidden potency.

07:00.000 --> 07:03.000
If I reach the contents from the hardware and calculate it

07:03.000 --> 07:06.000
into the generic representation,

07:06.000 --> 07:10.000
I want that if I do it the other way with the outcome

07:10.000 --> 07:15.000
that I have the exact same register values,

07:15.000 --> 07:22.000
so I don't change something just by get the parameters

07:22.000 --> 07:25.000
and write it back.

07:25.000 --> 07:31.000
A difficulty in that is that the generic representation

07:31.000 --> 07:33.000
has some ambiguities.

07:33.000 --> 07:38.000
In general, you don't see the start of the period,

07:38.000 --> 07:44.000
so I can represent the same waveform signal,

07:44.000 --> 07:48.000
which is so identical,

07:48.000 --> 07:52.000
but depending on when the period starts,

07:52.000 --> 07:55.000
the duty offset changes.

07:55.000 --> 07:59.000
The outcome is the exactly same,

08:00.000 --> 08:03.000
but it's still,

08:03.000 --> 08:09.000
it starts to get relevant if you have more than one signal

08:09.000 --> 08:14.000
that you want to use in parallel.

08:14.000 --> 08:21.000
The other problem is that if you have a duty cycle of zero,

08:21.000 --> 08:23.000
it's all ambiguous.

08:23.000 --> 08:27.000
So the period is not fixed,

08:27.000 --> 08:31.000
you can pick anything longer or anything smaller,

08:31.000 --> 08:36.000
and also the duty offset again is ambiguous.

08:36.000 --> 08:41.000
The idea is just that you just assume

08:41.000 --> 08:45.000
that the period is relevant,

08:45.000 --> 08:48.000
and if usually represented also in hardware,

08:48.000 --> 08:50.000
so it's easy.

08:51.000 --> 08:55.000
The overall goal is to present something consistent.

08:55.000 --> 09:02.000
It's not always easy to know beforehand what consistent is,

09:02.000 --> 09:05.000
but it's something about it in potency,

09:05.000 --> 09:11.000
and I try to come up with some documentation,

09:11.000 --> 09:12.000
what I expect,

09:12.000 --> 09:14.000
but it's not yet clear.

09:14.000 --> 09:16.000
There are not so many drivers yet converted,

09:16.000 --> 09:19.000
and so this is a bit inflex yet,

09:19.000 --> 09:28.000
and a period of zero in the original,

09:28.000 --> 09:31.000
in the representation means it's off.

09:31.000 --> 09:34.000
This is also a bit different than the old approach,

09:34.000 --> 09:39.000
but it's a nice reuse of the parameter,

09:39.000 --> 09:45.000
because I don't need a special field for this abling the hardware.

09:46.000 --> 09:51.000
Something to improve testing.

09:51.000 --> 09:55.000
There is a great open source project,

09:55.000 --> 09:56.000
a thick rock,

09:56.000 --> 10:00.000
but uses tea part where

10:00.000 --> 10:03.000
and makes it an oscilloscope.

10:03.000 --> 10:05.000
I have one here.

10:05.000 --> 10:10.000
If you want to have a look after the talk,

10:10.000 --> 10:12.000
I will stick around.

10:12.000 --> 10:14.000
It looks like that.

10:15.000 --> 10:19.000
You just connect the output of your hardware,

10:19.000 --> 10:25.000
and it's connected via USB to your host,

10:25.000 --> 10:30.000
and then you can start a measurement,

10:30.000 --> 10:34.000
and you can even say this output is a PWM,

10:34.000 --> 10:38.000
and you get the parameters shown,

10:38.000 --> 10:41.000
and you can play around with the registers,

10:41.000 --> 10:43.000
and how it changes,

10:43.000 --> 10:48.000
and with that it's easy to find things like the hardware,

10:48.000 --> 10:51.000
or you configure a certain,

10:51.000 --> 10:55.000
you configure the registers somehow,

10:55.000 --> 10:58.000
but there's an offset of minus one,

10:58.000 --> 11:02.000
also missing in the specification.

11:02.000 --> 11:07.000
This is quite nice.

11:07.000 --> 11:09.000
And for the, well,

11:09.000 --> 11:12.000
the both of you is for checking the output,

11:12.000 --> 11:17.000
and to control the actual hardware.

11:17.000 --> 11:21.000
There is library with some tools

11:21.000 --> 11:25.000
that uses a new charity device interface

11:25.000 --> 11:27.000
to control the PWM,

11:27.000 --> 11:30.000
where you can easily modify

11:30.000 --> 11:34.000
or where you feed in the waveform description you want,

11:34.000 --> 11:38.000
and you get the hardware programs accordingly.

11:38.000 --> 11:41.000
There is a debug of S of file,

11:41.000 --> 11:44.000
where you can see what the kernel things

11:44.000 --> 11:47.000
your PWM is programmed to,

11:47.000 --> 11:49.000
and I use MAM2L,

11:49.000 --> 11:54.000
essentially this is to access registers

11:54.000 --> 11:56.000
without bothering the driver,

11:56.000 --> 12:02.000
where you can just assign values to the registers directly.

12:02.000 --> 12:04.000
Some of you might know,

12:04.000 --> 12:06.000
Death MAM2,

12:06.000 --> 12:08.000
which has the same purpose,

12:08.000 --> 12:11.000
but MAM2L is a bit nicer,

12:11.000 --> 12:14.000
API wise.

12:14.000 --> 12:17.000
And when you think you're done with the kernel,

12:17.000 --> 12:19.000
I will be a driver,

12:19.000 --> 12:22.000
the important things are testing your,

12:22.000 --> 12:24.000
the corner cases,

12:24.000 --> 12:25.000
so use,

12:25.000 --> 12:28.000
well, min and max period is a bit annoying,

12:28.000 --> 12:30.000
depending what the max period is,

12:30.000 --> 12:32.000
if it's several minutes,

12:32.000 --> 12:35.000
it's not so feasible,

12:35.000 --> 12:40.000
but 0% and 100% relative to the cycle is something

12:40.000 --> 12:43.000
that some hardware failed to do,

12:43.000 --> 12:45.000
and so this is important at least to know

12:45.000 --> 12:49.000
that there is some problem,

12:49.000 --> 12:51.000
and this should be documented.

12:51.000 --> 12:54.000
There is a tool PWM test path.

12:54.000 --> 12:57.000
It was initially done to,

12:58.000 --> 13:02.000
to compare the timing constraints,

13:02.000 --> 13:05.000
or the timing that,

13:05.000 --> 13:10.000
all sorts of S control API,

13:10.000 --> 13:13.000
and the new character device,

13:13.000 --> 13:16.000
but it also does exactly the pattern

13:16.000 --> 13:19.000
that the debug symbol,

13:19.000 --> 13:24.000
the PWM test needs,

13:25.000 --> 13:28.000
so you can effectively test your driver

13:28.000 --> 13:30.000
in a good way.

13:30.000 --> 13:32.000
And also M2L is,

13:32.000 --> 13:34.000
comes into play here.

13:34.000 --> 13:37.000
This is good for,

13:37.000 --> 13:39.000
for testing,

13:39.000 --> 13:41.000
changing one configuration to the other.

13:41.000 --> 13:43.000
So there are PWM's,

13:43.000 --> 13:45.000
where you,

13:45.000 --> 13:47.000
where it can happen,

13:47.000 --> 13:49.000
but if you change your,

13:49.000 --> 13:52.000
the generated waveform,

13:52.000 --> 13:55.000
where you see one period,

13:55.000 --> 13:57.000
where it's still the old cuticycle,

13:57.000 --> 14:00.000
but already the new period.

14:00.000 --> 14:02.000
And this is also,

14:02.000 --> 14:04.000
I want that documented,

14:04.000 --> 14:08.000
there's currently no need to have a smooth transition,

14:08.000 --> 14:13.000
but this is something I want to know during the review.

14:13.000 --> 14:15.000
And in general,

14:15.000 --> 14:16.000
if you,

14:16.000 --> 14:19.000
if you want to have something usable for you,

14:19.000 --> 14:21.000
if you want to see something good,

14:21.000 --> 14:24.000
also if you only have an LED to debug

14:24.000 --> 14:28.000
and not a certain oscilloscope board,

14:28.000 --> 14:31.000
you want a slow input clock,

14:31.000 --> 14:36.000
which simplifies things where you can see things easier.

14:36.000 --> 14:39.000
I think I'll skip to the rest,

14:39.000 --> 14:43.000
because the time is tight.

14:43.000 --> 14:45.000
I just want to hint,

14:45.000 --> 14:49.000
there is another conference in May,

14:49.000 --> 14:50.000
in these,

14:50.000 --> 14:52.000
for embedded,

14:52.000 --> 14:55.000
it's a conference

14:55.000 --> 14:58.000
that has some tradition already,

14:58.000 --> 15:00.000
with interesting people.

15:00.000 --> 15:04.000
And my company also is involved in,

15:04.000 --> 15:05.000
in commit,

15:05.000 --> 15:09.000
which is a venture capital company supporting

15:09.000 --> 15:12.000
European open source startups,

15:12.000 --> 15:15.000
which might be interesting for you.

15:15.000 --> 15:17.000
Thanks for your attention.

15:17.000 --> 15:27.000
Thank you.

15:27.000 --> 15:30.000
So, you've described very simple,

15:30.000 --> 15:34.000
basically single channel PVWMs.

15:34.000 --> 15:36.000
Now, a state of the art,

15:36.000 --> 15:38.000
SOC that is designed for,

15:38.000 --> 15:39.000
for example,

15:39.000 --> 15:41.000
motor control,

15:41.000 --> 15:43.000
actually has a huge state machine,

15:43.000 --> 15:46.000
and batteries of PWMs and safety circuitry,

15:47.000 --> 15:50.000
so how would you best integrate

15:50.000 --> 15:55.000
a driver for these complex applications

15:55.000 --> 15:56.000
into the Linux kernel?

15:56.000 --> 15:59.000
How would you best model that?

15:59.000 --> 16:01.000
I think the question is about,

16:01.000 --> 16:03.000
if you have several PWMs,

16:03.000 --> 16:04.000
let's have to,

16:04.000 --> 16:06.000
but I use in pairs.

16:06.000 --> 16:08.000
Well, for example,

16:08.000 --> 16:10.000
they need to be synchronized and so on,

16:10.000 --> 16:11.000
so forth,

16:11.000 --> 16:13.000
and then there's safety circuitry,

16:13.000 --> 16:14.000
or safety inputs,

16:14.000 --> 16:18.000
so that these things go flat and so on,

16:18.000 --> 16:19.000
and the question is,

16:19.000 --> 16:23.000
what layer in the software of the kernel

16:23.000 --> 16:28.000
would be the best place to put in a module that can do this?

16:28.000 --> 16:31.000
I would like to hear the things you need.

16:31.000 --> 16:33.000
I have a few ideas,

16:33.000 --> 16:34.000
a few use cases in mind,

16:34.000 --> 16:38.000
that I want to work up on the future,

16:38.000 --> 16:42.000
but if you have something that you want to do,

16:42.000 --> 16:45.000
I will be outside after the talk come to me.

16:45.000 --> 16:47.000
Yeah.

16:47.000 --> 16:52.000
All right, thanks a lot.

