aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc/mediatek/i2c/mt6735/mt_i2c.h
blob: 61a68c4e1acfd060210510dcafd7c928d62fb3af (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
#ifndef __MT_I2C_H__
#define __MT_I2C_H__
#include <mach/mt_typedefs.h>

#define I2CTAG			"[mt-i2c]"
#define I2CLOG(fmt, arg...)	printk(KERN_ERR I2CTAG fmt, ##arg)
#define I2CMSG(fmt, arg...)	printk(fmt, ##arg)
#define I2CERR(fmt, arg...)	printk(KERN_ERR I2CTAG "ERROR,%d: "fmt, __LINE__, ##arg)
#define I2CFUC(fmt, arg...)	printk(I2CTAG "%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()
//#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 */
#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,
};

typedef enum {
	ST_MODE,
	FS_MODE,
	HS_MODE,
} I2C_SPEED_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;
};

typedef 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 mt_i2c 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 funtion============//
	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;
}mt_i2c;

//external API
void _i2c_dump_info(mt_i2c *i2c);
void i2c_writel(mt_i2c * i2c, U8 offset, U16 value);
U32 i2c_readl(mt_i2c * i2c, U8 offset);

#endif /* __MT_I2C_H__ */