/* SPDX-License-Identifier: GPL-2.0-only * * I2C driver of ArtInChip SoC * * Copyright (C) 2020-2023 ArtInChip Technology Co., Ltd. * Authors: dwj */ #include #include #include #include #define I2C_CTL 0x00 #define I2C_TAR 0x04 #define I2C_SAR 0x08 #define I2C_ACK_GEN_CALL 0x0C #define I2C_DATA_CMD 0x10 #define I2C_SS_SCL_HCNT 0x20 #define I2C_SS_SCL_LCNT 0x24 #define I2C_FS_SCL_HCNT 0x28 #define I2C_FS_SCL_LCNT 0x2C #define I2C_SDA_HOLD 0x30 #define I2C_SDA_SETUP 0x34 #define I2C_INTR_MASK 0x38 #define I2C_INTR_CLR 0x3C #define I2C_INTR_STAT 0x40 #define I2C_ENABLE 0x48 #define I2C_ENABLE_STATUS 0x4C #define I2C_STATUS 0x50 #define I2C_TX_ABRT_SOURCE 0x54 #define I2C_RX_TL 0x90 #define I2C_TX_TL 0x94 #define I2C_TXFLR 0x98 #define I2C_RXFLR 0x9C #define I2C_SCL_STUCK_TIMEOUT 0xA0 #define I2C_SDA_STUCK_TIMEOUT 0xA4 #define I2C_FS_SPIKELEN 0xB0 #define I2C_VERSION 0xFC #define I2C_CTL_10BIT_SELECT_MASTER BIT(2) #define I2C_CTL_10BIT_SELECT_SLAVE BIT(3) #define I2C_CTL_SPEED_MODE_SELECT_MASK GENMASK(4, 5) #define I2C_CTL_SPEED_MODE_SS (0x1 << 4) #define I2C_CTL_SPEED_MODE_FS (0x2 << 4) #define I2C_CTL_RESTART_ENABLE BIT(6) #define I2C_CTL_STOP_DET_IFADDR BIT(7) #define I2C_CTL_TX_EMPTY_CTL BIT(8) #define I2C_CTL_RX_FIFO_FULL_HLD BIT(9) #define I2C_CTL_BUS_CLEAR_FEATURE BIT(10) #define I2C_TAR_ADDR GENMASK(0, 9) #define I2C_TAR_START_BYTE BIT(10) #define I2C_TAR_GEN_CALL_CTL BIT(11) #define I2C_DATA_CMD_DAT GENMASK(0, 7) #define I2C_DATA_CMD_READ BIT(8) #define I2C_DATA_CMD_STOP BIT(9) #define I2C_DATA_CMD_RESTART BIT(10) #define I2C_SDA_TX_HOLD GENMASK(0, 15) #define I2C_SDA_RX_HOLD GENMASK(16, 23) #define I2C_INTR_RX_UNDER BIT(0) #define I2C_INTR_RX_OVER BIT(1) #define I2C_INTR_RX_FULL BIT(2) #define I2C_INTR_TX_OVER BIT(3) #define I2C_INTR_TX_EMPTY BIT(4) #define I2C_INTR_RD_REQ BIT(5) #define I2C_INTR_TX_ABRT BIT(6) #define I2C_INTR_RX_DONE BIT(7) #define I2C_INTR_ACTIVITY BIT(8) #define I2C_INTR_STOP_DET BIT(9) #define I2C_INTR_START_DET BIT(10) #define I2C_INTR_GEN_CALL BIT(11) #define I2C_INTR_MASTER_ON_HOLD BIT(13) #define I2C_INTR_SCL_STUCK_AT_LOW BIT(14) #define I2C_ENABLE_BIT BIT(0) #define I2C_ENABLE_ABORT BIT(1) #define I2C_TX_CMD_BLOCK BIT(2) #define I2C_SDA_STUCK_RECOVERY_ENABLE BIT(3) #define I2C_STATUS_ACTIVITY BIT(0) #define ABRT_7BIT_ADDR_NOACK 0 #define ABRT_10BIT_ADDR1_NOACK 1 #define ABRT_10BIT_ADDR2_NOACK 2 #define ABRT_TXDATA_NOACK 3 #define ABRT_GCALL_NOACK 4 #define ABRT_GCALL_READ 5 #define ABRT_SBYTE_ACKDET 7 #define ABRT_SBYTE_NORSTRT 9 #define ABRT_10BIT_RD_NORSTRT 10 #define ABRT_MASTER_DIS 11 #define ABRT_LOST 12 #define ABRT_SLVFLUSH_TXFIFO 13 #define ABRT_SLV_ARBLOST 14 #define ABRT_SLVRD_INTX 15 #define ABRT_USER_ABRT 16 #define ABRT_SDA_STUCK_AT_LOW 17 #define I2C_ABRT_7BIT_ADDR_NOACK BIT(0) #define I2C_ABRT_10BIT_ADDR1_NOACK BIT(1) #define I2C_ABRT_10BIT_ADDR2_NOACK BIT(2) #define I2C_ABRT_TXDATA_NOACK BIT(3) #define I2C_ABRT_GCALL_NOACK BIT(4) #define I2C_ABRT_GCALL_READ BIT(5) #define I2C_ABRT_SBYTE_ACKDET BIT(7) #define I2C_ABRT_SBYTE_NORSTRT BIT(9) #define I2C_ABRT_10BIT_RD_NORSTRT BIT(10) #define I2C_ABRT_MASTER_DIS BIT(11) #define I2C_ABRT_LOST BIT(12) #define I2C_ABRT_SLVFLUSH_TXFIFO BIT(13) #define I2C_ABRT_SLV_ARBLOST BIT(14) #define I2C_ABRT_SLVRD_INTX BIT(15) #define I2C_ABRT_USER_ABRT BIT(16) #define I2C_ABRT_SDA_STUCK_AT_LOW BIT(17) #define I2C_TX_ABRT_NOACK (I2C_ABRT_7BIT_ADDR_NOACK |\ I2C_ABRT_10BIT_ADDR1_NOACK |\ I2C_ABRT_10BIT_ADDR2_NOACK |\ I2C_ABRT_TXDATA_NOACK |\ I2C_ABRT_GCALL_NOACK) #define I2C_ENABLE_MASTER_DISABLE_SLAVE (0x3) #define I2C_ENABLE_SLAVE_DISABLE_MASTER (0) #define I2C_FIFO_DEPTH 8 #define I2C_TXFIFO_THRESHOLD (I2C_FIFO_DEPTH / 2 - 1) #define I2C_RXFIFO_THRESHOLD 0 #define I2C_INTR_DEFAULT_MASK (I2C_INTR_RX_FULL |\ I2C_INTR_TX_ABRT) #define I2C_INTR_MASTER_MASK (I2C_INTR_DEFAULT_MASK |\ I2C_INTR_RX_OVER |\ I2C_INTR_RX_UNDER |\ I2C_INTR_TX_OVER |\ I2C_INTR_TX_EMPTY |\ I2C_INTR_STOP_DET) #define I2C_INTR_SLAVE_MASK (I2C_INTR_DEFAULT_MASK |\ I2C_INTR_START_DET |\ I2C_INTR_RX_DONE |\ I2C_INTR_RX_UNDER |\ I2C_INTR_RD_REQ) #define I2C_INTR_ERROR_TX_RX 0x0001 #define I2C_INTR_ERROR_ABRT 0x0002 enum aic_i2c_speed { I2C_SPEED_STD = 1, I2C_SPEED_FAST = 2, }; /* * Indicate one message status */ enum aic_msg_status { MSG_IDLE = 0, MSG_IN_PROCESS = 1, }; struct aic_i2c_dev { struct device *dev; void __iomem *base; struct i2c_adapter adap; struct completion cmd_complete; struct clk *clk; struct reset_control *rst; int irq; enum aic_i2c_speed i2c_speed; u32 target_rate; u16 scl_hcnt; u16 scl_lcnt; u32 abort_source; struct i2c_msg *msg; enum aic_msg_status msg_status; int buf_write_idx; int buf_read_idx; bool is_first_message; bool is_last_message; int msg_err; struct i2c_timings timings; u32 master_cfg; u32 slave_cfg; struct i2c_client *slave; }; u32 i2c_readl(struct aic_i2c_dev *i2c_dev, int offset); void i2c_writel(struct aic_i2c_dev *i2c_dev, u32 val, int offset); void i2c_disable_interrupts(struct aic_i2c_dev *i2c_dev); void i2c_enable(struct aic_i2c_dev *i2c_dev); void i2c_disable(struct aic_i2c_dev *i2c_dev); int i2c_scl_cnt(u32 ic_clk, enum aic_i2c_speed aic_speed, u16 *hcnt, u16 *lcnt); int i2c_handle_tx_abort(struct aic_i2c_dev *i2c_dev); int i2c_wait_bus_free(struct aic_i2c_dev *i2c_dev); extern int i2c_probe_master(struct aic_i2c_dev *i2c_dev); #if IS_ENABLED(CONFIG_I2C_ARTINCHIP_SLAVE) extern int i2c_probe_slave(struct aic_i2c_dev *i2c_dev); #else static inline int i2c_probe_slave(struct aic_i2c_dev *i2c_dev) { return -EINVAL; } #endif