====== 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/|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. 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 ==== 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 --mode=input ++++ Example | gpioset 0 4 --mode=input # gpiochip0, GPIO4, Input gpioset 0 4 --mode=output # gpiochip0, GPIO4, Input ++++ Set GPIO to Low / High level gpioset =1 # High gpioset =0 # Low ++++ Example | gpioset 0 4=0 # gpiochip0, GPIO4, Output low level gpioset 0 4=1 # gpiochip0, GPIO4, Output high level ++++ Get GPIO level gpioget # 0 = Low, 1 = High ++++ Example | gpioget 0 4 0 # gpiochip0, GPIO4 has low level gpioget 0 4 1 # gpiochip0, GPIO4 has low level ++++ ==== 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. 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 [size=150%]GPIO address = Base address + GPIO number[/size] echo [GPIO Address] > export echo 16 > export # export first GPIO with Base Address 16 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" > /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" > /direction echo "out" > gpio16/direction # Set GPIO16 to output Replace **** 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 > /value echo 0 > gpio16/value # set level of GPIO16 to low Replace **** with **0** for a low level or **1** for a high level. **** 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 /value cat gpio16/value # read level of GPIO16 Replace **** 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. 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 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 === 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 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