This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/AM5728: PWM on Timer15

Part Number: AM5728

Tool/software: Linux

I'm using TI's Linux Kernel 4.9 with SDK 4.02 on my custom AM5728 board.

My board got a PWM controlled beeper on Timer 15. The hardware was verified by directly manipulating the register bank associated with it, but setting it up through the Linux Device Tree is proving it to be difficult.

We have enabled a few things in the kernel:

CONFIG_PWM_TIEHRPWM=y

CONFIG_PWM_TIPWMSS=y

CONFIG_INPUT_PWM_BEEPER=y

CONFIG_PWM_OMAP_DMTIMER=y

And added a node here in the DTS:

beeper {

                compatible = "pwm-beeper";

                pwms = <&timer15>;

};

The U-Boot is also mux'ed correctly. 

With the above changes, there is still no new device under /sys/class/pwm. 

Anywhere else I should look at?

  • Hello,

    I am wondering if you have enabled timer15 in the dts file. Also, I do not see any "pinctrl-0" definition in your code.

    Regards,

    Krunal

  • Hi Krunal, thanks for the response. Once I enabled timer15, I'm making some progress. Here is my full change:

    @@ -89,6 +89,11 @@
    gpio = <&gpio7 3>;
    };

    + beeper: pwm_beeper {
    + status = "okay";
    + compatible = "pwm-beeper";
    + pwms = <&timer15 0 5000 1>;
    + };


    +&timer15 {
    + status = "okay";
    + pinctrl-names = "default";
    + pinctrl-0 = <&timer15_pins>;
    +};
    +
    +


    &dra7_pmx_core {
    + timer15_pins: timer15_pins_default {
    + pinctrl-single,pins = <
    + DRA7XX_CORE_IOPAD(0x36A0, PIN_OUTPUT | MUX_MODE10)
    + >;
    + };

    Unfortunately, it's not working 100% yet:

    root@dev:~# dmesg | grep -i pwm
    [    2.248063] palmas 0-0058: Muxing GPIO 2b, PWM 0, LED 0
    [    7.269426] lp8863 0-003c: BL Mode Register Read (0x0: PWM 0x2: DISPLAY_BRT): 0x302
    [    7.444450] OF: /pwm_beeper: could not get #pwm-cells for /ocp/timer@4882c000
    [    7.463389] of_pwm_get(): can't parse "pwms" property
    [    7.480388] pwm-beeper pwm_beeper: Failed to request PWM device: -22
    [    7.501369] pwm-beeper: probe of pwm_beeper failed with error -22
    root@dev:~# dmesg | grep -i timer
    [    0.000000] OMAP clockevent source: timer1 at 32786 Hz
    [    0.000000] arch_timer: cp15 timer(s) running at 6.14MHz (phys).
    [    0.000017] Switching to timer-based delay loop, resolution 162ns
    [    0.000885] Calibrating delay loop (skipped), value calculated using timer frequency.. 12.29 BogoMIPS (lpj=61475)
    [    7.181794] omap_wdt: OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec
    [    7.444450] OF: /pwm_beeper: could not get #pwm-cells for /ocp/timer@4882c000
    

    Pointers will be appreciated, especially I'd like some check on the pwms property I bold faced above.

  • I think an important missing piece is the configuration of the timer as a PWM.  Take a look at the following documentation i the kernel:

    • <kernel_dir>/Documentation/devicetree/bindings/arm/omap/timer.txt
    • <kernel_dir>/Documentation/devicetree/bindings/pwm/pwm-omap-dmtimer.txt.

    So from timer.txt, I see there's an optional property called ti,timer-pwm.  I expect that should be added to your timer15 node.

    Addtionally, it looks like you need a PWM node along these lines:

    pwm15: dmtimer-pwm@15 {
    compatible = "ti,omap-dmtimer-pwm";
    ti,timers = <&timer15>;
    #pwm-cells = <3>;
    };

  • Ok thanks that did do the trick. I can hear the beep now:

    root:~# cat /sys/kernel/debug/pwm
    platform/dmtimer-pwm@15, 1 PWM device
     pwm-0   (pwm_beeper          ): requested period: 250000 ns duty: 0 ns polarity: normal
    
    root:~# cd /sys/class/pwm
    root:/sys/class/pwm# cd pwmchip0
    root:/sys/class/pwm/pwmchip0# echo 0 > export
    root@solix:/sys/class/pwm/pwmchip0# cd pwm0
    root@solix:/sys/class/pwm/pwmchip0/pwm0# echo 190000 > duty_cycle
    root@solix:/sys/class/pwm/pwmchip0/pwm0# cat /sys/kernel/debug/pwm
    platform/dmtimer-pwm@15, 1 PWM device
     pwm-0   (sysfs               ): requested period: 250000 ns duty: 190000 ns polarity: normal
    
    root@solix:/sys/class/pwm/pwmchip0/pwm0# echo 1 > enable
    

    All this is good. Thanks!

  • I'm working with Adam, we made the following changes in the correct sections in the dts file:

    +       pwm15: dmtimer-pwm@15 {
    +               compatible = "ti,omap-dmtimer-pwm";
    +               ti,timers = <&timer15>;
    +               #pwm-cells = <3>;
    +       };
    +
    +       beeper: pwm_beeper {
    +               status = "okay";
    +               compatible = "pwm-beeper";
    +               pwms = <&pwm15 0 250000 0>;
    +       };

    +&timer15 {
    +       status = "okay";
    +       ti,timer-pwm;
    +       pinctrl-names = "default";
    +       pinctrl-0 = <&timer15_pins>;
    +};
    +

    +       timer15_pins: timer15_pins_default {
    +               pinctrl-single,pins = <
    +                       DRA7XX_CORE_IOPAD(0x369C, PIN_OUTPUT | MUX_MODE10)
    +               >;
    +       };
    +

    We also used menuconfig to enable the following options:

    CONFIG_INPUT_PWM_BEEPER=m

    CONFIG_PWM_OMAP_DMTIMER=m

    We tried both as part of the kernel (=y) but we couldn't communicate with the device. Is that expected or can it be configured as part of the kernel? Is there a better way to enable & access the PWM functionality to drive a beeper connected to B26 / output from timer15?

  • ScottS said:
    We tried both as part of the kernel (=y) but we couldn't communicate with the device.

    Can you elaborate?  What are you doing to communicate with it, and what is the result?  (Any error messages, etc.)

  • Hi Brad,

    I used "menuconfig" to change the CONFIG_INPUT_PWM_BEEPER and CONFIG_PWM_OMAP_DMTIMER values. Only if both are modules / 'm' can we communicate with the device to generate a tone.

    CONFIG_INPUT_PWM_BEEPER=y
    CONFIG_PWM_OMAP_DMTIMER=y
    lsmod shows neither pwm_beeper now pwm_omap_dmtimer
    /sys/class/pwm/pwmchip0 doesn't exist
    # dmesg | grep beep shows nothing
    # dmesg | grep -i dmtimer
    omap-dmtimer-pwm dmtimer-pwm@15: dmtimer pdata structure NULL
    omap-dmtimer-pwm: probe of dmtimer-pwm@15 failed with error -22



    CONFIG_INPUT_PWM_BEEPER=m
    CONFIG_PWM_OMAP_DMTIMER=y
    lsmod shows pwm_beeper
    /sys/class/pwm/pwmchip0 doesn't exist
    # dmesg | grep beep shows nothing
    # dmesg | grep -i dmtimer
    omap-dmtimer-pwm dmtimer-pwm@15: dmtimer pdata structure NULL
    omap-dmtimer-pwm: probe of dmtimer-pwm@15 failed with error -22




    CONFIG_INPUT_PWM_BEEPER=y
    CONFIG_PWM_OMAP_DMTIMER=m
    lsmod shows pwm_omap_dmtimer
    /sys/class/pwm/pwmchip0 exists
    /sys/class/pwm/pwmchip0/pwm0 doesn't exist

    # echo 0 > /sys/class/pwm/pwmchip0/export
    -sh: echo: write error: Device or resource busy

    # cat /sys/class/pwm/pwmchip0/npwm
    1

    # rmmod pwm_omap_dmtimer
    rmmod: ERROR: Module pwm_omap_dmtimer is in use

    # cat /sys/kernel/debug/pwm
    platform/dmtimer-pwm@15, 1 PWM device
     pwm-0   (pwm_beeper          ): requested period: 250000 ns duty: 0 ns polarity: normal




    CONFIG_INPUT_PWM_BEEPER=m
    CONFIG_PWM_OMAP_DMTIMER=m
    lsmod shows both pwm_beeper and pwm_omap_dmtimer
    /sys/class/pwm/pwmchip0 exists
    /sys/class/pwm/pwmchip0/pwm0 doesn't exist
    have to "rmmod pwm_beeper" before we use "echo 0 > /sys/class/pwm/pwmchip0/export", then "/sys/class/pwm/pwmchip0/pwm0" exists
    can now write to "period", "duty_cycle", and "enable" as needed

    # cat /sys/kernel/debug/pwm
    platform/dmtimer-pwm@15, 1 PWM device
     pwm-0   (pwm_beeper          ): requested period: 250000 ns duty: 0 ns polarity: normal

    # dmesg | grep beep
    [    6.759203] pwm-beeper pwm_beeper: pwm_beeper supply amp not found, using dummy regulator
    [    6.780730] pwm-beeper pwm_beeper: failed to parse 'beeper-hz' property, using default: 1000Hz
    [    6.781021] input: pwm-beeper as /devices/platform/pwm_beeper/input/input0

    # dmesg | grep -i dmtimer
    [    6.618756] omap-dmtimer-pwm dmtimer-pwm@15: requested duty cycle: 0 ns, period: 250000 ns
    [    6.618767] omap-dmtimer-pwm dmtimer-pwm@15: clk rate: 32786Hz
    [    6.716315] omap-dmtimer-pwm dmtimer-pwm@15: duty cycle 0 ns is too short for clock rate 32786 Hz
    [    6.716323] omap-dmtimer-pwm dmtimer-pwm@15: using minimum of 1 clock cycle
    [    6.716329] omap-dmtimer-pwm dmtimer-pwm@15: effective duty cycle: 30501 ns, period: 244007 ns
    [    6.717808] omap-dmtimer-pwm dmtimer-pwm@15: load value: 0xfffffff8 (-8), match value: 0xfffffff8 (-8)

    Thanks,

    Scott

  • Did you use make modules_install to properly install these modules into the file system?  Did they ever get loaded, either automatically or through insmod/depmod?

  • I have the same question. When the timer-pwm is configured as a part of kernel, the timer-pwm will not work properly. It's like there are some boot sequence requirements.

  • Hi Brad,

    We tried everything we could think of but the only combination that works is configure both as loadable modules. It doesn't work if either are part of the kernel.

    Unfortunately, we had to stop using the drivers and write directly to the registers for timer 15 due to a 80ms +- 20ms delay when changing frequency. We are playing a sequence of tones and a those delays between notes is very noticeable.

    Scott

  • Hi Scott,

    I was able to replicate your problem and I was only able to generate a PWM with CONFIG_PWM_OMAP_DMTIMER=m. I believe this may be a bug with the driver and I am investigating more into this problem. 

    In the meantime, if you plan on using the driver, please build it as a module.

    Regards,
    Krunal

  • Update: It seems like the issue is resolved in kernel 4.19 and here is the reference.

    Regards,
    Krunal

  • Hi Krunal,

    Thank you for researching the module vs kernel issue and finding a resolution.

    Unfortunately, we had to stop using the drivers and write directly to the registers for timer 15. Using the pwm driver, there is a 80ms +- 20ms delay when changing frequency. We are playing a sequence of tones and a those delays between notes is very noticeable.

    Scott

  • Hi Scott,

    Thank you for the update. I will be closing the ticket and if you have more questions, please feel free to open the ticket in the future.

    Regards,
    Krunal