Skip to content
Digital Rhyme

Using I2C on Linux

A command-line and architecture guide for working with I2C devices on a Linux machine: buses, adapters, addresses, wiring, scans, register reads, register writes, and what the tools are really doing.

Single-board computer wired to I2C breakout boards with logic analyzer traces

Architecture

I2C is a shared two-wire serial bus. Linux models each hardware controller as an i2c_adapter. Userspace sees adapters as character devices named /dev/i2c-N, where N is the Linux bus number.

CPU / SoC / USB adapter
  -> I2C controller driver
  -> Linux i2c_adapter
  -> /dev/i2c-0, /dev/i2c-1, ...
  -> devices at 7-bit addresses like 0x1a, 0x3c, 0x68

The bus number is not the device address. /dev/i2c-1 means adapter or bus number 1. A device address such as 0x68 is selected on that bus for one transaction.

ConceptLinux representationExample
Controller / adapter/dev/i2c-N/dev/i2c-1
Device address7-bit address on one bus0x3c
Register offsetDevice-specific internal address0x00, 0x10
Kernel clientstruct i2c_clientDriver-bound device

Physical Wiring

A basic I2C connection has four important lines: SCL, SDA, GND, and the device supply rail. SCL is the clock, SDA is data, and all devices on the same bus share those lines.

Linux board SCL ----+---- sensor SCL
                   +---- EEPROM SCL

Linux board SDA ----+---- sensor SDA
                   +---- EEPROM SDA

Linux board GND -------- all device grounds
Power rail 3.3V -------- devices that are 3.3V tolerant
  • I2C lines are open-drain/open-collector style and need pull-up resistors.
  • Many boards already have pull-ups; too many parallel pull-ups can make the bus too strong.
  • Voltage matters: do not connect a 1.8V-only device directly to a 3.3V bus without level shifting.
  • All devices on one bus need unique addresses unless an I2C mux or address-select pin separates them.
  • Long wires, high speed, and weak grounding are a classic recipe for intermittent failures.

Install Command-Line Tools

The common Linux package is i2c-tools.

# Debian / Ubuntu
sudo apt update
sudo apt install i2c-tools

# Fedora
sudo dnf install i2c-tools

# Arch
sudo pacman -S i2c-tools

You usually also need the kernel character-device interface:

sudo modprobe i2c-dev
ls /dev/i2c-*

On many embedded boards you may need to enable the controller in Device Tree, firmware settings, BIOS, or board configuration before it appears as /dev/i2c-N.

Find I2C Buses

Start with the high-level adapter list:

i2cdetect -l

Example output:

i2c-0   i2c        Synopsys DesignWare I2C adapter      I2C adapter
i2c-1   i2c        bcm2835 I2C adapter                  I2C adapter
i2c-3   smbus      SMBus I801 adapter at efa0           SMBus adapter

Other useful ways to inspect buses:

ls -l /dev/i2c-*
ls /sys/class/i2c-adapter/
for b in /sys/class/i2c-adapter/i2c-*; do
  echo "$b: $(cat "$b/name")"
done

SMBus adapters are often I2C-like but may not support every raw I2C transaction. Many PC motherboard management controllers show up as SMBus.

List Devices On A Bus

Scan a bus for responding 7-bit addresses:

sudo i2cdetect -y 1

Meaning: scan Linux bus 1, using -y to skip the interactive warning.

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- 3c -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
OutputMeaning
--No device acknowledged that address.
3cA device acknowledged address 0x3c.
UUA kernel driver already owns that address.
Scanning is not perfectly harmless. Some devices interpret scan probes as commands. Be cautious with power controllers, PMICs, battery gauges, DDR SPD EEPROMs, and live production hardware.

Read From Devices

Most register-style devices use a device address plus an internal register address. Read one byte:

sudo i2cget -y 1 0x68 0x00

Read a word using SMBus word access:

sudo i2cget -y 1 0x68 0x10 w

Dump a range of registers:

sudo i2cdump -y 1 0x68

Read a block, when the adapter and device support it:

sudo i2ctransfer -y 1 w1@0x68 0x00 r16

That i2ctransfer command writes one byte, 0x00, to select the starting register, then performs a repeated-start read of 16 bytes from address 0x68. It is often closer to what a kernel driver does than i2cget.

Write To Devices

Write one byte to register 0x10:

sudo i2cset -y 1 0x68 0x10 0x01

Write a word:

sudo i2cset -y 1 0x68 0x20 0x1234 w

Use i2ctransfer for explicit multi-byte writes:

sudo i2ctransfer -y 1 w3@0x68 0x20 0x12 0x34

Here w3@0x68 means one write message of three bytes to device 0x68. The first byte is commonly the register address, and the following bytes are data, but that is a device convention, not an I2C rule.

Writes can change modes, disable rails, erase EEPROM, reconfigure clocks, or wedge a device until power-cycle. Read the datasheet and avoid writes on unknown devices.

Sysfs View

The kernel's I2C model is visible under /sys/bus/i2c and /sys/class/i2c-adapter. Useful commands:

ls /sys/bus/i2c/devices
find /sys/bus/i2c/devices -maxdepth 2 -type f -name name -print -exec cat {} \;
readlink -f /sys/class/i2c-adapter/i2c-1/device

Device directories are often named like 1-0068, meaning bus 1, address 0x68. If a kernel driver is bound, you can usually see a driver symlink in that device directory.

ls -l /sys/bus/i2c/devices/1-0068/driver

Debug Checklist

  1. Confirm the adapter exists: i2cdetect -l.
  2. Confirm /dev/i2c-N exists: ls /dev/i2c-*.
  3. Load userspace access support: sudo modprobe i2c-dev.
  4. Check permissions: use sudo or add your user to the board's I2C group if configured.
  5. Check physical wiring: SCL, SDA, GND, voltage, pull-ups, connector orientation.
  6. Scan gently: sudo i2cdetect -y N.
  7. If you see UU, inspect the bound kernel driver instead of poking blindly.
  8. Use a logic analyzer if the bus is electrically suspicious.

Safety And Interpretation

  • An I2C address alone does not identify a chip. Many unrelated devices share addresses.
  • Some chips have multiple possible addresses controlled by address pins.
  • An absent scan result can mean no power, wrong bus, wrong voltage, missing pull-ups, held reset, or driver ownership.
  • i2cdump can have side effects on devices where reads clear interrupt/status bits.
  • SMBus word endianness may surprise you; always compare with the datasheet.
  • For production software, prefer a kernel driver or a careful userspace library over shelling out to tools.