# A388 base control RESET# on M.2 bus

**URL:** https://community.solid-run.com/t/a388-base-control-reset-on-m-2-bus/923
**Category:** ARMADA A388
**Created:** [November 14, 2024, 10:02am UTC](https://community.solid-run.com/t/a388-base-control-reset-on-m-2-bus/923 "2024-11-14T10:02:50Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![chris](https://avatars.discourse-cdn.com/v4/letter/c/958977/32.png) [@chris](https://community.solid-run.com/u/chris)
#### Post date: [November 14, 2024, 10:02am UTC](https://community.solid-run.com/t/a388-base-control-reset-on-m-2-bus/923/1 "2024-11-14T10:02:50Z")

</div>

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?

---

<div class="post-metadata">

### Author: ![chris](https://avatars.discourse-cdn.com/v4/letter/c/958977/32.png) [@chris](https://community.solid-run.com/u/chris)
#### Post date: [December 29, 2024, 11:02pm UTC](https://community.solid-run.com/t/a388-base-control-reset-on-m-2-bus/923/2 "2024-12-29T23:02:30Z")

</div>

Can someone from SolidRun please reply? Anyone? It has been more than a month.

---

<div class="post-metadata">

### Author: ![YazanShhadySR](https://avatars.discourse-cdn.com/v4/letter/y/a6a055/32.png) [@YazanShhadySR](https://community.solid-run.com/u/YazanShhadySR)
#### Post date: [December 30, 2024, 1:51pm UTC](https://community.solid-run.com/t/a388-base-control-reset-on-m-2-bus/923/3 "2024-12-30T13:51:47Z")

</div>

### 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](https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/marvell/armada-388-clearfog.dtsi#L133).Example DTS node:

```auto
expander0: gpio-expander@20 {
    compatible = "nxp,pca9555";
    gpio-controller;
    #gpio-cells = <2>;
    reg = <0x20>;
};

```

- Configure the needed GPIOs (e.g., `I2C_IO_0_2` or `I2C_IO_1_2`) as shown in this example: [Clearfog DTS GPIO Configuration](https://github.com/torvalds/linux/blob/master/arch/arm/boot/dts/marvell/armada-388-clearfog.dtsi#L144).

* * *

### **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:

```auto
ls /sys/class/gpio/

```

Example output:

```auto
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**

1. Export the GPIO:

```auto
echo 498 > /sys/class/gpio/export

```

1. Configure direction and value:

```auto
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:

```auto
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**

```auto
sudo apt update
sudo apt install i2c-tools

```

#### b. **Modify Registers**

- Use the PCA9655 datasheet [Page 9-10](https://www.onsemi.com/download/data-sheet/pdf/pca9655e-d.pdf) to locate the direction and value registers.
- Example commands:
  - Set direction:

```auto
i2cset -y 0 0x20 0x06 0xFB # Set pin 2 of port 0 as output

```

- Set output value:

```auto
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.

---

<div class="post-metadata">

### Author: ![chris](https://avatars.discourse-cdn.com/v4/letter/c/958977/32.png) [@chris](https://community.solid-run.com/u/chris)
#### Post date: [January 7, 2025, 8:21am UTC](https://community.solid-run.com/t/a388-base-control-reset-on-m-2-bus/923/4 "2025-01-07T08:21:42Z")

</div>

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

---

<div class="post-metadata">

### Author: ![jnettlet](https://dub1.discourse-cdn.com/flex005/user_avatar/community.solid-run.com/jnettlet/32/62_2.png) [@jnettlet](https://community.solid-run.com/u/jnettlet)
#### Post date: [January 7, 2025, 11:02am UTC](https://community.solid-run.com/t/a388-base-control-reset-on-m-2-bus/923/5 "2025-01-07T11:02:07Z")

</div>

can you run rfkill list and post the results?

---

<div class="post-metadata">

### Author: ![chris](https://avatars.discourse-cdn.com/v4/letter/c/958977/32.png) [@chris](https://community.solid-run.com/u/chris)
#### Post date: [January 16, 2025, 3:32am UTC](https://community.solid-run.com/t/a388-base-control-reset-on-m-2-bus/923/6 "2025-01-16T03:32:25Z")

</div>

How do I add rfkill to openwrt?
