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.
Features
- Control GPIOs on Board from Linux
- Access General Purpose I2C Bus
- Read DMI data about the Module
- Use Watchdogs
- Use Module EEPROM
Installation
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/
Verify the installation
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
Use Interfaces and Functions
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.
Use GPIOs using the gpiod Tool
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 ==
gpioset <Chip-Number> <GPIO-Number> --mode=input
Set GPIO to Low / High level
gpioset <Chip-Number> <GPIO-Number>=1 # High gpioset <Chip-Number> <GPIO-Number>=0 # Low
Get GPIO level
gpioget <Chip-Number> <GPIO-Number> # 0 = Low, 1 = High
Use GPIOs using the SysFS
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 23echo [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.
Use The GP-I2C using the Linux I2C-Tools
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
Use the Watchdog in Linux
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