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
解決済! 解決策の投稿を見る。
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.
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
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
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
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.
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.
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: