linuxOS_D21X/source/linux-5.10/drivers/i2c/busses/i2c-artinchip.h
2024-11-29 16:33:21 +08:00

213 lines
5.9 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only
*
* I2C driver of ArtInChip SoC
*
* Copyright (C) 2020-2023 ArtInChip Technology Co., Ltd.
* Authors: dwj <weijie.ding@artinchip.com>
*/
#include <linux/clk.h>
#include <linux/reset.h>
#include <linux/completion.h>
#include <linux/i2c.h>
#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