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 = ®addr;
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 = ®addr;
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