TQMx86 Linux MFD Driver

Our X86 modules have some interfaces that can be accessed and used in Linux via our MFD (Multi Function Device) driver. After loading the driver, interfaces like GPIO, I2C, Watchdogs and many other module functions can be used via standard Linux tools, without the need of own software development.

With most newer Linux distributions (e.g. Ubuntu 20.04) the driver is loaded automatically when the operating system is run on a TQ module.

  • Control GPIOs on Board from Linux
  • Access General Purpose I2C Bus
  • Read DMI data about the Module
  • Use Watchdogs
  • Use Module EEPROM

The driver is loaded automatically as a module in current Linux distributions based on the mainline kernel when running on a TQ x86 module. If the driver is not loaded as a module or should be compiled hard, this can be implemented by adapting the kernel config.

CONFIG_MFD_TQMX86=y
CONFIG_GPIO_TQMX86=y
CONFIG_TQMX86_WDT=y
CONFIG_I2C_OCORES=y

Please see our Yocto Meta-Layer for more information:
https://github.com/tq-systems/meta-tqmx86/

If the module is installed and loaded properly, you will get the following output at boot time:

 Found TQMxXXX - Board ID X, PCB Revision X, PLD Revision X

The lsmod command can be used to check whether the driver was loaded as a module:

lsmod | grep tqmx86

The following sections describe how to access the individual interfaces and functions.

GPIOs

Depending on the connector form factor used, the modules offer several GPIOs that can be controlled directly via Linux SysFS (deprecated) and other tools.

Incompatibility

For the current version of gpiod to work, the kernel config CONFIG_GPIO_CDEV_V1 must be set. This may no longer be the case with newer Ubuntu versions.

The Linux gpiod tools are a collection of command-line utilities that facilitate the use of the General-Purpose Input/Output (GPIO) interface in Linux. They provide functions for reading and writing GPIO pins, configuring pull-up and pull-down resistors, and managing interrupts.

Installation

Ubuntu / Debian

sudo apt update
sudo apt install gpiod

RHEL, CentOS, Fedora

sudo dnf upgrade
sudo dnf install gpiod-tools


Usage

Find the TQMx86 GPIO chip that can be used to control the GPIOs
sudo gpiodetect | grep tqmx86
 
> gpiochip1 [gpio-tqmx86] (8 lines)

?? Configure GPIO as input / output ==

With some module types (like COM Express Modules) the GPIOs are fixed to inputs or outputs and cannot be configured.
gpioset <Chip-Number> <GPIO-Number> --mode=input

Example

Set GPIO to Low / High level

gpioset <Chip-Number> <GPIO-Number>=1  # High
gpioset <Chip-Number> <GPIO-Number>=0  # Low

Example

Get GPIO level

gpioget <Chip-Number> <GPIO-Number> # 0 = Low, 1 = High

Example

Controlling GPIOs using the SysFS interface driver is one way to control GPIO pins in Linux-based systems. By using the file interfaces in the SysFS directory, you can configure the GPIO pins, read and set their state, and respond to changes.

Find the TQMx86 GPIO chip that can be used to control the GPIOs:

cd /sys/class/gpio
ls -al| grep tqmx86 | grep -oP "(?<=gpiochip)\d+"  # get base address of tqmx86 gpiochip

Export GPIOs

In order to use a GPIO, it must be initialized and bound. This process is called exporting GPIOs.

Base address

The number is the base address of the GPIOs. For example, if the module has 8 GPIOs and the base address starts at 16 (gpiochip16), the GPIO address of the first GPIO is 16, the second GPIO is 17 and so on. The address of the last GPIO is 23
GPIO address = Base address + GPIO number
echo [GPIO Address] > export
 
echo 16 > export # export first GPIO with Base Address 16 

Permissions

If you get a permission denied error log in as superuser.
sudo su

after successful export the chip should show up in the current directory (gpioX).

Configuring GPIO as Input or Output

Set the GPIO pin to input mode using the following command in the Ubuntu shell:

echo "in" > <gpio_number>/direction
echo "in" > gpio16/direction # Set GPIO16 to input

