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