---
# System prepended metadata

title: MX610HD GPIO Linux Programming Guide
tags: [GPIO, Linux]

---

MX610HD Linux GPIO Programming Guide
=
### 1. GPIO Header of [MX610HD](https://www.bcmcom.com/bcm_product_MX610HD.html)

|Function   |Pin   |Pin|Function |
| :---:   | :---:    | :---:   |:---:   |
|GPIO4    |2    | 1 | GPIO0 |
|GPIO5    |4    | 3 | GPIO1 |
|GPIO6    |6    | 5 | GPIO2 |
|GPIO7    |8    | 8 | GPIO3 |
|SMB_DATA    |10    | 9 | SMB_CLK |
|+3.3VSB    |12    | 11 | GND |

Please verify the connector orientation and the location of pin 1 on the board.

### 2. PCH GPIO and Linux Pinctrl mappings
Ubuntu 22.04.5 kernel 6.8, [drivers/pinctrl/intel/pinctrl-alderlake.c](https://elixir.bootlin.com/linux/v6.8/source/drivers/pinctrl/intel/pinctrl-alderlake.c#L554)

   |Pin   |Function   |PCH|Pin# |GPIO#|
   | :---:   | :---:    | :---:   |:---:   |:---:   |
   |1    |GPIO0    | GPP_C8/UART0_RXD | 184 | 296 |
   |3    |GPIO1    | GPP_C9/UART0_TXD | 185 | 297 |
   |5    |GPIO2    | GPP_C10/UART0_RTS# | 186 | 298 |
   |7    |GPIO3    | GPP_C11/UART0_CTS# | 187 | 299 |
   |2    |GPIO4    | GPP_C12/UART1_RXD | 188 | 300 |
   |4    |GPIO5    | GPP_C13/UART1_TXD | 189 | 301 |
   |6    |GPIO6    | GPP_C14/UART1_RTS# | 190 | 302 |
   |8    |GPIO7    | GPP_C15/UART1_CTS# | 191 | 303 |
   
#### Check driver status:
```bash=
lsmod | grep pin
pinctrl_alderlake      32768  0
```

To find the GPIO number for "UART0_RXD" based on the provided information from your Intel Alderlake platform configuration, let's follow these steps:

### Locate the Pin in pinctrl_pin_desc:
#### Pin Description for "UART0_RXD":
   ```
   PINCTRL_PIN(184, "UART0_RXD"),
   ```
This line tells us that "UART0_RXD" is identified as pin number 184.

### Identify Pad Group and Community:
#### Locate the Pad Group for Pin 184:
From the intel_padgroup structures provided, we find that pin 184 falls within the following pad group in adls_community3_gpps:
```
ADL_GPP(2, 176, 199, 288),  // GPP_C
```
This group starts at pin 176 and ends at pin 199 with a GPIO base of 288.

### Calculate the GPIO Number:
#### Formula to Determine GPIO Number:
Given the starting GPIO base and the range, you can calculate the GPIO number as follows:
* GPIO number = GPIO base + (Pin number - First pin number in group)
* Calculation:
  * GPIO number for "UART0_RXD" = 288 + (184 - 176)
  * GPIO number for "UART0_RXD" = 288 + 8
  * GPIO number for "UART0_RXD" = 296

### 3. Access GPIO using libgpiod
`libgpiod` is a C library and set of tools for interacting with the GPIO character device introduced in Linux kernels 4.8+. It replaces the older method of directly accessing GPIOs via sysfs and provides a more robust interface for GPIO manipulation.
#### Installing libgpiod
On Debian or Ubuntu:
```bash=
sudo apt update
sudo apt install gpiod libgpiod2 libgpiod-dev
```
#### Using libgiod Tools

#### Listing available GPIO chips:
```bash=
sudo gpiodetect
gpiochip0 [INTC1056:00] (473 lines)
```

#### Check the GPIO Info: All GPIOs are Input by default
```bash=
sudo gpioinfo
...
        line 296:      unnamed       unused   input  active-high
        line 297:      unnamed       unused   input  active-high
        line 298:      unnamed       unused   input  active-high
        line 299:      unnamed       unused   input  active-high
        line 300:      unnamed       unused   input  active-high
        line 301:      unnamed       unused   input  active-high
        line 302:      unnamed       unused   input  active-high
        line 303:      unnamed       unused   input  active-high
...
```

#### Check the Current State
```bash=
for i in $(seq 296 303); do
  echo -n "line $i: "
  sudo gpioget gpiochip0 $i
done

line 296: 1
line 297: 1
line 298: 1
line 299: 1
line 300: 1
line 301: 1
line 302: 1
line 303: 1
```

#### Set the GPIO Direction and Value
```bash=
To set it high:
sudo gpioset gpiochip0 296=1

To set it low:
sudo gpioset gpiochip0 296=0
```

### Using libgpiod in a C Program
```clike=
#include <gpiod.h>
#include <stdio.h>
#include <unistd.h>

#define GPIO_CHIP_NAME "gpiochip0"
#define GPIO_LINE_NUMBER 296

int main(void) {
    struct gpiod_chip *chip;
    struct gpiod_line *line;
    int i, ret;

    chip = gpiod_chip_open_by_name(GPIO_CHIP_NAME);
    if (!chip) {
        perror("Open chip failed");
        return -1;
    }

    line = gpiod_chip_get_line(chip, GPIO_LINE_NUMBER);
    if (!line) {
        perror("Get line failed");
        gpiod_chip_close(chip);
        return -1;
    }

    ret = gpiod_line_request_output(line, "example_program", 0);
    if (ret < 0) {
        perror("Request line as output failed");
        gpiod_line_release(line);
        gpiod_chip_close(chip);
        return -1;
    }

    // Toggle the GPIO line 10 times
    for (i = 0; i < 10; i++) {
        gpiod_line_set_value(line, 1);
        sleep(1);
        gpiod_line_set_value(line, 0);
        sleep(1);
    }

    gpiod_line_release(line);
    gpiod_chip_close(chip);

    return 0;
}
```
Compile
`cc gpio_296.c -lgpiod -o gpio_296`

More examples can be found here:
https://github.com/starnight/libgpiod-example
