xref: /freebsd/sys/dev/iicbus/iiconf.c (revision f5ef5f675d9d9eb6e35ed9142d70ecf774456ad4)
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 iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
141 	int error = 0;
142 
143 	IICBUS_LOCK(sc);
144 
145 	for (;;) {
146 		if (sc->owner == NULL)
147 			break;
148 		if ((how & IIC_RECURSIVE) && sc->owner == dev)
149 			break;
150 		if ((error = iicbus_poll(sc, how)) != 0)
151 			break;
152 	}
153 
154 	if (error == 0) {
155 		++sc->owncount;
156 		if (sc->owner == NULL) {
157 			sc->owner = dev;
158 			/*
159 			 * Mark the device busy while it owns the bus, to
160 			 * prevent detaching the device, bus, or hardware
161 			 * controller, until ownership is relinquished.  If the
162 			 * device is doing IO from its probe method before
163 			 * attaching, it cannot be busied; mark the bus busy.
164 			 */
165 			if (device_get_state(dev) < DS_ATTACHING)
166 				sc->busydev = bus;
167 			else
168 				sc->busydev = dev;
169 			device_busy(sc->busydev);
170 			/*
171 			 * Drop the lock around the call to the bus driver, it
172 			 * should be allowed to sleep in the IIC_WAIT case.
173 			 * Drivers might also need to grab locks that would
174 			 * cause a LOR if our lock is held.
175 			 */
176 			IICBUS_UNLOCK(sc);
177 			/* Ask the underlying layers if the request is ok */
178 			error = IICBUS_CALLBACK(device_get_parent(bus),
179 			    IIC_REQUEST_BUS, (caddr_t)&how);
180 			IICBUS_LOCK(sc);
181 
182 			if (error != 0) {
183 				sc->owner = NULL;
184 				sc->owncount = 0;
185 				wakeup_one(sc);
186 				device_unbusy(sc->busydev);
187 			}
188 		}
189 	}
190 
191 	IICBUS_UNLOCK(sc);
192 
193 	return (error);
194 }
195 
196 /*
197  * iicbus_release_bus()
198  *
199  * Release the device allocated with iicbus_request_dev()
200  */
201 int
202 iicbus_release_bus(device_t bus, device_t dev)
203 {
204 	struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
205 
206 	IICBUS_LOCK(sc);
207 
208 	if (sc->owner != dev) {
209 		IICBUS_UNLOCK(sc);
210 		return (IIC_EBUSBSY);
211 	}
212 
213 	if (--sc->owncount == 0) {
214 		/* Drop the lock while informing the low-level driver. */
215 		IICBUS_UNLOCK(sc);
216 		IICBUS_CALLBACK(device_get_parent(bus), IIC_RELEASE_BUS, NULL);
217 		IICBUS_LOCK(sc);
218 		sc->owner = NULL;
219 		wakeup_one(sc);
220 		device_unbusy(sc->busydev);
221 	}
222 	IICBUS_UNLOCK(sc);
223 	return (0);
224 }
225 
226 /*
227  * iicbus_started()
228  *
229  * Test if the iicbus is started by the controller
230  */
231 int
232 iicbus_started(device_t bus)
233 {
234 	struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
235 
236 	return (sc->started);
237 }
238 
239 /*
240  * iicbus_start()
241  *
242  * Send start condition to the slave addressed by 'slave'
243  */
244 int
245 iicbus_start(device_t bus, u_char slave, int timeout)
246 {
247 	struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
248 	int error = 0;
249 
250 	if (sc->started)
251 		return (IIC_ESTATUS); /* protocol error, bus already started */
252 
253 	if (!(error = IICBUS_START(device_get_parent(bus), slave, timeout)))
254 		sc->started = slave;
255 	else
256 		sc->started = 0;
257 
258 	return (error);
259 }
260 
261 /*
262  * iicbus_repeated_start()
263  *
264  * Send start condition to the slave addressed by 'slave'
265  */
266 int
267 iicbus_repeated_start(device_t bus, u_char slave, int timeout)
268 {
269 	struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
270 	int error = 0;
271 
272 	if (!sc->started)
273 		return (IIC_ESTATUS); /* protocol error, bus not started */
274 
275 	if (!(error = IICBUS_REPEATED_START(device_get_parent(bus), slave, timeout)))
276 		sc->started = slave;
277 	else
278 		sc->started = 0;
279 
280 	return (error);
281 }
282 
283 /*
284  * iicbus_stop()
285  *
286  * Send stop condition to the bus
287  */
288 int
289 iicbus_stop(device_t bus)
290 {
291 	struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
292 	int error = 0;
293 
294 	if (!sc->started)
295 		return (IIC_ESTATUS); /* protocol error, bus not started */
296 
297 	error = IICBUS_STOP(device_get_parent(bus));
298 
299 	/* refuse any further access */
300 	sc->started = 0;
301 
302 	return (error);
303 }
304 
305 /*
306  * iicbus_write()
307  *
308  * Write a block of data to the slave previously started by
309  * iicbus_start() call
310  */
311 int
312 iicbus_write(device_t bus, const char *buf, int len, int *sent, int timeout)
313 {
314 	struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
315 
316 	/* a slave must have been started for writing */
317 	if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) != 0))
318 		return (IIC_ESTATUS);
319 
320 	return (IICBUS_WRITE(device_get_parent(bus), buf, len, sent, timeout));
321 }
322 
323 /*
324  * iicbus_read()
325  *
326  * Read a block of data from the slave previously started by
327  * iicbus_read() call
328  */
329 int
330 iicbus_read(device_t bus, char *buf, int len, int *read, int last, int delay)
331 {
332 	struct iicbus_softc *sc = (struct iicbus_softc *)device_get_softc(bus);
333 
334 	/* a slave must have been started for reading */
335 	if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) == 0))
336 		return (IIC_ESTATUS);
337 
338 	return (IICBUS_READ(device_get_parent(bus), buf, len, read, last, delay));
339 }
340 
341 /*
342  * iicbus_write_byte()
343  *
344  * Write a byte to the slave previously started by iicbus_start() call
345  */
346 int
347 iicbus_write_byte(device_t bus, char byte, int timeout)
348 {
349 	struct iicbus_softc *sc = device_get_softc(bus);
350 	char data = byte;
351 	int sent;
352 
353 	/* a slave must have been started for writing */
354 	if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) != 0))
355 		return (IIC_ESTATUS);
356 
357 	return (iicbus_write(bus, &data, 1, &sent, timeout));
358 }
359 
360 /*
361  * iicbus_read_byte()
362  *
363  * Read a byte from the slave previously started by iicbus_start() call
364  */
365 int
366 iicbus_read_byte(device_t bus, char *byte, int timeout)
367 {
368 	struct iicbus_softc *sc = device_get_softc(bus);
369 	int read;
370 
371 	/* a slave must have been started for reading */
372 	if (sc->started == 0 || (sc->strict != 0 && (sc->started & LSB) == 0))
373 		return (IIC_ESTATUS);
374 
375 	return (iicbus_read(bus, byte, 1, &read, IIC_LAST_READ, timeout));
376 }
377 
378 /*
379  * iicbus_block_write()
380  *
381  * Write a block of data to slave ; start/stop protocol managed
382  */
383 int
384 iicbus_block_write(device_t bus, u_char slave, char *buf, int len, int *sent)
385 {
386 	u_char addr = slave & ~LSB;
387 	int error;
388 
389 	if ((error = iicbus_start(bus, addr, 0)))
390 		return (error);
391 
392 	error = iicbus_write(bus, buf, len, sent, 0);
393 
394 	iicbus_stop(bus);
395 
396 	return (error);
397 }
398 
399 /*
400  * iicbus_block_read()
401  *
402  * Read a block of data from slave ; start/stop protocol managed
403  */
404 int
405 iicbus_block_read(device_t bus, u_char slave, char *buf, int len, int *read)
406 {
407 	u_char addr = slave | LSB;
408 	int error;
409 
410 	if ((error = iicbus_start(bus, addr, 0)))
411 		return (error);
412 
413 	error = iicbus_read(bus, buf, len, read, IIC_LAST_READ, 0);
414 
415 	iicbus_stop(bus);
416 
417 	return (error);
418 }
419 
420 /*
421  * iicbus_transfer()
422  *
423  * Do an aribtrary number of transfers on the iicbus.  We pass these
424  * raw requests to the bridge driver.  If the bridge driver supports
425  * them directly, then it manages all the details.  If not, it can use
426  * the helper function iicbus_transfer_gen() which will do the
427  * transfers at a low level.
428  *
429  * Pointers passed in as part of iic_msg must be kernel pointers.
430  * Callers that have user addresses to manage must do so on their own.
431  */
432 int
433 iicbus_transfer(device_t bus, struct iic_msg *msgs, uint32_t nmsgs)
434 {
435 
436 	return (IICBUS_TRANSFER(device_get_parent(bus), msgs, nmsgs));
437 }
438 
439 int
440 iicbus_transfer_excl(device_t dev, struct iic_msg *msgs, uint32_t nmsgs,
441     int how)
442 {
443 	device_t bus;
444 	int error;
445 
446 	bus = device_get_parent(dev);
447 	error = iicbus_request_bus(bus, dev, how);
448 	if (error == 0)
449 		error = IICBUS_TRANSFER(bus, msgs, nmsgs);
450 	iicbus_release_bus(bus, dev);
451 	return (error);
452 }
453 
454 /*
455  * Generic version of iicbus_transfer that calls the appropriate
456  * routines to accomplish this.  See note above about acceptable
457  * buffer addresses.
458  */
459 int
460 iicbus_transfer_gen(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
461 {
462 	int i, error, lenread, lenwrote, nkid, rpstart, addr;
463 	device_t *children, bus;
464 	bool started;
465 
466 	if ((error = device_get_children(dev, &children, &nkid)) != 0)
467 		return (IIC_ERESOURCE);
468 	if (nkid != 1) {
469 		free(children, M_TEMP);
470 		return (IIC_ENOTSUPP);
471 	}
472 	bus = children[0];
473 	rpstart = 0;
474 	free(children, M_TEMP);
475 	started = false;
476 	for (i = 0, error = 0; i < nmsgs && error == 0; i++) {
477 		addr = msgs[i].slave;
478 		if (msgs[i].flags & IIC_M_RD)
479 			addr |= LSB;
480 		else
481 			addr &= ~LSB;
482 
483 		if (!(msgs[i].flags & IIC_M_NOSTART)) {
484 			if (rpstart)
485 				error = iicbus_repeated_start(bus, addr, 0);
486 			else
487 				error = iicbus_start(bus, addr, 0);
488 			if (error != 0)
489 				break;
490 			started = true;
491 		}
492 
493 		if (msgs[i].flags & IIC_M_RD)
494 			error = iicbus_read(bus, msgs[i].buf, msgs[i].len,
495 			    &lenread, IIC_LAST_READ, 0);
496 		else
497 			error = iicbus_write(bus, msgs[i].buf, msgs[i].len,
498 			    &lenwrote, 0);
499 		if (error != 0)
500 			break;
501 
502 		if (!(msgs[i].flags & IIC_M_NOSTOP)) {
503 			rpstart = 0;
504 			iicbus_stop(bus);
505 		} else {
506 			rpstart = 1;	/* Next message gets repeated start */
507 		}
508 	}
509 	if (error != 0 && started)
510 		iicbus_stop(bus);
511 	return (error);
512 }
513 
514 int
515 iicdev_readfrom(device_t slavedev, uint8_t regaddr, void *buffer,
516     uint16_t buflen, int waithow)
517 {
518 	struct iic_msg msgs[2];
519 	uint8_t slaveaddr;
520 
521 	/*
522 	 * Two transfers back to back with a repeat-start between them; first we
523 	 * write the address-within-device, then we read from the device.
524 	 */
525 	slaveaddr = iicbus_get_addr(slavedev);
526 
527 	msgs[0].slave = slaveaddr;
528 	msgs[0].flags = IIC_M_WR | IIC_M_NOSTOP;
529 	msgs[0].len   = 1;
530 	msgs[0].buf   = &regaddr;
531 
532 	msgs[1].slave = slaveaddr;
533 	msgs[1].flags = IIC_M_RD;
534 	msgs[1].len   = buflen;
535 	msgs[1].buf   = buffer;
536 
537 	return (iicbus_transfer_excl(slavedev, msgs, nitems(msgs), waithow));
538 }
539 
540 int iicdev_writeto(device_t slavedev, uint8_t regaddr, void *buffer,
541     uint16_t buflen, int waithow)
542 {
543 	struct iic_msg msgs[2];
544 	uint8_t slaveaddr;
545 
546 	/*
547 	 * Two transfers back to back with no stop or start between them; first
548 	 * we write the address then we write the data to that address, all in a
549 	 * single transfer from two scattered buffers.
550 	 */
551 	slaveaddr = iicbus_get_addr(slavedev);
552 
553 	msgs[0].slave = slaveaddr;
554 	msgs[0].flags = IIC_M_WR | IIC_M_NOSTOP;
555 	msgs[0].len   = 1;
556 	msgs[0].buf   = &regaddr;
557 
558 	msgs[1].slave = slaveaddr;
559 	msgs[1].flags = IIC_M_WR | IIC_M_NOSTART;
560 	msgs[1].len   = buflen;
561 	msgs[1].buf   = buffer;
562 
563 	return (iicbus_transfer_excl(slavedev, msgs, nitems(msgs), waithow));
564 }
565