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