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__ */
|