In this lesson, you will learn how to verify and interact with I2C-connected hardware directly from the user space using the i2c-tools suite.
When you define a sensor in your Device Tree and the kernel driver probes it successfully, the Linux kernel exposes that bus to the user space via /dev/i2c-x nodes. However, when things don't behave as expected—such as a sensor returning unexpected data or failing to respond—you need a way to probe the bus without writing a custom C application. This is where i2c-tools comes in.
Probing the Bus
The primary utility is i2cdetect. It performs a quick scan of an I2C bus to see which addresses respond with an acknowledgment. If your device tree is configured correctly and the hardware is wired properly, you should see your device’s hexadecimal address appear in the grid:
# Scan I2C bus 1
i2cdetect -y 1
If the address shows up as UU, it means the kernel driver has already claimed that device, which is usually a sign that your Device Tree binding was successful. If it shows the hex address (e.g., 0x48), the device is alive but not currently bound to a driver.
Direct Register Interaction
Once you identify the address, you can perform raw reads and writes to specific device registers using i2cget and i2cset. This is invaluable for verifying sensor calibration or triggering an immediate measurement:
# Read 1 byte from register 0x00 of the device at address 0x48 on bus 1
i2cget -y 1 0x48 0x00
# Write 0x01 to register 0x02 to initiate a sensor start
i2cset -y 1 0x48 0x02 0x01
Using these utilities allows you to isolate hardware-level issues from software-driver issues. If you can read the "Who Am I" ID register of your sensor using i2cget, you know your physical I2C lines (SDA/SCL) are electrically sound and your kernel-space configuration is providing the necessary clock signals. If you cannot reach the device, you know to re-examine your Device Tree pinmux or physical connectivity before digging into kernel driver code.
Key Takeaway: The i2c-tools suite allows you to bridge the gap between kernel-space hardware definitions and user-space verification, providing a direct path to debug physical communication before verifying your driver logic.