IIC_ACQUIRE_BUS(9) | Kernel Developer's Manual | IIC_ACQUIRE_BUS(9)

# NAME

`iic_acquire_bus`, `iic_release_bus`, `iic_exec`, `iic_smbus_write_byte`, `iic_smbus_read_byte`, `iic_smbus_receive_byte`, `iic_is_compatible` — Inter IC (I2C) bus

# SYNOPSIS

`#include <dev/i2c/i2cvar.h>`

int
`iic_acquire_bus`(i2c_tag_t ic, int flags);

int
`iic_release_bus`(i2c_tag_t ic, int flags);

int
`iic_exec`(i2c_tag_t ic, i2c_op_t op, i2c_addr_t addr, const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags);

int
`iic_smbus_write_byte`(i2c_tag_t ic, i2c_addr_t addr, uint8_t cmd, uint8_t data, int flags);

int
`iic_smbus_read_byte`(i2c_tag_t ic, i2c_addr_t addr, uint8_t cmd, uint8_t *datap, int flags);

int
`iic_smbus_receive_byte`(i2c_tag_t ic, i2c_addr_t addr, uint8_t *datap, int flags);

int
`iic_is_compatible`(const struct i2c_attach_args *ia, const char *name);

# DESCRIPTION

I2C is a two-wire bus developed by Philips used for connecting integrated circuits. It is commonly used for connecting devices such as EEPROMs, temperature sensors, fan controllers, real-time clocks, tuners, and other types of integrated circuits. The `iic` interface provides a means of communicating with I2C-connected devices. The System Management Bus, or SMBus, is a variant of the I2C bus with a simplified command protocol and some electrical differences.

# DATA TYPES

Drivers for devices attached to the I2C bus will make use of the following data types:

i2c_tag_t
  Controller tag for the I2C bus. This is a pointer to a struct i2c_controller, consisting of function pointers filled in by the I2C controller driver.
i2c_op_t
  I2C bus operation. The following I2C bus operations are defined:
  I2C_OP_READ
    Perform a read operation.
  I2C_OP_READ_WITH_STOP
    Perform a read operation and send a STOP condition on the I2C bus at the conclusion of the read.
  I2C_OP_WRITE
    Perform a write operation.
  I2C_OP_WRITE_WITH_STOP
    Perform a write operation and send a STOP condition on the I2C bus at the conclusion of the write.
i2c_addr_t
  I2C device address.
struct i2c_attach_args
  Devices are attached to an I2C bus using this structure. The structure is defined as follows:

      struct i2c_attach_args {
      	i2c_tag_t ia_tag;	/* controller */
      	i2c_addr_t ia_addr;	/* address of device */
      	int ia_size;		/* size (for EEPROMs) */
      	char *ia_name;		/* chip name */
      	size_t ia_namelen	/* length of name concatenation */
      	void *ia_cookie;	/* pass extra info from
      				   bus to dev */
      	void *ia_intr		/* interrupt info */
      	int ia_poll;		/* to force polling */
      };

# FUNCTIONS

The following functions comprise the API provided to drivers of I2C-connected devices:

`iic_acquire_bus`(ic, flags)
  Acquire an exclusive lock on the I2C bus. This is required since only one device may communicate on the I2C bus at a time. Drivers should acquire the bus lock, perform the I2C bus operations necessary, and then release the bus lock. Passing the I2C_F_POLL flag indicates to `iic_acquire_bus`() that sleeping is not permitted.
`iic_release_bus`(ic, flags)
  Release an exclusive lock on the I2C bus. If the I2C_F_POLL flag was passed to `iic_acquire_bus`(), it must also be passed to `iic_release_bus`().
`iic_exec`(ic, op, addr, cmdbuf, cmdlen, buf, len, flags);
  Perform a series of I2C transactions on the bus. `iic_exec`() initiates the operation by sending a START condition on the I2C bus and then transmitting the address of the target device along with the transaction type. If cmdlen is non-zero, the command pointed to by cmdbuf is then sent to the device. If buflen is non-zero, `iic_exec`() will then transmit or receive the data, as indicated by op. If op indicates a read operation, `iic_exec`() will send a REPEATED START before transferring the data. If op so indicates, a STOP condition will be sent on the I2C bus at the conclusion of the operation. Passing the I2C_F_POLL flag indicates to `iic_exec`() that sleeping is not permitted.
