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