Terminal showing i2cdetect output scanning I2C bus on MediaTek Genio 720 EVK
mediatekgeniospii2cperipheraldevice treeembedded linuxevk

SPI and I2C peripheral setup on MediaTek Genio

Aaron Angulo ·

SPI and I2C are the two most common buses for adding peripheral hardware to a Genio board: sensors, ADCs, display controllers, LoRa radios, and EEPROMs all use them. Both buses are exposed on the Raspberry Pi-compatible 40-pin HAT header on all Genio EVKs. Getting them working requires knowing the correct bus numbers, handling pin conflicts in the device tree, and verifying the connection before writing application code.

Key Insights

  • I2C buses are numbered differently between Genio 510/700 and 520/720 EVKs — the HAT header is always I2C-0 on 520/720, and shared I2C-0 on 510/700
  • SPI on 520/720 EVK requires a DTS patch — GPIO75 is shared with WiFi power enable; remapping to GPIO42 is mandatory before SPI1 works
  • SPI loopback test requires a physical short between MOSI and MISO pins — without it, spidev_test output looks like a failure
  • i2cdetect -y <bus> is the fastest way to confirm an I2C device is wired and responding before touching application code
  • /dev/spidev1.0 is the standard spidev node for SPI1 on the 520/720 EVK after the DTS patch is applied

I2C setup and testing

List all I2C adapters

i2cdetect -l

On the Genio 520/720 EVK (9 I2C adapters total):

BusConnected hardware
I2C-0Raspberry Pi HAT (SDA pin 3, SCL pin 5)
I2C-1Raspberry Pi HAT alternate (I2C-1 SDA/SCL)
I2C-2Current Monitor
I2C-4Charger IC, Buck regulator
I2C-5USB PD Controller
I2C-6Touch panel, SBU MUX
I2C-7CAM0 (CSI camera 0)
I2C-8CAM1 (CSI camera 1)

On the Genio 510/700 EVK (7 I2C adapters):

BusConnected hardware
I2C-0Touch CTP0 + Raspberry Pi HAT
I2C-1Charger IC, Buck IC, USB-C MUX
I2C-2Audio DTB + Raspberry Pi HAT
I2C-3Touch CTP1 + CSI1
I2C-4USB PD Controller
I2C-5CSI0
I2C-6CSI0 (additional)

Scan a bus for devices

# Scan I2C bus 0 — shows addresses as a hex grid
i2cdetect -y 0

Example output with a device at 0x48 (TMP102 temperature sensor):

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
...
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --

Read and write registers

# Read all registers of device at 0x48 on bus 0
i2cdump -y 0 0x48

# Read register 0x00 (temperature register on TMP102)
i2cget -f -y 0 0x48 0x00

# Write configuration to register 0x01
i2cset -f -y 0 0x48 0x01 0x60

The -f flag forces access even if the kernel driver has claimed the device. Use it cautiously in production — it bypasses the driver’s exclusive claim.

I2C in a Yocto image

The i2c-tools package provides i2cdetect, i2cget, i2cset, and i2cdump. Add to IMAGE_INSTALL:

IMAGE_INSTALL:append = " i2c-tools"

For kernel-level I2C access, ensure CONFIG_I2C_CHARDEV=y is set (it is in the default Genio kernel config).

SPI setup on Genio 520/720 EVK

The 520/720 EVK exposes SPI1 on the 40-pin HAT header. There is a pin conflict: GPIO75 is shared between SPI1 MOSI and the WiFi 3.3V power enable regulator. You must fix this in the device tree before SPI1 is usable.

HAT SPI pin mapping (520/720)

PinSignal
19SPI1 MOSI (GPIO75)
21SPI1 MISO (GPIO76)
23SPI1 SCLK (GPIO74)
24SPI1 CS (GPIO73)

DTS fix: remap WiFi power enable

File: arch/arm64/boot/dts/mediatek/mt8391-genio-720-evk.dts

