Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

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.

Managing a PWM (ecap) inside a SPI device driver

Other Parts Discussed in Thread: TLC5940

Hi, I've written a linux kernel driver for the TI TLC5940 LED controller which works okay. Now I am cleaning it up and making it configurable. Aside from an SPI bus, this device needs at least 1 GPIO pin and 1 PWM. I am using the ecap driver for the PWM and it works when it is unclaimed by my driver and configured over sysfs. When writing the driver, I was able to use:

of_get_named_gpio()

to make the specific GPIO configurable with a device tree property and that works okay. I also want to make a the PWM configurable using:

devm_of_pwm_get()

which has been more problematic.

These are my device tree overrides for the controller:

&ecap1 {
    status = "okay";
    #pwm-cells = <1>;
    pinctrl-names = "default";
    pinctrl-0 = <&ecap1_pins>;
};

&spi0 {
    tlc5940: tlc5940 {
        compatible = "linux,tlc5940";
        spi-max-frequency = <24000000>;
        reg = <0>;
        blank-gpio = <&gpio2 22 GPIO_ACTIVE_HIGH>;
        vprg-gpio = <&gpio2 23 GPIO_ACTIVE_HIGH>;
        pwms = <&ecap1 0 1638400 0>;
     };
};

And here is the setup code (in the module probe method):

ret = of_get_named_gpio(np, "blank-gpio", 0);
if (ret < 0) {
    dev_err(dev, "failed to read property `blank-gpio': %d\n", ret);
    return ret;
}
tlc->gpio_blank = ret;
ret = devm_gpio_request(dev, tlc->gpio_blank, "TLC5940 BLANK");
if (ret) {
    dev_err(dev, "failed to request BLANK pin: %d\n", ret);
    return ret;
}
/* this can be left HIGH initially to avoid any startup flicker */
ret = gpio_direction_output(tlc->gpio_blank, 1);
if (ret) {
    dev_err(dev, "failed to configure BLANK pin for output: %d\n", ret);
    return ret;
}

pwm = devm_of_pwm_get(dev, np, NULL);
if (IS_ERR(pwm)) {
    ret = PTR_ERR(pwm);
    dev_err(dev, "failed to get GSCLK PWM pin: %d\n", ret);
    return ret;
}

When this code runs, devm_of_pwm_get() always fails with -EINVAL even though it looks like I have valid information in my tlc5940 device tree node. The selection of the PWM device (and the device tree property "pwms") is modeled after the leds-pwm driver which I assume works so I assume I'm doing something wrong.

Does anyone know what needs to be done to take ownership of a PWM from inside a device driver?

The entire code is available at: https://github.com/jyelloz/tlc5940-linux/blob/master/leds-tlc5940.c

Thanks.