]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/iicbus/twsi/twsi.c
MFV r346563:
[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         twsi_control_clear(sc, TWSI_CONTROL_IFLG);
151         DELAY(1000);
152 }
153
154
155 /*
156  * timeout given in us
157  * returns
158  *   0 on successful mask change
159  *   non-zero on timeout
160  */
161 static int
162 twsi_poll_ctrl(struct twsi_softc *sc, int timeout, uint32_t mask)
163 {
164
165         timeout /= 10;
166         debugf(sc->dev, "Waiting for ctrl reg to match mask %x\n", mask);
167         while (!(TWSI_READ(sc, sc->reg_control) & mask)) {
168                 DELAY(10);
169                 if (--timeout < 0)
170                         return (timeout);
171         }
172         debugf(sc->dev, "done\n");
173         return (0);
174 }
175
176
177 /*
178  * 'timeout' is given in us. Note also that timeout handling is not exact --
179  * twsi_locked_start() total wait can be more than 2 x timeout
180  * (twsi_poll_ctrl() is called twice). 'mask' can be either TWSI_STATUS_START
181  * or TWSI_STATUS_RPTD_START
182  */
183 static int
184 twsi_locked_start(device_t dev, struct twsi_softc *sc, int32_t mask,
185     u_char slave, int timeout)
186 {
187         int read_access, iflg_set = 0;
188         uint32_t status;
189
190         mtx_assert(&sc->mutex, MA_OWNED);
191
192         if (mask == TWSI_STATUS_RPTD_START)
193                 /* read IFLG to know if it should be cleared later; from NBSD */
194                 iflg_set = TWSI_READ(sc, sc->reg_control) & TWSI_CONTROL_IFLG;
195
196         debugf(dev, "send start\n");
197         twsi_control_set(sc, TWSI_CONTROL_START);
198
199         if (mask == TWSI_STATUS_RPTD_START && iflg_set) {
200                 debugf(dev, "IFLG set, clearing (mask=%x)\n", mask);
201                 twsi_clear_iflg(sc);
202         }
203
204         /*
205          * Without this delay we timeout checking IFLG if the timeout is 0.
206          * NBSD driver always waits here too.
207          */
208         DELAY(1000);
209
210         if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
211                 debugf(dev, "timeout sending %sSTART condition\n",
212                     mask == TWSI_STATUS_START ? "" : "repeated ");
213                 return (IIC_ETIMEOUT);
214         }
215
216         status = TWSI_READ(sc, sc->reg_status);
217         debugf(dev, "status=%x\n", status);
218
219         if (status != mask) {
220                 debugf(dev, "wrong status (%02x) after sending %sSTART condition\n",
221                     status, mask == TWSI_STATUS_START ? "" : "repeated ");
222                 return (IIC_ESTATUS);
223         }
224
225         TWSI_WRITE(sc, sc->reg_data, slave);
226         twsi_clear_iflg(sc);
227         DELAY(1000);
228
229         if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
230                 debugf(dev, "timeout sending slave address (timeout=%d)\n", timeout);
231                 return (IIC_ETIMEOUT);
232         }
233
234         read_access = (slave & 0x1) ? 1 : 0;
235         status = TWSI_READ(sc, sc->reg_status);
236         if (status != (read_access ?
237             TWSI_STATUS_ADDR_R_ACK : TWSI_STATUS_ADDR_W_ACK)) {
238                 debugf(dev, "no ACK (status: %02x) after sending slave address\n",
239                     status);
240                 return (IIC_ENOACK);
241         }
242
243         return (IIC_NOERR);
244 }
245
246 /*
247  * Only slave mode supported, disregard [old]addr
248  */
249 static int
250 twsi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
251 {
252         struct twsi_softc *sc;
253         uint32_t param;
254         /* uint32_t val; */
255
256         sc = device_get_softc(dev);
257
258         switch (speed) {
259         case IIC_SLOW:
260         case IIC_FAST:
261                 param = sc->baud_rate[speed].param;
262                 debugf(dev, "Using IIC_FAST mode with speed param=%x\n", param);
263                 break;
264         case IIC_FASTEST:
265         case IIC_UNKNOWN:
266         default:
267                 param = sc->baud_rate[IIC_FAST].param;
268                 debugf(dev, "Using IIC_FASTEST/UNKNOWN mode with speed param=%x\n", param);
269                 break;
270         }
271
272         mtx_lock(&sc->mutex);
273         TWSI_WRITE(sc, sc->reg_soft_reset, 0x0);
274         TWSI_WRITE(sc, sc->reg_baud_rate, param);
275         TWSI_WRITE(sc, sc->reg_control, TWSI_CONTROL_TWSIEN);
276         DELAY(1000);
277         mtx_unlock(&sc->mutex);
278
279         return (0);
280 }
281
282 static int
283 twsi_stop(device_t dev)
284 {
285         struct twsi_softc *sc;
286
287         sc = device_get_softc(dev);
288
289         debugf(dev, "%s\n", __func__);
290         mtx_lock(&sc->mutex);
291         twsi_control_clear(sc, TWSI_CONTROL_ACK);
292         twsi_control_set(sc, TWSI_CONTROL_STOP);
293         twsi_clear_iflg(sc);
294         DELAY(1000);
295         mtx_unlock(&sc->mutex);
296
297         return (IIC_NOERR);
298 }
299
300 /*
301  * timeout is given in us
302  */
303 static int
304 twsi_repeated_start(device_t dev, u_char slave, int timeout)
305 {
306         struct twsi_softc *sc;
307         int rv;
308
309         sc = device_get_softc(dev);
310
311         debugf(dev, "%s: slave=%x\n", __func__, slave);
312         mtx_lock(&sc->mutex);
313         rv = twsi_locked_start(dev, sc, TWSI_STATUS_RPTD_START, slave,
314             timeout);
315         mtx_unlock(&sc->mutex);
316
317         if (rv) {
318                 twsi_stop(dev);
319                 return (rv);
320         } else
321                 return (IIC_NOERR);
322 }
323
324 /*
325  * timeout is given in us
326  */
327 static int
328 twsi_start(device_t dev, u_char slave, int timeout)
329 {
330         struct twsi_softc *sc;
331         int rv;
332
333         sc = device_get_softc(dev);
334
335         debugf(dev, "%s: slave=%x\n", __func__, slave);
336         mtx_lock(&sc->mutex);
337         rv = twsi_locked_start(dev, sc, TWSI_STATUS_START, slave, timeout);
338         mtx_unlock(&sc->mutex);
339
340         if (rv) {
341                 twsi_stop(dev);
342                 return (rv);
343         } else
344                 return (IIC_NOERR);
345 }
346
347 static int
348 twsi_read(device_t dev, char *buf, int len, int *read, int last, int delay)
349 {
350         struct twsi_softc *sc;
351         uint32_t status;
352         int last_byte, rv;
353
354         sc = device_get_softc(dev);
355
356         mtx_lock(&sc->mutex);
357         *read = 0;
358         while (*read < len) {
359                 /*
360                  * Check if we are reading last byte of the last buffer,
361                  * do not send ACK then, per I2C specs
362                  */
363                 last_byte = ((*read == len - 1) && last) ? 1 : 0;
364                 if (last_byte)
365                         twsi_control_clear(sc, TWSI_CONTROL_ACK);
366                 else
367                         twsi_control_set(sc, TWSI_CONTROL_ACK);
368
369                 twsi_clear_iflg(sc);
370                 DELAY(1000);
371
372                 if (twsi_poll_ctrl(sc, delay, TWSI_CONTROL_IFLG)) {
373                         debugf(dev, "timeout reading data (delay=%d)\n", delay);
374                         rv = IIC_ETIMEOUT;
375                         goto out;
376                 }
377
378                 status = TWSI_READ(sc, sc->reg_status);
379                 if (status != (last_byte ?
380                     TWSI_STATUS_DATA_RD_NOACK : TWSI_STATUS_DATA_RD_ACK)) {
381                         debugf(dev, "wrong status (%02x) while reading\n", status);
382                         rv = IIC_ESTATUS;
383                         goto out;
384                 }
385
386                 *buf++ = TWSI_READ(sc, sc->reg_data);
387                 (*read)++;
388         }
389         rv = IIC_NOERR;
390 out:
391         mtx_unlock(&sc->mutex);
392         return (rv);
393 }
394
395 static int
396 twsi_write(device_t dev, const char *buf, int len, int *sent, int timeout)
397 {
398         struct twsi_softc *sc;
399         uint32_t status;
400         int rv;
401
402         sc = device_get_softc(dev);
403
404         mtx_lock(&sc->mutex);
405         *sent = 0;
406         while (*sent < len) {
407                 TWSI_WRITE(sc, sc->reg_data, *buf++);
408
409                 twsi_clear_iflg(sc);
410                 DELAY(1000);
411                 if (twsi_poll_ctrl(sc, timeout, TWSI_CONTROL_IFLG)) {
412                         debugf(dev, "timeout writing data (timeout=%d)\n", timeout);
413                         rv = IIC_ETIMEOUT;
414                         goto out;
415                 }
416
417                 status = TWSI_READ(sc, sc->reg_status);
418                 if (status != TWSI_STATUS_DATA_WR_ACK) {
419                         debugf(dev, "wrong status (%02x) while writing\n", status);
420                         rv = IIC_ESTATUS;
421                         goto out;
422                 }
423                 (*sent)++;
424         }
425         rv = IIC_NOERR;
426 out:
427         mtx_unlock(&sc->mutex);
428         return (rv);
429 }
430
431 static int
432 twsi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
433 {
434         struct twsi_softc *sc;
435         int i;
436
437         sc = device_get_softc(dev);
438
439         if (sc->have_intr == false)
440                 return (iicbus_transfer_gen(dev, msgs, nmsgs));
441
442         sc->error = 0;
443
444         sc->control_val = TWSI_CONTROL_TWSIEN |
445                 TWSI_CONTROL_INTEN | TWSI_CONTROL_ACK;
446         TWSI_WRITE(sc, sc->reg_control, sc->control_val);
447         debugf(dev, "transmitting %d messages\n", nmsgs);
448         debugf(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status));
449         for (i = 0; i < nmsgs && sc->error == 0; i++) {
450                 sc->transfer = 1;
451                 sc->msg = &msgs[i];
452                 debugf(dev, "msg[%d] flags: %x\n", i, msgs[i].flags);
453                 debugf(dev, "msg[%d] len: %d\n", i, msgs[i].len);
454
455                 /* Send start and re-enable interrupts */
456                 sc->control_val = TWSI_CONTROL_TWSIEN |
457                         TWSI_CONTROL_INTEN | TWSI_CONTROL_ACK;
458                 if (sc->msg->len == 1)
459                         sc->control_val &= ~TWSI_CONTROL_ACK;
460                 TWSI_WRITE(sc, sc->reg_control, sc->control_val | TWSI_CONTROL_START);
461                 while (sc->error == 0 && sc->transfer != 0) {
462                         pause_sbt("twsi", SBT_1MS * 30, SBT_1MS, 0);
463                 }
464
465                 debugf(dev, "Done with msg[%d]\n", i);
466                 if (sc->error) {
467                         debugf(sc->dev, "Error, aborting (%d)\n", sc->error);
468                         TWSI_WRITE(sc, sc->reg_control, 0);
469                         goto out;
470                 }
471         }
472
473         /* Disable module and interrupts */
474         debugf(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status));
475         TWSI_WRITE(sc, sc->reg_control, 0);
476         debugf(sc->dev, "status=%x\n", TWSI_READ(sc, sc->reg_status));
477
478 out:
479         return (sc->error);
480 }
481
482 static void
483 twsi_intr(void *arg)
484 {
485         struct twsi_softc *sc;
486         uint32_t status;
487         int transfer_done = 0;
488
489         sc = arg;
490
491         debugf(sc->dev, "Got interrupt\n");
492
493         while (TWSI_READ(sc, sc->reg_control) & TWSI_CONTROL_IFLG) {
494                 status = TWSI_READ(sc, sc->reg_status);
495                 debugf(sc->dev, "status=%x\n", status);
496
497                 switch (status) {
498                 case TWSI_STATUS_START:
499                 case TWSI_STATUS_RPTD_START:
500                         /* Transmit the address */
501                         debugf(sc->dev, "Send the address\n");
502
503                         if (sc->msg->flags & IIC_M_RD)
504                                 TWSI_WRITE(sc, sc->reg_data,
505                                     sc->msg->slave | LSB);
506                         else
507                                 TWSI_WRITE(sc, sc->reg_data,
508                                     sc->msg->slave & ~LSB);
509
510                         TWSI_WRITE(sc, sc->reg_control, sc->control_val);
511                         break;
512
513                 case TWSI_STATUS_ADDR_W_ACK:
514                         debugf(sc->dev, "Ack received after transmitting the address\n");
515                         /* Directly send the first byte */
516                         sc->sent_bytes = 0;
517                         debugf(sc->dev, "Sending byte 0 = %x\n", sc->msg->buf[0]);
518                         TWSI_WRITE(sc, sc->reg_data, sc->msg->buf[0]);
519
520                         TWSI_WRITE(sc, sc->reg_control, sc->control_val);
521                         break;
522
523                 case TWSI_STATUS_ADDR_R_ACK:
524                         sc->recv_bytes = 0;
525
526                         TWSI_WRITE(sc, sc->reg_control, sc->control_val);
527                         break;
528
529                 case TWSI_STATUS_ADDR_W_NACK:
530                 case TWSI_STATUS_ADDR_R_NACK:
531                         debugf(sc->dev, "No ack received after transmitting the address\n");
532                         sc->transfer = 0;
533                         sc->error = ETIMEDOUT;
534                         sc->control_val = 0;
535                         wakeup(sc);
536                         break;
537
538                 case TWSI_STATUS_DATA_WR_ACK:
539                         debugf(sc->dev, "Ack received after transmitting data\n");
540                         if (sc->sent_bytes++ == (sc->msg->len - 1)) {
541                                 debugf(sc->dev, "Done sending all the bytes\n");
542                                 /* Send stop, no interrupts on stop */
543                                 if (!(sc->msg->flags & IIC_M_NOSTOP)) {
544                                         debugf(sc->dev, "Done TX data, send stop\n");
545                                         TWSI_WRITE(sc, sc->reg_control,
546                                           sc->control_val | TWSI_CONTROL_STOP);
547                                 } else {
548                                         sc->control_val &= ~TWSI_CONTROL_INTEN;
549                                         TWSI_WRITE(sc, sc->reg_control,
550                                             sc->control_val);
551                                 }
552                                 transfer_done = 1;
553                         } else {
554                                 debugf(sc->dev, "Sending byte %d = %x\n",
555                                     sc->sent_bytes,
556                                     sc->msg->buf[sc->sent_bytes]);
557                                 TWSI_WRITE(sc, sc->reg_data,
558                                     sc->msg->buf[sc->sent_bytes]);
559                                 TWSI_WRITE(sc, sc->reg_control,
560                                     sc->control_val);
561                         }
562
563                         break;
564                 case TWSI_STATUS_DATA_RD_ACK:
565                         debugf(sc->dev, "Ack received after receiving data\n");
566                         debugf(sc->dev, "msg_len=%d recv_bytes=%d\n", sc->msg->len, sc->recv_bytes);
567                         sc->msg->buf[sc->recv_bytes++] = TWSI_READ(sc, sc->reg_data);
568
569                         /* If we only have one byte left, disable ACK */
570                         if (sc->msg->len - sc->recv_bytes == 1)
571                                 sc->control_val &= ~TWSI_CONTROL_ACK;
572                         TWSI_WRITE(sc, sc->reg_control, sc->control_val);
573                         break;
574
575                 case TWSI_STATUS_DATA_RD_NOACK:
576                         if (sc->msg->len - sc->recv_bytes == 1) {
577                                 sc->msg->buf[sc->recv_bytes++] = TWSI_READ(sc, sc->reg_data);
578                                 debugf(sc->dev, "Done RX data, send stop (2)\n");
579                                 if (!(sc->msg->flags & IIC_M_NOSTOP))
580                                         TWSI_WRITE(sc, sc->reg_control,
581                                           sc->control_val | TWSI_CONTROL_STOP);
582                         } else {
583                                 debugf(sc->dev, "No ack when receiving data\n");
584                                 sc->error = ENXIO;
585                                 sc->control_val = 0;
586                         }
587                         sc->transfer = 0;
588                         transfer_done = 1;
589                         break;
590
591                 default:
592                         debugf(sc->dev, "status=%x hot handled\n", status);
593                         sc->transfer = 0;
594                         sc->error = ENXIO;
595                         sc->control_val = 0;
596                         wakeup(sc);
597                         break;
598                 }
599
600                 if (sc->need_ack)
601                         TWSI_WRITE(sc, sc->reg_control,
602                             sc->control_val | TWSI_CONTROL_IFLG);
603         }
604
605         debugf(sc->dev, "Done with interrupts\n");
606         if (transfer_done == 1) {
607                 sc->transfer = 0;
608                 wakeup(sc);
609         }
610 }
611
612 static void
613 twsi_intr_start(void *pdev)
614 {
615         struct twsi_softc *sc;
616
617         sc = device_get_softc(pdev);
618
619         if ((bus_setup_intr(pdev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE,
620               NULL, twsi_intr, sc, &sc->intrhand)))
621                 device_printf(pdev, "unable to register interrupt handler\n");
622
623         sc->have_intr = true;
624 }
625
626 int
627 twsi_attach(device_t dev)
628 {
629         struct twsi_softc *sc;
630
631         sc = device_get_softc(dev);
632         sc->dev = dev;
633
634         mtx_init(&sc->mutex, device_get_nameunit(dev), "twsi", MTX_DEF);
635
636         if (bus_alloc_resources(dev, res_spec, sc->res)) {
637                 device_printf(dev, "could not allocate resources\n");
638                 twsi_detach(dev);
639                 return (ENXIO);
640         }
641
642         /* Attach the iicbus. */
643         if ((sc->iicbus = device_add_child(dev, "iicbus", -1)) == NULL) {
644                 device_printf(dev, "could not allocate iicbus instance\n");
645                 twsi_detach(dev);
646                 return (ENXIO);
647         }
648         bus_generic_attach(dev);
649
650         config_intrhook_oneshot(twsi_intr_start, dev);
651
652         return (0);
653 }
654
655 int
656 twsi_detach(device_t dev)
657 {
658         struct twsi_softc *sc;
659         int rv;
660
661         sc = device_get_softc(dev);
662
663         if ((rv = bus_generic_detach(dev)) != 0)
664                 return (rv);
665
666         if (sc->iicbus != NULL)
667                 if ((rv = device_delete_child(dev, sc->iicbus)) != 0)
668                         return (rv);
669
670         if (sc->intrhand != NULL)
671                 bus_teardown_intr(sc->dev, sc->res[1], sc->intrhand);
672
673         bus_release_resources(dev, res_spec, sc->res);
674
675         mtx_destroy(&sc->mutex);
676         return (0);
677 }
678
679 static device_method_t twsi_methods[] = {
680         /* device interface */
681         DEVMETHOD(device_detach,        twsi_detach),
682
683         /* Bus interface */
684         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
685         DEVMETHOD(bus_teardown_intr,    bus_generic_teardown_intr),
686         DEVMETHOD(bus_alloc_resource,   bus_generic_alloc_resource),
687         DEVMETHOD(bus_release_resource, bus_generic_release_resource),
688         DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
689         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
690         DEVMETHOD(bus_adjust_resource,  bus_generic_adjust_resource),
691         DEVMETHOD(bus_set_resource,     bus_generic_rl_set_resource),
692         DEVMETHOD(bus_get_resource,     bus_generic_rl_get_resource),
693
694         /* iicbus interface */
695         DEVMETHOD(iicbus_callback, iicbus_null_callback),
696         DEVMETHOD(iicbus_repeated_start, twsi_repeated_start),
697         DEVMETHOD(iicbus_start,         twsi_start),
698         DEVMETHOD(iicbus_stop,          twsi_stop),
699         DEVMETHOD(iicbus_write,         twsi_write),
700         DEVMETHOD(iicbus_read,          twsi_read),
701         DEVMETHOD(iicbus_reset,         twsi_reset),
702         DEVMETHOD(iicbus_transfer,      twsi_transfer),
703         { 0, 0 }
704 };
705
706 DEFINE_CLASS_0(twsi, twsi_driver, twsi_methods,
707     sizeof(struct twsi_softc));