Zephyr Cadence IIC Driver Implementation
This page provides details on the implementation of the IIC Cadence Zephyr driver.
Zephyr - IIC Cadence Driver - File
Zephyr - IIC Cadence Device Tree
Iicps Node
ps_i2c1: i2c@ff030000 { compatible = "cdns,i2c-r1p14"; status = "okay"; #address-cells = <1>; #size-cells = <0>; reg = <0xff030000 0x1000>; interrupt-parent = <&gic>; interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL IRQ_DEFAULT_PRIORITY>; clocks = <&i2c_ref_clk>; };
cdns,i2c-r1p14.yaml
description: Cadence I2C controller version 1.4 compatible: "cdns,i2c-r1p14" include: [i2c-controller.yaml, reset-device.yaml] properties: reg: required: true clocks: required: true interrupts: required: true fifo-depth: type: int description: Size of the data FIFO in bytes. default: 16 enum: [2, 4, 8, 16, 32, 64, 128, 256]
Node properties are similar to Linux device tree
Zephyr - IIC Cadence Kconfig
Kconfig.cdns
config I2C_CADENCE bool "Cadence I2C driver" default y depends on DT_HAS_CDNS_I2C_R1P10_ENABLED || DT_HAS_CDNS_I2C_R1P14_ENABLED select EVENTS help Enable Cadence I2C driver.
Zephyr - I2C Driver - Common Framework Hooks
i2c.h
/* Driver APIs supported by Zephyr I2C Framework */ __subsystem struct i2c_driver_api { /* configuring the I2C bus settings */ i2c_api_configure_t configure; /* get the current I2C bus configuration */ i2c_api_get_config_t get_config; /* transferring data over the I2C bus */ i2c_api_full_io_t transfer; /* registering a target device */ i2c_api_target_register_t target_register; /* unregistering a target device */ i2c_api_target_unregister_t target_unregister; /* callback for I2C transfer completion */ i2c_api_transfer_cb_t transfer_cb; /* I/O device submission in real-time I/O */ i2c_api_iodev_submit iodev_submit; /* Recover I2C bus from error state */ i2c_api_recover_bus_t recover_bus; };
Zephyr - IIC Cadence Driver - Supported APIs
Driver - API
/* IIC Cadence Driver - Supported Driver APIs */ static const struct i2c_driver_api cdns_i2c_driver_api = { /* configure the I2C controller speed */ .configure = cdns_i2c_configure, /* Get configuration of I2C controller */ .get_config = cdns_i2c_get_config, /* Data transfers on the I2C bus (Master Mode) */ .transfer = cdns_i2c_master_transfer, #if defined(CONFIG_I2C_TARGET) /* registers the device as an I2C target (Slave Mode) */ .target_register = cdns_i2c_target_register, /* removes the device as an I2C target (Slave Mode) */ .target_unregister = cdns_i2c_target_unregister, #endif };
Zephyr - IIC Cadence Driver - Data Structures
Driver - Structures
/** * struct cdns_i2c_data - Cadence I2C device private data structure * @membase: Base address of the I2C device. * @ctrl_reg: Cached value of the control register. * @input_clk: Input clock to I2C controller. * @i2c_clk: Maximum I2C clock speed. * @i2c_config: Configuration of I2C settings. * @fifo_depth: The depth of the transfer FIFO. * @transfer_size: The maximum number of bytes in one transfer. * @bus_hold_flag: Flag used in repeated start for clearing HOLD bit. * @broken_hold_flag: Flag for broken hold bit usage in r1p10. * @xfer_done: Transfer complete event. * @err_status: Error status in Interrupt Status Register. * @p_msg: Message pointer for I2C communication. * @p_send_buf: Pointer to transmit buffer. * @p_recv_buf: Pointer to receive buffer. * @send_count: Number of bytes still expected to send. * @recv_count: Number of bytes still expected to receive. * @curr_recv_count: Number of bytes to be received in current transfer. * @bus_mutex: Mutex for bus access synchronization * @ctrl_reg_diva_divb: Value of fields DIV_A and DIV_B from CR register. * @slave: Registered slave instance. * @dev_mode: I2C operating role (master/slave). * @slave_state: I2C Slave state (idle/read/write). */ struct cdns_i2c_data { mem_addr_t membase; uint32_t ctrl_reg; uint32_t input_clk; uint32_t i2c_clk; uint32_t i2c_config; uint32_t fifo_depth; uint32_t transfer_size; uint32_t bus_hold_flag; uint32_t broken_hold_flag; struct k_event xfer_done; uint32_t err_status; struct i2c_msg *p_msg; uint8_t *p_send_buf; uint8_t *p_recv_buf; uint32_t send_count; uint32_t recv_count; uint32_t curr_recv_count; struct k_mutex bus_mutex; #if defined(CONFIG_I2C_TARGET) uint16_t ctrl_reg_diva_divb; struct i2c_target_config *slave; enum cdns_i2c_mode dev_mode; enum cdns_i2c_slave_state slave_state; #endif };
Zephyr - IIC Cadence Driver - Master Mode Example Flow
Zephyr - IIC Cadence Driver - Slave Mode Example Flow