Step 1: Move WiFi 3.3V enable from GPIO75 → GPIO42

pins_wcn_3v3_en: regulator-8 {
    regulator-name = "pins_wcn_3v3_en";
    regulator-min-microvolt = <3300000>;
    regulator-max-microvolt = <3300000>;
    gpio = <&pio 42 GPIO_ACTIVE_HIGH>;  /* was: 75 */
    enable-active-high;
    regulator-always-on;
};

Step 2: Update the pinctrl group to use GPIO42

pins-wifichip-wcn-3v3-en {
    gpio-hog;
    pinmux = <PINMUX_GPIO42__FUNC_GPIO42>,  /* was: GPIO75 */
             <PINMUX_GPIO79__FUNC_GPIO79>;
    output-high;
};

Step 3: Add SPI1 pingroup and enable the node

spi1_pins: spi1-pins {
    pins-spi-bus {
        pinmux = <PINMUX_GPIO73__FUNC_SPIM1_CSB>,
                 <PINMUX_GPIO74__FUNC_SPIM1_CLK>,
                 <PINMUX_GPIO75__FUNC_SPIM1_MO>;
        drive-strength = <MTK_DRIVE_6mA>;
        bias-disable;
    };
    pins-spi-mi {
        pinmux = <PINMUX_GPIO76__FUNC_SPIM1_MI>;
        bias-pull-down;
    };
};

&spi1 {
    pinctrl-0 = <&spi1_pins>;
    pinctrl-names = "default";
    #address-cells = <1>;
    #size-cells = <0>;
    status = "okay";

    spidev@0 {
        compatible = "mediatek,aiot-board";
        spi-max-frequency = <5000000>;
        reg = <0>;
    };
};

After applying and rebuilding, /dev/spidev1.0 appears on boot.

SPI testing

Critical first step: short MOSI (pin 19) to MISO (pin 21) on the HAT header. Without this physical loopback, RX data will not match TX and the test appears to fail.

# Load spidev module (should already be loaded)
modprobe spidev

# Verify device exists
ls /dev/spidev1.0

# Run loopback test at 400kHz
dd if=/dev/random of=test.bin bs=96 count=1
spidev_test -D /dev/spidev1.0 -s 400000 -i test.bin -v

Expected: TX and RX bytes match exactly. If they don’t, check the physical short between pins 19 and 21, and confirm the DTS patch is applied.

SPI setup on Genio 510/700 EVK

SPI-2 is exposed on the 40-pin HAT header. Unlike the 520/720, no WiFi pin conflict exists — but SPI-2 shares pins with CSI1 (camera 1).

Before enabling SPI-2: disconnect any CSI1 camera cable, then set jumpers:

JumperSet to positionSignal
J42072-3SPI2 MOSI
J42082-3SPI2 MISO
J42092-3SPI2 CLK
J42152-3SPI2 CS

After setting jumpers, the SPI device appears at /dev/spidev2.0.

Adding a real SPI device (example: MCP2515 CAN controller)

&spi1 {
    pinctrl-0 = <&spi1_pins>;
    pinctrl-names = "default";
    #address-cells = <1>;
    #size-cells = <0>;
    status = "okay";

    can0: mcp2515@0 {
        compatible = "microchip,mcp2515";
        reg = <0>;
        spi-max-frequency = <10000000>;
        clocks = <&mcp2515_osc>;
        interrupt-parent = <&pio>;
        interrupts = <110 IRQ_TYPE_EDGE_FALLING>;
    };
};

mcp2515_osc: mcp2515-oscillator {
    compatible = "fixed-clock";
    #clock-cells = <0>;
    clock-frequency = <16000000>;
};

Applying the DTS change in Yocto

Capture the change as a patch and apply it in your kernel bbappend, scoped to your specific machine:

# Generate patch from kernel source tree
git diff > mt8391-spi1-enable.patch

In your layer:

