]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/iicbus/iiconf.c
MFV r361937:
[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  * Encode a system errno value into the IIC_Exxxxx space by setting the
46  * IIC_ERRNO marker bit, so that iic2errno() can turn it back into a plain
47  * system errno value later.  This lets controller- and bus-layer code get
48  * important system errno values (such as EINTR/ERESTART) back to the caller.
49  */
50 int
51 errno2iic(int errno)
52 {
53         return ((errno == 0) ? 0 : errno | IIC_ERRNO);
54 }
55
56 /*
57  * Translate IIC_Exxxxx status values to vaguely-equivelent errno values.
58  */
59 int
60 iic2errno(int iic_status)
61 {
62         switch (iic_status) {
63         case IIC_NOERR:         return (0);
64         case IIC_EBUSERR:       return (EALREADY);
65         case IIC_ENOACK:        return (EIO);
66         case IIC_ETIMEOUT:      return (ETIMEDOUT);
67         case IIC_EBUSBSY:       return (EWOULDBLOCK);
68         case IIC_ESTATUS:       return (EPROTO);
69         case IIC_EUNDERFLOW:    return (EIO);
70         case IIC_EOVERFLOW:     return (EOVERFLOW);
71         case IIC_ENOTSUPP:      return (EOPNOTSUPP);
72         case IIC_ENOADDR:       return (EADDRNOTAVAIL);
73         case IIC_ERESOURCE:     return (ENOMEM);
74         default:
75                 /*
76                  * If the high bit is set, that means it's a system errno value
77                  * that was encoded into the IIC_Exxxxxx space by setting the
78                  * IIC_ERRNO marker bit.  If lots of high-order bits are set,
79                  * then it's one of the negative pseudo-errors such as ERESTART
80                  * and we return it as-is.  Otherwise it's a plain "small
81                  * positive integer" errno, so just remove the IIC_ERRNO marker
82                  * bit.  If it's some unknown number without the high bit set,
83                  * there isn't much we can do except call it an I/O error.
84                  */
85                 if ((iic_status & IIC_ERRNO) == 0)
86                         return (EIO);
87                 if ((iic_status & 0xFFFF0000) != 0)
88                         return (iic_status);
89                 return (iic_status & ~IIC_ERRNO);
90         }
91 }
92
93 /*
94  * iicbus_intr()
95  */
96 void
97 iicbus_intr(device_t bus, int event, char *buf)
98 {
99         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
100
101         /* call owner's intr routine */
102         if (sc->owner)
103                 IICBUS_INTR(sc->owner, event, buf);
104
105         return;
106 }
107
108 static int
109 iicbus_poll(struct iicbus_softc *sc, int how)
110 {
111         int error;
112
113         IICBUS_ASSERT_LOCKED(sc);
114         switch (how & IIC_INTRWAIT) {
115         case IIC_WAIT | IIC_INTR:
116                 error = mtx_sleep(sc, &sc->lock, IICPRI|PCATCH, "iicreq", 0);
117                 break;
118
119         case IIC_WAIT | IIC_NOINTR:
120                 error = mtx_sleep(sc, &sc->lock, IICPRI, "iicreq", 0);
121                 break;
122
123         default:
124                 return (IIC_EBUSBSY);
125         }
126
127         return (errno2iic(error));
128 }
129
130 /*
131  * iicbus_request_bus()
132  *
133  * Allocate the device to perform transfers.
134  *
135  * how  : IIC_WAIT or IIC_DONTWAIT
136  */
137 int
138 iicbus_request_bus(device_t bus, device_t dev, int how)
139 {
140         struct iic_reqbus_data reqdata;
141         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
142         int error = 0;
143
144         IICBUS_LOCK(sc);
145
146         for (;;) {
147                 if (sc->owner == NULL)
148                         break;
149                 if ((how & IIC_RECURSIVE) && sc->owner == dev)
150                         break;
151                 if ((error = iicbus_poll(sc, how)) != 0)
152                         break;
153         }
154
155         if (error == 0) {
156                 ++sc->owncount;
157                 if (sc->owner == NULL) {
158                         sc->owner = dev;
159                         /*
160                          * Mark the device busy while it owns the bus, to
161                          * prevent detaching the device, bus, or hardware
162                          * controller, until ownership is relinquished.  If the
163                          * device is doing IO from its probe method before
164                          * attaching, it cannot be busied; mark the bus busy.
165                          */
166                         if (device_get_state(dev) < DS_ATTACHING)
167                                 sc->busydev = bus;
168                         else
169                                 sc->busydev = dev;
170                         device_busy(sc->busydev);
171                         /* 
172                          * Drop the lock around the call to the bus driver, it
173                          * should be allowed to sleep in the IIC_WAIT case.
174                          * Drivers might also need to grab locks that would
175                          * cause a LOR if our lock is held.
176                          */
177                         IICBUS_UNLOCK(sc);
178                         /* Ask the underlying layers if the request is ok */
179                         reqdata.dev = dev;
180                         reqdata.bus = bus;
181                         reqdata.flags = how | IIC_REQBUS_DEV;
182                         error = IICBUS_CALLBACK(device_get_parent(bus),
183                             IIC_REQUEST_BUS, (caddr_t)&reqdata);
184                         IICBUS_LOCK(sc);
185         
186                         if (error != 0) {
187                                 sc->owner = NULL;
188                                 sc->owncount = 0;
189                                 wakeup_one(sc);
190                                 device_unbusy(sc->busydev);
191                         }
192                 }
193         }
194
195         IICBUS_UNLOCK(sc);
196
197         return (error);
198 }
199
200 /*
201  * iicbus_release_bus()
202  *
203  * Release the device allocated with iicbus_request_dev()
204  */
205 int
206 iicbus_release_bus(device_t bus, device_t dev)
207 {
208         struct iic_reqbus_data reqdata;
209         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
210
211         IICBUS_LOCK(sc);
212
213         if (sc->owner != dev) {
214                 IICBUS_UNLOCK(sc);
215                 return (IIC_EBUSBSY);
216         }
217
218         if (--sc->owncount == 0) {
219                 /* Drop the lock while informing the low-level driver. */
220                 IICBUS_UNLOCK(sc);
221                 reqdata.dev = dev;
222                 reqdata.bus = bus;
223                 reqdata.flags = IIC_REQBUS_DEV;
224                 IICBUS_CALLBACK(device_get_parent(bus), IIC_RELEASE_BUS,
225                     (caddr_t)&reqdata);
226                 IICBUS_LOCK(sc);
227                 sc->owner = NULL;
228                 wakeup_one(sc);
229                 device_unbusy(sc->busydev);
230         }
231         IICBUS_UNLOCK(sc);
232         return (0);
233 }
234
235 /*
236  * iicbus_started()
237  *
238  * Test if the iicbus is started by the controller
239  */
240 int
241 iicbus_started(device_t bus)
242 {
243         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
244
245         return (sc->started);
246 }
247
248 /*
249  * iicbus_start()
250  *
251  * Send start condition to the slave addressed by 'slave'
252  */
253 int
254 iicbus_start(device_t bus, u_char slave, int timeout)
255 {
256         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
257         int error = 0;
258
259         if (sc->started)
260                 return (IIC_ESTATUS); /* protocol error, bus already started */
261
262         if (!(error = IICBUS_START(device_get_parent(bus), slave, timeout)))
263                 sc->started = slave;
264         else
265                 sc->started = 0;
266
267         return (error);
268 }
269
270 /*
271  * iicbus_repeated_start()
272  *
273  * Send start condition to the slave addressed by 'slave'
274  */
275 int
276 iicbus_repeated_start(device_t bus, u_char slave, int timeout)
277 {
278         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
279         int error = 0;
280
281         if (!sc->started)
282                 return (IIC_ESTATUS); /* protocol error, bus not started */
283
284         if (!(error = IICBUS_REPEATED_START(device_get_parent(bus), slave, timeout)))
285                 sc->started = slave;
286         else
287                 sc->started = 0;
288
289         return (error);
290 }
291
292 /*
293  * iicbus_stop()
294  *
295  * Send stop condition to the bus
296  */
297 int
298 iicbus_stop(device_t bus)
299 {
300         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
301         int error = 0;
302
303         if (!sc->started)
304                 return (IIC_ESTATUS); /* protocol error, bus not started */
305
306         error = IICBUS_STOP(device_get_parent(bus));
307
308         /* refuse any further access */
309         sc->started = 0;
310
311         return (error);
312 }
313
314 /*
315  * iicbus_write()
316  *
317  * Write a block of data to the slave previously started by
318  * iicbus_start() call
319  */
320 int
321 iicbus_write(device_t bus, const char *buf, int len, int *sent, int timeout)
322 {
323         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
324         
325         /* a slave must have been started for writing */
326         if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) != 0))
327                 return (IIC_ESTATUS);
328
329         return (IICBUS_WRITE(device_get_parent(bus), buf, len, sent, timeout));
330 }
331
332 /*
333  * iicbus_read()
334  *
335  * Read a block of data from the slave previously started by
336  * iicbus_read() call
337  */
338 int 
339 iicbus_read(device_t bus, char *buf, int len, int *read, int last, int delay)
340 {
341         struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
342         
343         /* a slave must have been started for reading */
344         if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) == 0))
345                 return (IIC_ESTATUS);
346
347         return (IICBUS_READ(device_get_parent(bus), buf, len, read, last, delay));
348 }
349
350 /*
351  * iicbus_write_byte()
352  *
353  * Write a byte to the slave previously started by iicbus_start() call
354  */
355 int
356 iicbus_write_byte(device_t bus, char byte, int timeout)
357 {
358         struct iicbus_softc *sc = device_get_softc(bus);
359         char data = byte;
360         int sent;
361
362         /* a slave must have been started for writing */
363         if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) != 0))
364                 return (IIC_ESTATUS);
365
366         return (iicbus_write(bus, &data, 1, &sent, timeout));
367 }
368
369 /*
370  * iicbus_read_byte()
371  *
372  * Read a byte from the slave previously started by iicbus_start() call
373  */
374 int
375 iicbus_read_byte(device_t bus, char *byte, int timeout)
376 {
377         struct iicbus_softc *sc = device_get_softc(bus);
378         int read;
379
380         /* a slave must have been started for reading */
381         if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) == 0))
382                 return (IIC_ESTATUS);
383
384         return (iicbus_read(bus, byte, 1, &read, IIC_LAST_READ, timeout));
385 }
386
387 /*
388  * iicbus_block_write()
389  *
390  * Write a block of data to slave ; start/stop protocol managed
391  */
392 int
393 iicbus_block_write(device_t bus, u_char slave, char *buf, int len, int *sent)
394 {
395         u_char addr = slave & ~LSB;
396         int error;
397
398         if ((error = iicbus_start(bus, addr, 0)))
399                 return (error);
400
401         error = iicbus_write(bus, buf, len, sent, 0);
402
403         iicbus_stop(bus);
404
405         return (error);
406 }
407
408 /*
409  * iicbus_block_read()
410  *
411  * Read a block of data from slave ; start/stop protocol managed
412  */
413 int
414 iicbus_block_read(device_t bus, u_char slave, char *buf, int len, int *read)
415 {
416         u_char addr = slave | LSB;
417         int error;
418
419         if ((error = iicbus_start(bus, addr, 0)))
420                 return (error);
421
422         error = iicbus_read(bus, buf, len, read, IIC_LAST_READ, 0);
423
424         iicbus_stop(bus);
425
426         return (error);
427 }
428
429 /*
430  * iicbus_transfer()
431  *
432  * Do an aribtrary number of transfers on the iicbus.  We pass these
433  * raw requests to the bridge driver.  If the bridge driver supports
434  * them directly, then it manages all the details.  If not, it can use
435  * the helper function iicbus_transfer_gen() which will do the
436  * transfers at a low level.
437  *
438  * Pointers passed in as part of iic_msg must be kernel pointers.
439  * Callers that have user addresses to manage must do so on their own.
440  */
441 int
442 iicbus_transfer(device_t bus, struct iic_msg *msgs, uint32_t nmsgs)
443 {
444
445         return (IICBUS_TRANSFER(device_get_parent(bus), msgs, nmsgs));
446 }
447
448 int
449 iicbus_transfer_excl(device_t dev, struct iic_msg *msgs, uint32_t nmsgs,
450     int how)
451 {
452         device_t bus;
453         int error;
454
455         bus = device_get_parent(dev);
456         error = iicbus_request_bus(bus, dev, how);
457         if (error == 0)
458                 error = IICBUS_TRANSFER(bus, msgs, nmsgs);
459         iicbus_release_bus(bus, dev);
460         return (error);
461 }
462
463 /*
464  * Generic version of iicbus_transfer that calls the appropriate
465  * routines to accomplish this.  See note above about acceptable
466  * buffer addresses.
467  */
468 int
469 iicbus_transfer_gen(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
470 {
471         int i, error, lenread, lenwrote, nkid, rpstart, addr;
472         device_t *children, bus;
473         bool started;
474
475         if ((error = device_get_children(dev, &children, &nkid)) != 0)
476                 return (IIC_ERESOURCE);
477         if (nkid != 1) {
478                 free(children, M_TEMP);
479                 return (IIC_ENOTSUPP);
480         }
481         bus = children[0];
482         rpstart = 0;
483         free(children, M_TEMP);
484         started = false;
485         for (i = 0, error = 0; i < nmsgs && error == 0; i++) {
486                 addr = msgs[i].slave;
487                 if (msgs[i].flags & IIC_M_RD)
488                         addr |= LSB;
489                 else
490                         addr &= ~LSB;
491
492                 if (!(msgs[i].flags & IIC_M_NOSTART)) {
493                         if (rpstart)
494                                 error = iicbus_repeated_start(bus, addr, 0);
495                         else
496                                 error = iicbus_start(bus, addr, 0);
497                         if (error != 0)
498                                 break;
499                         started = true;
500                 }
501
502                 if (msgs[i].flags & IIC_M_RD)
503                         error = iicbus_read(bus, msgs[i].buf, msgs[i].len,
504                             &lenread, IIC_LAST_READ, 0);
505                 else
506                         error = iicbus_write(bus, msgs[i].buf, msgs[i].len,
507                             &lenwrote, 0);
508                 if (error != 0)
509                         break;
510
511                 if (!(msgs[i].flags & IIC_M_NOSTOP)) {
512                         rpstart = 0;
513                         iicbus_stop(bus);
514                 } else {
515                         rpstart = 1;    /* Next message gets repeated start */
516                 }
517         }
518         if (error != 0 && started)
519                 iicbus_stop(bus);
520         return (error);
521 }
522
523 int
524 iicdev_readfrom(device_t slavedev, uint8_t regaddr, void *buffer,
525     uint16_t buflen, int waithow)
526 {
527         struct iic_msg msgs[2];
528         uint8_t slaveaddr;
529
530         /*
531          * Two transfers back to back with a repeat-start between them; first we
532          * write the address-within-device, then we read from the device.
533          */
534         slaveaddr = iicbus_get_addr(slavedev);
535
536         msgs[0].slave = slaveaddr;
537         msgs[0].flags = IIC_M_WR | IIC_M_NOSTOP;
538         msgs[0].len   = 1;
539         msgs[0].buf   = &regaddr;
540
541         msgs[1].slave = slaveaddr;
542         msgs[1].flags = IIC_M_RD;
543         msgs[1].len   = buflen;
544         msgs[1].buf   = buffer;
545
546         return (iicbus_transfer_excl(slavedev, msgs, nitems(msgs), waithow));
547 }
548
549 int iicdev_writeto(device_t slavedev, uint8_t regaddr, void *buffer,
550     uint16_t buflen, int waithow)
551 {
552         struct iic_msg msg;
553         uint8_t local_buffer[32];
554         uint8_t *bufptr;
555         size_t bufsize;
556         int error;
557
558         /*
559          * Ideally, we would do two transfers back to back with no stop or start
560          * between them using an array of 2 iic_msgs; first we'd write the
561          * address byte using the IIC_M_NOSTOP flag, then we write the data
562          * using IIC_M_NOSTART, all in a single transfer.  Unfortunately,
563          * several i2c hardware drivers don't support that (perhaps because the
564          * hardware itself can't support it).  So instead we gather the
565          * scattered bytes into a single buffer here before writing them using a
566          * single iic_msg.  This function is typically used to write a few bytes
567          * at a time, so we try to use a small local buffer on the stack, but
568          * fall back to allocating a temporary buffer when necessary.
569          */
570
571         bufsize = buflen + 1;
572         if (bufsize <= sizeof(local_buffer)) {
573                 bufptr = local_buffer;
574         } else {
575                 bufptr = malloc(bufsize, M_DEVBUF,
576                     (waithow & IIC_WAIT) ? M_WAITOK : M_NOWAIT);
577                 if (bufptr == NULL)
578                         return (errno2iic(ENOMEM));
579         }
580
581         bufptr[0] = regaddr;
582         memcpy(&bufptr[1], buffer, buflen);
583
584         msg.slave = iicbus_get_addr(slavedev);
585         msg.flags = IIC_M_WR;
586         msg.len   = bufsize;
587         msg.buf   = bufptr;
588
589         error = iicbus_transfer_excl(slavedev, &msg, 1, waithow);
590
591         if (bufptr != local_buffer)
592                 free(bufptr, M_DEVBUF);
593
594         return (error);
595 }