[i.MX8M Plus] Config an i2c io-expansion device and set one pin to leds-gpio

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

[i.MX8M Plus] Config an i2c io-expansion device and set one pin to leds-gpio

ソリューションへジャンプ
4,539件の閲覧回数
sophiehu
Contributor III

Hi NXP,

We have a custom board with i2c io-expansion PCAL6408. There are 8 gpios. I config it in dts and all the gpios work well.

&i2c3 {
    clock-frequency = <400000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c3>;
    status = "okay"

    pcal6408: pcal6408@20 {
    compatible = "nxp,pcal6408";
    reg = <0x20>;
    gpio-controller;
    #gpio-cells = <2>;
};

We connect one gpio to led and wish to config the gpio as led. Is it possible?

I try to config like this:

&i2c3 {
    clock-frequency = <400000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c3>;
    status = "okay"

    pcal6408: pcal6408@20 {
        compatible = "nxp,pcal6408";
        reg = <0x20>;
        gpio-controller;
        #gpio-cells = <2>;

        pwr_led: led@6 {
            label = "green:pwr";
            gpios = <6 GPIO_ACTIVE_HIGH>;
            default-state = "on";
        };
    };
};

It shows error:

[ 0.071647] OF: /soc@0/bus@30800000/i2c@30a40000/pcal6408@20/led@4: could not get #gpio-cells for /soc@0/bus@30000000/efuse@30350000/speed-grade@10
[ 0.071700] OF: /soc@0/bus@30800000/i2c@30a40000/pcal6408@20/led@5: could not get #gpio-cells for /cpus/l2-cache0
[ 0.071738] OF: /soc@0/bus@30800000/i2c@30a40000/pcal6408@20/led@6: could not get #gpio-cells for /cpus/idle-states/cpu-pd-wait
[ 0.071777] OF: /soc@0/bus@30800000/i2c@30a40000/pcal6408@20/led@7: could not get #gpio-cells for /soc@0/bus@30800000/i2c@30a20000/pmic@25/regulators/BUCK2

I also try this:

/ {
    leds {
      compatible = "gpio-leds";
        pwr_led {
          label = "pwr";
          gpios = <&pcal6408 6 GPIO_ACTIVE_HIGH>;
          default-state = "on";
      };
};

It compiles error:

ERROR (phandle_references): /leds/wifi_led: Reference to non-existent node or label "pcal6408"

Would you give me some suggestion?
Thank you.

Best Regards,

Sophie

0 件の賞賛
返信
1 解決策
4,480件の閲覧回数
Zhiming_Liu
NXP TechSupport
NXP TechSupport

Hello @sophiehu 

The orignal pcaxxx driver can only support common gpio control, it can't support embed led driver. You can use libgpio to control in/out, high/low in userspace.

 

https://stackoverflow.com/questions/66106568/how-to-programmatically-use-gpio-expander-driver-in-lin...

元の投稿で解決策を見る

0 件の賞賛
返信
6 返答(返信)
4,522件の閲覧回数
Zhiming_Liu
NXP TechSupport
NXP TechSupport

Hello @sophiehu 

Please refer the kernel docuement to config dts node: Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml The gpio-hog and gpios is required.

 

patternProperties:
  "^(hog-[0-9]+|.+-hog(-[0-9]+)?)$":
    type: object
    properties:
      gpio-hog: true
      gpios: true
      input: true
      output-high: true
      output-low: true
      line-name: true

    required:
      - gpio-hog
      - gpios

    additionalProperties: false

 

0 件の賞賛
返信
4,513件の閲覧回数
sophiehu
Contributor III

Hi Qmiller,

I moldify dts like this:
pcal6408: pcal6408@20 {
    compatible = "nxp,pcal6408";
    reg = <0x20>;
    gpio-controller;
    #gpio-cells = <2>;
    pwr_led {
        compatible = "gpio-leds";
        label = "green:pwr";
        gpio-hog;
        gpios = <6 GPIO_ACTIVE_HIGH>;
        output-high;
        default-state = "on";
    };
};

It will be set to gpio not led. The kernel log:
[ 2.161174] gpio-509 (wifi_led): hogged as output/low
The gpioinfo:
gpiochip5 - 8 lines:
line 0: unnamed unused input active-high
line 1: unnamed unused input active-high
line 2: unnamed unused input active-high
line 3: unnamed unused input active-high
line 4: unnamed unused input active-high
line 5: unnamed unused input active-high
line 6: unnamed "pwr_led" output active-high [used]
line 7: unnamed unused input active-high

It cannot be a "led" in /sys/class/led and control it like a led. Would you give me some succestion?
Thank you.

Best Regards,
Sophie

0 件の賞賛
返信
4,499件の閲覧回数
sophiehu
Contributor III

Hi Qmiller,

Any updated?
I also try to set dts like this:

&i2c3 {
    pcal6408: pcal6408@20 {
        compatible = "nxp,pcal6408";
        reg = <0x20>;
        gpio-controller;
        #gpio-cells = <2>;
        leds {
            compatible = "gpio-leds";
            led0: led0 {
                gpios = <&pcal6408 0 GPIO_ACTIVE_HIGH>;
                label = "pcal6408:led0";
            };
            led1: led1 {
                gpios = <&pcal6408 1 GPIO_ACTIVE_HIGH>;
                label = "pcal6408:led1";
            };
        };
    };
};

And it still not works. I add some debug message in drivers/leds/leds_gpio.c and it fail in calling device_get_child_node_count of gpio_leds_create of gpio_led_probe.

[    1.682012] gpio_led_probe
[    1.684745] gpio_leds_create
[    1.687639] gpio_leds_create: device_get_child_node_count 1
[    1.693235] gpio_leds_create: devm_fwnode_get_gpiod_from_child fail
[    1.699512] gpio_led_probe: gpio_leds_create fail

[    2.099153] nxp-pca9450 0-0025: pca9450bc probed.
[    2.157122] pca953x 2-0020: using no AI

Best Regards,
Sophie

0 件の賞賛
返信
4,481件の閲覧回数
Zhiming_Liu
NXP TechSupport
NXP TechSupport

Hello @sophiehu 

The orignal pcaxxx driver can only support common gpio control, it can't support embed led driver. You can use libgpio to control in/out, high/low in userspace.

 

https://stackoverflow.com/questions/66106568/how-to-programmatically-use-gpio-expander-driver-in-lin...

0 件の賞賛
返信
4,472件の閲覧回数
sophiehu
Contributor III

Hi @Zhiming_Liu ,

Thank you.

Since I cannot config pca6408 gpio as led device by gpio-pca953x driver and leds-gpio driver, how about leds-pca* driver? I see some leds-pca* drivers in kernel/drivers/leds/, such as leds-pca9532.c, leds-pca955x.c and leds-pca963x.c. Is there any leds-pca* driver compatible with pcal6408 just like gpio-pca953x driver?

I have tried to insert pcal6408 in leds-pca9532.c 

enum {
    ...
    pcal6408,
};

static const struct i2c_device_id pca9532_id[] = {
    ...
    { "pcal6408", pcal6408 },
    { }
};

static const struct pca9532_chip_info pca9532_chip_info_tbl[] = {
    ...
    [pcal6408] = {
        .num_leds = 8,
    },
};
static const struct of_device_id of_pca9532_leds_match[] = {
    ...
    { .compatible = "nxp,pcal6408", .data = (void *)pcal6408 },
    {},
};

And also leds-pca955x.c

enum pca955x_type {
   ...
    pcal6408,
};

static struct pca955x_chipdef pca955x_chipdefs[] = {
   ...
    [pcal6408] = {
        .bits = 8,
        .slv_addr = 0x20,
        .slv_addr_shift = 3,
    },
};

static const struct i2c_device_id pca955x_id[] = {
   ...
    { "pcal6408", pcal6408 },
    { }
};
static const struct of_device_id of_pca955x_match[] = {
   ...
    { .compatible = "nxp,pcal6408", .data = (void *)pcal6408 },
    {},
};

But they don't work.

0 件の賞賛
返信
4,460件の閲覧回数
Zhiming_Liu
NXP TechSupport
NXP TechSupport

Hello @sophiehu 

It's possible to porting pca6408 refering these  leds-pca9xxx driver. But you can't just add such codes in original driver and change the register definition. The codes is designed to probe led drivers(pca95xx), this means some structure members in these driver is not suitable for pca6408. Conclusion is that you need write a new led-xxx driver for pca6408 refering these leds-pca9xxx driver.

Here is the pca6408 spec:

https://www.nxp.com.cn/docs/en/data-sheet/PCAL6408A.pdf

0 件の賞賛
返信