aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorZubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com>2015-03-31 09:03:55 -0400
committerWolfram Sang <wsa@the-dreams.de>2015-04-03 15:22:52 -0400
commitba92222ed63a12d09120df9b92f56cc990abac19 (patch)
tree9cf7f2b45533e3c18030f85550eba5f041dee0c0 /drivers/i2c
parent3b10db23c0411524357c5834731df2e24897b53b (diff)
i2c: jz4780: Add i2c bus controller driver for Ingenic JZ4780
Adds the i2c bus controller driver for the Ingenic JZ4780 SoC. Signed-off-by: Zubair Lutfullah Kakakhel <Zubair.Kakakhel@imgtec.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/Kconfig9
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-jz4780.c832
3 files changed, 842 insertions, 0 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index db09881614b7..0b0ca7dd5d1f 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -583,6 +583,15 @@ config I2C_IOP3XX
583 This driver can also be built as a module. If so, the module 583 This driver can also be built as a module. If so, the module
584 will be called i2c-iop3xx. 584 will be called i2c-iop3xx.
585 585
586config I2C_JZ4780
587 tristate "JZ4780 I2C controller interface support"
588 depends on MACH_JZ4780 || COMPILE_TEST
589 help
590 If you say yes to this option, support will be included for the
591 Ingenic JZ4780 I2C controller.
592
593 If you don't know what to do here, say N.
594
586config I2C_KEMPLD 595config I2C_KEMPLD
587 tristate "Kontron COM I2C Controller" 596 tristate "Kontron COM I2C Controller"
588 depends on MFD_KEMPLD 597 depends on MFD_KEMPLD
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 4413f09996cb..ab6a0a67aca1 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -56,6 +56,7 @@ obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
56obj-$(CONFIG_I2C_IMG) += i2c-img-scb.o 56obj-$(CONFIG_I2C_IMG) += i2c-img-scb.o
57obj-$(CONFIG_I2C_IMX) += i2c-imx.o 57obj-$(CONFIG_I2C_IMX) += i2c-imx.o
58obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o 58obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
59obj-$(CONFIG_I2C_JZ4780) += i2c-jz4780.o
59obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o 60obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o
60obj-$(CONFIG_I2C_MESON) += i2c-meson.o 61obj-$(CONFIG_I2C_MESON) += i2c-meson.o
61obj-$(CONFIG_I2C_MPC) += i2c-mpc.o 62obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
diff --git a/drivers/i2c/busses/i2c-jz4780.c b/drivers/i2c/busses/i2c-jz4780.c
new file mode 100644
index 000000000000..ce1d69324169
--- /dev/null
+++ b/drivers/i2c/busses/i2c-jz4780.c
@@ -0,0 +1,832 @@
1/*
2 * Ingenic JZ4780 I2C bus driver
3 *
4 * Copyright (C) 2006 - 2009 Ingenic Semiconductor Inc.
5 * Copyright (C) 2015 Imagination Technologies
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/bitops.h>
19#include <linux/clk.h>
20#include <linux/completion.h>
21#include <linux/delay.h>
22#include <linux/errno.h>
23#include <linux/i2c.h>
24#include <linux/init.h>
25#include <linux/interrupt.h>
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/platform_device.h>
29#include <linux/sched.h>
30#include <linux/slab.h>
31#include <linux/time.h>
32
33#define JZ4780_I2C_CTRL 0x00
34#define JZ4780_I2C_TAR 0x04
35#define JZ4780_I2C_SAR 0x08
36#define JZ4780_I2C_DC 0x10
37#define JZ4780_I2C_SHCNT 0x14
38#define JZ4780_I2C_SLCNT 0x18
39#define JZ4780_I2C_FHCNT 0x1C
40#define JZ4780_I2C_FLCNT 0x20
41#define JZ4780_I2C_INTST 0x2C
42#define JZ4780_I2C_INTM 0x30
43#define JZ4780_I2C_RXTL 0x38
44#define JZ4780_I2C_TXTL 0x3C
45#define JZ4780_I2C_CINTR 0x40
46#define JZ4780_I2C_CRXUF 0x44
47#define JZ4780_I2C_CRXOF 0x48
48#define JZ4780_I2C_CTXOF 0x4C
49#define JZ4780_I2C_CRXREQ 0x50
50#define JZ4780_I2C_CTXABRT 0x54
51#define JZ4780_I2C_CRXDONE 0x58
52#define JZ4780_I2C_CACT 0x5C
53#define JZ4780_I2C_CSTP 0x60
54#define JZ4780_I2C_CSTT 0x64
55#define JZ4780_I2C_CGC 0x68
56#define JZ4780_I2C_ENB 0x6C
57#define JZ4780_I2C_STA 0x70
58#define JZ4780_I2C_TXABRT 0x80
59#define JZ4780_I2C_DMACR 0x88
60#define JZ4780_I2C_DMATDLR 0x8C
61#define JZ4780_I2C_DMARDLR 0x90
62#define JZ4780_I2C_SDASU 0x94
63#define JZ4780_I2C_ACKGC 0x98
64#define JZ4780_I2C_ENSTA 0x9C
65#define JZ4780_I2C_SDAHD 0xD0
66
67#define JZ4780_I2C_CTRL_STPHLD BIT(7)
68#define JZ4780_I2C_CTRL_SLVDIS BIT(6)
69#define JZ4780_I2C_CTRL_REST BIT(5)
70#define JZ4780_I2C_CTRL_MATP BIT(4)
71#define JZ4780_I2C_CTRL_SATP BIT(3)
72#define JZ4780_I2C_CTRL_SPDF BIT(2)
73#define JZ4780_I2C_CTRL_SPDS BIT(1)
74#define JZ4780_I2C_CTRL_MD BIT(0)
75
76#define JZ4780_I2C_STA_SLVACT BIT(6)
77#define JZ4780_I2C_STA_MSTACT BIT(5)
78#define JZ4780_I2C_STA_RFF BIT(4)
79#define JZ4780_I2C_STA_RFNE BIT(3)
80#define JZ4780_I2C_STA_TFE BIT(2)
81#define JZ4780_I2C_STA_TFNF BIT(1)
82#define JZ4780_I2C_STA_ACT BIT(0)
83
84static const char * const jz4780_i2c_abrt_src[] = {
85 "ABRT_7B_ADDR_NOACK",
86 "ABRT_10ADDR1_NOACK",
87 "ABRT_10ADDR2_NOACK",
88 "ABRT_XDATA_NOACK",
89 "ABRT_GCALL_NOACK",
90 "ABRT_GCALL_READ",
91 "ABRT_HS_ACKD",
92 "SBYTE_ACKDET",
93 "ABRT_HS_NORSTRT",
94 "SBYTE_NORSTRT",
95 "ABRT_10B_RD_NORSTRT",
96 "ABRT_MASTER_DIS",
97 "ARB_LOST",
98 "SLVFLUSH_TXFIFO",
99 "SLV_ARBLOST",
100 "SLVRD_INTX",
101};
102
103#define JZ4780_I2C_INTST_IGC BIT(11)
104#define JZ4780_I2C_INTST_ISTT BIT(10)
105#define JZ4780_I2C_INTST_ISTP BIT(9)
106#define JZ4780_I2C_INTST_IACT BIT(8)
107#define JZ4780_I2C_INTST_RXDN BIT(7)
108#define JZ4780_I2C_INTST_TXABT BIT(6)
109#define JZ4780_I2C_INTST_RDREQ BIT(5)
110#define JZ4780_I2C_INTST_TXEMP BIT(4)
111#define JZ4780_I2C_INTST_TXOF BIT(3)
112#define JZ4780_I2C_INTST_RXFL BIT(2)
113#define JZ4780_I2C_INTST_RXOF BIT(1)
114#define JZ4780_I2C_INTST_RXUF BIT(0)
115
116#define JZ4780_I2C_INTM_MIGC BIT(11)
117#define JZ4780_I2C_INTM_MISTT BIT(10)
118#define JZ4780_I2C_INTM_MISTP BIT(9)
119#define JZ4780_I2C_INTM_MIACT BIT(8)
120#define JZ4780_I2C_INTM_MRXDN BIT(7)
121#define JZ4780_I2C_INTM_MTXABT BIT(6)
122#define JZ4780_I2C_INTM_MRDREQ BIT(5)
123#define JZ4780_I2C_INTM_MTXEMP BIT(4)
124#define JZ4780_I2C_INTM_MTXOF BIT(3)
125#define JZ4780_I2C_INTM_MRXFL BIT(2)
126#define JZ4780_I2C_INTM_MRXOF BIT(1)
127#define JZ4780_I2C_INTM_MRXUF BIT(0)
128
129#define JZ4780_I2C_DC_READ BIT(8)
130
131#define JZ4780_I2C_SDAHD_HDENB BIT(8)
132
133#define JZ4780_I2C_ENB_I2C BIT(0)
134
135#define JZ4780_I2CSHCNT_ADJUST(n) (((n) - 8) < 6 ? 6 : ((n) - 8))
136#define JZ4780_I2CSLCNT_ADJUST(n) (((n) - 1) < 8 ? 8 : ((n) - 1))
137#define JZ4780_I2CFHCNT_ADJUST(n) (((n) - 8) < 6 ? 6 : ((n) - 8))
138#define JZ4780_I2CFLCNT_ADJUST(n) (((n) - 1) < 8 ? 8 : ((n) - 1))
139
140#define JZ4780_I2C_FIFO_LEN 16
141#define TX_LEVEL 3
142#define RX_LEVEL (JZ4780_I2C_FIFO_LEN - TX_LEVEL - 1)
143
144#define JZ4780_I2C_TIMEOUT 300
145
146#define BUFSIZE 200
147
148struct jz4780_i2c {
149 void __iomem *iomem;
150 int irq;
151 struct clk *clk;
152 struct i2c_adapter adap;
153
154 /* lock to protect rbuf and wbuf between xfer_rd/wr and irq handler */
155 spinlock_t lock;
156
157 /* beginning of lock scope */
158 unsigned char *rbuf;
159 int rd_total_len;
160 int rd_data_xfered;
161 int rd_cmd_xfered;
162
163 unsigned char *wbuf;
164 int wt_len;
165
166 int is_write;
167 int stop_hold;
168 int speed;
169
170 int data_buf[BUFSIZE];
171 int cmd_buf[BUFSIZE];
172 int cmd;
173
174 /* end of lock scope */
175 struct completion trans_waitq;
176};
177
178static inline unsigned short jz4780_i2c_readw(struct jz4780_i2c *i2c,
179 unsigned long offset)
180{
181 return readw(i2c->iomem + offset);
182}
183
184static inline void jz4780_i2c_writew(struct jz4780_i2c *i2c,
185 unsigned long offset, unsigned short val)
186{
187 writew(val, i2c->iomem + offset);
188}
189
190static int jz4780_i2c_disable(struct jz4780_i2c *i2c)
191{
192 unsigned short regval;
193 unsigned long loops = 5;
194
195 jz4780_i2c_writew(i2c, JZ4780_I2C_ENB, 0);
196
197 do {
198 regval = jz4780_i2c_readw(i2c, JZ4780_I2C_ENSTA);
199 if (!(regval & JZ4780_I2C_ENB_I2C))
200 return 0;
201
202 usleep_range(5000, 15000);
203 } while (--loops);
204
205 dev_err(&i2c->adap.dev, "disable failed: ENSTA=0x%04x\n", regval);
206 return -ETIMEDOUT;
207}
208
209static int jz4780_i2c_enable(struct jz4780_i2c *i2c)
210{
211 unsigned short regval;
212 unsigned long loops = 5;
213
214 jz4780_i2c_writew(i2c, JZ4780_I2C_ENB, 1);
215
216 do {
217 regval = jz4780_i2c_readw(i2c, JZ4780_I2C_ENSTA);
218 if (regval & JZ4780_I2C_ENB_I2C)
219 return 0;
220
221 usleep_range(5000, 15000);
222 } while (--loops);
223
224 dev_err(&i2c->adap.dev, "enable failed: ENSTA=0x%04x\n", regval);
225 return -ETIMEDOUT;
226}
227
228static int jz4780_i2c_set_target(struct jz4780_i2c *i2c, unsigned char address)
229{
230 unsigned short regval;
231 unsigned long loops = 5;
232
233 do {
234 regval = jz4780_i2c_readw(i2c, JZ4780_I2C_STA);
235 if ((regval & JZ4780_I2C_STA_TFE) &&
236 !(regval & JZ4780_I2C_STA_MSTACT))
237 break;
238
239 usleep_range(5000, 15000);
240 } while (--loops);
241
242 if (loops) {
243 jz4780_i2c_writew(i2c, JZ4780_I2C_TAR, address);
244 return 0;
245 }
246
247 dev_err(&i2c->adap.dev,
248 "set device to address 0x%02x failed, STA=0x%04x\n",
249 address, regval);
250
251 return -ENXIO;
252}
253
254static int jz4780_i2c_set_speed(struct jz4780_i2c *i2c)
255{
256 int dev_clk_khz = clk_get_rate(i2c->clk) / 1000;
257 int cnt_high = 0; /* HIGH period count of the SCL clock */
258 int cnt_low = 0; /* LOW period count of the SCL clock */
259 int cnt_period = 0; /* period count of the SCL clock */
260 int setup_time = 0;
261 int hold_time = 0;
262 unsigned short tmp = 0;
263 int i2c_clk = i2c->speed;
264
265 if (jz4780_i2c_disable(i2c))
266 dev_dbg(&i2c->adap.dev, "i2c not disabled\n");
267
268 /*
269 * 1 JZ4780_I2C cycle equals to cnt_period PCLK(i2c_clk)
270 * standard mode, min LOW and HIGH period are 4700 ns and 4000 ns
271 * fast mode, min LOW and HIGH period are 1300 ns and 600 ns
272 */
273 cnt_period = dev_clk_khz / i2c_clk;
274
275 if (i2c_clk <= 100)
276 cnt_high = (cnt_period * 4000) / (4700 + 4000);
277 else
278 cnt_high = (cnt_period * 600) / (1300 + 600);
279
280 cnt_low = cnt_period - cnt_high;
281
282 /*
283 * NOTE: JZ4780_I2C_CTRL_REST can't set when i2c enabled, because
284 * normal read are 2 messages, we cannot disable i2c controller
285 * between these two messages, this means that we must always set
286 * JZ4780_I2C_CTRL_REST when init JZ4780_I2C_CTRL
287 *
288 */
289 if (i2c_clk <= 100) {
290 tmp = JZ4780_I2C_CTRL_SPDS | JZ4780_I2C_CTRL_REST
291 | JZ4780_I2C_CTRL_SLVDIS | JZ4780_I2C_CTRL_MD;
292 jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
293
294 jz4780_i2c_writew(i2c, JZ4780_I2C_SHCNT,
295 JZ4780_I2CSHCNT_ADJUST(cnt_high));
296 jz4780_i2c_writew(i2c, JZ4780_I2C_SLCNT,
297 JZ4780_I2CSLCNT_ADJUST(cnt_low));
298 } else {
299 tmp = JZ4780_I2C_CTRL_SPDF | JZ4780_I2C_CTRL_REST
300 | JZ4780_I2C_CTRL_SLVDIS | JZ4780_I2C_CTRL_MD;
301 jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
302
303 jz4780_i2c_writew(i2c, JZ4780_I2C_FHCNT,
304 JZ4780_I2CFHCNT_ADJUST(cnt_high));
305 jz4780_i2c_writew(i2c, JZ4780_I2C_FLCNT,
306 JZ4780_I2CFLCNT_ADJUST(cnt_low));
307 }
308
309 /*
310 * a i2c device must internally provide a hold time at least 300ns
311 * tHD:DAT
312 * Standard Mode: min=300ns, max=3450ns
313 * Fast Mode: min=0ns, max=900ns
314 * tSU:DAT
315 * Standard Mode: min=250ns, max=infinite
316 * Fast Mode: min=100(250ns is recommended), max=infinite
317 *
318 * 1i2c_clk = 10^6 / dev_clk_khz
319 * on FPGA, dev_clk_khz = 12000, so 1i2c_clk = 1000/12 = 83ns
320 * on Pisces(1008M), dev_clk_khz=126000, so 1i2c_clk = 1000 / 126 = 8ns
321 *
322 * The actual hold time is (SDAHD + 1) * (i2c_clk period).
323 *
324 * Length of setup time calculated using (SDASU - 1) * (ic_clk_period)
325 *
326 */
327 if (i2c_clk <= 100) { /* standard mode */
328 setup_time = 300;
329 hold_time = 400;
330 } else {
331 setup_time = 450;
332 hold_time = 450;
333 }
334
335 hold_time = ((hold_time * dev_clk_khz) / 1000000) - 1;
336 setup_time = ((setup_time * dev_clk_khz) / 1000000) + 1;
337
338 if (setup_time > 255)
339 setup_time = 255;
340
341 if (setup_time <= 0)
342 setup_time = 1;
343
344 jz4780_i2c_writew(i2c, JZ4780_I2C_SDASU, setup_time);
345
346 if (hold_time > 255)
347 hold_time = 255;
348
349 if (hold_time >= 0) {
350 /*i2c hold time enable */
351 hold_time |= JZ4780_I2C_SDAHD_HDENB;
352 jz4780_i2c_writew(i2c, JZ4780_I2C_SDAHD, hold_time);
353 } else {
354 /* disable hold time */
355 jz4780_i2c_writew(i2c, JZ4780_I2C_SDAHD, 0);
356 }
357
358 return 0;
359}
360
361static int jz4780_i2c_cleanup(struct jz4780_i2c *i2c)
362{
363 int ret;
364 unsigned long flags;
365 unsigned short tmp;
366
367 spin_lock_irqsave(&i2c->lock, flags);
368
369 /* can send stop now if need */
370 tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
371 tmp &= ~JZ4780_I2C_CTRL_STPHLD;
372 jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
373
374 /* disable all interrupts first */
375 jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, 0);
376
377 /* then clear all interrupts */
378 jz4780_i2c_readw(i2c, JZ4780_I2C_CTXABRT);
379 jz4780_i2c_readw(i2c, JZ4780_I2C_CINTR);
380
381 /* then disable the controller */
382 tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
383 tmp &= ~JZ4780_I2C_ENB_I2C;
384 jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
385 udelay(10);
386 tmp |= JZ4780_I2C_ENB_I2C;
387 jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
388
389 spin_unlock_irqrestore(&i2c->lock, flags);
390
391 ret = jz4780_i2c_disable(i2c);
392 if (ret)
393 dev_err(&i2c->adap.dev,
394 "unable to disable device during cleanup!\n");
395
396 if (unlikely(jz4780_i2c_readw(i2c, JZ4780_I2C_INTM)
397 & jz4780_i2c_readw(i2c, JZ4780_I2C_INTST)))
398 dev_err(&i2c->adap.dev,
399 "device has interrupts after a complete cleanup!\n");
400
401 return ret;
402}
403
404static int jz4780_i2c_prepare(struct jz4780_i2c *i2c)
405{
406 jz4780_i2c_set_speed(i2c);
407 return jz4780_i2c_enable(i2c);
408}
409
410static void jz4780_i2c_send_rcmd(struct jz4780_i2c *i2c, int cmd_count)
411{
412 int i;
413
414 for (i = 0; i < cmd_count; i++)
415 jz4780_i2c_writew(i2c, JZ4780_I2C_DC, JZ4780_I2C_DC_READ);
416}
417
418static void jz4780_i2c_trans_done(struct jz4780_i2c *i2c)
419{
420 jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, 0);
421 complete(&i2c->trans_waitq);
422}
423
424static irqreturn_t jz4780_i2c_irq(int irqno, void *dev_id)
425{
426 unsigned short tmp;
427 unsigned short intst;
428 unsigned short intmsk;
429 struct jz4780_i2c *i2c = dev_id;
430 unsigned long flags;
431
432 spin_lock_irqsave(&i2c->lock, flags);
433 intmsk = jz4780_i2c_readw(i2c, JZ4780_I2C_INTM);
434 intst = jz4780_i2c_readw(i2c, JZ4780_I2C_INTST);
435
436 intst &= intmsk;
437
438 if (intst & JZ4780_I2C_INTST_TXABT) {
439 jz4780_i2c_trans_done(i2c);
440 goto done;
441 }
442
443 if (intst & JZ4780_I2C_INTST_RXOF) {
444 dev_dbg(&i2c->adap.dev, "received fifo overflow!\n");
445 jz4780_i2c_trans_done(i2c);
446 goto done;
447 }
448
449 /*
450 * When reading, always drain RX FIFO before we send more Read
451 * Commands to avoid fifo overrun
452 */
453 if (i2c->is_write == 0) {
454 int rd_left;
455
456 while ((jz4780_i2c_readw(i2c, JZ4780_I2C_STA)
457 & JZ4780_I2C_STA_RFNE)) {
458 *(i2c->rbuf++) = jz4780_i2c_readw(i2c, JZ4780_I2C_DC)
459 & 0xff;
460 i2c->rd_data_xfered++;
461 if (i2c->rd_data_xfered == i2c->rd_total_len) {
462 jz4780_i2c_trans_done(i2c);
463 goto done;
464 }
465 }
466
467 rd_left = i2c->rd_total_len - i2c->rd_data_xfered;
468
469 if (rd_left <= JZ4780_I2C_FIFO_LEN)
470 jz4780_i2c_writew(i2c, JZ4780_I2C_RXTL, rd_left - 1);
471 }
472
473 if (intst & JZ4780_I2C_INTST_TXEMP) {
474 if (i2c->is_write == 0) {
475 int cmd_left = i2c->rd_total_len - i2c->rd_cmd_xfered;
476 int max_send = (JZ4780_I2C_FIFO_LEN - 1)
477 - (i2c->rd_cmd_xfered
478 - i2c->rd_data_xfered);
479 int cmd_to_send = min(cmd_left, max_send);
480
481 if (i2c->rd_cmd_xfered != 0)
482 cmd_to_send = min(cmd_to_send,
483 JZ4780_I2C_FIFO_LEN
484 - TX_LEVEL - 1);
485
486 if (cmd_to_send) {
487 jz4780_i2c_send_rcmd(i2c, cmd_to_send);
488 i2c->rd_cmd_xfered += cmd_to_send;
489 }
490
491 cmd_left = i2c->rd_total_len - i2c->rd_cmd_xfered;
492 if (cmd_left == 0) {
493 intmsk = jz4780_i2c_readw(i2c, JZ4780_I2C_INTM);
494 intmsk &= ~JZ4780_I2C_INTM_MTXEMP;
495 jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, intmsk);
496
497 tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
498 tmp &= ~JZ4780_I2C_CTRL_STPHLD;
499 jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
500 }
501 } else {
502 unsigned short data;
503 unsigned short i2c_sta;
504
505 i2c_sta = jz4780_i2c_readw(i2c, JZ4780_I2C_STA);
506
507 while ((i2c_sta & JZ4780_I2C_STA_TFNF) &&
508 (i2c->wt_len > 0)) {
509 i2c_sta = jz4780_i2c_readw(i2c, JZ4780_I2C_STA);
510 data = *i2c->wbuf;
511 data &= ~JZ4780_I2C_DC_READ;
512 jz4780_i2c_writew(i2c, JZ4780_I2C_DC,
513 data);
514 i2c->wbuf++;
515 i2c->wt_len--;
516 }
517
518 if (i2c->wt_len == 0) {
519 if (!i2c->stop_hold) {
520 tmp = jz4780_i2c_readw(i2c,
521 JZ4780_I2C_CTRL);
522 tmp &= ~JZ4780_I2C_CTRL_STPHLD;
523 jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL,
524 tmp);
525 }
526
527 jz4780_i2c_trans_done(i2c);
528 goto done;
529 }
530 }
531 }
532
533done:
534 spin_unlock_irqrestore(&i2c->lock, flags);
535 return IRQ_HANDLED;
536}
537
538static void jz4780_i2c_txabrt(struct jz4780_i2c *i2c, int src)
539{
540 int i;
541
542 dev_err(&i2c->adap.dev, "txabrt: 0x%08x\n", src);
543 dev_err(&i2c->adap.dev, "device addr=%x\n",
544 jz4780_i2c_readw(i2c, JZ4780_I2C_TAR));
545 dev_err(&i2c->adap.dev, "send cmd count:%d %d\n",
546 i2c->cmd, i2c->cmd_buf[i2c->cmd]);
547 dev_err(&i2c->adap.dev, "receive data count:%d %d\n",
548 i2c->cmd, i2c->data_buf[i2c->cmd]);
549
550 for (i = 0; i < 16; i++) {
551 if (src & BIT(i))
552 dev_dbg(&i2c->adap.dev, "I2C TXABRT[%d]=%s\n",
553 i, jz4780_i2c_abrt_src[i]);
554 }
555}
556
557static inline int jz4780_i2c_xfer_read(struct jz4780_i2c *i2c,
558 unsigned char *buf, int len, int cnt,
559 int idx)
560{
561 int ret = 0;
562 long timeout;
563 int wait_time = JZ4780_I2C_TIMEOUT * (len + 5);
564 unsigned short tmp;
565 unsigned long flags;
566
567 memset(buf, 0, len);
568
569 spin_lock_irqsave(&i2c->lock, flags);
570
571 i2c->stop_hold = 0;
572 i2c->is_write = 0;
573 i2c->rbuf = buf;
574 i2c->rd_total_len = len;
575 i2c->rd_data_xfered = 0;
576 i2c->rd_cmd_xfered = 0;
577
578 if (len <= JZ4780_I2C_FIFO_LEN)
579 jz4780_i2c_writew(i2c, JZ4780_I2C_RXTL, len - 1);
580 else
581 jz4780_i2c_writew(i2c, JZ4780_I2C_RXTL, RX_LEVEL);
582
583 jz4780_i2c_writew(i2c, JZ4780_I2C_TXTL, TX_LEVEL);
584
585 jz4780_i2c_writew(i2c, JZ4780_I2C_INTM,
586 JZ4780_I2C_INTM_MRXFL | JZ4780_I2C_INTM_MTXEMP
587 | JZ4780_I2C_INTM_MTXABT | JZ4780_I2C_INTM_MRXOF);
588
589 tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
590 tmp |= JZ4780_I2C_CTRL_STPHLD;
591 jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
592
593 spin_unlock_irqrestore(&i2c->lock, flags);
594
595 timeout = wait_for_completion_timeout(&i2c->trans_waitq,
596 msecs_to_jiffies(wait_time));
597
598 if (!timeout) {
599 dev_err(&i2c->adap.dev, "irq read timeout\n");
600 dev_dbg(&i2c->adap.dev, "send cmd count:%d %d\n",
601 i2c->cmd, i2c->cmd_buf[i2c->cmd]);
602 dev_dbg(&i2c->adap.dev, "receive data count:%d %d\n",
603 i2c->cmd, i2c->data_buf[i2c->cmd]);
604 ret = -EIO;
605 }
606
607 tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_TXABRT);
608 if (tmp) {
609 jz4780_i2c_txabrt(i2c, tmp);
610 ret = -EIO;
611 }
612
613 return ret;
614}
615
616static inline int jz4780_i2c_xfer_write(struct jz4780_i2c *i2c,
617 unsigned char *buf, int len,
618 int cnt, int idx)
619{
620 int ret = 0;
621 int wait_time = JZ4780_I2C_TIMEOUT * (len + 5);
622 long timeout;
623 unsigned short tmp;
624 unsigned long flags;
625
626 spin_lock_irqsave(&i2c->lock, flags);
627
628 if (idx < (cnt - 1))
629 i2c->stop_hold = 1;
630 else
631 i2c->stop_hold = 0;
632
633 i2c->is_write = 1;
634 i2c->wbuf = buf;
635 i2c->wt_len = len;
636
637 jz4780_i2c_writew(i2c, JZ4780_I2C_TXTL, TX_LEVEL);
638
639 jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, JZ4780_I2C_INTM_MTXEMP
640 | JZ4780_I2C_INTM_MTXABT);
641
642 tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
643 tmp |= JZ4780_I2C_CTRL_STPHLD;
644 jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
645
646 spin_unlock_irqrestore(&i2c->lock, flags);
647
648 timeout = wait_for_completion_timeout(&i2c->trans_waitq,
649 msecs_to_jiffies(wait_time));
650 if (timeout && !i2c->stop_hold) {
651 unsigned short i2c_sta;
652 int write_in_process;
653
654 timeout = JZ4780_I2C_TIMEOUT * 100;
655 for (; timeout > 0; timeout--) {
656 i2c_sta = jz4780_i2c_readw(i2c, JZ4780_I2C_STA);
657
658 write_in_process = (i2c_sta & JZ4780_I2C_STA_MSTACT) ||
659 !(i2c_sta & JZ4780_I2C_STA_TFE);
660 if (!write_in_process)
661 break;
662 udelay(10);
663 }
664 }
665
666 if (!timeout) {
667 dev_err(&i2c->adap.dev, "write wait timeout\n");
668 ret = -EIO;
669 }
670
671 tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_TXABRT);
672 if (tmp) {
673 jz4780_i2c_txabrt(i2c, tmp);
674 ret = -EIO;
675 }
676
677 return ret;
678}
679
680static int jz4780_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
681 int count)
682{
683 int i = -EIO;
684 int ret = 0;
685 struct jz4780_i2c *i2c = adap->algo_data;
686
687 ret = jz4780_i2c_prepare(i2c);
688 if (ret) {
689 dev_err(&i2c->adap.dev, "I2C prepare failed\n");
690 goto out;
691 }
692
693 if (msg->addr != jz4780_i2c_readw(i2c, JZ4780_I2C_TAR)) {
694 ret = jz4780_i2c_set_target(i2c, msg->addr);
695 if (ret)
696 goto out;
697 }
698 for (i = 0; i < count; i++, msg++) {
699 if (msg->flags & I2C_M_RD)
700 ret = jz4780_i2c_xfer_read(i2c, msg->buf, msg->len,
701 count, i);
702 else
703 ret = jz4780_i2c_xfer_write(i2c, msg->buf, msg->len,
704 count, i);
705
706 if (ret)
707 goto out;
708 }
709
710 ret = i;
711
712out:
713 jz4780_i2c_cleanup(i2c);
714 return ret;
715}
716
717static u32 jz4780_i2c_functionality(struct i2c_adapter *adap)
718{
719 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
720}
721
722static const struct i2c_algorithm jz4780_i2c_algorithm = {
723 .master_xfer = jz4780_i2c_xfer,
724 .functionality = jz4780_i2c_functionality,
725};
726
727static const struct of_device_id jz4780_i2c_of_matches[] = {
728 { .compatible = "ingenic,jz4780-i2c", },
729 { /* sentinel */ }
730};
731
732static int jz4780_i2c_probe(struct platform_device *pdev)
733{
734 int ret = 0;
735 unsigned int clk_freq = 0;
736 unsigned short tmp;
737 struct resource *r;
738 struct jz4780_i2c *i2c;
739
740 i2c = devm_kzalloc(&pdev->dev, sizeof(struct jz4780_i2c), GFP_KERNEL);
741 if (!i2c)
742 return -ENOMEM;
743
744 i2c->adap.owner = THIS_MODULE;
745 i2c->adap.algo = &jz4780_i2c_algorithm;
746 i2c->adap.algo_data = i2c;
747 i2c->adap.retries = 5;
748 i2c->adap.dev.parent = &pdev->dev;
749 i2c->adap.dev.of_node = pdev->dev.of_node;
750 sprintf(i2c->adap.name, "%s", pdev->name);
751
752 init_completion(&i2c->trans_waitq);
753 spin_lock_init(&i2c->lock);
754
755 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
756 i2c->iomem = devm_ioremap_resource(&pdev->dev, r);
757 if (IS_ERR(i2c->iomem))
758 return PTR_ERR(i2c->iomem);
759
760 platform_set_drvdata(pdev, i2c);
761
762 i2c->clk = devm_clk_get(&pdev->dev, NULL);
763 if (IS_ERR(i2c->clk))
764 return PTR_ERR(i2c->clk);
765
766 clk_prepare_enable(i2c->clk);
767
768 if (of_property_read_u32(pdev->dev.of_node, "clock-frequency",
769 &clk_freq)) {
770 dev_err(&pdev->dev, "clock-frequency not specified in DT");
771 return clk_freq;
772 }
773
774 i2c->speed = clk_freq / 1000;
775 jz4780_i2c_set_speed(i2c);
776
777 dev_info(&pdev->dev, "Bus frequency is %d KHz\n", i2c->speed);
778
779 tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
780 tmp &= ~JZ4780_I2C_CTRL_STPHLD;
781 jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
782
783 jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, 0x0);
784
785 i2c->cmd = 0;
786 memset(i2c->cmd_buf, 0, BUFSIZE);
787 memset(i2c->data_buf, 0, BUFSIZE);
788
789 i2c->irq = platform_get_irq(pdev, 0);
790 ret = devm_request_irq(&pdev->dev, i2c->irq, jz4780_i2c_irq, 0,
791 dev_name(&pdev->dev), i2c);
792 if (ret) {
793 ret = -ENODEV;
794 goto err;
795 }
796
797 ret = i2c_add_adapter(&i2c->adap);
798 if (ret < 0) {
799 dev_err(&pdev->dev, "Failed to add bus\n");
800 goto err;
801 }
802
803 return 0;
804
805err:
806 clk_disable_unprepare(i2c->clk);
807 return ret;
808}
809
810static int jz4780_i2c_remove(struct platform_device *pdev)
811{
812 struct jz4780_i2c *i2c = platform_get_drvdata(pdev);
813
814 clk_disable_unprepare(i2c->clk);
815 i2c_del_adapter(&i2c->adap);
816 return 0;
817}
818
819static struct platform_driver jz4780_i2c_driver = {
820 .probe = jz4780_i2c_probe,
821 .remove = jz4780_i2c_remove,
822 .driver = {
823 .name = "jz4780-i2c",
824 .of_match_table = of_match_ptr(jz4780_i2c_of_matches),
825 },
826};
827
828module_platform_driver(jz4780_i2c_driver);
829
830MODULE_LICENSE("GPL");
831MODULE_AUTHOR("ztyan<ztyan@ingenic.cn>");
832MODULE_DESCRIPTION("i2c driver for JZ4780 SoCs");