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