Set the GPIO pin to output mode using the following command in the Ubuntu shell:

echo "out" > <gpio_number>/direction
echo "out" > gpio16/direction # Set GPIO16 to output

Replace <gpio_number> with the GPIO pin number.

Changing Output Level

Set the GPIO pin to the desired output level (low or high) using the following command in the Ubuntu shell:

echo <level> > <gpio_number>/value
echo 0 > gpio16/value # set level of GPIO16 to low

Replace <level> with 0 for a low level or 1 for a high level. <gpio_number> should be replaced with the GPIO pin number.

Reading Input Level

Read the input level of the GPIO pin using the following command in the Ubuntu shell:

cat <gpio_number>/value
cat gpio16/value # read level of GPIO16

Replace <gpio_number> with the GPIO pin number.

These steps will allow you to configure GPIO pins as input or output, change the output level, and read the input level using the SysFS interface on Linux.

General Purpose I2C

Each of our x86 modules provides a freely usable general purpose I2C bus. The driver allows the use of the I2C bus in the Linux kernel and in userspace via the i2c-dev module, which adds the i2c bus to /dev.

For testing the general purpose i2c devices, the i2c-tools can be used. These tools can be used to view and address i2c devices on this bus.

Installation

Ubuntu / Debian

sudo apt update
sudo apt install i2c-tools

Load modules if necessary

If there are no i2c devices listed under /dev/, it is possible that the appropriate modules have not yet been loaded.
This is possible with the following commands:

modprobe -r tqmx86
modprobe tqmx86 i2c-speed=0,100
modprobe i2c-dev



List all I2C Busses

This command allows you to list all the I2C busses available to the system.

i2cdetect -l

Some buses are displayed as output. The GP I2C of our module is the one with the name i2c-machox2. At the beginning of the column the corresponding device can be found (e.g. i2c-0).

i2cdetect -l

i2c-0   i2c         i2c-machxo2                         I2C adapter
i2c-1   i2c         i915 gmbus vga                      I2C adapter
i2c-2   i2c         i915 gmbus panel                    I2C adapter


List all I2C Devices

To list all devices found on a specific bus the following command can be used:

i2cdetect -y [I2C Bus]
i2cdetect -y 0


Read Data from an I2C Device

This command reads data from a specific I2C device and address.

i2cget -y [bus] [address] [data_address]
i2cget -y 0 0x50 0x05


Write Data to an I2C Device

This command writes data to a specific I2C device and address.

i2cset -y [bus] [address] [data_address] [value]
i2cset -y 1 0x51 0x03 0xAB


I2C Data Transfer

You can use these commands to perform read and write operations in a single line.

i2ctransfer -y [bus] [read/write flag] [address] [length] [data]

Read:
i2ctransfer -y 0 r 0x50 2

Write:
i2ctransfer -y 1 w 0x51 0xAB

Watchdog

A standard Watchdog API is provided by the driver. Please refer to official documentation for further reference: https://www.kernel.org/doc/Documentation/watchdog/watchdog-api.txt

Load Watchdog Driver

to use the watchdog via the /dev interface the appropriate driver must be loaded. The following command can be used to check whether the driver has already been loaded:

lsmod | grep tqmx86_wdt

If the driver is not loaded (no lsmod Output) it can be loaded with the following command:

modprobe tqmx86_wdt

Start the Watchdog

Warning

Once the watchdog is started, it is difficult to stop it again!

The watchdog is located at /dev/watchdog0. The operating system (e.g. Ubuntu) always writes to the device to prevent a watchdog from being triggered. The following command accesses and occupies the watchdog, preventing the system from overwriting it and triggering it after the appropriate timeout:

cat > /dev/watchdog0

Permissions

If you get a permission error when accessing the device, this operation could be performed as superuser:
sudo su

Configure the Watchdog

The watchdog can be configured via the SysFS. The timeout can be displayed and configured as follows:

# Enter directory
cd /sys/class/watchdog/watchdog0

# Read timeout
cat timeout

# Set timeout to 32 Seconds:
echo 32 > timeout
  • Last modified: 2023/10/06 13:29