Discussion:
mini2440 pwm beeper works unreliably
Pawel Suchanecki
2013-12-19 11:23:36 UTC
Permalink
Dear list,

I run Linux 3.7.1 built with ptxdist 2012.12.0 on mini2440.

I have the /dev/input/beeper device ready:

***@xxx:~ dmesg | grep pwm
s3c24xx-pwm s3c24xx-pwm.0: tin at 25312500, tdiv at 25312500, tin=divclk, base 0
input: pwm-beeper as /devices/platform/s3c24xx-pwm.0/pwm-beeper/input/input1

The ring-bell tool is producing sound, however the beeper fails to
mute (turn off the beeping sound) very often, like every other time (a
few per 10 runs).

What the be the root cause of this?
Is there any known solution?


I also created a simple code tone-uni.c (should have based it on
ring-bell.c) that looks like:

#include<fcntl.h>
#include<stdio.h>
#include<linux/input.h>

int main(int argc, char *argv[])
{
int fd, version, ret;
struct input_event event;

if (argc < 3) {
printf ("usage: <device> <tone value>");
return 1;
}

if ((fd = open(argv[1], O_RDWR)) < 0) {
perror("beep test");
return 1;
}

event.type = EV_SND;
event.code = SND_TONE;
event.value = atoi(argv[2]);

ret = write(fd, &event, sizeof(struct input_event));

close(fd);
return 0;
}


And I set two variables ON and OFF like this:

ON=./tone-uni /dev/input/beeper 333
OFF=./tone-uni /dev/input/beeper 0


The beeper turning off works "quite reliably" only using one-liner of
form (double call to $ON is needed to make it work):

while [ 1 ] ; do $ON; $ON && $OFF && for i in `seq 1 5` ; do $OFF;
done ; sleep 2; done

but also occasionally (1 per hundreds of while loops) it beeps longer
than normally, basically up to next loop.


How can I get this working? I need this for my project (the device is
going to be sent tomorrow to the client).


Thank you in advance,
Pawel.
Jürgen Beisert
2013-12-19 14:29:32 UTC
Permalink
Hi Pawel,
Post by Pawel Suchanecki
[...]
but also occasionally (1 per hundreds of while loops) it beeps longer
than normally, basically up to next loop.
How can I get this working? I need this for my project (the device is
going to be sent tomorrow to the client).
I think it's not defined what electrical level the PWM output pin has, when the
software stops the PWM. At least such kind of failure we have seen on
different platforms like i.MX SoCs.

The only solution is to configure the pin to act as a GPIO with a well defined
level when the PWM stops. And to reconfigure the pin to act as a PWM output,
if the PWM is enabled again.

Regards,
Juergen
--
Pengutronix e.K.                              | Juergen Beisert             |
Linux Solutions for Science and Industry      | http://www.pengutronix.de/ |
Guillermo Rodriguez
2014-06-12 13:47:53 UTC
Permalink
I am aware this thread is a bit old but I have a patch ready that fixes this
behaviour. Is anyone interested?

Guillermo Rodriguez
Post by Jürgen Beisert
Hi Pawel,
Post by Pawel Suchanecki
[...]
but also occasionally (1 per hundreds of while loops) it beeps longer
than normally, basically up to next loop.
How can I get this working? I need this for my project (the device is
going to be sent tomorrow to the client).
I think it's not defined what electrical level the PWM output pin has, when the
software stops the PWM. At least such kind of failure we have seen on
different platforms like i.MX SoCs.
The only solution is to configure the pin to act as a GPIO with a well defined
level when the PWM stops. And to reconfigure the pin to act as a PWM output,
if the PWM is enabled again.
Regards,
Juergen
Juergen Borleis
2014-06-12 13:52:41 UTC
Permalink
Hi Guillermo,
Post by Guillermo Rodriguez
I am aware this thread is a bit old but I have a patch ready that fixes
this behaviour. Is anyone interested?
We are always interested :) Maybe Linux mainline as well.

Regards,
Juergen
--
Pengutronix e.K.                              | Juergen Borleis             |
Linux Solutions for Science and Industry      | http://www.pengutronix.de/ |
Guillermo Rodriguez
2014-06-12 14:01:45 UTC
Permalink
I will prepare a patch and send it to the list. Will also check if it is applicable to mainline as well.

Thank you,

Guillermo
Post by Juergen Borleis
Hi Guillermo,
Post by Guillermo Rodriguez
I am aware this thread is a bit old but I have a patch ready that fixes
this behaviour. Is anyone interested?
We are always interested :) Maybe Linux mainline as well.
Regards,
Juergen
Tomasz Figa
2014-06-12 19:08:59 UTC
Permalink
Hi Guillermo,
Post by Guillermo Rodriguez
I will prepare a patch and send it to the list. Will also check if it is applicable to mainline as well.
Thank you,
Guillermo
Post by Juergen Borleis
Hi Guillermo,
Post by Guillermo Rodriguez
I am aware this thread is a bit old but I have a patch ready that fixes
this behaviour. Is anyone interested?
We are always interested :) Maybe Linux mainline as well.
What is the latest kernel version you observed this behavior on? AFAIK
on mainline Linux, since version 3.12, the pwm-samsung driver doesn't
stop a channel immediately, but instead lets it fully finish current
period and stop at 0 (the timer is downcounting).

Best regards,
Tomasz
Guillermo Rodriguez
2014-06-13 09:23:27 UTC
Permalink
Hi Tomasz,
Post by Juergen Borleis
Hi Guillermo,
Post by Guillermo Rodriguez
I will prepare a patch and send it to the list. Will also check if it is applicable to mainline as well.
Thank you,
Guillermo
Post by Juergen Borleis
Hi Guillermo,
Post by Guillermo Rodriguez
I am aware this thread is a bit old but I have a patch ready that fixes
this behaviour. Is anyone interested?
We are always interested :) Maybe Linux mainline as well.
What is the latest kernel version you observed this behavior on? AFAIK
on mainline Linux, since version 3.12, the pwm-samsung driver doesn't
stop a channel immediately, but instead lets it fully finish current
period and stop at 0 (the timer is downcounting).
I am currently using 3.7. The latest available in OSELAS.BSP-Pengutronix-Mini2440-2013.10.0 is 3.11, which still suffers from the same problem (however both 3.10 and 3.11 are broken for the mini2440).

Yesterday I checked to see if my changes were applicable to mainstream and realized that indeed a fix for this problem was introduced in 3.12. The fix is equivalent to what I did for 3.7 -- instead of clearing the START bit, just disable autoreload (which is the recommended procedure according to Samsung's documentation), as this guarantees that the PWM output will be left in a known state.

I will still send the patch as it is applicable to older kernels.

Guillermo

Loading...