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 | */ | |
e68bb91b | 28 | #include <linux/export.h> |
1ab52cf9 BS |
29 | #include <linux/clk.h> |
30 | #include <linux/errno.h> | |
1ab52cf9 | 31 | #include <linux/err.h> |
2373f6b9 | 32 | #include <linux/i2c.h> |
1ab52cf9 | 33 | #include <linux/interrupt.h> |
1ab52cf9 | 34 | #include <linux/io.h> |
18dbdda8 | 35 | #include <linux/pm_runtime.h> |
2373f6b9 | 36 | #include <linux/delay.h> |
9dd3162d | 37 | #include <linux/module.h> |
2373f6b9 | 38 | #include "i2c-designware-core.h" |
ce6eb574 | 39 | |
f3fa9f3d DB |
40 | /* |
41 | * Registers offset | |
42 | */ | |
43 | #define DW_IC_CON 0x0 | |
44 | #define DW_IC_TAR 0x4 | |
45 | #define DW_IC_DATA_CMD 0x10 | |
46 | #define DW_IC_SS_SCL_HCNT 0x14 | |
47 | #define DW_IC_SS_SCL_LCNT 0x18 | |
48 | #define DW_IC_FS_SCL_HCNT 0x1c | |
49 | #define DW_IC_FS_SCL_LCNT 0x20 | |
50 | #define DW_IC_INTR_STAT 0x2c | |
51 | #define DW_IC_INTR_MASK 0x30 | |
52 | #define DW_IC_RAW_INTR_STAT 0x34 | |
53 | #define DW_IC_RX_TL 0x38 | |
54 | #define DW_IC_TX_TL 0x3c | |
55 | #define DW_IC_CLR_INTR 0x40 | |
56 | #define DW_IC_CLR_RX_UNDER 0x44 | |
57 | #define DW_IC_CLR_RX_OVER 0x48 | |
58 | #define DW_IC_CLR_TX_OVER 0x4c | |
59 | #define DW_IC_CLR_RD_REQ 0x50 | |
60 | #define DW_IC_CLR_TX_ABRT 0x54 | |
61 | #define DW_IC_CLR_RX_DONE 0x58 | |
62 | #define DW_IC_CLR_ACTIVITY 0x5c | |
63 | #define DW_IC_CLR_STOP_DET 0x60 | |
64 | #define DW_IC_CLR_START_DET 0x64 | |
65 | #define DW_IC_CLR_GEN_CALL 0x68 | |
66 | #define DW_IC_ENABLE 0x6c | |
67 | #define DW_IC_STATUS 0x70 | |
68 | #define DW_IC_TXFLR 0x74 | |
69 | #define DW_IC_RXFLR 0x78 | |
70 | #define DW_IC_TX_ABRT_SOURCE 0x80 | |
71 | #define DW_IC_COMP_PARAM_1 0xf4 | |
72 | #define DW_IC_COMP_TYPE 0xfc | |
73 | #define DW_IC_COMP_TYPE_VALUE 0x44570140 | |
74 | ||
75 | #define DW_IC_INTR_RX_UNDER 0x001 | |
76 | #define DW_IC_INTR_RX_OVER 0x002 | |
77 | #define DW_IC_INTR_RX_FULL 0x004 | |
78 | #define DW_IC_INTR_TX_OVER 0x008 | |
79 | #define DW_IC_INTR_TX_EMPTY 0x010 | |
80 | #define DW_IC_INTR_RD_REQ 0x020 | |
81 | #define DW_IC_INTR_TX_ABRT 0x040 | |
82 | #define DW_IC_INTR_RX_DONE 0x080 | |
83 | #define DW_IC_INTR_ACTIVITY 0x100 | |
84 | #define DW_IC_INTR_STOP_DET 0x200 | |
85 | #define DW_IC_INTR_START_DET 0x400 | |
86 | #define DW_IC_INTR_GEN_CALL 0x800 | |
87 | ||
88 | #define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \ | |
89 | DW_IC_INTR_TX_EMPTY | \ | |
90 | DW_IC_INTR_TX_ABRT | \ | |
91 | DW_IC_INTR_STOP_DET) | |
92 | ||
93 | #define DW_IC_STATUS_ACTIVITY 0x1 | |
94 | ||
95 | #define DW_IC_ERR_TX_ABRT 0x1 | |
96 | ||
97 | /* | |
98 | * status codes | |
99 | */ | |
100 | #define STATUS_IDLE 0x0 | |
101 | #define STATUS_WRITE_IN_PROGRESS 0x1 | |
102 | #define STATUS_READ_IN_PROGRESS 0x2 | |
103 | ||
104 | #define TIMEOUT 20 /* ms */ | |
105 | ||
106 | /* | |
107 | * hardware abort codes from the DW_IC_TX_ABRT_SOURCE register | |
108 | * | |
109 | * only expected abort codes are listed here | |
110 | * refer to the datasheet for the full list | |
111 | */ | |
112 | #define ABRT_7B_ADDR_NOACK 0 | |
113 | #define ABRT_10ADDR1_NOACK 1 | |
114 | #define ABRT_10ADDR2_NOACK 2 | |
115 | #define ABRT_TXDATA_NOACK 3 | |
116 | #define ABRT_GCALL_NOACK 4 | |
117 | #define ABRT_GCALL_READ 5 | |
118 | #define ABRT_SBYTE_ACKDET 7 | |
119 | #define ABRT_SBYTE_NORSTRT 9 | |
120 | #define ABRT_10B_RD_NORSTRT 10 | |
121 | #define ABRT_MASTER_DIS 11 | |
122 | #define ARB_LOST 12 | |
123 | ||
124 | #define DW_IC_TX_ABRT_7B_ADDR_NOACK (1UL << ABRT_7B_ADDR_NOACK) | |
125 | #define DW_IC_TX_ABRT_10ADDR1_NOACK (1UL << ABRT_10ADDR1_NOACK) | |
126 | #define DW_IC_TX_ABRT_10ADDR2_NOACK (1UL << ABRT_10ADDR2_NOACK) | |
127 | #define DW_IC_TX_ABRT_TXDATA_NOACK (1UL << ABRT_TXDATA_NOACK) | |
128 | #define DW_IC_TX_ABRT_GCALL_NOACK (1UL << ABRT_GCALL_NOACK) | |
129 | #define DW_IC_TX_ABRT_GCALL_READ (1UL << ABRT_GCALL_READ) | |
130 | #define DW_IC_TX_ABRT_SBYTE_ACKDET (1UL << ABRT_SBYTE_ACKDET) | |
131 | #define DW_IC_TX_ABRT_SBYTE_NORSTRT (1UL << ABRT_SBYTE_NORSTRT) | |
132 | #define DW_IC_TX_ABRT_10B_RD_NORSTRT (1UL << ABRT_10B_RD_NORSTRT) | |
133 | #define DW_IC_TX_ABRT_MASTER_DIS (1UL << ABRT_MASTER_DIS) | |
134 | #define DW_IC_TX_ARB_LOST (1UL << ARB_LOST) | |
135 | ||
136 | #define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \ | |
137 | DW_IC_TX_ABRT_10ADDR1_NOACK | \ | |
138 | DW_IC_TX_ABRT_10ADDR2_NOACK | \ | |
139 | DW_IC_TX_ABRT_TXDATA_NOACK | \ | |
140 | DW_IC_TX_ABRT_GCALL_NOACK) | |
141 | ||
1ab52cf9 | 142 | static char *abort_sources[] = { |
a0e06ea6 | 143 | [ABRT_7B_ADDR_NOACK] = |
1ab52cf9 | 144 | "slave address not acknowledged (7bit mode)", |
a0e06ea6 | 145 | [ABRT_10ADDR1_NOACK] = |
1ab52cf9 | 146 | "first address byte not acknowledged (10bit mode)", |
a0e06ea6 | 147 | [ABRT_10ADDR2_NOACK] = |
1ab52cf9 | 148 | "second address byte not acknowledged (10bit mode)", |
a0e06ea6 | 149 | [ABRT_TXDATA_NOACK] = |
1ab52cf9 | 150 | "data not acknowledged", |
a0e06ea6 | 151 | [ABRT_GCALL_NOACK] = |
1ab52cf9 | 152 | "no acknowledgement for a general call", |
a0e06ea6 | 153 | [ABRT_GCALL_READ] = |
1ab52cf9 | 154 | "read after general call", |
a0e06ea6 | 155 | [ABRT_SBYTE_ACKDET] = |
1ab52cf9 | 156 | "start byte acknowledged", |
a0e06ea6 | 157 | [ABRT_SBYTE_NORSTRT] = |
1ab52cf9 | 158 | "trying to send start byte when restart is disabled", |
a0e06ea6 | 159 | [ABRT_10B_RD_NORSTRT] = |
1ab52cf9 | 160 | "trying to read when restart is disabled (10bit mode)", |
a0e06ea6 | 161 | [ABRT_MASTER_DIS] = |
1ab52cf9 | 162 | "trying to use disabled adapter", |
a0e06ea6 | 163 | [ARB_LOST] = |
1ab52cf9 BS |
164 | "lost arbitration", |
165 | }; | |
166 | ||
2373f6b9 | 167 | u32 dw_readl(struct dw_i2c_dev *dev, int offset) |
7f279601 | 168 | { |
a8a9f3fe | 169 | u32 value; |
18c4089e | 170 | |
a8a9f3fe SR |
171 | if (dev->accessor_flags & ACCESS_16BIT) |
172 | value = readw(dev->base + offset) | | |
173 | (readw(dev->base + offset + 2) << 16); | |
174 | else | |
175 | value = readl(dev->base + offset); | |
176 | ||
177 | if (dev->accessor_flags & ACCESS_SWAP) | |
18c4089e JHD |
178 | return swab32(value); |
179 | else | |
180 | return value; | |
7f279601 JHD |
181 | } |
182 | ||
2373f6b9 | 183 | void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset) |
7f279601 | 184 | { |
a8a9f3fe | 185 | if (dev->accessor_flags & ACCESS_SWAP) |
18c4089e JHD |
186 | b = swab32(b); |
187 | ||
a8a9f3fe SR |
188 | if (dev->accessor_flags & ACCESS_16BIT) { |
189 | writew((u16)b, dev->base + offset); | |
190 | writew((u16)(b >> 16), dev->base + offset + 2); | |
191 | } else { | |
192 | writel(b, dev->base + offset); | |
193 | } | |
7f279601 JHD |
194 | } |
195 | ||
d60c7e81 SK |
196 | static u32 |
197 | i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int offset) | |
198 | { | |
199 | /* | |
200 | * DesignWare I2C core doesn't seem to have solid strategy to meet | |
201 | * the tHD;STA timing spec. Configuring _HCNT based on tHIGH spec | |
202 | * will result in violation of the tHD;STA spec. | |
203 | */ | |
204 | if (cond) | |
205 | /* | |
206 | * Conditional expression: | |
207 | * | |
208 | * IC_[FS]S_SCL_HCNT + (1+4+3) >= IC_CLK * tHIGH | |
209 | * | |
210 | * This is based on the DW manuals, and represents an ideal | |
211 | * configuration. The resulting I2C bus speed will be | |
212 | * faster than any of the others. | |
213 | * | |
214 | * If your hardware is free from tHD;STA issue, try this one. | |
215 | */ | |
216 | return (ic_clk * tSYMBOL + 5000) / 10000 - 8 + offset; | |
217 | else | |
218 | /* | |
219 | * Conditional expression: | |
220 | * | |
221 | * IC_[FS]S_SCL_HCNT + 3 >= IC_CLK * (tHD;STA + tf) | |
222 | * | |
223 | * This is just experimental rule; the tHD;STA period turned | |
224 | * out to be proportinal to (_HCNT + 3). With this setting, | |
225 | * we could meet both tHIGH and tHD;STA timing specs. | |
226 | * | |
227 | * If unsure, you'd better to take this alternative. | |
228 | * | |
229 | * The reason why we need to take into account "tf" here, | |
230 | * is the same as described in i2c_dw_scl_lcnt(). | |
231 | */ | |
232 | return (ic_clk * (tSYMBOL + tf) + 5000) / 10000 - 3 + offset; | |
233 | } | |
234 | ||
235 | static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) | |
236 | { | |
237 | /* | |
238 | * Conditional expression: | |
239 | * | |
240 | * IC_[FS]S_SCL_LCNT + 1 >= IC_CLK * (tLOW + tf) | |
241 | * | |
242 | * DW I2C core starts counting the SCL CNTs for the LOW period | |
243 | * of the SCL clock (tLOW) as soon as it pulls the SCL line. | |
244 | * In order to meet the tLOW timing spec, we need to take into | |
245 | * account the fall time of SCL signal (tf). Default tf value | |
246 | * should be 0.3 us, for safety. | |
247 | */ | |
248 | return ((ic_clk * (tLOW + tf) + 5000) / 10000) - 1 + offset; | |
249 | } | |
250 | ||
1ab52cf9 BS |
251 | /** |
252 | * i2c_dw_init() - initialize the designware i2c master hardware | |
253 | * @dev: device private data | |
254 | * | |
255 | * This functions configures and enables the I2C master. | |
256 | * This function is called during I2C init function, and in case of timeout at | |
257 | * run time. | |
258 | */ | |
2373f6b9 | 259 | int i2c_dw_init(struct dw_i2c_dev *dev) |
1ab52cf9 | 260 | { |
1d31b58f | 261 | u32 input_clock_khz; |
e18563fc | 262 | u32 hcnt, lcnt; |
4a423a8c DB |
263 | u32 reg; |
264 | ||
1d31b58f DB |
265 | input_clock_khz = dev->get_clk_rate_khz(dev); |
266 | ||
4a423a8c DB |
267 | reg = dw_readl(dev, DW_IC_COMP_TYPE); |
268 | if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) { | |
a8a9f3fe SR |
269 | /* Configure register endianess access */ |
270 | dev->accessor_flags |= ACCESS_SWAP; | |
271 | } else if (reg == (DW_IC_COMP_TYPE_VALUE & 0x0000ffff)) { | |
272 | /* Configure register access mode 16bit */ | |
273 | dev->accessor_flags |= ACCESS_16BIT; | |
274 | } else if (reg != DW_IC_COMP_TYPE_VALUE) { | |
4a423a8c DB |
275 | dev_err(dev->dev, "Unknown Synopsys component type: " |
276 | "0x%08x\n", reg); | |
277 | return -ENODEV; | |
278 | } | |
1ab52cf9 BS |
279 | |
280 | /* Disable the adapter */ | |
7f279601 | 281 | dw_writel(dev, 0, DW_IC_ENABLE); |
1ab52cf9 BS |
282 | |
283 | /* set standard and fast speed deviders for high/low periods */ | |
d60c7e81 SK |
284 | |
285 | /* Standard-mode */ | |
286 | hcnt = i2c_dw_scl_hcnt(input_clock_khz, | |
287 | 40, /* tHD;STA = tHIGH = 4.0 us */ | |
288 | 3, /* tf = 0.3 us */ | |
289 | 0, /* 0: DW default, 1: Ideal */ | |
290 | 0); /* No offset */ | |
291 | lcnt = i2c_dw_scl_lcnt(input_clock_khz, | |
292 | 47, /* tLOW = 4.7 us */ | |
293 | 3, /* tf = 0.3 us */ | |
294 | 0); /* No offset */ | |
7f279601 JHD |
295 | dw_writel(dev, hcnt, DW_IC_SS_SCL_HCNT); |
296 | dw_writel(dev, lcnt, DW_IC_SS_SCL_LCNT); | |
d60c7e81 SK |
297 | dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt); |
298 | ||
299 | /* Fast-mode */ | |
300 | hcnt = i2c_dw_scl_hcnt(input_clock_khz, | |
301 | 6, /* tHD;STA = tHIGH = 0.6 us */ | |
302 | 3, /* tf = 0.3 us */ | |
303 | 0, /* 0: DW default, 1: Ideal */ | |
304 | 0); /* No offset */ | |
305 | lcnt = i2c_dw_scl_lcnt(input_clock_khz, | |
306 | 13, /* tLOW = 1.3 us */ | |
307 | 3, /* tf = 0.3 us */ | |
308 | 0); /* No offset */ | |
7f279601 JHD |
309 | dw_writel(dev, hcnt, DW_IC_FS_SCL_HCNT); |
310 | dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT); | |
d60c7e81 | 311 | dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt); |
1ab52cf9 | 312 | |
4cb6d1d6 | 313 | /* Configure Tx/Rx FIFO threshold levels */ |
7f279601 JHD |
314 | dw_writel(dev, dev->tx_fifo_depth - 1, DW_IC_TX_TL); |
315 | dw_writel(dev, 0, DW_IC_RX_TL); | |
4cb6d1d6 | 316 | |
1ab52cf9 | 317 | /* configure the i2c master */ |
e18563fc | 318 | dw_writel(dev, dev->master_cfg , DW_IC_CON); |
4a423a8c | 319 | return 0; |
1ab52cf9 | 320 | } |
e68bb91b | 321 | EXPORT_SYMBOL_GPL(i2c_dw_init); |
1ab52cf9 BS |
322 | |
323 | /* | |
324 | * Waiting for bus not busy | |
325 | */ | |
326 | static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) | |
327 | { | |
328 | int timeout = TIMEOUT; | |
329 | ||
7f279601 | 330 | while (dw_readl(dev, DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) { |
1ab52cf9 BS |
331 | if (timeout <= 0) { |
332 | dev_warn(dev->dev, "timeout waiting for bus ready\n"); | |
333 | return -ETIMEDOUT; | |
334 | } | |
335 | timeout--; | |
336 | mdelay(1); | |
337 | } | |
338 | ||
339 | return 0; | |
340 | } | |
341 | ||
81e798b7 SK |
342 | static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) |
343 | { | |
344 | struct i2c_msg *msgs = dev->msgs; | |
345 | u32 ic_con; | |
346 | ||
347 | /* Disable the adapter */ | |
7f279601 | 348 | dw_writel(dev, 0, DW_IC_ENABLE); |
81e798b7 SK |
349 | |
350 | /* set the slave (target) address */ | |
7f279601 | 351 | dw_writel(dev, msgs[dev->msg_write_idx].addr, DW_IC_TAR); |
81e798b7 SK |
352 | |
353 | /* if the slave address is ten bit address, enable 10BITADDR */ | |
7f279601 | 354 | ic_con = dw_readl(dev, DW_IC_CON); |
81e798b7 SK |
355 | if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) |
356 | ic_con |= DW_IC_CON_10BITADDR_MASTER; | |
357 | else | |
358 | ic_con &= ~DW_IC_CON_10BITADDR_MASTER; | |
7f279601 | 359 | dw_writel(dev, ic_con, DW_IC_CON); |
81e798b7 SK |
360 | |
361 | /* Enable the adapter */ | |
7f279601 | 362 | dw_writel(dev, 1, DW_IC_ENABLE); |
201d6a70 SK |
363 | |
364 | /* Enable interrupts */ | |
7f279601 | 365 | dw_writel(dev, DW_IC_INTR_DEFAULT_MASK, DW_IC_INTR_MASK); |
81e798b7 SK |
366 | } |
367 | ||
1ab52cf9 | 368 | /* |
201d6a70 SK |
369 | * Initiate (and continue) low level master read/write transaction. |
370 | * This function is only called from i2c_dw_isr, and pumping i2c_msg | |
371 | * messages into the tx buffer. Even if the size of i2c_msg data is | |
372 | * longer than the size of the tx buffer, it handles everything. | |
1ab52cf9 | 373 | */ |
bccd780f | 374 | static void |
e77cf232 | 375 | i2c_dw_xfer_msg(struct dw_i2c_dev *dev) |
1ab52cf9 | 376 | { |
1ab52cf9 | 377 | struct i2c_msg *msgs = dev->msgs; |
81e798b7 | 378 | u32 intr_mask; |
ae72222d | 379 | int tx_limit, rx_limit; |
ed5e1dd5 SK |
380 | u32 addr = msgs[dev->msg_write_idx].addr; |
381 | u32 buf_len = dev->tx_buf_len; | |
69932487 | 382 | u8 *buf = dev->tx_buf; |
1ab52cf9 | 383 | |
201d6a70 | 384 | intr_mask = DW_IC_INTR_DEFAULT_MASK; |
c70c5cd3 | 385 | |
6d2ea487 | 386 | for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) { |
a0e06ea6 SK |
387 | /* |
388 | * if target address has changed, we need to | |
1ab52cf9 BS |
389 | * reprogram the target address in the i2c |
390 | * adapter when we are done with this transfer | |
391 | */ | |
8f588e40 SK |
392 | if (msgs[dev->msg_write_idx].addr != addr) { |
393 | dev_err(dev->dev, | |
394 | "%s: invalid target address\n", __func__); | |
395 | dev->msg_err = -EINVAL; | |
396 | break; | |
397 | } | |
1ab52cf9 BS |
398 | |
399 | if (msgs[dev->msg_write_idx].len == 0) { | |
400 | dev_err(dev->dev, | |
401 | "%s: invalid message length\n", __func__); | |
402 | dev->msg_err = -EINVAL; | |
8f588e40 | 403 | break; |
1ab52cf9 BS |
404 | } |
405 | ||
406 | if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { | |
407 | /* new i2c_msg */ | |
26ea15b1 | 408 | buf = msgs[dev->msg_write_idx].buf; |
1ab52cf9 BS |
409 | buf_len = msgs[dev->msg_write_idx].len; |
410 | } | |
411 | ||
7f279601 JHD |
412 | tx_limit = dev->tx_fifo_depth - dw_readl(dev, DW_IC_TXFLR); |
413 | rx_limit = dev->rx_fifo_depth - dw_readl(dev, DW_IC_RXFLR); | |
ae72222d | 414 | |
1ab52cf9 BS |
415 | while (buf_len > 0 && tx_limit > 0 && rx_limit > 0) { |
416 | if (msgs[dev->msg_write_idx].flags & I2C_M_RD) { | |
7f279601 | 417 | dw_writel(dev, 0x100, DW_IC_DATA_CMD); |
1ab52cf9 BS |
418 | rx_limit--; |
419 | } else | |
7f279601 | 420 | dw_writel(dev, *buf++, DW_IC_DATA_CMD); |
1ab52cf9 BS |
421 | tx_limit--; buf_len--; |
422 | } | |
c70c5cd3 | 423 | |
26ea15b1 | 424 | dev->tx_buf = buf; |
c70c5cd3 SK |
425 | dev->tx_buf_len = buf_len; |
426 | ||
427 | if (buf_len > 0) { | |
428 | /* more bytes to be written */ | |
c70c5cd3 SK |
429 | dev->status |= STATUS_WRITE_IN_PROGRESS; |
430 | break; | |
69151e53 | 431 | } else |
c70c5cd3 | 432 | dev->status &= ~STATUS_WRITE_IN_PROGRESS; |
1ab52cf9 BS |
433 | } |
434 | ||
69151e53 SK |
435 | /* |
436 | * If i2c_msg index search is completed, we don't need TX_EMPTY | |
437 | * interrupt any more. | |
438 | */ | |
439 | if (dev->msg_write_idx == dev->msgs_num) | |
440 | intr_mask &= ~DW_IC_INTR_TX_EMPTY; | |
441 | ||
8f588e40 SK |
442 | if (dev->msg_err) |
443 | intr_mask = 0; | |
444 | ||
2373f6b9 | 445 | dw_writel(dev, intr_mask, DW_IC_INTR_MASK); |
1ab52cf9 BS |
446 | } |
447 | ||
448 | static void | |
78839bd0 | 449 | i2c_dw_read(struct dw_i2c_dev *dev) |
1ab52cf9 | 450 | { |
1ab52cf9 | 451 | struct i2c_msg *msgs = dev->msgs; |
ae72222d | 452 | int rx_valid; |
1ab52cf9 | 453 | |
6d2ea487 | 454 | for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) { |
ed5e1dd5 | 455 | u32 len; |
1ab52cf9 BS |
456 | u8 *buf; |
457 | ||
458 | if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD)) | |
459 | continue; | |
460 | ||
1ab52cf9 BS |
461 | if (!(dev->status & STATUS_READ_IN_PROGRESS)) { |
462 | len = msgs[dev->msg_read_idx].len; | |
463 | buf = msgs[dev->msg_read_idx].buf; | |
464 | } else { | |
465 | len = dev->rx_buf_len; | |
466 | buf = dev->rx_buf; | |
467 | } | |
468 | ||
7f279601 | 469 | rx_valid = dw_readl(dev, DW_IC_RXFLR); |
ae72222d | 470 | |
1ab52cf9 | 471 | for (; len > 0 && rx_valid > 0; len--, rx_valid--) |
7f279601 | 472 | *buf++ = dw_readl(dev, DW_IC_DATA_CMD); |
1ab52cf9 BS |
473 | |
474 | if (len > 0) { | |
475 | dev->status |= STATUS_READ_IN_PROGRESS; | |
476 | dev->rx_buf_len = len; | |
477 | dev->rx_buf = buf; | |
478 | return; | |
479 | } else | |
480 | dev->status &= ~STATUS_READ_IN_PROGRESS; | |
481 | } | |
482 | } | |
483 | ||
ce6eb574 SK |
484 | static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev) |
485 | { | |
486 | unsigned long abort_source = dev->abort_source; | |
487 | int i; | |
488 | ||
6d1ea0f6 | 489 | if (abort_source & DW_IC_TX_ABRT_NOACK) { |
984b3f57 | 490 | for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) |
6d1ea0f6 SK |
491 | dev_dbg(dev->dev, |
492 | "%s: %s\n", __func__, abort_sources[i]); | |
493 | return -EREMOTEIO; | |
494 | } | |
495 | ||
984b3f57 | 496 | for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) |
ce6eb574 SK |
497 | dev_err(dev->dev, "%s: %s\n", __func__, abort_sources[i]); |
498 | ||
499 | if (abort_source & DW_IC_TX_ARB_LOST) | |
500 | return -EAGAIN; | |
ce6eb574 SK |
501 | else if (abort_source & DW_IC_TX_ABRT_GCALL_READ) |
502 | return -EINVAL; /* wrong msgs[] data */ | |
503 | else | |
504 | return -EIO; | |
505 | } | |
506 | ||
1ab52cf9 BS |
507 | /* |
508 | * Prepare controller for a transaction and call i2c_dw_xfer_msg | |
509 | */ | |
2373f6b9 | 510 | int |
1ab52cf9 BS |
511 | i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) |
512 | { | |
513 | struct dw_i2c_dev *dev = i2c_get_adapdata(adap); | |
514 | int ret; | |
515 | ||
516 | dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); | |
517 | ||
518 | mutex_lock(&dev->lock); | |
18dbdda8 | 519 | pm_runtime_get_sync(dev->dev); |
1ab52cf9 BS |
520 | |
521 | INIT_COMPLETION(dev->cmd_complete); | |
522 | dev->msgs = msgs; | |
523 | dev->msgs_num = num; | |
524 | dev->cmd_err = 0; | |
525 | dev->msg_write_idx = 0; | |
526 | dev->msg_read_idx = 0; | |
527 | dev->msg_err = 0; | |
528 | dev->status = STATUS_IDLE; | |
ce6eb574 | 529 | dev->abort_source = 0; |
1ab52cf9 BS |
530 | |
531 | ret = i2c_dw_wait_bus_not_busy(dev); | |
532 | if (ret < 0) | |
533 | goto done; | |
534 | ||
535 | /* start the transfers */ | |
81e798b7 | 536 | i2c_dw_xfer_init(dev); |
1ab52cf9 BS |
537 | |
538 | /* wait for tx to complete */ | |
539 | ret = wait_for_completion_interruptible_timeout(&dev->cmd_complete, HZ); | |
540 | if (ret == 0) { | |
541 | dev_err(dev->dev, "controller timed out\n"); | |
542 | i2c_dw_init(dev); | |
543 | ret = -ETIMEDOUT; | |
544 | goto done; | |
545 | } else if (ret < 0) | |
546 | goto done; | |
547 | ||
548 | if (dev->msg_err) { | |
549 | ret = dev->msg_err; | |
550 | goto done; | |
551 | } | |
552 | ||
553 | /* no error */ | |
554 | if (likely(!dev->cmd_err)) { | |
07745399 | 555 | /* Disable the adapter */ |
7f279601 | 556 | dw_writel(dev, 0, DW_IC_ENABLE); |
1ab52cf9 BS |
557 | ret = num; |
558 | goto done; | |
559 | } | |
560 | ||
561 | /* We have an error */ | |
562 | if (dev->cmd_err == DW_IC_ERR_TX_ABRT) { | |
ce6eb574 SK |
563 | ret = i2c_dw_handle_tx_abort(dev); |
564 | goto done; | |
1ab52cf9 BS |
565 | } |
566 | ret = -EIO; | |
567 | ||
568 | done: | |
18dbdda8 | 569 | pm_runtime_put(dev->dev); |
1ab52cf9 BS |
570 | mutex_unlock(&dev->lock); |
571 | ||
572 | return ret; | |
573 | } | |
e68bb91b | 574 | EXPORT_SYMBOL_GPL(i2c_dw_xfer); |
1ab52cf9 | 575 | |
2373f6b9 | 576 | u32 i2c_dw_func(struct i2c_adapter *adap) |
1ab52cf9 | 577 | { |
2fa8326b DB |
578 | struct dw_i2c_dev *dev = i2c_get_adapdata(adap); |
579 | return dev->functionality; | |
1ab52cf9 | 580 | } |
e68bb91b | 581 | EXPORT_SYMBOL_GPL(i2c_dw_func); |
1ab52cf9 | 582 | |
e28000a3 SK |
583 | static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) |
584 | { | |
585 | u32 stat; | |
586 | ||
587 | /* | |
588 | * The IC_INTR_STAT register just indicates "enabled" interrupts. | |
589 | * Ths unmasked raw version of interrupt status bits are available | |
590 | * in the IC_RAW_INTR_STAT register. | |
591 | * | |
592 | * That is, | |
2373f6b9 | 593 | * stat = dw_readl(IC_INTR_STAT); |
e28000a3 | 594 | * equals to, |
2373f6b9 | 595 | * stat = dw_readl(IC_RAW_INTR_STAT) & dw_readl(IC_INTR_MASK); |
e28000a3 SK |
596 | * |
597 | * The raw version might be useful for debugging purposes. | |
598 | */ | |
7f279601 | 599 | stat = dw_readl(dev, DW_IC_INTR_STAT); |
e28000a3 SK |
600 | |
601 | /* | |
602 | * Do not use the IC_CLR_INTR register to clear interrupts, or | |
603 | * you'll miss some interrupts, triggered during the period from | |
2373f6b9 | 604 | * dw_readl(IC_INTR_STAT) to dw_readl(IC_CLR_INTR). |
e28000a3 SK |
605 | * |
606 | * Instead, use the separately-prepared IC_CLR_* registers. | |
607 | */ | |
608 | if (stat & DW_IC_INTR_RX_UNDER) | |
7f279601 | 609 | dw_readl(dev, DW_IC_CLR_RX_UNDER); |
e28000a3 | 610 | if (stat & DW_IC_INTR_RX_OVER) |
7f279601 | 611 | dw_readl(dev, DW_IC_CLR_RX_OVER); |
e28000a3 | 612 | if (stat & DW_IC_INTR_TX_OVER) |
7f279601 | 613 | dw_readl(dev, DW_IC_CLR_TX_OVER); |
e28000a3 | 614 | if (stat & DW_IC_INTR_RD_REQ) |
7f279601 | 615 | dw_readl(dev, DW_IC_CLR_RD_REQ); |
e28000a3 SK |
616 | if (stat & DW_IC_INTR_TX_ABRT) { |
617 | /* | |
618 | * The IC_TX_ABRT_SOURCE register is cleared whenever | |
619 | * the IC_CLR_TX_ABRT is read. Preserve it beforehand. | |
620 | */ | |
7f279601 JHD |
621 | dev->abort_source = dw_readl(dev, DW_IC_TX_ABRT_SOURCE); |
622 | dw_readl(dev, DW_IC_CLR_TX_ABRT); | |
e28000a3 SK |
623 | } |
624 | if (stat & DW_IC_INTR_RX_DONE) | |
7f279601 | 625 | dw_readl(dev, DW_IC_CLR_RX_DONE); |
e28000a3 | 626 | if (stat & DW_IC_INTR_ACTIVITY) |
7f279601 | 627 | dw_readl(dev, DW_IC_CLR_ACTIVITY); |
e28000a3 | 628 | if (stat & DW_IC_INTR_STOP_DET) |
7f279601 | 629 | dw_readl(dev, DW_IC_CLR_STOP_DET); |
e28000a3 | 630 | if (stat & DW_IC_INTR_START_DET) |
7f279601 | 631 | dw_readl(dev, DW_IC_CLR_START_DET); |
e28000a3 | 632 | if (stat & DW_IC_INTR_GEN_CALL) |
7f279601 | 633 | dw_readl(dev, DW_IC_CLR_GEN_CALL); |
e28000a3 SK |
634 | |
635 | return stat; | |
636 | } | |
637 | ||
1ab52cf9 BS |
638 | /* |
639 | * Interrupt service routine. This gets called whenever an I2C interrupt | |
640 | * occurs. | |
641 | */ | |
2373f6b9 | 642 | irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) |
1ab52cf9 BS |
643 | { |
644 | struct dw_i2c_dev *dev = dev_id; | |
af06cf6c DB |
645 | u32 stat, enabled; |
646 | ||
647 | enabled = dw_readl(dev, DW_IC_ENABLE); | |
648 | stat = dw_readl(dev, DW_IC_RAW_INTR_STAT); | |
649 | dev_dbg(dev->dev, "%s: %s enabled= 0x%x stat=0x%x\n", __func__, | |
650 | dev->adapter.name, enabled, stat); | |
651 | if (!enabled || !(stat & ~DW_IC_INTR_ACTIVITY)) | |
652 | return IRQ_NONE; | |
1ab52cf9 | 653 | |
e28000a3 | 654 | stat = i2c_dw_read_clear_intrbits(dev); |
e28000a3 | 655 | |
1ab52cf9 | 656 | if (stat & DW_IC_INTR_TX_ABRT) { |
1ab52cf9 BS |
657 | dev->cmd_err |= DW_IC_ERR_TX_ABRT; |
658 | dev->status = STATUS_IDLE; | |
597fe310 SK |
659 | |
660 | /* | |
661 | * Anytime TX_ABRT is set, the contents of the tx/rx | |
662 | * buffers are flushed. Make sure to skip them. | |
663 | */ | |
7f279601 | 664 | dw_writel(dev, 0, DW_IC_INTR_MASK); |
597fe310 | 665 | goto tx_aborted; |
07745399 SK |
666 | } |
667 | ||
21a89d41 | 668 | if (stat & DW_IC_INTR_RX_FULL) |
07745399 | 669 | i2c_dw_read(dev); |
21a89d41 SK |
670 | |
671 | if (stat & DW_IC_INTR_TX_EMPTY) | |
07745399 | 672 | i2c_dw_xfer_msg(dev); |
07745399 SK |
673 | |
674 | /* | |
675 | * No need to modify or disable the interrupt mask here. | |
676 | * i2c_dw_xfer_msg() will take care of it according to | |
677 | * the current transmit status. | |
678 | */ | |
1ab52cf9 | 679 | |
597fe310 | 680 | tx_aborted: |
8f588e40 | 681 | if ((stat & (DW_IC_INTR_TX_ABRT | DW_IC_INTR_STOP_DET)) || dev->msg_err) |
1ab52cf9 BS |
682 | complete(&dev->cmd_complete); |
683 | ||
684 | return IRQ_HANDLED; | |
685 | } | |
e68bb91b | 686 | EXPORT_SYMBOL_GPL(i2c_dw_isr); |
f3fa9f3d DB |
687 | |
688 | void i2c_dw_enable(struct dw_i2c_dev *dev) | |
689 | { | |
690 | /* Enable the adapter */ | |
691 | dw_writel(dev, 1, DW_IC_ENABLE); | |
692 | } | |
e68bb91b | 693 | EXPORT_SYMBOL_GPL(i2c_dw_enable); |
f3fa9f3d | 694 | |
18dbdda8 | 695 | u32 i2c_dw_is_enabled(struct dw_i2c_dev *dev) |
f3fa9f3d | 696 | { |
18dbdda8 DB |
697 | return dw_readl(dev, DW_IC_ENABLE); |
698 | } | |
e68bb91b | 699 | EXPORT_SYMBOL_GPL(i2c_dw_is_enabled); |
f3fa9f3d | 700 | |
18dbdda8 DB |
701 | void i2c_dw_disable(struct dw_i2c_dev *dev) |
702 | { | |
f3fa9f3d DB |
703 | /* Disable controller */ |
704 | dw_writel(dev, 0, DW_IC_ENABLE); | |
705 | ||
706 | /* Disable all interupts */ | |
707 | dw_writel(dev, 0, DW_IC_INTR_MASK); | |
708 | dw_readl(dev, DW_IC_CLR_INTR); | |
709 | } | |
e68bb91b | 710 | EXPORT_SYMBOL_GPL(i2c_dw_disable); |
f3fa9f3d DB |
711 | |
712 | void i2c_dw_clear_int(struct dw_i2c_dev *dev) | |
713 | { | |
714 | dw_readl(dev, DW_IC_CLR_INTR); | |
715 | } | |
e68bb91b | 716 | EXPORT_SYMBOL_GPL(i2c_dw_clear_int); |
f3fa9f3d DB |
717 | |
718 | void i2c_dw_disable_int(struct dw_i2c_dev *dev) | |
719 | { | |
720 | dw_writel(dev, 0, DW_IC_INTR_MASK); | |
721 | } | |
e68bb91b | 722 | EXPORT_SYMBOL_GPL(i2c_dw_disable_int); |
f3fa9f3d DB |
723 | |
724 | u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev) | |
725 | { | |
726 | return dw_readl(dev, DW_IC_COMP_PARAM_1); | |
727 | } | |
e68bb91b | 728 | EXPORT_SYMBOL_GPL(i2c_dw_read_comp_param); |
9dd3162d MW |
729 | |
730 | MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter core"); | |
731 | MODULE_LICENSE("GPL"); |