x86 COM Express® EAPI Linux

Please note that the x86 COM Express® EAPI Linux package is only available on request: Request EAPI


The Linux drivers package tqmx86-dist-1.3.tar.gz is intended to be installed on TQ modules based on the COM Express® standard.

Tested operating systems:

  • Ubuntu 14.04 (Trusty Tahr) i386
  • Ubuntu 16.04 (XenialXerus) i386
  • Ubuntu 16.04 (XenialXerus) x86_64


  • TQMx86 PLD:
    • Board ID
    • I2C (both “soft” and “hard” types of I2C controller)
    • GPIO
    • Watchdog
  • HW Monitor:
    • Built-in coretemp sensors
    • NCT7802 voltage sensors: 3V3, RTC-bat, 5VSB, COMe-Input
    • NCT7802 temperature sensors: CPU and on-module
    • NCT7802 fans: CPU and system
  • On-module EEPROM


  • Boot Ubuntu, unpack tqmx86-dist-1.3.tar.gz and deploy provided drivers, configs and examples to rootfs
  • Install additional test and developer tools, drivers package and corresponding dependencies:
    $ sudo apt-get install i2c-tools lm-sensors 
    $ sudo apt-get install dkms linux-headers-$(uname -r)
    $ sudo dpkg -i tqmx86-drivers_1.3_{i386,amd64}.deb 
  • Copy configs/sensors.tqmx from tqmx86-dist-1.3.tar.gz to /etc/sensors.d/
    $ cp configs/sensors.tqmx /etc/sensors.d/

    Note: this configuration file has been tested on TQMxE38x module. For other TQ COMExpress modules, a following change may be required to make CPU-Temp sensor functional:
    label temp1 “CPUtemp” should be changed to label temp5 “CPUtemp”

  • Copy configs/tqmx86.conf from tqmx86-dist-1.3.tar.gz to /etc/modules-load.d/
    $ cp configs/tqmx86.conf /etc/modules-load.d/
  • Edit /etc/modprobe.d/blacklist.conf: Comment out 'blacklist i2c_i801'
    $ nano /etc/modprobe.d/blacklist.conf
  • Edit /etc/default/grub: Add 'acpi_enforce_resources=lax' parameter to the 'GRUB_CMDLINE_LINUX_DEFAULT' variable definition
    $ nano /etc/default/grub

Example


  • $ update-grub
  • $ reboot


  • $ lsmod

    Check that the following kernel modules/drivers have been automatically loaded:

    tqmx86
    tqmx86_wdt
    gpio_tqmx86
    at24
    nct7802
    i2c_i801
    i2c_machxo2 or i2c_wishbone 

    Note: starting from version R01.02, the package also supports a Lattice Wishbone soft I2C controller which is present on some versions of TQMx86 boards. For such boards, all instances of “i2c-machxo2” should be replaced with “i2c-wishbone” throughout this document.

  • If some driver has not been loaded, manually load it with command modprobe