`iic_smbus_write_byte`(ic, addr, cmd, data, flags)
  Perform an SMBus WRITE BYTE operation. This is equivalent to I2C_OP_WRITE_WITH_STOP with cmdlen of 1 and len of 1.
`iic_smbus_read_byte`(ic, addr, cmd, datap, flags)
  Perform an SMBus READ BYTE operation. This is equivalent to I2C_OP_READ_WITH_STOP with cmdlen of 1 and len of 1.
`iic_smbus_receive_byte`(ic, addr, datap, flags)
  Perform an SMBus RECEIVE BYTE operation. This is equivalent to I2C_OP_READ_WITH_STOP with cmdlen of 0 and len of 1.
`iic_is_compatible`(ia, name)
  Test if the device is compatible with name.

# CONTROLLER INTERFACE

The I2C controller driver must fill in the function pointers of an i2c_controller structure, which is defined as follows:

    struct i2c_controller {
    	void	*ic_cookie;	/* controller private */

    	int	(*ic_acquire_bus)(void *, int);
    	void	(*ic_release_bus)(void *, int);

    	int	(*ic_exec)(void *, i2c_op_t, i2c_addr_t,
    		   const void *, size_t, void *, size_t, int);

    	int	(*ic_send_start)(void *, int);
    	int	(*ic_send_stop)(void *, int);
    	int	(*ic_initiate_xfer)(void *, i2c_addr_t, int);
    	int	(*ic_read_byte)(void *, uint8_t *, int);
    	int	(*ic_write_byte)(void *, uint8_t, int);
    };

The `(*ic_acquire_bus)`() and `(*ic_release_bus)`() functions must always be provided.

The controller driver may elect to provide an `(*ic_exec)`() function. This function is intended for use by automated controllers that do not provide manual control over I2C bus conditions such as START and STOP.

If the `(*ic_exec)`() function is not provided, the following 5 functions will be used by `iic_exec`() in order to execute the I2C bus operation:

`(*ic_send_start)`(cookie, flags)
  Send a START condition on the I2C bus. The I2C_F_POLL flag indicates that sleeping is not permitted.
`(*ic_send_stop)`(cookie, flags)
  Send a STOP condition on the I2C bus. The I2C_F_POLL flag indicates that sleeping is not permitted.
`(*ic_initiate_xfer)`(cookie, addr, flags)
  Initiate a transfer on the I2C bus by sending a START condition and then transmitting the I2C device address and transfer type. The I2C_F_READ flag indicates a read transfer; the lack of this flag indicates a write transfer. The I2C_F_POLL flag indicates that sleeping is not permitted. The error code `ETIMEDOUT` should be returned if a timeout that would indicate that the device is not present occurs.
`(*ic_read_byte)`(cookie, datap, flags)
  Read a byte from the I2C bus into the memory location referenced by datap. The I2C_F_LAST flag indicates that this is the final byte of the transfer, and that a NACK condition should be sent on the I2C bus following the transfer of the byte. The I2C_F_STOP flag indicates that a STOP condition should be sent on the I2C bus following the transfer of the byte. The I2C_F_POLL flag indicates that sleeping is not permitted.
`(*ic_write_byte)`(cookie, data, flags)
  Write the byte contained in data to the I2C bus. The I2C_F_STOP flag indicates that a STOP condition should be sent on the I2C bus following the transfer of the byte. The I2C_F_POLL flag indicates that sleeping is not permitted.

# SEE ALSO

iic(4)

# HISTORY

The `iic` API first appeared in NetBSD 2.0. OpenBSD support was added in OpenBSD 3.6.

# AUTHORS

The `iic` API was written by Steve C. Woodford and Jason R. Thorpe for NetBSD and then ported to OpenBSD by Alexander Yurchenko <grange@openbsd.org>.

February 9, 2022 | Debian