1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 1998, 2001 Nicolas Souchu
5 * Copyright (c) 2023 Juniper Networks, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30 #include <sys/param.h>
31 #include <sys/abi_compat.h>
32 #include <sys/bus.h>
33 #include <sys/conf.h>
34 #include <sys/file.h>
35 #include <sys/fcntl.h>
36 #include <sys/lock.h>
37 #include <sys/kernel.h>
38 #include <sys/malloc.h>
39 #include <sys/module.h>
40 #include <sys/proc.h>
41 #include <sys/sx.h>
42 #include <sys/systm.h>
43 #include <sys/uio.h>
44 #include <sys/errno.h>
45
46 #include <dev/iicbus/iiconf.h>
47 #include <dev/iicbus/iicbus.h>
48 #include <dev/iicbus/iic.h>
49
50 #include "iicbus_if.h"
51
52 struct iic_softc {
53 device_t sc_dev;
54 struct cdev *sc_devnode;
55 };
56
57 struct iic_cdevpriv {
58 struct sx lock;
59 struct iic_softc *sc;
60 bool started;
61 uint8_t addr;
62 };
63
64 #ifdef COMPAT_FREEBSD32
65 struct iic_msg32 {
66 uint16_t slave;
67 uint16_t flags;
68 uint16_t len;
69 uint32_t buf;
70 };
71
72 struct iiccmd32 {
73 u_char slave;
74 uint32_t count;
75 uint32_t last;
76 uint32_t buf;
77 };
78
79 struct iic_rdwr_data32 {
80 uint32_t msgs;
81 uint32_t nmsgs;
82 };
83
84 #define I2CWRITE32 _IOW('i', 4, struct iiccmd32)
85 #define I2CREAD32 _IOW('i', 5, struct iiccmd32)
86 #define I2CRDWR32 _IOW('i', 6, struct iic_rdwr_data32)
87 #endif
88
89 #define IIC_LOCK(cdp) sx_xlock(&(cdp)->lock)
90 #define IIC_UNLOCK(cdp) sx_xunlock(&(cdp)->lock)
91
92 static MALLOC_DEFINE(M_IIC, "iic", "I2C device data");
93
94 static int iic_probe(device_t);
95 static int iic_attach(device_t);
96 static int iic_detach(device_t);
97 static void iic_identify(driver_t *driver, device_t parent);
98 static void iicdtor(void *data);
99 static int iicuio_move(struct iic_cdevpriv *priv, struct uio *uio, int last);
100 static int iicuio(struct cdev *dev, struct uio *uio, int ioflag);
101 static int iicrdwr(struct iic_cdevpriv *priv, struct iic_rdwr_data *d,
102 int flags, bool compat32, bool kernel_msgs);
103 static int iic_linux_rdwr(struct file *fp, struct iic_rdwr_data *d,
104 int flags, struct thread *td);
105
106 static device_method_t iic_methods[] = {
107 /* device interface */
108 DEVMETHOD(device_identify, iic_identify),
109 DEVMETHOD(device_probe, iic_probe),
110 DEVMETHOD(device_attach, iic_attach),
111 DEVMETHOD(device_detach, iic_detach),
112
113 /* iicbus interface */
114 DEVMETHOD(iicbus_intr, iicbus_generic_intr),
115
116 DEVMETHOD_END
117 };
118
119 static driver_t iic_driver = {
120 "iic",
121 iic_methods,
122 sizeof(struct iic_softc),
123 };
124
125 static d_open_t iicopen;
126 static d_ioctl_t iicioctl;
127
128 static struct cdevsw iic_cdevsw = {
129 .d_version = D_VERSION,
130 .d_open = iicopen,
131 .d_read = iicuio,
132 .d_write = iicuio,
133 .d_ioctl = iicioctl,
134 .d_name = "iic",
135 };
136
137 static void
iic_identify(driver_t * driver,device_t parent)138 iic_identify(driver_t *driver, device_t parent)
139 {
140
141 if (device_find_child(parent, "iic", DEVICE_UNIT_ANY) == NULL)
142 BUS_ADD_CHILD(parent, 0, "iic", DEVICE_UNIT_ANY);
143 }
144
145 static int
iic_probe(device_t dev)146 iic_probe(device_t dev)
147 {
148 if (iicbus_get_addr(dev) > 0)
149 return (ENXIO);
150
151 device_set_desc(dev, "I2C generic I/O");
152
153 return (0);
154 }
155
156 static int
iic_attach(device_t dev)157 iic_attach(device_t dev)
158 {
159 struct iic_softc *sc;
160
161 sc = device_get_softc(dev);
162 sc->sc_dev = dev;
163 sc->sc_devnode = make_dev(&iic_cdevsw, device_get_unit(dev),
164 UID_ROOT, GID_WHEEL,
165 0600, "iic%d", device_get_unit(dev));
166 if (sc->sc_devnode == NULL) {
167 device_printf(dev, "failed to create character device\n");
168 return (ENXIO);
169 }
170 sc->sc_devnode->si_drv1 = sc;
171 sc->sc_devnode->si_drv2 = (void *)iic_linux_rdwr;
172
173 return (0);
174 }
175
176 static int
iic_detach(device_t dev)177 iic_detach(device_t dev)
178 {
179 struct iic_softc *sc;
180
181 sc = device_get_softc(dev);
182
183 if (sc->sc_devnode)
184 destroy_dev(sc->sc_devnode);
185
186 return (0);
187 }
188
189 static int
iicopen(struct cdev * dev,int flags,int fmt,struct thread * td)190 iicopen(struct cdev *dev, int flags, int fmt, struct thread *td)
191 {
192 struct iic_cdevpriv *priv;
193 int error;
194
195 priv = malloc(sizeof(*priv), M_IIC, M_WAITOK | M_ZERO);
196
197 sx_init(&priv->lock, "iic");
198 priv->sc = dev->si_drv1;
199
200 error = devfs_set_cdevpriv(priv, iicdtor);
201 if (error != 0)
202 free(priv, M_IIC);
203
204 return (error);
205 }
206
207 static void
iicdtor(void * data)208 iicdtor(void *data)
209 {
210 device_t iicdev, parent;
211 struct iic_cdevpriv *priv;
212
213 priv = data;
214 KASSERT(priv != NULL, ("iic cdevpriv should not be NULL!"));
215
216 iicdev = priv->sc->sc_dev;
217 parent = device_get_parent(iicdev);
218
219 if (priv->started) {
220 iicbus_stop(parent);
221 iicbus_reset(parent, IIC_UNKNOWN, 0, NULL);
222 iicbus_release_bus(parent, iicdev);
223 }
224
225 sx_destroy(&priv->lock);
226 free(priv, M_IIC);
227 }
228
229 static int
iicuio_move(struct iic_cdevpriv * priv,struct uio * uio,int last)230 iicuio_move(struct iic_cdevpriv *priv, struct uio *uio, int last)
231 {
232 device_t parent;
233 int error, num_bytes, transferred_bytes, written_bytes;
234 char buffer[128];
235
236 parent = device_get_parent(priv->sc->sc_dev);
237 error = 0;
238
239 /*
240 * We can only transfer up to sizeof(buffer) bytes in 1 shot, so loop until
241 * everything has been transferred.
242 */
243 while ((error == 0) && (uio->uio_resid > 0)) {
244
245 num_bytes = MIN(uio->uio_resid, sizeof(buffer));
246 transferred_bytes = 0;
247
248 switch (uio->uio_rw) {
249 case UIO_WRITE:
250 error = uiomove(buffer, num_bytes, uio);
251
252 while ((error == 0) && (transferred_bytes < num_bytes)) {
253 written_bytes = 0;
254 error = iicbus_write(parent, &buffer[transferred_bytes],
255 num_bytes - transferred_bytes, &written_bytes, 0);
256 transferred_bytes += written_bytes;
257 }
258 break;
259 case UIO_READ:
260 error = iicbus_read(parent, buffer,
261 num_bytes, &transferred_bytes,
262 ((uio->uio_resid <= sizeof(buffer)) ? last : 0), 0);
263 if (error == 0)
264 error = uiomove(buffer, transferred_bytes, uio);
265 break;
266 }
267 }
268
269 return (error);
270 }
271
272 static int
iicuio(struct cdev * dev,struct uio * uio,int ioflag)273 iicuio(struct cdev *dev, struct uio *uio, int ioflag)
274 {
275 device_t parent;
276 struct iic_cdevpriv *priv;
277 int error;
278 uint8_t addr;
279
280 priv = NULL;
281 error = devfs_get_cdevpriv((void**)&priv);
282
283 if (error != 0)
284 return (error);
285 KASSERT(priv != NULL, ("iic cdevpriv should not be NULL!"));
286
287 IIC_LOCK(priv);
288 if (priv->started || (priv->addr == 0)) {
289 IIC_UNLOCK(priv);
290 return (ENXIO);
291 }
292 parent = device_get_parent(priv->sc->sc_dev);
293
294 error = iicbus_request_bus(parent, priv->sc->sc_dev,
295 (ioflag & O_NONBLOCK) ? IIC_DONTWAIT : (IIC_WAIT | IIC_INTR));
296 if (error != 0) {
297 IIC_UNLOCK(priv);
298 return (error);
299 }
300
301 switch (uio->uio_rw) {
302 case UIO_READ:
303 addr = priv->addr | LSB;
304 break;
305 case UIO_WRITE:
306 addr = priv->addr & ~LSB;
307 break;
308 }
309
310 error = iicbus_start(parent, addr, 0);
311 if (error != 0)
312 {
313 iicbus_release_bus(parent, priv->sc->sc_dev);
314 IIC_UNLOCK(priv);
315 return (error);
316 }
317
318 error = iicuio_move(priv, uio, IIC_LAST_READ);
319
320 iicbus_stop(parent);
321 iicbus_release_bus(parent, priv->sc->sc_dev);
322 IIC_UNLOCK(priv);
323 return (error);
324 }
325
326 #ifdef COMPAT_FREEBSD32
327 static int
iic_copyinmsgs32(struct iic_rdwr_data * d,struct iic_msg * buf)328 iic_copyinmsgs32(struct iic_rdwr_data *d, struct iic_msg *buf)
329 {
330 struct iic_msg32 msg32;
331 struct iic_msg32 *m32;
332 int error, i;
333
334 m32 = (struct iic_msg32 *)d->msgs;
335 for (i = 0; i < d->nmsgs; i++) {
336 error = copyin(&m32[i], &msg32, sizeof(msg32));
337 if (error != 0)
338 return (error);
339 CP(msg32, buf[i], slave);
340 CP(msg32, buf[i], flags);
341 CP(msg32, buf[i], len);
342 PTRIN_CP(msg32, buf[i], buf);
343 }
344 return (0);
345 }
346 #endif
347
348 static int
iicrdwr(struct iic_cdevpriv * priv,struct iic_rdwr_data * d,int flags,bool compat32 __unused,bool kernel_msgs)349 iicrdwr(struct iic_cdevpriv *priv, struct iic_rdwr_data *d, int flags,
350 bool compat32 __unused, bool kernel_msgs)
351 {
352 #ifdef COMPAT_FREEBSD32
353 struct iic_rdwr_data dswab;
354 struct iic_rdwr_data32 *d32;
355 #endif
356 struct iic_msg *buf, *m;
357 void **usrbufs;
358 device_t iicdev, parent;
359 int error;
360 uint32_t i;
361
362 iicdev = priv->sc->sc_dev;
363 parent = device_get_parent(iicdev);
364 error = 0;
365 #ifdef COMPAT_FREEBSD32
366 if (compat32) {
367 d32 = (struct iic_rdwr_data32 *)d;
368 PTRIN_CP(*d32, dswab, msgs);
369 CP(*d32, dswab, nmsgs);
370 d = &dswab;
371 }
372 #endif
373
374 if (d->nmsgs > IIC_RDRW_MAX_MSGS)
375 return (EINVAL);
376
377 buf = malloc(sizeof(*d->msgs) * d->nmsgs, M_IIC, M_WAITOK);
378
379 #ifdef COMPAT_FREEBSD32
380 if (compat32)
381 error = iic_copyinmsgs32(d, buf);
382 else
383 #endif
384 if (kernel_msgs)
385 memcpy(buf, d->msgs, sizeof(*d->msgs) * d->nmsgs);
386 else
387 error = copyin(d->msgs, buf,
388 sizeof(*d->msgs) * d->nmsgs);
389 if (error != 0) {
390 free(buf, M_IIC);
391 return (error);
392 }
393
394 /* Alloc kernel buffers for userland data, copyin write data */
395 usrbufs = malloc(sizeof(void *) * d->nmsgs, M_IIC, M_WAITOK | M_ZERO);
396
397 for (i = 0; i < d->nmsgs; i++) {
398 m = &(buf[i]);
399 usrbufs[i] = m->buf;
400
401 /*
402 * At least init the buffer to NULL so we can safely free() it later.
403 * If the copyin() to buf failed, don't try to malloc bogus m->len.
404 */
405 m->buf = NULL;
406 if (error != 0)
407 continue;
408
409 /* m->len is uint16_t, so allocation size is capped at 64K. */
410 m->buf = malloc(m->len, M_IIC, M_WAITOK);
411 if (!(m->flags & IIC_M_RD))
412 error = copyin(usrbufs[i], m->buf, m->len);
413 }
414
415 if (error == 0)
416 error = iicbus_request_bus(parent, iicdev,
417 (flags & O_NONBLOCK) ? IIC_DONTWAIT : (IIC_WAIT | IIC_INTR));
418
419 if (error == 0) {
420 error = iicbus_transfer(iicdev, buf, d->nmsgs);
421 iicbus_release_bus(parent, iicdev);
422 }
423
424 /* Copyout all read segments, free up kernel buffers */
425 for (i = 0; i < d->nmsgs; i++) {
426 m = &(buf[i]);
427 if ((error == 0) && (m->flags & IIC_M_RD))
428 error = copyout(m->buf, usrbufs[i], m->len);
429 free(m->buf, M_IIC);
430 }
431
432 free(usrbufs, M_IIC);
433 free(buf, M_IIC);
434 return (error);
435 }
436
437 static int
iic_linux_rdwr(struct file * fp,struct iic_rdwr_data * d,int flags,struct thread * td)438 iic_linux_rdwr(struct file *fp, struct iic_rdwr_data *d, int flags,
439 struct thread *td)
440 {
441 struct file *saved_fp;
442 struct iic_cdevpriv *priv;
443 int error;
444
445 saved_fp = td->td_fpop;
446 td->td_fpop = fp;
447 error = devfs_get_cdevpriv((void **)&priv);
448 td->td_fpop = saved_fp;
449 if (error != 0)
450 return (error);
451
452 IIC_LOCK(priv);
453 error = iicrdwr(priv, d, flags, false, true);
454 IIC_UNLOCK(priv);
455 return (error);
456 }
457
458 static int
iicioctl(struct cdev * dev,u_long cmd,caddr_t data,int flags,struct thread * td)459 iicioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *td)
460 {
461 #ifdef COMPAT_FREEBSD32
462 struct iiccmd iicswab;
463 #endif
464 device_t parent, iicdev;
465 struct iiccmd *s;
466 #ifdef COMPAT_FREEBSD32
467 struct iiccmd32 *s32;
468 #endif
469 struct uio ubuf;
470 struct iovec uvec;
471 struct iic_cdevpriv *priv;
472 int error;
473 bool compat32;
474
475 s = (struct iiccmd *)data;
476 #ifdef COMPAT_FREEBSD32
477 s32 = (struct iiccmd32 *)data;
478 #endif
479 error = devfs_get_cdevpriv((void**)&priv);
480 if (error != 0)
481 return (error);
482
483 KASSERT(priv != NULL, ("iic cdevpriv should not be NULL!"));
484
485 iicdev = priv->sc->sc_dev;
486 parent = device_get_parent(iicdev);
487 IIC_LOCK(priv);
488
489 #ifdef COMPAT_FREEBSD32
490 switch (cmd) {
491 case I2CWRITE32:
492 case I2CREAD32:
493 CP(*s32, iicswab, slave);
494 CP(*s32, iicswab, count);
495 CP(*s32, iicswab, last);
496 PTRIN_CP(*s32, iicswab, buf);
497 s = &iicswab;
498 break;
499 default:
500 break;
501 }
502 #endif
503
504 switch (cmd) {
505 case I2CSTART:
506 if (priv->started) {
507 error = EINVAL;
508 break;
509 }
510 error = iicbus_request_bus(parent, iicdev,
511 (flags & O_NONBLOCK) ? IIC_DONTWAIT : (IIC_WAIT | IIC_INTR));
512
513 if (error == 0)
514 error = iicbus_start(parent, s->slave, 0);
515
516 if (error == 0) {
517 priv->addr = s->slave;
518 priv->started = true;
519 } else
520 iicbus_release_bus(parent, iicdev);
521
522 break;
523
524 case I2CSTOP:
525 if (priv->started) {
526 error = iicbus_stop(parent);
527 iicbus_release_bus(parent, iicdev);
528 priv->started = false;
529 }
530
531 break;
532
533 case I2CRSTCARD:
534 /*
535 * Bus should be owned before we reset it.
536 * We allow the bus to be already owned as the result of an in-progress
537 * sequence; however, bus reset will always be followed by release
538 * (a new start is presumably needed for I/O anyway). */
539 if (!priv->started)
540 error = iicbus_request_bus(parent, iicdev,
541 (flags & O_NONBLOCK) ? IIC_DONTWAIT : (IIC_WAIT | IIC_INTR));
542
543 if (error == 0) {
544 error = iicbus_reset(parent, IIC_UNKNOWN, 0, NULL);
545 /*
546 * Ignore IIC_ENOADDR as it only means we have a master-only
547 * controller.
548 */
549 if (error == IIC_ENOADDR)
550 error = 0;
551
552 iicbus_release_bus(parent, iicdev);
553 priv->started = false;
554 }
555 break;
556
557 case I2CWRITE:
558 #ifdef COMPAT_FREEBSD32
559 case I2CWRITE32:
560 #endif
561 if (!priv->started) {
562 error = EINVAL;
563 break;
564 }
565 uvec.iov_base = s->buf;
566 uvec.iov_len = s->count;
567 ubuf.uio_iov = &uvec;
568 ubuf.uio_iovcnt = 1;
569 ubuf.uio_segflg = UIO_USERSPACE;
570 ubuf.uio_td = td;
571 ubuf.uio_resid = s->count;
572 ubuf.uio_offset = 0;
573 ubuf.uio_rw = UIO_WRITE;
574 error = iicuio_move(priv, &ubuf, 0);
575 break;
576
577 case I2CREAD:
578 #ifdef COMPAT_FREEBSD32
579 case I2CREAD32:
580 #endif
581 if (!priv->started) {
582 error = EINVAL;
583 break;
584 }
585 uvec.iov_base = s->buf;
586 uvec.iov_len = s->count;
587 ubuf.uio_iov = &uvec;
588 ubuf.uio_iovcnt = 1;
589 ubuf.uio_segflg = UIO_USERSPACE;
590 ubuf.uio_td = td;
591 ubuf.uio_resid = s->count;
592 ubuf.uio_offset = 0;
593 ubuf.uio_rw = UIO_READ;
594 error = iicuio_move(priv, &ubuf, s->last);
595 break;
596
597 #ifdef COMPAT_FREEBSD32
598 case I2CRDWR32:
599 #endif
600 case I2CRDWR:
601 /*
602 * The rdwr list should be a self-contained set of
603 * transactions. Fail if another transaction is in progress.
604 */
605 if (priv->started) {
606 error = EINVAL;
607 break;
608 }
609
610 #ifdef COMPAT_FREEBSD32
611 compat32 = (cmd == I2CRDWR32);
612 #else
613 compat32 = false;
614 #endif
615 error = iicrdwr(priv, (struct iic_rdwr_data *)data, flags,
616 compat32, false);
617
618 break;
619
620 case I2CRPTSTART:
621 if (!priv->started) {
622 error = EINVAL;
623 break;
624 }
625 error = iicbus_repeated_start(parent, s->slave, 0);
626 break;
627
628 case I2CSADDR:
629 priv->addr = *((uint8_t*)data);
630 break;
631
632 default:
633 error = ENOTTY;
634 }
635
636 IIC_UNLOCK(priv);
637 return (error);
638 }
639
640 DRIVER_MODULE(iic, iicbus, iic_driver, 0, 0);
641 MODULE_DEPEND(iic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
642 MODULE_VERSION(iic, 1);
643