Example


  • Check that everything is configured properly, i.e. the following device special and sysfs files and directories are present:
    /dev/watchdog
    /dev/watchdog0
    /sys/devices/platform/tqmx86/
    /sys/devices/platform/tqmx86/i2c-machxo2/ (or i2c-wishbone)
    /sys/devices/platform/tqmx86/tqmx86wdt/
    /sys/devices/platform/tqmx86/tqmx86gpio/
    /sys/devices/pci0000:00/0000:00:1f.*/i2c*/*002c/hwmon/hwmon*
    /sys/devices/platform/tqmx86/i2c*/i2c*/*0050/ 


To obtain board and system information, following commands can be used:

  1. BOARD_MANUFACTURER:
    $ cat /sys/class/dmi/id/sys_vendor
  2. BOARD_NAME:
    $ cat /sys/devices/platform/tqmx86/board_id
  3. BOARD_HW_REVISION:
    $ cat /sys/devices/platform/tqmx86/board_version
  4. BOARD_BIOS_REVISION:
    $ cat /sys/class/dmi/id/bios_version

Example


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

  1. An example test program (wdtest) makes use of this API provided in examples directory of the tqmx86-dist-1.3.tar.gz archive. It can be compiled with following command:
    $ gcc wdtest.c -o wdtest
  2. Normal usage for the program is to run as daemon which periodically “pings” watchdog:
    sudo sh -c "./wdtest -p 20 &" 

    The above command pings watchdog every 20 seconds - this is short enough for the default timeout period of 32 sec.
    WARNING: once the watchdog is first accessed it is started and cannot be stopped by any means - it can only be restarted by wdtest or similar watchdog daemon program or just by writing a character into /dev/watchdog (/dev/watchdog0) file.

  3. The wdtest command can also print watchdog info and set timeout. Following sequence of commands can be used to get watchdog info:
    $ ps ax | grep wdtest
    1686 pts/8 S 0:00 ./wdtest -p 20
    $ sudo kill -9 1686 ;sudo ./wdtest i ;sudo sh -c "./wdtest -p 20 &"
    Options: 8080, Version: 0, Id: TQMx86 Watchdog
    Status: 0
    Timeout: 32 

    The above command kills the running daemon, requests watchdog info and starts new daemon.

  4. The watchdog timeout can be changed in similar way:
    $ ps ax |grep wdtest
    1703 pts/8 S 0:00 ./wdtest -p 20
    $ sudo kill -9 1703; sudo ./wdtest -t 800
    $ sudo sh -c "./wdtest -p 500 &" 

    The timeout is set to 1024sec
    Note: delay between 'kill' and 'start' commands should be short not to allow watchdog to reset the board.


A standard GPIO API is provided by the driver. Please refer to official documentation for further reference:
https://www.kernel.org/doc/Documentation/gpio/sysfs.txt

GPIO functionality may be tested by a gpio-test.sh shell script provided in examples directory of the tqmx86-dist-1.3.tar.gz archive. The program requires root privileges to export a 'pin' (once) and to change the output value. With a single 'pin' argument the program reports pin status (direction and value). When the second argument is provided it changes state of (output) pin accordingly:

sudo ./gpio-test.sh 2
Direction: out
Value: 0
$ sudo ./gpio-test.sh 5
Direction: in
Value: 1
$ sudo ./gpio-test.sh 2 1
$ ./gpio-test.sh 2
Direction: out
Value: 1 

Note: GPIO[0:3] are hardwired as outputs and GPIO[4:7] as inputs. Direction cannot be changed.

A standard I2C dev API is provided by the driver. Please refer to official documentation for further reference:
https://www.kernel.org/doc/Documentation/i2c/dev-interface

Let's consider several examples how to access devices on I2C bus:

  • A standard EEPROM driver is automatically loaded for the “on-module” EEPROM at address 0x50. This driver represents the EEPROM as a regular file which can be read/written (truncation is not possible). E.g. to read the whole EEPROM, a following command can be used (note the wildcards usage in the pathname):
     $ sudo hexdump -C /sys/devices/platform/tqmx86/i2c-*/i2c-*/*-0050/eeprom
    00000000 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
    00000010 54 51 4d 78 45 33 38 4d 0a ff ff ff ff ff ff ff |TQMxE38M........|
    00000020 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
    *
    000002a0 ff a1 ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
    000002b0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................|
    *
    00001000 


  • A PCA9538 GPIO expander chip on MB-COME6-1 and MB-COME10-1 carrier board can be accessed using i2c-tools according to following algorithm:
    • Determine the number of i2c-machxo2 (or i2c-wishbone) bus:
      $ i2cdetect l
      i2c-0   unknown       i915 gmbus ssc                  N/A
      i2c-1   unknown       i915 gmbus vga                  N/A
      i2c-2   unknown       i915 gmbus panel                N/A
      i2c-3   unknown       i915 gmbus dpc                  N/A
      i2c-4   unknown       i915 gmbus dpb                  N/A
      i2c-5   unknown       i915 gmbus dpd                  N/A
      i2c-6   unknown       DPDDCB                          N/A
      i2c-7   unknown       DPDDCC                          N/A
      i2c-8   unknown       i2c-machxo2                      N/A
      i2c-9   unknown       SMBus I801 adapter at 3000      N/A 

      (According to the output above, it's 8.)

    • Read all 8 GPIO ports of PCA9538 located on this I2C bus:
      $ sudo i2cdump -r 0-3 8 0x70
      [part of the output skipped]
      0 1 2 3 4 5 6 7 8 9 a b c d e f     0123456789abcdef
      00: 05 ff 00 ff 

      All pins are configured as input, pins 0 and 2 are pulled up to 3.3V.

    • Configure pins 0-3 as outputs:
      $ sudo i2cset 8 0x70 3 0xf0
      $ sudo i2cdump -r 0-3 8 0x70
      00: 0f ff 00 f0 
    • Change output state for pins 0-3 (pins 4-7 not affected as they are inputs):
      $ sudo i2cset 8 0x70 1 0x06 
      $ sudo i2cdump -r 0-3 8 0x70
      00: 06 06 00 f0 

      Note: setting pin 0 to output value 0 should turn on LED.

Option: PCA9540 I/O multiplexer


  • Accessing EEPROM on carrier using i2c-rw program:
    • Source code for i2c-rw test program is provided in examples directory of the tqmx86-dist-1.3.tar.gz archive. To compile it, execute following command:
      $ gcc i2c-rw.c -o i2c-rw 
    • Read EEPROM on i2c bus 8 at address 0x57 from offset 0, size 64:
      $ sudo ./i2c-rw -s 8 0x57 0 0x40
      Time: 6344 usec
      0000: 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................
      0010: 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 ................
      0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
      0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
    • Read EEPROM on i2c bus 8 at address 0x57 from offset 0xa00, size 512:
      $ sudo ./i2c-rw -s 8 0x57 0xa00 0x200
      Time: 47233 usec
      0a00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
      [skipped]
      0af0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
      0b00: 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b ................
      0b10: 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b 1b ................
      0b20: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
      [skipped]
      0bf0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 
    • Write “Hello!” to the same EEPROM at offset 0x30:
      $ echo -n "Hello!" |sudo ./i2c-rw -s -w 8 0x57 0x30
      Time: 978 usec
      $ sudo ./i2c-rw -s 8 0x57 0x20 0x20
      Time: 3400 usec
      0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
      0030: 48 65 6c 6c 6f 21 ff ff ff ff ff ff ff ff ff ff Hello!.......... 

      Note: the program supports reading/writing up to 8K of data in a single request. However, i2c slave devices may impose different limits for a single operation. In particular:

      • when reading EEPROM chip across its size boundary the read rolls over the chip memory size to the start;
      • EEPROM chips installed on TQMx modules do not support writing across 32-byte 'page' boundary (the write wraps around the 'page' boundary).

      Refer to datasheet for Microchip 24AA32A EEPROM for further details.


A standard hwmon API is provided by the driver via sysfs. But a high-level wrapper/library libsensors can be used to access sensors as well. Please refer to official documentation for further reference:
https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface

Standard Linux 'sensors' command can be used to obtain NCT7802 and coretemp (MSR registers of CPU) hardware monitor data:

$ sensors
coretemp-isa-0000
Adapter: ISA adapter
Core 0:        +30.0°C (high = +110.0°C, crit = +110.0°C)
Core 1:        +30.0°C (high = +110.0°C, crit = +110.0°C)
Core 2:        +31.0°C (high = +110.0°C, crit = +110.0°C)
Core 3:        +31.0°C (high = +110.0°C, crit = +110.0°C)

soc_dts0-virtual0
Adapter: Virtual device
temp1:        +29.0°C

soc_dts1-virtual0
Adapter: Virtual device
temp1:        +30.0°C

nct7802-i2c-9-2c
Adapter: SMBus I801 adapter at 3000
3V3:          +3.37 V (min = +0.00 V, max = +4.09 V)
RTCbat:       +3.02 V
5VSB:         +5.08 V (min = +0.00 V, max = +6.24 V)
COMeinput:    +12.38 V (min = +0.00 V, max = +21.99 V)
CPUfan:          0 RPM (min = 0 RPM)
COMefan:      3936 RPM (min = 0 RPM)
CPUtemp:      +30.2°C (low = +0.0°C, high = +85.0°C)
                      (crit = +100.0°C)
SYStemp:      +30.0°C (low = +0.0°C, high = +85.0°C)
                      (crit = +100.0°C) 


  • If Smart Battery is enabled in BIOS the i801 SMBus driver is not working anymore due to an ACPI handle conflict. If both has to be used the i801 SMBus driver has to be adapted.
  • Due to BIOS incompatibility, ACPI SMBus driver (i2c-scmi) does not work and legacy i801 SMBus driver reports “resource conflict”. To resolve the issue “acpi_enforce_resources=lax” should be added to the kernel command line.
  • Setting I2C bus speed is possible only when the driver is loaded. Default speed is 100KHz. If 50 or 400KHz is desired, specify that in driver parameters:
    $ sudo modprobe tqmx86 i2c_speed=50 

    This parameter may be also added to file in

    /etc/modprobe.d/

    as:

    options tqmx86 i2c_speed=50
  • The I2C driver supports operation in interrupt mode on modules with corresponding h/w support. IRQ number can be specified in tqmx86 driver parameters as “i2c_irq=7” (“i2c_irq=0” selects polling mode). However, this was not tested and may not be guaranteed.
  • The I2C driver for Hardened I2C controller may work unstable when the I2C bus speed is set to 400 kHZ. Incorrect write/read operations may occur in this mode, e.g. when somedata is written to I2C EERPOM it may be written to wrong offset. It is recommended to use Soft I2C controller instead.
  • When tqmx86.ko module is loaded, message about missing module signature is logged. This is caused by using DKMS based module package. Unfortunately DKMS is fundamentally incompatible with signed modules feature, because it builds modules on target system, where private key for module signing can't be available.
  • Second stage and generation of interrupts are not supported by the watchdog driver as a rework of existing Linux interfaces is required to implement this functionality.