How do we control the I2C_IO_1_2 and I2C_IO_0_2 signals via U19 PCA9655 to the M.2 connector from userspace or via C code?
Can someone from SolidRun please reply? Anyone? It has been more than a month.
Controlling U19 IO-Expander on I2C Bus-0 at Address 0x20
The U19 IO-Expander is connected to I2C bus-0 at address 0x20. Below are the three methods to control its GPIOs:
1. Configure GPIO in DTS
- Define the GPIO in the Device Tree (DTS) for kernel-level configuration.
- Refer to the example from the Armada Clearfog DTS file.Example DTS node:
expander0: gpio-expander@20 {
compatible = "nxp,pca9555";
gpio-controller;
#gpio-cells = <2>;
reg = <0x20>;
};
- Configure the needed GPIOs (e.g.,
I2C_IO_0_2
orI2C_IO_1_2
) as shown in this example: Clearfog DTS GPIO Configuration.
2. Control GPIOs Using GPIOLib or Sysfs
If the IO expander GPIOs are not pre-configured in the DTS, you can manage them from user space:
a. Determine GPIO Base Offset
- The GPIO base offset is assigned dynamically. To find it:
ls /sys/class/gpio/
Example output:
export gpiochip0 gpiochip32 gpiochip496 unexport
- In this example,
gpiochip496
corresponds to the IO expander base. - Calculate GPIO numbers for individual pins:
I2C_IO_0_2
: GPIO =496 + 0*8 + 2 = 498
I2C_IO_1_2
: GPIO =496 + 1*8 + 2 = 506
b. Control GPIOs Using Sysfs
- Export the GPIO:
echo 498 > /sys/class/gpio/export
- Configure direction and value:
echo out > /sys/class/gpio/gpio498/direction
echo 1 > /sys/class/gpio/gpio498/value # Set HIGH
echo 0 > /sys/class/gpio/gpio498/value # Set LOW
c. Control GPIOs Using GPIOLib Utilities
use the gpiolist command to find the correct gpio class name for the IO_Exapnder (for example gpiochip496 or expander0…)
- Use the
gpioset
command for modern kernels with GPIOLib support:
gpioset gpiochip496 2=1 # Set I2C_IO_0_2 HIGH
gpioset gpiochip496 2=0 # Set I2C_IO_0_2 LOW
gpioset gpiochip496 10=1 # Set I2C_IO_1_2 HIGH
gpioset gpiochip496 10=0 # Set I2C_IO_1_2 LOW
**3. Force GPIO Values Using I2C-Utils **
Note This also works when the GPIO is defined in the Device Tree (DTS)
You can directly modify the IO expander’s register values using i2c-utils
.
a. Install i2c-utils
sudo apt update
sudo apt install i2c-tools
b. Modify Registers
- Use the PCA9655 datasheet Page 9-10 to locate the direction and value registers.
- Example commands:
- Set direction:
i2cset -y 0 0x20 0x06 0xFB # Set pin 2 of port 0 as output
- Set output value:
i2cset -y 0 0x20 0x02 0x04 # Set pin 2 HIGH
i2cset -y 0 0x20 0x02 0x00 # Set pin 2 LOW
Summary
- DTS Configuration: Best for kernel-managed GPIOs.
- GPIOLib/Sysfs: Allows user-space control without kernel changes.
- I2C-Utils: Provides direct hardware access for fine-grained control.
All of the methods provided report “Resource busy”:
root@OpenWrt:/# echo 498 > /sys/class/gpio/export
ash: write error: Resource busy
root@OpenWrt:/# i2cset -y 0 0x20 0x06 0xFB
Error: Could not set address to 0x20: Resource busy
can you run rfkill list and post the results?
How do I add rfkill to openwrt?