]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/iicbus/iiconf.c
MFV r348573: 9993 zil writes can get delayed in zio pipeline
[FreeBSD/FreeBSD.git] / sys / dev / iicbus / iiconf.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 1998 Nicolas Souchu
5  * All rights reserved.
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  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/lock.h>
35 #include <sys/malloc.h>
36 #include <sys/module.h>
37 #include <sys/mutex.h>
38 #include <sys/bus.h>
39
40 #include <dev/iicbus/iiconf.h>
41 #include <dev/iicbus/iicbus.h>
42 #include "iicbus_if.h"
43
44 /*
45  * Translate IIC_Exxxxx status values to vaguely-equivelent errno values.
46  */
47 int
48 iic2errno(int iic_status)
49 {
50         switch (iic_status) {
51         case IIC_NOERR:         return (0);
52         case IIC_EBUSERR:       return (EALREADY);
53         case IIC_ENOACK:        return (EIO);
54         case IIC_ETIMEOUT:      return (ETIMEDOUT);
55         case IIC_EBUSBSY:       return (EWOULDBLOCK);
56         case IIC_ESTATUS:       return (EPROTO);
57         case IIC_EUNDERFLOW:    return (EIO);
58         case IIC_EOVERFLOW:     return (EOVERFLOW);
59         case IIC_ENOTSUPP:      return (EOPNOTSUPP);
60         case IIC_ENOADDR:       return (EADDRNOTAVAIL);
61         case IIC_ERESOURCE:     return (ENOMEM);
62         default:                return (EIO);
63         }
64 }
65
66 /*
67  * iicbus_intr()
68  */
69 void
70 iicbus_intr(device_t bus, int event, char *buf)
71 {
72         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
73
74         /* call owner's intr routine */
75         if (sc->owner)
76                 IICBUS_INTR(sc->owner, event, buf);
77
78         return;
79 }
80
81 static int
82 iicbus_poll(struct iicbus_softc *sc, int how)
83 {
84         int error;
85
86         IICBUS_ASSERT_LOCKED(sc);
87         switch (how & IIC_INTRWAIT) {
88         case IIC_WAIT | IIC_INTR:
89                 error = mtx_sleep(sc, &sc->lock, IICPRI|PCATCH, "iicreq", 0);
90                 break;
91
92         case IIC_WAIT | IIC_NOINTR:
93                 error = mtx_sleep(sc, &sc->lock, IICPRI, "iicreq", 0);
94                 break;
95
96         default:
97                 return (IIC_EBUSBSY);
98         }
99
100         return (error);
101 }
102
103 /*
104  * iicbus_request_bus()
105  *
106  * Allocate the device to perform transfers.
107  *
108  * how  : IIC_WAIT or IIC_DONTWAIT
109  */
110 int
111 iicbus_request_bus(device_t bus, device_t dev, int how)
112 {
113         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
114         int error = 0;
115
116         IICBUS_LOCK(sc);
117
118         for (;;) {
119                 if (sc->owner == NULL)
120                         break;
121                 if ((how & IIC_RECURSIVE) && sc->owner == dev)
122                         break;
123                 if ((error = iicbus_poll(sc, how)) != 0)
124                         break;
125         }
126
127         if (error == 0) {
128                 ++sc->owncount;
129                 if (sc->owner == NULL) {
130                         sc->owner = dev;
131                         /*
132                          * Mark the device busy while it owns the bus, to
133                          * prevent detaching the device, bus, or hardware
134                          * controller, until ownership is relinquished.
135                          */
136                         device_busy(dev);
137                         /* 
138                          * Drop the lock around the call to the bus driver, it
139                          * should be allowed to sleep in the IIC_WAIT case.
140                          * Drivers might also need to grab locks that would
141                          * cause a LOR if our lock is held.
142                          */
143                         IICBUS_UNLOCK(sc);
144                         /* Ask the underlying layers if the request is ok */
145                         error = IICBUS_CALLBACK(device_get_parent(bus),
146                             IIC_REQUEST_BUS, (caddr_t)&how);
147                         IICBUS_LOCK(sc);
148         
149                         if (error != 0) {
150                                 sc->owner = NULL;
151                                 sc->owncount = 0;
152                                 wakeup_one(sc);
153                         }
154                 }
155         }
156
157         IICBUS_UNLOCK(sc);
158
159         return (error);
160 }
161
162 /*
163  * iicbus_release_bus()
164  *
165  * Release the device allocated with iicbus_request_dev()
166  */
167 int
168 iicbus_release_bus(device_t bus, device_t dev)
169 {
170         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
171
172         IICBUS_LOCK(sc);
173
174         if (sc->owner != dev) {
175                 IICBUS_UNLOCK(sc);
176                 return (IIC_EBUSBSY);
177         }
178
179         if (--sc->owncount == 0) {
180                 /* Drop the lock while informing the low-level driver. */
181                 IICBUS_UNLOCK(sc);
182                 IICBUS_CALLBACK(device_get_parent(bus), IIC_RELEASE_BUS, NULL);
183                 IICBUS_LOCK(sc);
184                 sc->owner = NULL;
185                 wakeup_one(sc);
186                 device_unbusy(dev);
187         }
188         IICBUS_UNLOCK(sc);
189         return (0);
190 }
191
192 /*
193  * iicbus_started()
194  *
195  * Test if the iicbus is started by the controller
196  */
197 int
198 iicbus_started(device_t bus)
199 {
200         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
201
202         return (sc->started);
203 }
204
205 /*
206  * iicbus_start()
207  *
208  * Send start condition to the slave addressed by 'slave'
209  */
210 int
211 iicbus_start(device_t bus, u_char slave, int timeout)
212 {
213         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
214         int error = 0;
215
216         if (sc->started)
217                 return (IIC_ESTATUS); /* protocol error, bus already started */
218
219         if (!(error = IICBUS_START(device_get_parent(bus), slave, timeout)))
220                 sc->started = slave;
221         else
222                 sc->started = 0;
223
224         return (error);
225 }
226
227 /*
228  * iicbus_repeated_start()
229  *
230  * Send start condition to the slave addressed by 'slave'
231  */
232 int
233 iicbus_repeated_start(device_t bus, u_char slave, int timeout)
234 {
235         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
236         int error = 0;
237
238         if (!sc->started)
239                 return (IIC_ESTATUS); /* protocol error, bus not started */
240
241         if (!(error = IICBUS_REPEATED_START(device_get_parent(bus), slave, timeout)))
242                 sc->started = slave;
243         else
244                 sc->started = 0;
245
246         return (error);
247 }
248
249 /*
250  * iicbus_stop()
251  *
252  * Send stop condition to the bus
253  */
254 int
255 iicbus_stop(device_t bus)
256 {
257         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
258         int error = 0;
259
260         if (!sc->started)
261                 return (IIC_ESTATUS); /* protocol error, bus not started */
262
263         error = IICBUS_STOP(device_get_parent(bus));
264
265         /* refuse any further access */
266         sc->started = 0;
267
268         return (error);
269 }
270
271 /*
272  * iicbus_write()
273  *
274  * Write a block of data to the slave previously started by
275  * iicbus_start() call
276  */
277 int
278 iicbus_write(device_t bus, const char *buf, int len, int *sent, int timeout)
279 {
280         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
281         
282         /* a slave must have been started for writing */
283         if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) != 0))
284                 return (IIC_ESTATUS);
285
286         return (IICBUS_WRITE(device_get_parent(bus), buf, len, sent, timeout));
287 }
288
289 /*
290  * iicbus_read()
291  *
292  * Read a block of data from the slave previously started by
293  * iicbus_read() call
294  */
295 int 
296 iicbus_read(device_t bus, char *buf, int len, int *read, int last, int delay)
297 {
298         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
299         
300         /* a slave must have been started for reading */
301         if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) == 0))
302                 return (IIC_ESTATUS);
303
304         return (IICBUS_READ(device_get_parent(bus), buf, len, read, last, delay));
305 }
306
307 /*
308  * iicbus_write_byte()
309  *
310  * Write a byte to the slave previously started by iicbus_start() call
311  */
312 int
313 iicbus_write_byte(device_t bus, char byte, int timeout)
314 {
315         struct iicbus_softc *sc = device_get_softc(bus);
316         char data = byte;
317         int sent;
318
319         /* a slave must have been started for writing */
320         if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) != 0))
321                 return (IIC_ESTATUS);
322
323         return (iicbus_write(bus, &data, 1, &sent, timeout));
324 }
325
326 /*
327  * iicbus_read_byte()
328  *
329  * Read a byte from the slave previously started by iicbus_start() call
330  */
331 int
332 iicbus_read_byte(device_t bus, char *byte, int timeout)
333 {
334         struct iicbus_softc *sc = device_get_softc(bus);
335         int read;
336
337         /* a slave must have been started for reading */
338         if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) == 0))
339                 return (IIC_ESTATUS);
340
341         return (iicbus_read(bus, byte, 1, &read, IIC_LAST_READ, timeout));
342 }
343
344 /*
345  * iicbus_block_write()
346  *
347  * Write a block of data to slave ; start/stop protocol managed
348  */
349 int
350 iicbus_block_write(device_t bus, u_char slave, char *buf, int len, int *sent)
351 {
352         u_char addr = slave & ~LSB;
353         int error;
354
355         if ((error = iicbus_start(bus, addr, 0)))
356                 return (error);
357
358         error = iicbus_write(bus, buf, len, sent, 0);
359
360         iicbus_stop(bus);
361
362         return (error);
363 }
364
365 /*
366  * iicbus_block_read()
367  *
368  * Read a block of data from slave ; start/stop protocol managed
369  */
370 int
371 iicbus_block_read(device_t bus, u_char slave, char *buf, int len, int *read)
372 {
373         u_char addr = slave | LSB;
374         int error;
375
376         if ((error = iicbus_start(bus, addr, 0)))
377                 return (error);
378
379         error = iicbus_read(bus, buf, len, read, IIC_LAST_READ, 0);
380
381         iicbus_stop(bus);
382
383         return (error);
384 }
385
386 /*
387  * iicbus_transfer()
388  *
389  * Do an aribtrary number of transfers on the iicbus.  We pass these
390  * raw requests to the bridge driver.  If the bridge driver supports
391  * them directly, then it manages all the details.  If not, it can use
392  * the helper function iicbus_transfer_gen() which will do the
393  * transfers at a low level.
394  *
395  * Pointers passed in as part of iic_msg must be kernel pointers.
396  * Callers that have user addresses to manage must do so on their own.
397  */
398 int
399 iicbus_transfer(device_t bus, struct iic_msg *msgs, uint32_t nmsgs)
400 {
401
402         return (IICBUS_TRANSFER(device_get_parent(bus), msgs, nmsgs));
403 }
404
405 int
406 iicbus_transfer_excl(device_t dev, struct iic_msg *msgs, uint32_t nmsgs,
407     int how)
408 {
409         device_t bus;
410         int error;
411
412         bus = device_get_parent(dev);
413         error = iicbus_request_bus(bus, dev, how);
414         if (error == 0)
415                 error = IICBUS_TRANSFER(bus, msgs, nmsgs);
416         iicbus_release_bus(bus, dev);
417         return (error);
418 }
419
420 /*
421  * Generic version of iicbus_transfer that calls the appropriate
422  * routines to accomplish this.  See note above about acceptable
423  * buffer addresses.
424  */
425 int
426 iicbus_transfer_gen(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
427 {
428         int i, error, lenread, lenwrote, nkid, rpstart, addr;
429         device_t *children, bus;
430         bool started;
431
432         if ((error = device_get_children(dev, &children, &nkid)) != 0)
433                 return (IIC_ERESOURCE);
434         if (nkid != 1) {
435                 free(children, M_TEMP);
436                 return (IIC_ENOTSUPP);
437         }
438         bus = children[0];
439         rpstart = 0;
440         free(children, M_TEMP);
441         started = false;
442         for (i = 0, error = 0; i < nmsgs && error == 0; i++) {
443                 addr = msgs[i].slave;
444                 if (msgs[i].flags & IIC_M_RD)
445                         addr |= LSB;
446                 else
447                         addr &= ~LSB;
448
449                 if (!(msgs[i].flags & IIC_M_NOSTART)) {
450                         if (rpstart)
451                                 error = iicbus_repeated_start(bus, addr, 0);
452                         else
453                                 error = iicbus_start(bus, addr, 0);
454                         if (error != 0)
455                                 break;
456                         started = true;
457                 }
458
459                 if (msgs[i].flags & IIC_M_RD)
460                         error = iicbus_read(bus, msgs[i].buf, msgs[i].len,
461                             &lenread, IIC_LAST_READ, 0);
462                 else
463                         error = iicbus_write(bus, msgs[i].buf, msgs[i].len,
464                             &lenwrote, 0);
465                 if (error != 0)
466                         break;
467
468                 if (!(msgs[i].flags & IIC_M_NOSTOP)) {
469                         rpstart = 0;
470                         iicbus_stop(bus);
471                 } else {
472                         rpstart = 1;    /* Next message gets repeated start */
473                 }
474         }
475         if (error != 0 && started)
476                 iicbus_stop(bus);
477         return (error);
478 }
479
480 int
481 iicdev_readfrom(device_t slavedev, uint8_t regaddr, void *buffer,
482     uint16_t buflen, int waithow)
483 {
484         struct iic_msg msgs[2];
485         uint8_t slaveaddr;
486
487         /*
488          * Two transfers back to back with a repeat-start between them; first we
489          * write the address-within-device, then we read from the device.
490          */
491         slaveaddr = iicbus_get_addr(slavedev);
492
493         msgs[0].slave = slaveaddr;
494         msgs[0].flags = IIC_M_WR | IIC_M_NOSTOP;
495         msgs[0].len   = 1;
496         msgs[0].buf   = &regaddr;
497
498         msgs[1].slave = slaveaddr;
499         msgs[1].flags = IIC_M_RD;
500         msgs[1].len   = buflen;
501         msgs[1].buf   = buffer;
502
503         return (iicbus_transfer_excl(slavedev, msgs, nitems(msgs), waithow));
504 }
505
506 int iicdev_writeto(device_t slavedev, uint8_t regaddr, void *buffer,
507     uint16_t buflen, int waithow)
508 {
509         struct iic_msg msgs[2];
510         uint8_t slaveaddr;
511
512         /*
513          * Two transfers back to back with no stop or start between them; first
514          * we write the address then we write the data to that address, all in a
515          * single transfer from two scattered buffers.
516          */
517         slaveaddr = iicbus_get_addr(slavedev);
518
519         msgs[0].slave = slaveaddr;
520         msgs[0].flags = IIC_M_WR | IIC_M_NOSTOP;
521         msgs[0].len   = 1;
522         msgs[0].buf   = &regaddr;
523
524         msgs[1].slave = slaveaddr;
525         msgs[1].flags = IIC_M_WR | IIC_M_NOSTART;
526         msgs[1].len   = buflen;
527         msgs[1].buf   = buffer;
528
529         return (iicbus_transfer_excl(slavedev, msgs, nitems(msgs), waithow));
530 }