]>
Commit | Line | Data |
---|---|---|
1ab52cf9 | 1 | /* |
a0e06ea6 | 2 | * Synopsys DesignWare I2C adapter driver (master only). |
1ab52cf9 BS |
3 | * |
4 | * Based on the TI DAVINCI I2C adapter driver. | |
5 | * | |
6 | * Copyright (C) 2006 Texas Instruments. | |
7 | * Copyright (C) 2007 MontaVista Software Inc. | |
8 | * Copyright (C) 2009 Provigent Ltd. | |
9 | * | |
10 | * ---------------------------------------------------------------------------- | |
11 | * | |
12 | * This program is free software; you can redistribute it and/or modify | |
13 | * it under the terms of the GNU General Public License as published by | |
14 | * the Free Software Foundation; either version 2 of the License, or | |
15 | * (at your option) any later version. | |
16 | * | |
17 | * This program is distributed in the hope that it will be useful, | |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
20 | * GNU General Public License for more details. | |
21 | * | |
22 | * You should have received a copy of the GNU General Public License | |
23 | * along with this program; if not, write to the Free Software | |
24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
25 | * ---------------------------------------------------------------------------- | |
26 | * | |
27 | */ | |
28 | #include <linux/kernel.h> | |
29 | #include <linux/module.h> | |
30 | #include <linux/delay.h> | |
31 | #include <linux/i2c.h> | |
32 | #include <linux/clk.h> | |
33 | #include <linux/errno.h> | |
34 | #include <linux/sched.h> | |
35 | #include <linux/err.h> | |
36 | #include <linux/interrupt.h> | |
37 | #include <linux/platform_device.h> | |
38 | #include <linux/io.h> | |
5a0e3ad6 | 39 | #include <linux/slab.h> |
18c4089e | 40 | #include <linux/swab.h> |
1ab52cf9 BS |
41 | |
42 | /* | |
43 | * Registers offset | |
44 | */ | |
45 | #define DW_IC_CON 0x0 | |
46 | #define DW_IC_TAR 0x4 | |
47 | #define DW_IC_DATA_CMD 0x10 | |
48 | #define DW_IC_SS_SCL_HCNT 0x14 | |
49 | #define DW_IC_SS_SCL_LCNT 0x18 | |
50 | #define DW_IC_FS_SCL_HCNT 0x1c | |
51 | #define DW_IC_FS_SCL_LCNT 0x20 | |
52 | #define DW_IC_INTR_STAT 0x2c | |
53 | #define DW_IC_INTR_MASK 0x30 | |
e28000a3 | 54 | #define DW_IC_RAW_INTR_STAT 0x34 |
4cb6d1d6 SK |
55 | #define DW_IC_RX_TL 0x38 |
56 | #define DW_IC_TX_TL 0x3c | |
1ab52cf9 | 57 | #define DW_IC_CLR_INTR 0x40 |
e28000a3 SK |
58 | #define DW_IC_CLR_RX_UNDER 0x44 |
59 | #define DW_IC_CLR_RX_OVER 0x48 | |
60 | #define DW_IC_CLR_TX_OVER 0x4c | |
61 | #define DW_IC_CLR_RD_REQ 0x50 | |
62 | #define DW_IC_CLR_TX_ABRT 0x54 | |
63 | #define DW_IC_CLR_RX_DONE 0x58 | |
64 | #define DW_IC_CLR_ACTIVITY 0x5c | |
65 | #define DW_IC_CLR_STOP_DET 0x60 | |
66 | #define DW_IC_CLR_START_DET 0x64 | |
67 | #define DW_IC_CLR_GEN_CALL 0x68 | |
1ab52cf9 BS |
68 | #define DW_IC_ENABLE 0x6c |
69 | #define DW_IC_STATUS 0x70 | |
70 | #define DW_IC_TXFLR 0x74 | |
71 | #define DW_IC_RXFLR 0x78 | |
72 | #define DW_IC_COMP_PARAM_1 0xf4 | |
4ff895bc | 73 | #define DW_IC_COMP_TYPE 0xfc |
1ab52cf9 BS |
74 | #define DW_IC_TX_ABRT_SOURCE 0x80 |
75 | ||
76 | #define DW_IC_CON_MASTER 0x1 | |
77 | #define DW_IC_CON_SPEED_STD 0x2 | |
78 | #define DW_IC_CON_SPEED_FAST 0x4 | |
79 | #define DW_IC_CON_10BITADDR_MASTER 0x10 | |
80 | #define DW_IC_CON_RESTART_EN 0x20 | |
81 | #define DW_IC_CON_SLAVE_DISABLE 0x40 | |
82 | ||
e28000a3 SK |
83 | #define DW_IC_INTR_RX_UNDER 0x001 |
84 | #define DW_IC_INTR_RX_OVER 0x002 | |
85 | #define DW_IC_INTR_RX_FULL 0x004 | |
86 | #define DW_IC_INTR_TX_OVER 0x008 | |
87 | #define DW_IC_INTR_TX_EMPTY 0x010 | |
88 | #define DW_IC_INTR_RD_REQ 0x020 | |
89 | #define DW_IC_INTR_TX_ABRT 0x040 | |
90 | #define DW_IC_INTR_RX_DONE 0x080 | |
91 | #define DW_IC_INTR_ACTIVITY 0x100 | |
1ab52cf9 | 92 | #define DW_IC_INTR_STOP_DET 0x200 |
e28000a3 SK |
93 | #define DW_IC_INTR_START_DET 0x400 |
94 | #define DW_IC_INTR_GEN_CALL 0x800 | |
1ab52cf9 | 95 | |
201d6a70 SK |
96 | #define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \ |
97 | DW_IC_INTR_TX_EMPTY | \ | |
98 | DW_IC_INTR_TX_ABRT | \ | |
99 | DW_IC_INTR_STOP_DET) | |
100 | ||
1ab52cf9 BS |
101 | #define DW_IC_STATUS_ACTIVITY 0x1 |
102 | ||
103 | #define DW_IC_ERR_TX_ABRT 0x1 | |
104 | ||
105 | /* | |
106 | * status codes | |
107 | */ | |
108 | #define STATUS_IDLE 0x0 | |
109 | #define STATUS_WRITE_IN_PROGRESS 0x1 | |
110 | #define STATUS_READ_IN_PROGRESS 0x2 | |
111 | ||
112 | #define TIMEOUT 20 /* ms */ | |
113 | ||
114 | /* | |
115 | * hardware abort codes from the DW_IC_TX_ABRT_SOURCE register | |
116 | * | |
117 | * only expected abort codes are listed here | |
118 | * refer to the datasheet for the full list | |
119 | */ | |
120 | #define ABRT_7B_ADDR_NOACK 0 | |
121 | #define ABRT_10ADDR1_NOACK 1 | |
122 | #define ABRT_10ADDR2_NOACK 2 | |
123 | #define ABRT_TXDATA_NOACK 3 | |
124 | #define ABRT_GCALL_NOACK 4 | |
125 | #define ABRT_GCALL_READ 5 | |
126 | #define ABRT_SBYTE_ACKDET 7 | |
127 | #define ABRT_SBYTE_NORSTRT 9 | |
128 | #define ABRT_10B_RD_NORSTRT 10 | |
ce6eb574 | 129 | #define ABRT_MASTER_DIS 11 |
1ab52cf9 BS |
130 | #define ARB_LOST 12 |
131 | ||
ce6eb574 SK |
132 | #define DW_IC_TX_ABRT_7B_ADDR_NOACK (1UL << ABRT_7B_ADDR_NOACK) |
133 | #define DW_IC_TX_ABRT_10ADDR1_NOACK (1UL << ABRT_10ADDR1_NOACK) | |
134 | #define DW_IC_TX_ABRT_10ADDR2_NOACK (1UL << ABRT_10ADDR2_NOACK) | |
135 | #define DW_IC_TX_ABRT_TXDATA_NOACK (1UL << ABRT_TXDATA_NOACK) | |
136 | #define DW_IC_TX_ABRT_GCALL_NOACK (1UL << ABRT_GCALL_NOACK) | |
137 | #define DW_IC_TX_ABRT_GCALL_READ (1UL << ABRT_GCALL_READ) | |
138 | #define DW_IC_TX_ABRT_SBYTE_ACKDET (1UL << ABRT_SBYTE_ACKDET) | |
139 | #define DW_IC_TX_ABRT_SBYTE_NORSTRT (1UL << ABRT_SBYTE_NORSTRT) | |
140 | #define DW_IC_TX_ABRT_10B_RD_NORSTRT (1UL << ABRT_10B_RD_NORSTRT) | |
141 | #define DW_IC_TX_ABRT_MASTER_DIS (1UL << ABRT_MASTER_DIS) | |
142 | #define DW_IC_TX_ARB_LOST (1UL << ARB_LOST) | |
143 | ||
144 | #define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \ | |
145 | DW_IC_TX_ABRT_10ADDR1_NOACK | \ | |
146 | DW_IC_TX_ABRT_10ADDR2_NOACK | \ | |
147 | DW_IC_TX_ABRT_TXDATA_NOACK | \ | |
148 | DW_IC_TX_ABRT_GCALL_NOACK) | |
149 | ||
1ab52cf9 | 150 | static char *abort_sources[] = { |
a0e06ea6 | 151 | [ABRT_7B_ADDR_NOACK] = |
1ab52cf9 | 152 | "slave address not acknowledged (7bit mode)", |
a0e06ea6 | 153 | [ABRT_10ADDR1_NOACK] = |
1ab52cf9 | 154 | "first address byte not acknowledged (10bit mode)", |
a0e06ea6 | 155 | [ABRT_10ADDR2_NOACK] = |
1ab52cf9 | 156 | "second address byte not acknowledged (10bit mode)", |
a0e06ea6 | 157 | [ABRT_TXDATA_NOACK] = |
1ab52cf9 | 158 | "data not acknowledged", |
a0e06ea6 | 159 | [ABRT_GCALL_NOACK] = |
1ab52cf9 | 160 | "no acknowledgement for a general call", |
a0e06ea6 | 161 | [ABRT_GCALL_READ] = |
1ab52cf9 | 162 | "read after general call", |
a0e06ea6 | 163 | [ABRT_SBYTE_ACKDET] = |
1ab52cf9 | 164 | "start byte acknowledged", |
a0e06ea6 | 165 | [ABRT_SBYTE_NORSTRT] = |
1ab52cf9 | 166 | "trying to send start byte when restart is disabled", |
a0e06ea6 | 167 | [ABRT_10B_RD_NORSTRT] = |
1ab52cf9 | 168 | "trying to read when restart is disabled (10bit mode)", |
a0e06ea6 | 169 | [ABRT_MASTER_DIS] = |
1ab52cf9 | 170 | "trying to use disabled adapter", |
a0e06ea6 | 171 | [ARB_LOST] = |
1ab52cf9 BS |
172 | "lost arbitration", |
173 | }; | |
174 | ||
175 | /** | |
176 | * struct dw_i2c_dev - private i2c-designware data | |
177 | * @dev: driver model device node | |
178 | * @base: IO registers pointer | |
179 | * @cmd_complete: tx completion indicator | |
1ab52cf9 BS |
180 | * @lock: protect this struct and IO registers |
181 | * @clk: input reference clock | |
182 | * @cmd_err: run time hadware error code | |
25985edc | 183 | * @msgs: points to an array of messages currently being transferred |
1ab52cf9 BS |
184 | * @msgs_num: the number of elements in msgs |
185 | * @msg_write_idx: the element index of the current tx message in the msgs | |
186 | * array | |
187 | * @tx_buf_len: the length of the current tx buffer | |
188 | * @tx_buf: the current tx buffer | |
189 | * @msg_read_idx: the element index of the current rx message in the msgs | |
190 | * array | |
191 | * @rx_buf_len: the length of the current rx buffer | |
192 | * @rx_buf: the current rx buffer | |
193 | * @msg_err: error status of the current transfer | |
194 | * @status: i2c master status, one of STATUS_* | |
195 | * @abort_source: copy of the TX_ABRT_SOURCE register | |
196 | * @irq: interrupt number for the i2c master | |
18c4089e | 197 | * @swab: true if the instantiated IP is of different endianess |
1ab52cf9 BS |
198 | * @adapter: i2c subsystem adapter node |
199 | * @tx_fifo_depth: depth of the hardware tx fifo | |
200 | * @rx_fifo_depth: depth of the hardware rx fifo | |
201 | */ | |
202 | struct dw_i2c_dev { | |
203 | struct device *dev; | |
204 | void __iomem *base; | |
205 | struct completion cmd_complete; | |
1ab52cf9 BS |
206 | struct mutex lock; |
207 | struct clk *clk; | |
208 | int cmd_err; | |
209 | struct i2c_msg *msgs; | |
210 | int msgs_num; | |
211 | int msg_write_idx; | |
ed5e1dd5 | 212 | u32 tx_buf_len; |
1ab52cf9 BS |
213 | u8 *tx_buf; |
214 | int msg_read_idx; | |
ed5e1dd5 | 215 | u32 rx_buf_len; |
1ab52cf9 BS |
216 | u8 *rx_buf; |
217 | int msg_err; | |
218 | unsigned int status; | |
ed5e1dd5 | 219 | u32 abort_source; |
1ab52cf9 | 220 | int irq; |
18c4089e | 221 | int swab; |
1ab52cf9 BS |
222 | struct i2c_adapter adapter; |
223 | unsigned int tx_fifo_depth; | |
224 | unsigned int rx_fifo_depth; | |
225 | }; | |
226 | ||
7f279601 JHD |
227 | static u32 dw_readl(struct dw_i2c_dev *dev, int offset) |
228 | { | |
18c4089e JHD |
229 | u32 value = readl(dev->base + offset); |
230 | ||
231 | if (dev->swab) | |
232 | return swab32(value); | |
233 | else | |
234 | return value; | |
7f279601 JHD |
235 | } |
236 | ||
237 | static void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset) | |
238 | { | |
18c4089e JHD |
239 | if (dev->swab) |
240 | b = swab32(b); | |
241 | ||
7f279601 JHD |
242 | writel(b, dev->base + offset); |
243 | } | |
244 | ||
d60c7e81 SK |
245 | static u32 |
246 | i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) | |
247 | { | |
248 | /* | |
249 | * DesignWare I2C core doesn't seem to have solid strategy to meet | |
250 | * the tHD;STA timing spec. Configuring _HCNT based on tHIGH spec | |
251 | * will result in violation of the tHD;STA spec. | |
252 | */ | |
253 | if (cond) | |
254 | /* | |
255 | * Conditional expression: | |
256 | * | |
257 | * IC_[FS]S_SCL_HCNT + (1+4+3) >= IC_CLK * tHIGH | |
258 | * | |
259 | * This is based on the DW manuals, and represents an ideal | |
260 | * configuration. The resulting I2C bus speed will be | |
261 | * faster than any of the others. | |
262 | * | |
263 | * If your hardware is free from tHD;STA issue, try this one. | |
264 | */ | |
265 | return (ic_clk * tSYMBOL + 5000) / 10000 - 8 + offset; | |
266 | else | |
267 | /* | |
268 | * Conditional expression: | |
269 | * | |
270 | * IC_[FS]S_SCL_HCNT + 3 >= IC_CLK * (tHD;STA + tf) | |
271 | * | |
272 | * This is just experimental rule; the tHD;STA period turned | |
273 | * out to be proportinal to (_HCNT + 3). With this setting, | |
274 | * we could meet both tHIGH and tHD;STA timing specs. | |
275 | * | |
276 | * If unsure, you'd better to take this alternative. | |
277 | * | |
278 | * The reason why we need to take into account "tf" here, | |
279 | * is the same as described in i2c_dw_scl_lcnt(). | |
280 | */ | |
281 | return (ic_clk * (tSYMBOL + tf) + 5000) / 10000 - 3 + offset; | |
282 | } | |
283 | ||
284 | static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) | |
285 | { | |
286 | /* | |
287 | * Conditional expression: | |
288 | * | |
289 | * IC_[FS]S_SCL_LCNT + 1 >= IC_CLK * (tLOW + tf) | |
290 | * | |
291 | * DW I2C core starts counting the SCL CNTs for the LOW period | |
292 | * of the SCL clock (tLOW) as soon as it pulls the SCL line. | |
293 | * In order to meet the tLOW timing spec, we need to take into | |
294 | * account the fall time of SCL signal (tf). Default tf value | |
295 | * should be 0.3 us, for safety. | |
296 | */ | |
297 | return ((ic_clk * (tLOW + tf) + 5000) / 10000) - 1 + offset; | |
298 | } | |
299 | ||
1ab52cf9 BS |
300 | /** |
301 | * i2c_dw_init() - initialize the designware i2c master hardware | |
302 | * @dev: device private data | |
303 | * | |
304 | * This functions configures and enables the I2C master. | |
305 | * This function is called during I2C init function, and in case of timeout at | |
306 | * run time. | |
307 | */ | |
308 | static void i2c_dw_init(struct dw_i2c_dev *dev) | |
309 | { | |
310 | u32 input_clock_khz = clk_get_rate(dev->clk) / 1000; | |
d60c7e81 | 311 | u32 ic_con, hcnt, lcnt; |
1ab52cf9 BS |
312 | |
313 | /* Disable the adapter */ | |
7f279601 | 314 | dw_writel(dev, 0, DW_IC_ENABLE); |
1ab52cf9 BS |
315 | |
316 | /* set standard and fast speed deviders for high/low periods */ | |
d60c7e81 SK |
317 | |
318 | /* Standard-mode */ | |
319 | hcnt = i2c_dw_scl_hcnt(input_clock_khz, | |
320 | 40, /* tHD;STA = tHIGH = 4.0 us */ | |
321 | 3, /* tf = 0.3 us */ | |
322 | 0, /* 0: DW default, 1: Ideal */ | |
323 | 0); /* No offset */ | |
324 | lcnt = i2c_dw_scl_lcnt(input_clock_khz, | |
325 | 47, /* tLOW = 4.7 us */ | |
326 | 3, /* tf = 0.3 us */ | |
327 | 0); /* No offset */ | |
7f279601 JHD |
328 | dw_writel(dev, hcnt, DW_IC_SS_SCL_HCNT); |
329 | dw_writel(dev, lcnt, DW_IC_SS_SCL_LCNT); | |
d60c7e81 SK |
330 | dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt); |
331 | ||
332 | /* Fast-mode */ | |
333 | hcnt = i2c_dw_scl_hcnt(input_clock_khz, | |
334 | 6, /* tHD;STA = tHIGH = 0.6 us */ | |
335 | 3, /* tf = 0.3 us */ | |
336 | 0, /* 0: DW default, 1: Ideal */ | |
337 | 0); /* No offset */ | |
338 | lcnt = i2c_dw_scl_lcnt(input_clock_khz, | |
339 | 13, /* tLOW = 1.3 us */ | |
340 | 3, /* tf = 0.3 us */ | |
341 | 0); /* No offset */ | |
7f279601 JHD |
342 | dw_writel(dev, hcnt, DW_IC_FS_SCL_HCNT); |
343 | dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT); | |
d60c7e81 | 344 | dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt); |
1ab52cf9 | 345 | |
4cb6d1d6 | 346 | /* Configure Tx/Rx FIFO threshold levels */ |
7f279601 JHD |
347 | dw_writel(dev, dev->tx_fifo_depth - 1, DW_IC_TX_TL); |
348 | dw_writel(dev, 0, DW_IC_RX_TL); | |
4cb6d1d6 | 349 | |
1ab52cf9 BS |
350 | /* configure the i2c master */ |
351 | ic_con = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | | |
352 | DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST; | |
7f279601 | 353 | dw_writel(dev, ic_con, DW_IC_CON); |
1ab52cf9 BS |
354 | } |
355 | ||
356 | /* | |
357 | * Waiting for bus not busy | |
358 | */ | |
359 | static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) | |
360 | { | |
361 | int timeout = TIMEOUT; | |
362 | ||
7f279601 | 363 | while (dw_readl(dev, DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) { |
1ab52cf9 BS |
364 | if (timeout <= 0) { |
365 | dev_warn(dev->dev, "timeout waiting for bus ready\n"); | |
366 | return -ETIMEDOUT; | |
367 | } | |
368 | timeout--; | |
369 | mdelay(1); | |
370 | } | |
371 | ||
372 | return 0; | |
373 | } | |
374 | ||
81e798b7 SK |
375 | static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) |
376 | { | |
377 | struct i2c_msg *msgs = dev->msgs; | |
378 | u32 ic_con; | |
379 | ||
380 | /* Disable the adapter */ | |
7f279601 | 381 | dw_writel(dev, 0, DW_IC_ENABLE); |
81e798b7 SK |
382 | |
383 | /* set the slave (target) address */ | |
7f279601 | 384 | dw_writel(dev, msgs[dev->msg_write_idx].addr, DW_IC_TAR); |
81e798b7 SK |
385 | |
386 | /* if the slave address is ten bit address, enable 10BITADDR */ | |
7f279601 | 387 | ic_con = dw_readl(dev, DW_IC_CON); |
81e798b7 SK |
388 | if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) |
389 | ic_con |= DW_IC_CON_10BITADDR_MASTER; | |
390 | else | |
391 | ic_con &= ~DW_IC_CON_10BITADDR_MASTER; | |
7f279601 | 392 | dw_writel(dev, ic_con, DW_IC_CON); |
81e798b7 SK |
393 | |
394 | /* Enable the adapter */ | |
7f279601 | 395 | dw_writel(dev, 1, DW_IC_ENABLE); |
201d6a70 SK |
396 | |
397 | /* Enable interrupts */ | |
7f279601 | 398 | dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK); |
81e798b7 SK |
399 | } |
400 | ||
1ab52cf9 | 401 | /* |
201d6a70 SK |
402 | * Initiate (and continue) low level master read/write transaction. |
403 | * This function is only called from i2c_dw_isr, and pumping i2c_msg | |
404 | * messages into the tx buffer. Even if the size of i2c_msg data is | |
405 | * longer than the size of the tx buffer, it handles everything. | |
1ab52cf9 BS |
406 | */ |
407 | static void | |
e77cf232 | 408 | i2c_dw_xfer_msg(struct dw_i2c_dev *dev) |
1ab52cf9 | 409 | { |
1ab52cf9 | 410 | struct i2c_msg *msgs = dev->msgs; |
81e798b7 | 411 | u32 intr_mask; |
ae72222d | 412 | int tx_limit, rx_limit; |
ed5e1dd5 SK |
413 | u32 addr = msgs[dev->msg_write_idx].addr; |
414 | u32 buf_len = dev->tx_buf_len; | |
69932487 | 415 | u8 *buf = dev->tx_buf; |
1ab52cf9 | 416 | |
201d6a70 | 417 | intr_mask = DW_IC_INTR_DEFAULT_MASK; |
c70c5cd3 | 418 | |
6d2ea487 | 419 | for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) { |
a0e06ea6 SK |
420 | /* |
421 | * if target address has changed, we need to | |
1ab52cf9 BS |
422 | * reprogram the target address in the i2c |
423 | * adapter when we are done with this transfer | |
424 | */ | |
8f588e40 SK |
425 | if (msgs[dev->msg_write_idx].addr != addr) { |
426 | dev_err(dev->dev, | |
427 | "%s: invalid target address\n", __func__); | |
428 | dev->msg_err = -EINVAL; | |
429 | break; | |
430 | } | |
1ab52cf9 BS |
431 | |
432 | if (msgs[dev->msg_write_idx].len == 0) { | |
433 | dev_err(dev->dev, | |
434 | "%s: invalid message length\n", __func__); | |
435 | dev->msg_err = -EINVAL; | |
8f588e40 | 436 | break; |
1ab52cf9 BS |
437 | } |
438 | ||
439 | if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { | |
440 | /* new i2c_msg */ | |
26ea15b1 | 441 | buf = msgs[dev->msg_write_idx].buf; |
1ab52cf9 BS |
442 | buf_len = msgs[dev->msg_write_idx].len; |
443 | } | |
444 | ||
7f279601 JHD |
445 | tx_limit = dev->tx_fifo_depth - dw_readl(dev, DW_IC_TXFLR); |
446 | rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR); | |
ae72222d | 447 | |
1ab52cf9 BS |
448 | while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) { |
449 | if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { | |
7f279601 | 450 | dw_writel(dev, 0x100, DW_IC_DATA_CMD); |
1ab52cf9 BS |
451 | rx_limit--; |
452 | } else | |
7f279601 | 453 | dw_writel(dev, *buf++, DW_IC_DATA_CMD); |
1ab52cf9 BS |
454 | tx_limit--; buf_len--; |
455 | } | |
c70c5cd3 | 456 | |
26ea15b1 | 457 | dev->tx_buf = buf; |
c70c5cd3 SK |
458 | dev->tx_buf_len = buf_len; |
459 | ||
460 | if (buf_len > 0) { | |
461 | /* more bytes to be written */ | |
c70c5cd3 SK |
462 | dev->status |= STATUS_WRITE_IN_PROGRESS; |
463 | break; | |
69151e53 | 464 | } else |
c70c5cd3 | 465 | dev->status &= ~STATUS_WRITE_IN_PROGRESS; |
1ab52cf9 BS |
466 | } |
467 | ||
69151e53 SK |
468 | /* |
469 | * If i2c_msg index search is completed, we don't need TX_EMPTY | |
470 | * interrupt any more. | |
471 | */ | |
472 | if (dev->msg_write_idx == dev->msgs_num) | |
473 | intr_mask &= ~DW_IC_INTR_TX_EMPTY; | |
474 | ||
8f588e40 SK |
475 | if (dev->msg_err) |
476 | intr_mask = 0; | |
477 | ||
7f279601 | 478 | dw_writel(dev, intr_mask, DW_IC_INTR_MASK); |
1ab52cf9 BS |
479 | } |
480 | ||
481 | static void | |
78839bd0 | 482 | i2c_dw_read(struct dw_i2c_dev *dev) |
1ab52cf9 | 483 | { |
1ab52cf9 | 484 | struct i2c_msg *msgs = dev->msgs; |
ae72222d | 485 | int rx_valid; |
1ab52cf9 | 486 | |
6d2ea487 | 487 | for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) { |
ed5e1dd5 | 488 | u32 len; |
1ab52cf9 BS |
489 | u8 *buf; |
490 | ||
491 | if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD)) | |
492 | continue; | |
493 | ||
1ab52cf9 BS |
494 | if (!(dev->status & STATUS_READ_IN_PROGRESS)) { |
495 | len = msgs[dev->msg_read_idx].len; | |
496 | buf = msgs[dev->msg_read_idx].buf; | |
497 | } else { | |
498 | len = dev->rx_buf_len; | |
499 | buf = dev->rx_buf; | |
500 | } | |
501 | ||
7f279601 | 502 | rx_valid = dw_readl(dev, DW_IC_RXFLR); |
ae72222d | 503 | |
1ab52cf9 | 504 | for (; len > 0 && rx_valid > 0; len--, rx_valid--) |
7f279601 | 505 | *buf++ = dw_readl(dev, DW_IC_DATA_CMD); |
1ab52cf9 BS |
506 | |
507 | if (len > 0) { | |
508 | dev->status |= STATUS_READ_IN_PROGRESS; | |
509 | dev->rx_buf_len = len; | |
510 | dev->rx_buf = buf; | |
511 | return; | |
512 | } else | |
513 | dev->status &= ~STATUS_READ_IN_PROGRESS; | |
514 | } | |
515 | } | |
516 | ||
ce6eb574 SK |
517 | static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev) |
518 | { | |
519 | unsigned long abort_source = dev->abort_source; | |
520 | int i; | |
521 | ||
6d1ea0f6 | 522 | if (abort_source & DW_IC_TX_ABRT_NOACK) { |
984b3f57 | 523 | for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) |
6d1ea0f6 SK |
524 | dev_dbg(dev->dev, |
525 | "%s: %s\n", __func__, abort_sources[i]); | |
526 | return -EREMOTEIO; | |
527 | } | |
528 | ||
984b3f57 | 529 | for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) |
ce6eb574 SK |
530 | dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]); |
531 | ||
532 | if (abort_source & DW_IC_TX_ARB_LOST) | |
533 | return -EAGAIN; | |
ce6eb574 SK |
534 | else if (abort_source & DW_IC_TX_ABRT_GCALL_READ) |
535 | return -EINVAL; /* wrong msgs[] data */ | |
536 | else | |
537 | return -EIO; | |
538 | } | |
539 | ||
1ab52cf9 BS |
540 | /* |
541 | * Prepare controller for a transaction and call i2c_dw_xfer_msg | |
542 | */ | |
543 | static int | |
544 | i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) | |
545 | { | |
546 | struct dw_i2c_dev *dev = i2c_get_adapdata(adap); | |
547 | int ret; | |
548 | ||
549 | dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); | |
550 | ||
551 | mutex_lock(&dev->lock); | |
552 | ||
553 | INIT_COMPLETION(dev->cmd_complete); | |
554 | dev->msgs = msgs; | |
555 | dev->msgs_num = num; | |
556 | dev->cmd_err = 0; | |
557 | dev->msg_write_idx = 0; | |
558 | dev->msg_read_idx = 0; | |
559 | dev->msg_err = 0; | |
560 | dev->status = STATUS_IDLE; | |
ce6eb574 | 561 | dev->abort_source = 0; |
1ab52cf9 BS |
562 | |
563 | ret = i2c_dw_wait_bus_not_busy(dev); | |
564 | if (ret < 0) | |
565 | goto done; | |
566 | ||
567 | /* start the transfers */ | |
81e798b7 | 568 | i2c_dw_xfer_init(dev); |
1ab52cf9 BS |
569 | |
570 | /* wait for tx to complete */ | |
571 | ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, HZ); | |
572 | if (ret == 0) { | |
573 | dev_err(dev->dev, "controller timed out\n"); | |
574 | i2c_dw_init(dev); | |
575 | ret = -ETIMEDOUT; | |
576 | goto done; | |
577 | } else if (ret < 0) | |
578 | goto done; | |
579 | ||
580 | if (dev->msg_err) { | |
581 | ret = dev->msg_err; | |
582 | goto done; | |
583 | } | |
584 | ||
585 | /* no error */ | |
586 | if (likely(!dev->cmd_err)) { | |
07745399 | 587 | /* Disable the adapter */ |
7f279601 | 588 | dw_writel(dev, 0, DW_IC_ENABLE); |
1ab52cf9 BS |
589 | ret = num; |
590 | goto done; | |
591 | } | |
592 | ||
593 | /* We have an error */ | |
594 | if (dev->cmd_err == DW_IC_ERR_TX_ABRT) { | |
ce6eb574 SK |
595 | ret = i2c_dw_handle_tx_abort(dev); |
596 | goto done; | |
1ab52cf9 BS |
597 | } |
598 | ret = -EIO; | |
599 | ||
600 | done: | |
601 | mutex_unlock(&dev->lock); | |
602 | ||
603 | return ret; | |
604 | } | |
605 | ||
606 | static u32 i2c_dw_func(struct i2c_adapter *adap) | |
607 | { | |
52d7e430 SK |
608 | return I2C_FUNC_I2C | |
609 | I2C_FUNC_10BIT_ADDR | | |
610 | I2C_FUNC_SMBUS_BYTE | | |
611 | I2C_FUNC_SMBUS_BYTE_DATA | | |
612 | I2C_FUNC_SMBUS_WORD_DATA | | |
613 | I2C_FUNC_SMBUS_I2C_BLOCK; | |
1ab52cf9 BS |
614 | } |
615 | ||
e28000a3 SK |
616 | static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) |
617 | { | |
618 | u32 stat; | |
619 | ||
620 | /* | |
621 | * The IC_INTR_STAT register just indicates "enabled" interrupts. | |
622 | * Ths unmasked raw version of interrupt status bits are available | |
623 | * in the IC_RAW_INTR_STAT register. | |
624 | * | |
625 | * That is, | |
626 | * stat = readl(IC_INTR_STAT); | |
627 | * equals to, | |
628 | * stat = readl(IC_RAW_INTR_STAT) & readl(IC_INTR_MASK); | |
629 | * | |
630 | * The raw version might be useful for debugging purposes. | |
631 | */ | |
7f279601 | 632 | stat = dw_readl(dev, DW_IC_INTR_STAT); |
e28000a3 SK |
633 | |
634 | /* | |
635 | * Do not use the IC_CLR_INTR register to clear interrupts, or | |
636 | * you'll miss some interrupts, triggered during the period from | |
637 | * readl(IC_INTR_STAT) to readl(IC_CLR_INTR). | |
638 | * | |
639 | * Instead, use the separately-prepared IC_CLR_* registers. | |
640 | */ | |
641 | if (stat & DW_IC_INTR_RX_UNDER) | |
7f279601 | 642 | dw_readl(dev, DW_IC_CLR_RX_UNDER); |
e28000a3 | 643 | if (stat & DW_IC_INTR_RX_OVER) |
7f279601 | 644 | dw_readl(dev, DW_IC_CLR_RX_OVER); |
e28000a3 | 645 | if (stat & DW_IC_INTR_TX_OVER) |
7f279601 | 646 | dw_readl(dev, DW_IC_CLR_TX_OVER); |
e28000a3 | 647 | if (stat & DW_IC_INTR_RD_REQ) |
7f279601 | 648 | dw_readl(dev, DW_IC_CLR_RD_REQ); |
e28000a3 SK |
649 | if (stat & DW_IC_INTR_TX_ABRT) { |
650 | /* | |
651 | * The IC_TX_ABRT_SOURCE register is cleared whenever | |
652 | * the IC_CLR_TX_ABRT is read. Preserve it beforehand. | |
653 | */ | |
7f279601 JHD |
654 | dev->abort_source = dw_readl(dev, DW_IC_TX_ABRT_SOURCE); |
655 | dw_readl(dev, DW_IC_CLR_TX_ABRT); | |
e28000a3 SK |
656 | } |
657 | if (stat & DW_IC_INTR_RX_DONE) | |
7f279601 | 658 | dw_readl(dev, DW_IC_CLR_RX_DONE); |
e28000a3 | 659 | if (stat & DW_IC_INTR_ACTIVITY) |
7f279601 | 660 | dw_readl(dev, DW_IC_CLR_ACTIVITY); |
e28000a3 | 661 | if (stat & DW_IC_INTR_STOP_DET) |
7f279601 | 662 | dw_readl(dev, DW_IC_CLR_STOP_DET); |
e28000a3 | 663 | if (stat & DW_IC_INTR_START_DET) |
7f279601 | 664 | dw_readl(dev, DW_IC_CLR_START_DET); |
e28000a3 | 665 | if (stat & DW_IC_INTR_GEN_CALL) |
7f279601 | 666 | dw_readl(dev, DW_IC_CLR_GEN_CALL); |
e28000a3 SK |
667 | |
668 | return stat; | |
669 | } | |
670 | ||
1ab52cf9 BS |
671 | /* |
672 | * Interrupt service routine. This gets called whenever an I2C interrupt | |
673 | * occurs. | |
674 | */ | |
675 | static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) | |
676 | { | |
677 | struct dw_i2c_dev *dev = dev_id; | |
ed5e1dd5 | 678 | u32 stat; |
1ab52cf9 | 679 | |
e28000a3 | 680 | stat = i2c_dw_read_clear_intrbits(dev); |
1ab52cf9 | 681 | dev_dbg(dev->dev, "%s: stat=0x%x\n", __func__, stat); |
e28000a3 | 682 | |
1ab52cf9 | 683 | if (stat & DW_IC_INTR_TX_ABRT) { |
1ab52cf9 BS |
684 | dev->cmd_err |= DW_IC_ERR_TX_ABRT; |
685 | dev->status = STATUS_IDLE; | |
597fe310 SK |
686 | |
687 | /* | |
688 | * Anytime TX_ABRT is set, the contents of the tx/rx | |
689 | * buffers are flushed. Make sure to skip them. | |
690 | */ | |
7f279601 | 691 | dw_writel(dev, 0, DW_IC_INTR_MASK); |
597fe310 | 692 | goto tx_aborted; |
07745399 SK |
693 | } |
694 | ||
21a89d41 | 695 | if (stat & DW_IC_INTR_RX_FULL) |
07745399 | 696 | i2c_dw_read(dev); |
21a89d41 SK |
697 | |
698 | if (stat & DW_IC_INTR_TX_EMPTY) | |
07745399 | 699 | i2c_dw_xfer_msg(dev); |
07745399 SK |
700 | |
701 | /* | |
702 | * No need to modify or disable the interrupt mask here. | |
703 | * i2c_dw_xfer_msg() will take care of it according to | |
704 | * the current transmit status. | |
705 | */ | |
1ab52cf9 | 706 | |
597fe310 | 707 | tx_aborted: |
8f588e40 | 708 | if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) |
1ab52cf9 BS |
709 | complete(&dev->cmd_complete); |
710 | ||
711 | return IRQ_HANDLED; | |
712 | } | |
713 | ||
714 | static struct i2c_algorithm i2c_dw_algo = { | |
715 | .master_xfer = i2c_dw_xfer, | |
716 | .functionality = i2c_dw_func, | |
717 | }; | |
718 | ||
719 | static int __devinit dw_i2c_probe(struct platform_device *pdev) | |
720 | { | |
721 | struct dw_i2c_dev *dev; | |
722 | struct i2c_adapter *adap; | |
91b52cae SK |
723 | struct resource *mem, *ioarea; |
724 | int irq, r; | |
4ff895bc | 725 | u32 reg; |
1ab52cf9 BS |
726 | |
727 | /* NOTE: driver uses the static register mapping */ | |
728 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
729 | if (!mem) { | |
730 | dev_err(&pdev->dev, "no mem resource?\n"); | |
731 | return -EINVAL; | |
732 | } | |
733 | ||
91b52cae SK |
734 | irq = platform_get_irq(pdev, 0); |
735 | if (irq < 0) { | |
1ab52cf9 | 736 | dev_err(&pdev->dev, "no irq resource?\n"); |
91b52cae | 737 | return irq; /* -ENXIO */ |
1ab52cf9 BS |
738 | } |
739 | ||
740 | ioarea = request_mem_region(mem->start, resource_size(mem), | |
741 | pdev->name); | |
742 | if (!ioarea) { | |
743 | dev_err(&pdev->dev, "I2C region already claimed\n"); | |
744 | return -EBUSY; | |
745 | } | |
746 | ||
747 | dev = kzalloc(sizeof(struct dw_i2c_dev), GFP_KERNEL); | |
748 | if (!dev) { | |
749 | r = -ENOMEM; | |
750 | goto err_release_region; | |
751 | } | |
752 | ||
753 | init_completion(&dev->cmd_complete); | |
1ab52cf9 BS |
754 | mutex_init(&dev->lock); |
755 | dev->dev = get_device(&pdev->dev); | |
91b52cae | 756 | dev->irq = irq; |
1ab52cf9 BS |
757 | platform_set_drvdata(pdev, dev); |
758 | ||
759 | dev->clk = clk_get(&pdev->dev, NULL); | |
760 | if (IS_ERR(dev->clk)) { | |
761 | r = -ENODEV; | |
762 | goto err_free_mem; | |
763 | } | |
764 | clk_enable(dev->clk); | |
765 | ||
766 | dev->base = ioremap(mem->start, resource_size(mem)); | |
767 | if (dev->base == NULL) { | |
768 | dev_err(&pdev->dev, "failure mapping io resources\n"); | |
769 | r = -EBUSY; | |
770 | goto err_unuse_clocks; | |
771 | } | |
1ab52cf9 | 772 | |
4ff895bc | 773 | reg = dw_readl(dev, DW_IC_COMP_TYPE); |
18c4089e JHD |
774 | if (reg == ___constant_swab32(0x44570140)) |
775 | dev->swab = 1; | |
776 | else if (reg != 0x44570140) { | |
4ff895bc JHD |
777 | dev_err(&pdev->dev, "Unknown Synopsys component type: " |
778 | "0x%08x\n", reg); | |
779 | r = -ENODEV; | |
780 | goto err_iounmap; | |
1ab52cf9 | 781 | } |
4ff895bc JHD |
782 | |
783 | reg = dw_readl(dev, DW_IC_COMP_PARAM_1); | |
784 | dev->tx_fifo_depth = ((reg >> 16) & 0xff) + 1; | |
785 | dev->rx_fifo_depth = ((reg >> 8) & 0xff) + 1; | |
786 | ||
1ab52cf9 BS |
787 | i2c_dw_init(dev); |
788 | ||
7f279601 | 789 | dw_writel(dev, 0, DW_IC_INTR_MASK); /* disable IRQ */ |
201d6a70 | 790 | r = request_irq(dev->irq, i2c_dw_isr, IRQF_DISABLED, pdev->name, dev); |
1ab52cf9 BS |
791 | if (r) { |
792 | dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq); | |
793 | goto err_iounmap; | |
794 | } | |
795 | ||
796 | adap = &dev->adapter; | |
797 | i2c_set_adapdata(adap, dev); | |
798 | adap->owner = THIS_MODULE; | |
799 | adap->class = I2C_CLASS_HWMON; | |
800 | strlcpy(adap->name, "Synopsys DesignWare I2C adapter", | |
801 | sizeof(adap->name)); | |
802 | adap->algo = &i2c_dw_algo; | |
803 | adap->dev.parent = &pdev->dev; | |
804 | ||
805 | adap->nr = pdev->id; | |
806 | r = i2c_add_numbered_adapter(adap); | |
807 | if (r) { | |
808 | dev_err(&pdev->dev, "failure adding adapter\n"); | |
809 | goto err_free_irq; | |
810 | } | |
811 | ||
812 | return 0; | |
813 | ||
814 | err_free_irq: | |
815 | free_irq(dev->irq, dev); | |
816 | err_iounmap: | |
817 | iounmap(dev->base); | |
818 | err_unuse_clocks: | |
819 | clk_disable(dev->clk); | |
820 | clk_put(dev->clk); | |
821 | dev->clk = NULL; | |
822 | err_free_mem: | |
823 | platform_set_drvdata(pdev, NULL); | |
824 | put_device(&pdev->dev); | |
825 | kfree(dev); | |
826 | err_release_region: | |
827 | release_mem_region(mem->start, resource_size(mem)); | |
828 | ||
829 | return r; | |
830 | } | |
831 | ||
832 | static int __devexit dw_i2c_remove(struct platform_device *pdev) | |
833 | { | |
834 | struct dw_i2c_dev *dev = platform_get_drvdata(pdev); | |
835 | struct resource *mem; | |
836 | ||
837 | platform_set_drvdata(pdev, NULL); | |
838 | i2c_del_adapter(&dev->adapter); | |
839 | put_device(&pdev->dev); | |
840 | ||
841 | clk_disable(dev->clk); | |
842 | clk_put(dev->clk); | |
843 | dev->clk = NULL; | |
844 | ||
7f279601 | 845 | dw_writel(dev, 0, DW_IC_ENABLE); |
1ab52cf9 BS |
846 | free_irq(dev->irq, dev); |
847 | kfree(dev); | |
848 | ||
849 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
850 | release_mem_region(mem->start, resource_size(mem)); | |
851 | return 0; | |
852 | } | |
853 | ||
854 | /* work with hotplug and coldplug */ | |
855 | MODULE_ALIAS("platform:i2c_designware"); | |
856 | ||
857 | static struct platform_driver dw_i2c_driver = { | |
858 | .remove = __devexit_p(dw_i2c_remove), | |
859 | .driver = { | |
860 | .name = "i2c_designware", | |
861 | .owner = THIS_MODULE, | |
862 | }, | |
863 | }; | |
864 | ||
865 | static int __init dw_i2c_init_driver(void) | |
866 | { | |
867 | return platform_driver_probe(&dw_i2c_driver, dw_i2c_probe); | |
868 | } | |
869 | module_init(dw_i2c_init_driver); | |
870 | ||
871 | static void __exit dw_i2c_exit_driver(void) | |
872 | { | |
873 | platform_driver_unregister(&dw_i2c_driver); | |
874 | } | |
875 | module_exit(dw_i2c_exit_driver); | |
876 | ||
877 | MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>"); | |
878 | MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter"); | |
879 | MODULE_LICENSE("GPL"); |