| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- #ifndef __MT_I2C_H__
- #define __MT_I2C_H__
- #include <linux/i2c.h>
- #include <linux/types.h>
- #if !defined(CONFIG_MTK_CLKMGR)
- #include <linux/clk.h>
- #endif /* !defined(CONFIG_MTK_CLKMGR) */
- #define I2CTAG "[I2C]"
- /* #define pr_fmt(fmt) "[I2C]"fmt */
- #define I2CLOG(fmt, arg...) pr_err(fmt, ##arg)
- #define I2CMSG(fmt, arg...) pr_debug(fmt, ##arg)
- #define I2CERR(fmt, arg...) pr_err("ERROR,%d: "fmt, __LINE__, ##arg)
- #define I2CFUC(fmt, arg...) pr_debug("%s\n", __func__)
- #define I2C_DRV_NAME "mt-i2c"
- #define I2C_NR 4
- #define I2C_DRIVER_IN_KERNEL
- #ifdef I2C_DRIVER_IN_KERNEL
- #define I2C_MB() mb() /* foo */
- /* #define I2C_DEBUG */
- #ifdef I2C_DEBUG
- #define I2C_BUG_ON(a) BUG_ON(a)
- #else
- #define I2C_BUG_ON(a)
- #endif
- #ifdef CONFIG_MTK_FPGA
- #define CONFIG_MT_I2C_FPGA_ENABLE
- #endif
- #if (defined(CONFIG_MT_I2C_FPGA_ENABLE))
- #define FPGA_CLOCK 12000 /* FPGA crystal frequency (KHz) */
- #define I2C_CLK_DIV 5 /* frequency divider */
- #define I2C_CLK_RATE (FPGA_CLOCK / I2C_CLK_DIV) /* kHz for FPGA I2C work frequency */
- #else
- #define I2C_CLK_RATE 13600
- #endif
- #else
- #define I2C_MB()
- #define I2C_BUG_ON(a)
- #define I2C_M_RD 0x0001
- #endif
- #define I2C_OK 0x0000
- #define EAGAIN_I2C 11 /* Try again */
- #define EINVAL_I2C 22 /* Invalid argument */
- #define EOPNOTSUPP_I2C 95 /* Operation not supported on transport endpoint */
- #define ETIMEDOUT_I2C 110 /* Connection timed out */
- #define EREMOTEIO_I2C 121 /* Remote I/O error */
- #define ENOTSUPP_I2C 524 /* Remote I/O error */
- #define I2C_WRITE_FAIL_HS_NACKERR 0xA013
- #define I2C_WRITE_FAIL_ACKERR 0xA014
- #define I2C_WRITE_FAIL_TIMEOUT 0xA015
- /* enum for different I2C pins */
- enum {
- I2C0 = 0,
- I2C1,
- I2C2,
- I2C3,
- I2C4,
- };
- /******************************************register operation***********************************/
- enum I2C_REGS_OFFSET {
- OFFSET_DATA_PORT = 0x0,
- OFFSET_SLAVE_ADDR = 0x04,
- OFFSET_INTR_MASK = 0x08,
- OFFSET_INTR_STAT = 0x0C,
- OFFSET_CONTROL = 0x10,
- OFFSET_TRANSFER_LEN = 0x14,
- OFFSET_TRANSAC_LEN = 0x18,
- OFFSET_DELAY_LEN = 0x1C,
- OFFSET_TIMING = 0x20,
- OFFSET_START = 0x24,
- OFFSET_EXT_CONF = 0x28,
- OFFSET_FIFO_STAT = 0x30,
- OFFSET_FIFO_THRESH = 0x34,
- OFFSET_FIFO_ADDR_CLR = 0x38,
- OFFSET_IO_CONFIG = 0x40,
- OFFSET_RSV_DEBUG = 0x44,
- OFFSET_HS = 0x48,
- OFFSET_SOFTRESET = 0x50,
- OFFSET_DCM_EN = 0x54,
- OFFSET_DEBUGSTAT = 0x64,
- OFFSET_DEBUGCTRL = 0x68,
- OFFSET_TRANSFER_LEN_AUX = 0x6C,
- };
- #define I2C_HS_NACKERR (1 << 2)
- #define I2C_ACKERR (1 << 1)
- #define I2C_TRANSAC_COMP (1 << 0)
- #define I2C_FIFO_SIZE 8
- #define MAX_ST_MODE_SPEED 100 /* khz */
- #define MAX_FS_MODE_SPEED 400 /* khz */
- #define MAX_HS_MODE_SPEED 3400 /* khz */
- #define MAX_DMA_TRANS_SIZE 65532 /* Max(65535) aligned to 4 bytes = 65532 */
- #define MAX_DMA_TRANS_NUM 256
- #define MAX_SAMPLE_CNT_DIV 8
- #define MAX_STEP_CNT_DIV 64
- #define MAX_HS_STEP_CNT_DIV 8
- #define DMA_ADDRESS_HIGH (0xC0000000)
- /* refer to AP_DMA register address */
- #define DMA_I2C_BASE_CH(id) (AP_DMA_BASE + 0x180 + (0x80 * (id)))
- #define DMA_I2C_BASE(id, base) ((base) + 0x180 + (0x80 * (id)))
- enum DMA_REGS_OFFSET {
- OFFSET_INT_FLAG = 0x0,
- OFFSET_INT_EN = 0x04,
- OFFSET_EN = 0x08,
- OFFSET_RST = 0x0C,
- OFFSET_STOP = 0x10,
- OFFSET_FLUSH = 0x14,
- OFFSET_CON = 0x18,
- OFFSET_TX_MEM_ADDR = 0x1C,
- OFFSET_RX_MEM_ADDR = 0x20,
- OFFSET_TX_LEN = 0x24,
- OFFSET_RX_LEN = 0x28,
- OFFSET_INT_BUF_SIZE = 0x38,
- OFFSET_DEBUG_STA = 0x50,
- };
- struct i2c_dma_info {
- unsigned long base;
- unsigned int int_flag;
- unsigned int int_en;
- unsigned int en;
- unsigned int rst;
- unsigned int stop;
- unsigned int flush;
- unsigned int con;
- unsigned int tx_mem_addr;
- unsigned int rx_mem_addr;
- unsigned int tx_len;
- unsigned int rx_len;
- unsigned int int_buf_size;
- unsigned int debug_sta;
- };
- enum i2c_trans_st_rs {
- I2C_TRANS_STOP = 0,
- I2C_TRANS_REPEATED_START,
- };
- enum {
- ST_MODE,
- FS_MODE,
- HS_MODE,
- };
- enum mt_trans_op {
- I2C_MASTER_NONE = 0,
- I2C_MASTER_WR = 1,
- I2C_MASTER_RD,
- I2C_MASTER_WRRD,
- };
- /* CONTROL */
- #define I2C_CONTROL_RS (0x1 << 1)
- #define I2C_CONTROL_DMA_EN (0x1 << 2)
- #define I2C_CONTROL_CLK_EXT_EN (0x1 << 3)
- #define I2C_CONTROL_DIR_CHANGE (0x1 << 4)
- #define I2C_CONTROL_ACKERR_DET_EN (0x1 << 5)
- #define I2C_CONTROL_TRANSFER_LEN_CHANGE (0x1 << 6)
- /***********************************end of register operation****************************************/
- /***********************************I2C Param********************************************************/
- struct mt_trans_data {
- u16 trans_num;
- u16 data_size;
- u16 trans_len;
- u16 trans_auxlen;
- };
- struct i2c_dma_buf {
- u8 *vaddr;
- dma_addr_t paddr;
- };
- struct mt_i2c_t {
- #ifdef I2C_DRIVER_IN_KERNEL
- /* ==========only used in kernel================ */
- struct i2c_adapter adap; /* i2c host adapter */
- struct device *dev; /* the device object of i2c host adapter */
- atomic_t trans_err; /* i2c transfer error */
- atomic_t trans_comp; /* i2c transfer completion */
- atomic_t trans_stop; /* i2c transfer stop */
- spinlock_t lock; /* for struct mt_i2c_t struct protection */
- wait_queue_head_t wait; /* i2c transfer wait queue */
- #endif
- /* ==========set in i2c probe============ */
- void __iomem *base; /* i2c base addr */
- u16 id;
- u32 irqnr; /* i2c interrupt number */
- u16 irq_stat; /* i2c interrupt status */
- u32 clk; /* host clock speed in khz */
- u32 pdn; /*clock number */
- /* ==========common data define============ */
- enum i2c_trans_st_rs st_rs;
- enum mt_trans_op op;
- void __iomem *pdmabase;
- u32 speed; /* The speed (khz) */
- u16 delay_len; /* number of half pulse between transfers in a trasaction */
- u32 msg_len; /* number of bytes for transaction */
- u8 *msg_buf; /* pointer to msg data */
- u8 addr; /* The address of the slave device, 7bit,the value include read/write bit. */
- u8 master_code; /* master code in HS mode */
- u8 mode; /* ST/FS/HS mode */
- /* ==========reserved function============ */
- u8 is_push_pull_enable; /* IO push-pull or open-drain */
- u8 is_clk_ext_disable; /* clk entend default enable */
- u8 is_dma_enabled; /* Transaction via DMA instead of 8-byte FIFO */
- u8 read_flag; /* read,write,read_write */
- bool dma_en;
- bool poll_en;
- bool pushpull; /* open drain */
- bool filter_msg; /* filter msg error log */
- bool i2c_3dcamera_flag; /* flag for 3dcamera */
- /* ==========define reg============ */
- u16 timing_reg;
- u16 high_speed_reg;
- u16 control_reg;
- u32 last_speed;
- u8 last_mode;
- u32 defaul_speed;
- struct mt_trans_data trans_data;
- struct i2c_dma_buf dma_buf;
- #if !defined(CONFIG_MTK_CLKMGR)
- struct clk *clk_main; /* main clock for i2c bus */
- struct clk *clk_dma; /* DMA clock for i2c via DMA */
- #endif /* !defined(CONFIG_MTK_CLKMGR) */
- };
- struct mt_i2c_msg {
- u16 addr; /* slave address */
- u16 flags;
- #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
- #define I2C_M_RD 0x0001 /* read data, from slave to master */
- #define I2C_M_STOP 0x8000 /* if I2C_FUNC_PROTOCOL_MANGLING */
- #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_NOSTART */
- #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
- #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
- #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
- #define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
- u16 len; /* msg length */
- u8 *buf; /* pointer to msg data */
- u32 timing;
- u32 ext_flag;
- };
- #define I2C_A_FILTER_MSG 0x8000 /* filer out error messages */
- #define I2C_A_CHANGE_TIMING 0x4000 /* change timing parameters */
- #define I2C_MASK_FLAG (0x00ff)
- #define I2C_DMA_FLAG (0xdead2000)
- #define I2C_WR_FLAG (0x1000)
- #define I2C_RS_FLAG (0x0800)
- #define I2C_HS_FLAG (0x0400)
- #define I2C_ENEXT_FLAG (0x0200)
- #define I2C_DISEXT_FLAG (0x0000)
- #define I2C_POLL_FLAG (0x4000)
- #define I2C_CH2_FLAG (0x8000)
- #define I2C_POLLING_FLAG (0x00000001)
- #define I2C_PUSHPULL_FLAG (0x00000002)
- #define I2C_3DCAMERA_FLAG (0x00000004)
- #define I2C_DIRECTION_FLAG (0x00000008)
- /* external API */
- extern void __iomem *spm_get_i2c_base(void);
- extern char *mt_i2c_bus_to_virt(unsigned long address);
- void _i2c_dump_info(struct mt_i2c_t *i2c);
- void i2c_writel(struct mt_i2c_t *i2c, u8 offset, u16 value);
- u32 i2c_readl(struct mt_i2c_t *i2c, u8 offset);
- #endif /* __MT_I2C_H__ */
|