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