]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/iicbus/twsi/twsi.c
Merge upstream r948: fix race condition in openpam_ttyconv(3).
[FreeBSD/FreeBSD.git] / sys / dev / iicbus / twsi / twsi.c
1 /*-
2  * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
3  * All rights reserved.
4  *
5  * Developed by Semihalf.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of MARVELL nor the names of contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 /*
33  * Driver for the TWSI (aka I2C, aka IIC) bus controller found on Marvell
34  * and Allwinner SoCs. Supports master operation only.
35  *
36  * Calls to DELAY() are needed per Application Note AN-179 "TWSI Software
37  * Guidelines for Discovery(TM), Horizon (TM) and Feroceon(TM) Devices".
38  */
39
40 #include <sys/cdefs.h>
41 __FBSDID("$FreeBSD$");
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/bus.h>
46 #include <sys/kernel.h>
47 #include <sys/module.h>
48 #include <sys/resource.h>
49
50 #include <machine/_inttypes.h>
51 #include <machine/bus.h>
52 #include <machine/resource.h>
53
54 #include <sys/rman.h>
55
56 #include <sys/lock.h>
57 #include <sys/mutex.h>
58
59 #include <dev/iicbus/iiconf.h>
60 #include <dev/iicbus/iicbus.h>
61 #include <dev/ofw/ofw_bus.h>
62 #include <dev/ofw/ofw_bus_subr.h>
63
64 #include <dev/iicbus/twsi/twsi.h>
65
66 #include "iicbus_if.h"
67
68 #define TWSI_CONTROL_ACK        (1 << 2)
69 #define TWSI_CONTROL_IFLG       (1 << 3)
70 #define TWSI_CONTROL_STOP       (1 << 4)
71 #define TWSI_CONTROL_START      (1 << 5)
72 #define TWSI_CONTROL_TWSIEN     (1 << 6)
73 #define TWSI_CONTROL_INTEN      (1 << 7)
74
75 #define TWSI_STATUS_START               0x08
76 #define TWSI_STATUS_RPTD_START          0x10
77 #define TWSI_STATUS_ADDR_W_ACK          0x18
78 #define TWSI_STATUS_ADDR_W_NACK         0x20
79 #define TWSI_STATUS_DATA_WR_ACK         0x28
80 #define TWSI_STATUS_DATA_WR_NACK        0x30
81 #define TWSI_STATUS_ADDR_R_ACK          0x40
82 #define TWSI_STATUS_ADDR_R_NACK         0x48
83 #define TWSI_STATUS_DATA_RD_ACK         0x50
84 #define TWSI_STATUS_DATA_RD_NOACK       0x58
85
86 #define TWSI_DEBUG
87 #undef TWSI_DEBUG
88
89 #ifdef TWSI_DEBUG
90 #define debugf(dev, fmt, args...) device_printf(dev, "%s: " fmt, __func__, ##args)
91 #else
92 #define debugf(dev, fmt, args...)
93 #endif
94
95 static struct resource_spec res_spec[] = {
96         { SYS_RES_MEMORY, 0, RF_ACTIVE },
97         { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE},
98         { -1, 0 }
99 };
100
101 static __inline uint32_t
102 TWSI_READ(struct twsi_softc *sc, bus_size_t off)
103 {
104         uint32_t val;
105
106         val = bus_read_4(sc->res[0], off);
107         debugf(sc->dev, "read %x from %lx\n", val, off);
108         return (val);
109 }
110
111 static __inline void
112 TWSI_WRITE(struct twsi_softc *sc, bus_size_t off, uint32_t val)
113 {
114
115         debugf(sc->dev, "Writing %x to %lx\n", val, off);
116         bus_write_4(sc->res[0], off, val);
117 }
118
119 static __inline void
120 twsi_control_clear(struct twsi_softc *sc, uint32_t mask)
121 {
122         uint32_t val;
123
124         val = TWSI_READ(sc, sc->reg_control);
125         debugf(sc->dev, "read val=%x\n", val);
126         val &= ~(TWSI_CONTROL_STOP | TWSI_CONTROL_START);
127         val &= ~mask;
128         debugf(sc->dev, "write val=%x\n", val);
129         TWSI_WRITE(sc, sc->reg_control, val);
130 }
131
132 static __inline void
133 twsi_control_set(struct twsi_softc *sc, uint32_t mask)
134 {
135         uint32_t val;
136
137         val = TWSI_READ(sc, sc->reg_control);
138         debugf(sc->dev, "read val=%x\n", val);
139         val &= ~(TWSI_CONTROL_STOP | TWSI_CONTROL_START);
140         val |= mask;
141         debugf(sc->dev, "write val=%x\n", val);
142         TWSI_WRITE(sc, sc->reg_control, val);
143 }
144
145 static __inline void
146 twsi_clear_iflg(struct twsi_softc *sc)
147 {
148
149         DELAY(1000);
150         /* There are two ways of clearing IFLAG. */
151         if (sc->iflag_w1c)
152                 twsi_control_set(sc, TWSI_CONTROL_IFLG);
153         else
154                 twsi_control_clear(sc, TWSI_CONTROL_IFLG);
155         DELAY(1000);
156 }
157
158
159 /*
160  * timeout given in us
161  * returns
162  *   0 on successful mask change
163  *   non-zero on timeout
164  */
165 static int
166 twsi_poll_ctrl(struct twsi_softc *sc, int timeout, uint32_t mask)
167 {
168
169         timeout /= 10;
170         debugf(sc->dev, "Waiting for ctrl reg to match mask %x\n", mask);
171         while (!(TWSI_READ(sc, sc->reg_control) & mask)) {
172                 DELAY(10);
173                 if (--timeout < 0)
174                         return (timeout);
175         }
176         debugf(sc->dev, "done\n");
177         return (0);
178 }
179
180
181 /*
182  * 'timeout' is given in us. Note also that timeout handling is not exact --
183  * twsi_locked_start() total wait can be more than 2 x timeout
184  * (twsi_poll_ctrl() is called twice). 'mask' can be either TWSI_STATUS_START
185  * or TWSI_STATUS_RPTD_START
186  */
187 static int
188 twsi_locked_start(device_t dev, struct twsi_softc *sc, int32_t mask,
189     u_char slave, int timeout)
190 {
191         int read_access, iflg_set = 0;
192         uint32_t status;
193
194         mtx_assert(&sc->mutex, MA_OWNED);
195
196         if (mask == TWSI_STATUS_RPTD_START)
197                 /* read IFLG to know if it should be cleared later; from NBSD */
198                 iflg_set = TWSI_READ(sc, sc->reg_control) & TWSI_CONTROL_IFLG;
199
200         debugf(dev, "send start\n");
201         twsi_control_set(sc, TWSI_CONTROL_START);
202
203         if (mask == TWSI_STATUS_RPTD_START && iflg_set) {
204                 debugf(dev, "IFLG set, clearing (mask=%x)\n", mask);
205                 twsi_clear_iflg(sc);
206         }
207
208         /*
209          * Without this delay we timeout checking IFLG if the timeout is 0.
210          * NBSD driver always waits here too.
211          */
212         DELAY(1000);
213
214         if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
215                 debugf(dev, "timeout sending %sSTART condition\n",
216                     mask == TWSI_STATUS_START ? "" : "repeated ");
217                 return (IIC_ETIMEOUT);
218         }
219
220         status = TWSI_READ(sc, sc->reg_status);
221         debugf(dev, "status=%x\n", status);
222
223         if (status != mask) {
224                 debugf(dev, "wrong status (%02x) after sending %sSTART condition\n",
225                     status, mask == TWSI_STATUS_START ? "" : "repeated ");
226                 return (IIC_ESTATUS);
227         }
228
229         TWSI_WRITE(sc, sc->reg_data, slave);
230         twsi_clear_iflg(sc);
231         DELAY(1000);
232
233         if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
234                 debugf(dev, "timeout sending slave address (timeout=%d)\n", timeout);
235                 return (IIC_ETIMEOUT);
236         }
237
238         read_access = (slave & 0x1) ? 1 : 0;
239         status = TWSI_READ(sc, sc->reg_status);
240         if (status != (read_access ?
241             TWSI_STATUS_ADDR_R_ACK : TWSI_STATUS_ADDR_W_ACK)) {
242                 debugf(dev, "no ACK (status: %02x) after sending slave address\n",
243                     status);
244                 return (IIC_ENOACK);
245         }
246
247         return (IIC_NOERR);
248 }
249
250 #ifdef EXT_RESOURCES
251 #define TWSI_BAUD_RATE_RAW(C,M,N)       ((C)/((10*(M+1))<<(N)))
252 #define ABSSUB(a,b)     (((a) > (b)) ? (a) - (b) : (b) - (a))
253
254 static int
255 twsi_calc_baud_rate(struct twsi_softc *sc, const u_int target,
256   int *param)
257 {
258         uint64_t clk;
259         uint32_t cur, diff, diff0;
260         int m, n, m0, n0;
261
262         /* Calculate baud rate. */
263         diff0 = 0xffffffff;
264
265         if (clk_get_freq(sc->clk_core, &clk) < 0)
266                 return (-1);
267
268         debugf(sc->dev, "Bus clock is at %ju\n", clk);
269
270         for (n = 0; n < 8; n++) {
271                 for (m = 0; m < 16; m++) {
272                         cur = TWSI_BAUD_RATE_RAW(clk,m,n);
273                         diff = ABSSUB(target, cur);
274                         if (diff < diff0) {
275                                 m0 = m;
276                                 n0 = n;
277                                 diff0 = diff;
278                         }
279                 }
280         }
281         *param = TWSI_BAUD_RATE_PARAM(m0, n0);
282
283         return (0);
284 }
285 #endif /* EXT_RESOURCES */
286
287 /*
288  * Only slave mode supported, disregard [old]addr
289  */
290 static int
291 twsi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
292 {
293         struct twsi_softc *sc;
294         uint32_t param;
295 #ifdef EXT_RESOURCES
296         u_int busfreq;
297 #endif
298
299         sc = device_get_softc(dev);
300
301 #ifdef EXT_RESOURCES
302         busfreq = IICBUS_GET_FREQUENCY(sc->iicbus, speed);
303
304         if (twsi_calc_baud_rate(sc, busfreq, &param) == -1) {
305 #endif
306                 switch (speed) {
307                 case IIC_SLOW:
308                 case IIC_FAST:
309                         param = sc->baud_rate[speed].param;
310                         debugf(dev, "Using IIC_FAST mode with speed param=%x\n", param);
311                         break;
312                 case IIC_FASTEST:
313                 case IIC_UNKNOWN:
314                 default:
315                         param = sc->baud_rate[IIC_FAST].param;
316                         debugf(dev, "Using IIC_FASTEST/UNKNOWN mode with speed param=%x\n", param);
317                         break;
318                 }
319 #ifdef EXT_RESOURCES
320         }
321 #endif
322
323         debugf(dev, "Using clock param=%x\n", param);
324
325         mtx_lock(&sc->mutex);
326         TWSI_WRITE(sc, sc->reg_soft_reset, 0x0);
327         TWSI_WRITE(sc, sc->reg_baud_rate, param);
328         TWSI_WRITE(sc, sc->reg_control, TWSI_CONTROL_TWSIEN);
329         DELAY(1000);
330         mtx_unlock(&sc->mutex);
331
332         return (0);
333 }
334
335 static int
336 twsi_stop(device_t dev)
337 {
338         struct twsi_softc *sc;
339
340         sc = device_get_softc(dev);
341
342         debugf(dev, "%s\n", __func__);
343         mtx_lock(&sc->mutex);
344         twsi_control_clear(sc, TWSI_CONTROL_ACK);
345         twsi_control_set(sc, TWSI_CONTROL_STOP);
346         twsi_clear_iflg(sc);
347         DELAY(1000);
348         mtx_unlock(&sc->mutex);
349
350         return (IIC_NOERR);
351 }
352
353 /*
354  * timeout is given in us
355  */
356 static int
357 twsi_repeated_start(device_t dev, u_char slave, int timeout)
358 {
359         struct twsi_softc *sc;
360         int rv;
361
362         sc = device_get_softc(dev);
363
364         debugf(dev, "%s: slave=%x\n", __func__, slave);
365         mtx_lock(&sc->mutex);
366         rv = twsi_locked_start(dev, sc, TWSI_STATUS_RPTD_START, slave,
367             timeout);
368         mtx_unlock(&sc->mutex);
369
370         if (rv) {
371                 twsi_stop(dev);
372                 return (rv);
373         } else
374                 return (IIC_NOERR);
375 }
376
377 /*
378  * timeout is given in us
379  */
380 static int
381 twsi_start(device_t dev, u_char slave, int timeout)
382 {
383         struct twsi_softc *sc;
384         int rv;
385
386         sc = device_get_softc(dev);
387
388         debugf(dev, "%s: slave=%x\n", __func__, slave);
389         mtx_lock(&sc->mutex);
390         rv = twsi_locked_start(dev, sc, TWSI_STATUS_START, slave, timeout);
391         mtx_unlock(&sc->mutex);
392
393         if (rv) {
394                 twsi_stop(dev);
395                 return (rv);
396         } else
397                 return (IIC_NOERR);
398 }
399
400 static int
401 twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay)
402 {
403         struct twsi_softc *sc;
404         uint32_t status;
405         int last_byte, rv;
406
407         sc = device_get_softc(dev);
408
409         mtx_lock(&sc->mutex);
410         *read = 0;
411         while (*read < len) {
412                 /*
413                  * Check if we are reading last byte of the last buffer,
414                  * do not send ACK then, per I2C specs
415                  */
416                 last_byte = ((*read == len - 1) && last) ? 1 : 0;
417                 if (last_byte)
418                         twsi_control_clear(sc, TWSI_CONTROL_ACK);
419                 else
420                         twsi_control_set(sc, TWSI_CONTROL_ACK);
421
422                 twsi_clear_iflg(sc);
423                 DELAY(1000);
424
425                 if (twsi_poll_ctrl(sc, delay, TWSI_CONTROL_IFLG)) {
426                         debugf(dev, "timeout reading data (delay=%d)\n", delay);
427                         rv = IIC_ETIMEOUT;
428                         goto out;
429                 }
430
431                 status = TWSI_READ(sc, sc->reg_status);
432                 if (status != (last_byte ?
433                     TWSI_STATUS_DATA_RD_NOACK : TWSI_STATUS_DATA_RD_ACK)) {
434                         debugf(dev, "wrong status (%02x) while reading\n", status);
435                         rv = IIC_ESTATUS;
436                         goto out;
437                 }
438
439                 *buf++ = TWSI_READ(sc, sc->reg_data);
440                 (*read)++;
441         }
442         rv = IIC_NOERR;
443 out:
444         mtx_unlock(&sc->mutex);
445         return (rv);
446 }
447
448 static int
449 twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout)
450 {
451         struct twsi_softc *sc;
452         uint32_t status;
453         int rv;
454
455         sc = device_get_softc(dev);
456
457         mtx_lock(&sc->mutex);
458         *sent = 0;
459         while (*sent < len) {
460                 TWSI_WRITE(sc, sc->reg_data, *buf++);
461
462                 twsi_clear_iflg(sc);
463                 DELAY(1000);
464                 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
465                         debugf(dev, "timeout writing data (timeout=%d)\n", timeout);
466                         rv = IIC_ETIMEOUT;
467                         goto out;
468                 }
469
470                 status = TWSI_READ(sc, sc->reg_status);
471                 if (status != TWSI_STATUS_DATA_WR_ACK) {
472                         debugf(dev, "wrong status (%02x) while writing\n", status);
473                         rv = IIC_ESTATUS;
474                         goto out;
475                 }
476                 (*sent)++;
477         }
478         rv = IIC_NOERR;
479 out:
480         mtx_unlock(&sc->mutex);
481         return (rv);
482 }
483
484 static int
485 twsi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
486 {
487         struct twsi_softc *sc;
488
489         sc = device_get_softc(dev);
490
491         if (!sc->have_intr)
492                 return (iicbus_transfer_gen(dev, msgs, nmsgs));
493
494         sc->error = 0;
495
496         sc->control_val = TWSI_CONTROL_TWSIEN |
497                 TWSI_CONTROL_INTEN | TWSI_CONTROL_ACK;
498         TWSI_WRITE(sc, sc->reg_control, sc->control_val);
499         debugf(dev, "transmitting %d messages\n", nmsgs);
500         debugf(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status));
501         sc->nmsgs = nmsgs;
502         sc->msgs = msgs;
503         sc->msg_idx = 0;
504         sc->transfer = 1;
505
506 #ifdef TWSI_DEBUG
507         for (int i = 0; i < nmsgs; i++)
508                 debugf(sc->dev, "msg %d is %d bytes long\n", i, msgs[i].len);
509 #endif
510         /* Send start and re-enable interrupts */
511         sc->control_val = TWSI_CONTROL_TWSIEN |
512                 TWSI_CONTROL_INTEN | TWSI_CONTROL_ACK;
513         if (sc->msgs[0].len == 1)
514                 sc->control_val &= ~TWSI_CONTROL_ACK;
515         TWSI_WRITE(sc, sc->reg_control, sc->control_val | TWSI_CONTROL_START);
516         while (sc->error == 0 && sc->transfer != 0) {
517                 tsleep_sbt(sc, 0, "twsi", SBT_1MS * 30, SBT_1MS, 0);
518         }
519         debugf(sc->dev, "pause finish\n");
520
521         if (sc->error) {
522                 debugf(sc->dev, "Error, aborting (%d)\n", sc->error);
523                 TWSI_WRITE(sc, sc->reg_control, 0);
524         }
525
526         /* Disable module and interrupts */
527         debugf(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status));
528         TWSI_WRITE(sc, sc->reg_control, 0);
529         debugf(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status));
530
531         return (sc->error);
532 }
533
534 static void
535 twsi_intr(void *arg)
536 {
537         struct twsi_softc *sc;
538         uint32_t status;
539         int transfer_done = 0;
540
541         sc = arg;
542
543         debugf(sc->dev, "Got interrupt Current msg=%x\n", sc->msg_idx);
544
545         status = TWSI_READ(sc, sc->reg_status);
546         debugf(sc->dev, "reg control=%x\n", TWSI_READ(sc, sc->reg_control));
547
548         switch (status) {
549         case TWSI_STATUS_START:
550         case TWSI_STATUS_RPTD_START:
551                 /* Transmit the address */
552                 debugf(sc->dev, "Send the address (%x)", sc->msgs[sc->msg_idx].slave);
553
554                 if (sc->msgs[sc->msg_idx].flags & IIC_M_RD)
555                         TWSI_WRITE(sc, sc->reg_data,
556                             sc->msgs[sc->msg_idx].slave | LSB);
557                 else
558                         TWSI_WRITE(sc, sc->reg_data,
559                             sc->msgs[sc->msg_idx].slave & ~LSB);
560                 TWSI_WRITE(sc, sc->reg_control, sc->control_val);
561                 break;
562
563         case TWSI_STATUS_ADDR_W_ACK:
564                 debugf(sc->dev, "Ack received after transmitting the address (write)\n");
565                 /* Directly send the first byte */
566                 sc->sent_bytes = 1;
567                 debugf(sc->dev, "Sending byte 0 (of %d) = %x\n",
568                     sc->msgs[sc->msg_idx].len,
569                     sc->msgs[sc->msg_idx].buf[0]);
570                 TWSI_WRITE(sc, sc->reg_data, sc->msgs[sc->msg_idx].buf[0]);
571
572                 TWSI_WRITE(sc, sc->reg_control, sc->control_val);
573                 break;
574
575         case TWSI_STATUS_ADDR_R_ACK:
576                 debugf(sc->dev, "Ack received after transmitting the address (read)\n");
577                 sc->recv_bytes = 0;
578
579                 TWSI_WRITE(sc, sc->reg_control, sc->control_val);
580                 break;
581
582         case TWSI_STATUS_ADDR_W_NACK:
583         case TWSI_STATUS_ADDR_R_NACK:
584                 debugf(sc->dev, "No ack received after transmitting the address\n");
585                 sc->transfer = 0;
586                 sc->error = IIC_ENOACK;
587                 sc->control_val = 0;
588                 wakeup(sc);
589                 break;
590
591         case TWSI_STATUS_DATA_WR_ACK:
592                 debugf(sc->dev, "Ack received after transmitting data\n");
593                 if (sc->sent_bytes == sc->msgs[sc->msg_idx].len) {
594                         debugf(sc->dev, "Done sending all the bytes for msg %d\n", sc->msg_idx);
595                         /* Send stop, no interrupts on stop */
596                         if (!(sc->msgs[sc->msg_idx].flags & IIC_M_NOSTOP)) {
597                                 debugf(sc->dev, "Done TX data, send stop\n");
598                                 TWSI_WRITE(sc, sc->reg_control,
599                                     sc->control_val | TWSI_CONTROL_STOP);
600                         } else {
601                                 debugf(sc->dev, "Done TX data with NO_STOP\n");
602                                 TWSI_WRITE(sc, sc->reg_control, sc->control_val | TWSI_CONTROL_START);
603                         }
604                         sc->msg_idx++;
605                         if (sc->msg_idx == sc->nmsgs) {
606                                 debugf(sc->dev, "transfer_done=1\n");
607                                 transfer_done = 1;
608                                 sc->error = 0;
609                         } else {
610                                 debugf(sc->dev, "Send repeated start\n");
611                                 TWSI_WRITE(sc, sc->reg_control, sc->control_val | TWSI_CONTROL_START);
612                         }
613                 } else {
614                         debugf(sc->dev, "Sending byte %d (of %d) = %x\n",
615                             sc->sent_bytes,
616                             sc->msgs[sc->msg_idx].len,
617                             sc->msgs[sc->msg_idx].buf[sc->sent_bytes]);
618                         TWSI_WRITE(sc, sc->reg_data,
619                             sc->msgs[sc->msg_idx].buf[sc->sent_bytes]);
620                         TWSI_WRITE(sc, sc->reg_control,
621                             sc->control_val);
622                         sc->sent_bytes++;
623                 }
624                 break;
625
626         case TWSI_STATUS_DATA_RD_ACK:
627                 debugf(sc->dev, "Ack received after receiving data\n");
628                 sc->msgs[sc->msg_idx].buf[sc->recv_bytes++] = TWSI_READ(sc, sc->reg_data);
629                 debugf(sc->dev, "msg_len=%d recv_bytes=%d\n", sc->msgs[sc->msg_idx].len, sc->recv_bytes);
630
631                 /* If we only have one byte left, disable ACK */
632                 if (sc->msgs[sc->msg_idx].len - sc->recv_bytes == 1)
633                         sc->control_val &= ~TWSI_CONTROL_ACK;
634                 if (sc->msgs[sc->msg_idx].len == sc->recv_bytes) {
635                         debugf(sc->dev, "Done with msg %d\n", sc->msg_idx);
636                         sc->msg_idx++;
637                         if (sc->msg_idx == sc->nmsgs - 1) {
638                                 debugf(sc->dev, "No more msgs\n");
639                                 transfer_done = 1;
640                                 sc->error = 0;
641                         }
642                 }
643                 TWSI_WRITE(sc, sc->reg_control, sc->control_val);
644                 break;
645
646         case TWSI_STATUS_DATA_RD_NOACK:
647                 if (sc->msgs[sc->msg_idx].len - sc->recv_bytes == 1) {
648                         sc->msgs[sc->msg_idx].buf[sc->recv_bytes++] = TWSI_READ(sc, sc->reg_data);
649                         debugf(sc->dev, "Done RX data, send stop (2)\n");
650                         if (!(sc->msgs[sc->msg_idx].flags & IIC_M_NOSTOP))
651                                 TWSI_WRITE(sc, sc->reg_control,
652                                     sc->control_val | TWSI_CONTROL_STOP);
653                 } else {
654                         debugf(sc->dev, "No ack when receiving data, sending stop anyway\n");
655                         if (!(sc->msgs[sc->msg_idx].flags & IIC_M_NOSTOP))
656                                 TWSI_WRITE(sc, sc->reg_control,
657                                     sc->control_val | TWSI_CONTROL_STOP);
658                 }
659                 sc->transfer = 0;
660                 transfer_done = 1;
661                 sc->error = 0;
662                 break;
663
664         default:
665                 debugf(sc->dev, "status=%x hot handled\n", status);
666                 sc->transfer = 0;
667                 sc->error = IIC_EBUSERR;
668                 sc->control_val = 0;
669                 wakeup(sc);
670                 break;
671         }
672         debugf(sc->dev, "Refresh reg_control\n");
673
674         /*
675          * Newer Allwinner chips clear IFLG after writing 1 to it.
676          */
677         TWSI_WRITE(sc, sc->reg_control, sc->control_val |
678             (sc->iflag_w1c ? TWSI_CONTROL_IFLG : 0));
679
680         debugf(sc->dev, "Done with interrupts\n\n");
681         if (transfer_done == 1) {
682                 sc->transfer = 0;
683                 wakeup(sc);
684         }
685 }
686
687 static void
688 twsi_intr_start(void *pdev)
689 {
690         struct twsi_softc *sc;
691
692         sc = device_get_softc(pdev);
693
694         if ((bus_setup_intr(pdev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE,
695               NULL, twsi_intr, sc, &sc->intrhand)))
696                 device_printf(pdev, "unable to register interrupt handler\n");
697
698         sc->have_intr = true;
699 }
700
701 int
702 twsi_attach(device_t dev)
703 {
704         struct twsi_softc *sc;
705
706         sc = device_get_softc(dev);
707         sc->dev = dev;
708
709         mtx_init(&sc->mutex, device_get_nameunit(dev), "twsi", MTX_DEF);
710
711         if (bus_alloc_resources(dev, res_spec, sc->res)) {
712                 device_printf(dev, "could not allocate resources\n");
713                 twsi_detach(dev);
714                 return (ENXIO);
715         }
716
717         /* Attach the iicbus. */
718         if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL) {
719                 device_printf(dev, "could not allocate iicbus instance\n");
720                 twsi_detach(dev);
721                 return (ENXIO);
722         }
723         bus_generic_attach(dev);
724
725         config_intrhook_oneshot(twsi_intr_start, dev);
726
727         return (0);
728 }
729
730 int
731 twsi_detach(device_t dev)
732 {
733         struct twsi_softc *sc;
734         int rv;
735
736         sc = device_get_softc(dev);
737
738         if ((rv = bus_generic_detach(dev)) != 0)
739                 return (rv);
740
741         if (sc->iicbus != NULL)
742                 if ((rv = device_delete_child(dev, sc->iicbus)) != 0)
743                         return (rv);
744
745         if (sc->intrhand != NULL)
746                 bus_teardown_intr(sc->dev, sc->res[1], sc->intrhand);
747
748         bus_release_resources(dev, res_spec, sc->res);
749
750         mtx_destroy(&sc->mutex);
751         return (0);
752 }
753
754 static device_method_t twsi_methods[] = {
755         /* device interface */
756         DEVMETHOD(device_detach,        twsi_detach),
757
758         /* Bus interface */
759         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
760         DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
761         DEVMETHOD(bus_alloc_resource,   bus_generic_alloc_resource),
762         DEVMETHOD(bus_release_resource, bus_generic_release_resource),
763         DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
764         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
765         DEVMETHOD(bus_adjust_resource,  bus_generic_adjust_resource),
766         DEVMETHOD(bus_set_resource,     bus_generic_rl_set_resource),
767         DEVMETHOD(bus_get_resource,     bus_generic_rl_get_resource),
768
769         /* iicbus interface */
770         DEVMETHOD(iicbus_callback, iicbus_null_callback),
771         DEVMETHOD(iicbus_repeated_start, twsi_repeated_start),
772         DEVMETHOD(iicbus_start,         twsi_start),
773         DEVMETHOD(iicbus_stop,          twsi_stop),
774         DEVMETHOD(iicbus_write,         twsi_write),
775         DEVMETHOD(iicbus_read,          twsi_read),
776         DEVMETHOD(iicbus_reset,         twsi_reset),
777         DEVMETHOD(iicbus_transfer,      twsi_transfer),
778         { 0, 0 }
779 };
780
781 DEFINE_CLASS_0(twsi, twsi_driver, twsi_methods,
782     sizeof(struct twsi_softc));