STRUCT I2C_MSG(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

✨ struct i2c_msg(9) ✨

okay so bestie, welcome to the Kernel API Manual πŸ’– this is literally the whole vibe of an I2C transaction segment that begins with START. it's giving low-level but make it iconic πŸŽ€


🌸 NAME 🌸

struct i2c_msg β€” an I2C transaction segment beginning with START. no cap, that's the whole thing πŸ’…


πŸ¦‹ SYNOPSIS πŸ¦‹

struct i2c_msg {
    __u16 addr;
    __u16 flags;
  #define I2C_M_RD                0x0001  ;
  #define I2C_M_TEN               0x0010  ;
  #define I2C_M_DMA_SAFE          0x0200  ;
  #define I2C_M_RECV_LEN          0x0400  ;
  #define I2C_M_NO_RD_ACK         0x0800  ;
  #define I2C_M_IGNORE_NAK        0x1000  ;
  #define I2C_M_REV_DIR_ADDR      0x2000  ;
  #define I2C_M_NOSTART           0x4000  ;
  #define I2C_M_STOP              0x8000  ;
    __u16 len;
    __u8 *buf;
 };

like, look at all those defines β€” it's a whole aesthetic ✨


πŸŽ€ Members πŸŽ€

  • addr β€” the slave address, either 7 or 10 bits. when it's a 10 bit address, you must set I2C_M_TEN in flags and the adapter has to support I2C_FUNC_10BIT_ADDR. periodt.
  • flags β€” supported by all adapters: I2C_M_RD means read data (from slave to master). it's guaranteed to be 0x0001! if it's not set, the transaction is interpreted as write. iykyk.
  • len β€” number of data bytes in buf being read from or written to the I2C slave address. for read transactions where I2C_M_RECV_LEN is set, the caller guarantees that this buffer can hold up to I2C_SMBUS_BLOCK_MAX bytes in addition to the initial length byte sent by the slave (plus, if used, the SMBus PEC); and this value will be incremented by the number of block data bytes received. so plan ahead bestie 🫢
  • buf β€” the buffer into which data is read, or from which it's written. main character energy right there.

πŸ’– Description πŸ’–

optional: I2C_M_DMA_SAFE β€” the buffer of this message is DMA safe. makes only sense in kernelspace, because userspace buffers are copied anyway. no stress.

only if I2C_FUNC_10BIT_ADDR is set: I2C_M_TEN β€” this is a 10 bit chip address.

only if I2C_FUNC_SMBUS_READ_BLOCK_DATA is set: I2C_M_RECV_LEN β€” message length will be first received byte.

only if I2C_FUNC_NOSTART is set: I2C_M_NOSTART β€” skip repeated start sequence.

only if I2C_FUNC_PROTOCOL_MANGLING is set: I2C_M_NO_RD_ACK β€” in a read message, master ACK/NACK bit is skipped. I2C_M_IGNORE_NAK β€” treat NACK from client as ACK. I2C_M_REV_DIR_ADDR β€” toggles the Rd/Wr bit. I2C_M_STOP β€” force a STOP condition after the message.

an i2c_msg is the low level representation of one segment of an I2C transaction. it is visible to drivers in the i2c_transfer procedure, to userspace from i2c-dev, and to I2C adapter drivers through the i2c_adapter.master_xfer method. literally everywhere, it's famous πŸ’…

except when I2C "protocol mangling" is used, all I2C adapters implement the standard rules for I2C transactions. each transaction begins with a START. that is followed by the slave address, and a bit encoding read versus write. then follow all the data bytes, possibly including a byte with SMBus PEC. the transfer terminates with a NAK, or when all those bytes have been transferred and ACKed. if this is the last message in a group, it is followed by a STOP. otherwise it is followed by the next i2c_msg transaction segment, beginning with a (repeated) START. slay, that's the whole flow ✨

alternatively, when the adapter supports I2C_FUNC_PROTOCOL_MANGLING then passing certain flags may have changed those standard protocol behaviors. those flags are only for use with broken/nonconforming slaves, and with adapters which are known to support the specific mangling options they need.

⚠️ bestie warning: those protocol mangling flags are only for broken/nonconforming slaves and adapters known to support the specific mangling options they need. do not just yeet them around, fr fr.

🌈 SEE ALSO 🌈

Kernel file ./include/uapi/linux/i2c.h β€” go read it, it's giving lore πŸ“–


and that's the whole page, bestie! πŸŽ€ this came straight from the kernel api manual, source ./include/uapi/linux, dated October 2026. struct i2c_msg(9) β€” iconic, no notes πŸ’…βœ¨

πŸ“¦ where this page comes from