# recipes-kernel/linux/linux-mtk_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI:append:mt8391-genio-720-evk = " file://mt8391-spi1-enable.patch"

For custom carrier boards, author the SPI pinmux from scratch in your board DTS rather than patching the EVK DTS.

For device tree overlay patterns and the full Genio kernel bbappend workflow, see building a custom Yocto meta layer for Genio. For GMSL or MIPI camera bring-up on the same CSI connectors that share pins with these peripherals, see MIPI CSI camera driver setup on Genio.

FAQ

How do I detect I2C devices on MediaTek Genio?

Run i2cdetect -l to list all I2C adapters, then i2cdetect -y <bus> to scan a specific bus. On the Genio 520/720 EVK, I2C-0 is connected to the Raspberry Pi HAT header (SDA pin 3, SCL pin 5). On the Genio 510/700 EVK, I2C-0 is shared between Touch CTP0 and the Raspberry Pi HAT.

How do I enable SPI on the Genio 520/720 EVK?

GPIO75 is shared between SPI1 MOSI and the WiFi 3.3V power enable — you must remap the WiFi regulator from GPIO75 to GPIO42 in the DTS before SPI1 works. Without this DTS change, the WiFi module loses power when SPI is active.

What is the spidev_test command for verifying SPI on Genio?

Short MOSI (pin 19) to MISO (pin 21) on the HAT header first, then run: spidev_test -D /dev/spidev1.0 -s 400000 -v. TX and RX bytes should match exactly. Without the loopback short, RX data is garbage and the test appears to fail.

Does the Genio 510/700 EVK expose SPI on the Raspberry Pi HAT?

Yes, via SPI-2 on the 40-pin HAT header. SPI-2 pins are shared with CSI1 — disconnect any CSI1 camera cable before using SPI-2. Set jumpers J4207-J4209 and J4215 to position 2-3 to route SPI to the HAT pins.


MediaTek Genio Expert Support

Building on MediaTek Genio?

BSP bring-up, GStreamer pipelines, NeuroPilot integration, we've shipped it. Get unblocked fast. One call to scope it, fixed bid to deliver it.

Frequently Asked Questions

How do I detect I2C devices on MediaTek Genio?

Run 'i2cdetect -l' to list all I2C adapters, then 'i2cdetect -y <bus>' to scan a specific bus. On the Genio 520/720 EVK, I2C-0 is connected to the Raspberry Pi HAT header (SDA pin 3, SCL pin 5). On the Genio 510/700 EVK, I2C-0 is shared between Touch CTP0 and the Raspberry Pi HAT.

How do I enable SPI on the Genio 520/720 EVK?

The Genio 520/720 EVK exposes SPI1 on the Raspberry Pi HAT header (pins 19/21/23/24). GPIO75 is shared between SPI1 MOSI and the WiFi 3.3V power enable — you must remap the WiFi regulator from GPIO75 to GPIO42 in the DTS before SPI1 works. Without this DTS change, the WiFi module loses power when SPI is active.

What is the spidev_test command for verifying SPI on Genio?

Short MOSI (pin 19) to MISO (pin 21) on the HAT header first, then run: spidev_test -D /dev/spidev1.0 -s 400000 -v. TX and RX bytes should match exactly. Without the loopback short, RX data is garbage and the test appears to fail.

Does the Genio 510/700 EVK expose SPI on the Raspberry Pi HAT?

Yes, via SPI-2 on the 40-pin HAT header. However, SPI-2 pins are shared with CSI1 (the second camera connector). You must disconnect any CSI1 camera cable before using SPI-2. Set jumpers J4207-J4209 and J4215 to position 2-3 to route SPI to the HAT pins.

Aarón Angulo, Co-Founder & CEO at ProventusNova

Written by

Aarón Angulo

Co-Founder & CEO · ProventusNova

Obsessed with client outcomes. Aarón ensures every engagement delivers real results, on time, on scope, no exceptions.

Connect on LinkedIn