1 /* 2 * Copyright (c) 2014 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@backplane.com> 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 * 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 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 /* 35 * Intel 4th generation mobile cpus integrated I2C device, smbus driver. 36 * 37 * See ig4_reg.h for datasheet reference and notes. 38 */ 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/kernel.h> 43 #include <sys/module.h> 44 #include <sys/errno.h> 45 #include <sys/lock.h> 46 #include <sys/mutex.h> 47 #include <sys/syslog.h> 48 #include <sys/bus.h> 49 50 #include <sys/rman.h> 51 52 #include <bus/pci/pcivar.h> 53 #include <bus/pci/pcireg.h> 54 #include <bus/smbus/smbconf.h> 55 56 #include "smbus_if.h" 57 58 #include "ig4_reg.h" 59 #include "ig4_var.h" 60 61 #define TRANS_NORMAL 1 62 #define TRANS_PCALL 2 63 #define TRANS_BLOCK 3 64 65 static void ig4iic_intr(void *cookie); 66 67 /* 68 * Low-level inline support functions 69 */ 70 static __inline 71 void 72 reg_write(ig4iic_softc_t *sc, uint32_t reg, uint32_t value) 73 { 74 bus_space_write_4(sc->regs_t, sc->regs_h, reg, value); 75 bus_space_barrier(sc->regs_t, sc->regs_h, reg, 4, 76 BUS_SPACE_BARRIER_WRITE); 77 } 78 79 static __inline 80 uint32_t 81 reg_read(ig4iic_softc_t *sc, uint32_t reg) 82 { 83 uint32_t value; 84 85 bus_space_barrier(sc->regs_t, sc->regs_h, reg, 4, 86 BUS_SPACE_BARRIER_READ); 87 value = bus_space_read_4(sc->regs_t, sc->regs_h, reg); 88 return value; 89 } 90 91 /* 92 * Enable or disable the controller and wait for the controller to acknowledge 93 * the state change. 94 */ 95 static 96 int 97 set_controller(ig4iic_softc_t *sc, uint32_t ctl) 98 { 99 int retry; 100 int error; 101 uint32_t v; 102 103 reg_write(sc, IG4_REG_I2C_EN, ctl); 104 error = SMB_ETIMEOUT; 105 106 for (retry = 100; retry > 0; --retry) { 107 v = reg_read(sc, IG4_REG_ENABLE_STATUS); 108 if (((v ^ ctl) & IG4_I2C_ENABLE) == 0) { 109 error = 0; 110 break; 111 } 112 tsleep(sc, 0, "i2cslv", 1); 113 } 114 return error; 115 } 116 117 /* 118 * Wait up to 25ms for the requested status using a 25uS polling loop. 119 */ 120 static 121 int 122 wait_status(ig4iic_softc_t *sc, uint32_t status) 123 { 124 uint32_t v; 125 int error; 126 int txlvl = -1; 127 sysclock_t count; 128 sysclock_t limit; 129 130 error = SMB_ETIMEOUT; 131 count = sys_cputimer->count(); 132 limit = sys_cputimer->freq / 40; 133 134 while (sys_cputimer->count() - count <= limit) { 135 /* 136 * Check requested status 137 */ 138 v = reg_read(sc, IG4_REG_I2C_STA); 139 if (v & status) { 140 error = 0; 141 break; 142 } 143 144 /* 145 * Shim RX_NOTEMPTY of the data was read by the 146 * interrupt code. 147 */ 148 if (status & IG4_STATUS_RX_NOTEMPTY) { 149 if (sc->rpos != sc->rnext) { 150 error = 0; 151 break; 152 } 153 } 154 155 /* 156 * Shim TX_EMPTY by resetting the retry timer if we 157 * see a change in the transmit fifo level. 158 */ 159 if (status & IG4_STATUS_TX_EMPTY) { 160 v = reg_read(sc, IG4_REG_TXFLR) & IG4_FIFOLVL_MASK; 161 if (txlvl != v) { 162 txlvl = v; 163 count = sys_cputimer->count(); 164 } 165 } 166 167 /* 168 * The interrupt will wake us up if we are waiting for 169 * read data, otherwise poll. 170 */ 171 if (status & IG4_STATUS_RX_NOTEMPTY) { 172 lksleep(sc, &sc->lk, 0, "i2cwait", (hz + 99) / 100); 173 } else { 174 DELAY(25); 175 } 176 } 177 return error; 178 } 179 180 /* 181 * Read I2C data. The data might have already been read by 182 * the interrupt code, otherwise it is sitting in the data 183 * register. 184 */ 185 static 186 uint8_t 187 data_read(ig4iic_softc_t *sc) 188 { 189 uint8_t c; 190 191 if (sc->rpos == sc->rnext) { 192 c = (uint8_t)reg_read(sc, IG4_REG_DATA_CMD); 193 } else { 194 c = sc->rbuf[sc->rpos & IG4_RBUFMASK]; 195 ++sc->rpos; 196 } 197 return c; 198 } 199 200 /* 201 * Set the slave address. The controller must be disabled when 202 * changing the address. 203 * 204 * This operation does not issue anything to the I2C bus but sets 205 * the target address for when the controller later issues a START. 206 */ 207 static 208 void 209 set_slave_addr(ig4iic_softc_t *sc, uint8_t slave, int trans_op) 210 { 211 uint32_t tar; 212 uint32_t ctl; 213 int use_10bit; 214 215 use_10bit = sc->use_10bit; 216 if (trans_op & SMB_TRANS_7BIT) 217 use_10bit = 0; 218 if (trans_op & SMB_TRANS_10BIT) 219 use_10bit = 1; 220 221 if (sc->slave_valid && sc->last_slave == slave && 222 sc->use_10bit == use_10bit) { 223 return; 224 } 225 sc->use_10bit = use_10bit; 226 227 /* 228 * Wait for TXFIFO to drain before disabling the controller. 229 * 230 * If a write message has not been completed it's really a 231 * programming error, but for now in that case issue an extra 232 * byte + STOP. 233 * 234 * If a read message has not been completed it's also a programming 235 * error, for now just ignore it. 236 */ 237 wait_status(sc, IG4_STATUS_TX_NOTFULL); 238 if (sc->write_started) { 239 reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_STOP); 240 sc->write_started = 0; 241 } 242 if (sc->read_started) 243 sc->read_started = 0; 244 wait_status(sc, IG4_STATUS_TX_EMPTY); 245 246 set_controller(sc, 0); 247 ctl = reg_read(sc, IG4_REG_CTL); 248 ctl &= ~IG4_CTL_10BIT; 249 ctl |= IG4_CTL_RESTARTEN; 250 251 tar = slave; 252 if (sc->use_10bit) { 253 tar |= IG4_TAR_10BIT; 254 ctl |= IG4_CTL_10BIT; 255 } 256 reg_write(sc, IG4_REG_CTL, ctl); 257 reg_write(sc, IG4_REG_TAR_ADD, tar); 258 set_controller(sc, IG4_I2C_ENABLE); 259 sc->slave_valid = 1; 260 sc->last_slave = slave; 261 } 262 263 /* 264 * Issue START with byte command, possible count, and a variable length 265 * read or write buffer, then possible turn-around read. The read also 266 * has a possible count received. 267 * 268 * For SMBUS - 269 * 270 * Quick: START+ADDR+RD/WR STOP 271 * 272 * Normal: START+ADDR+WR COMM DATA..DATA STOP 273 * 274 * START+ADDR+RD COMM 275 * RESTART+ADDR RDATA..RDATA STOP 276 * (can also be used for I2C transactions) 277 * 278 * Process Call: START+ADDR+WR COMM DATAL DATAH 279 * RESTART+ADDR+RD RDATAL RDATAH STOP 280 * 281 * Block: START+ADDR+RD COMM 282 * RESTART+ADDR+RD RCOUNT DATA... STOP 283 * 284 * START+ADDR+WR COMM 285 * RESTART+ADDR+WR WCOUNT DATA... STOP 286 * 287 * For I2C - basically, no *COUNT fields. 288 * 289 * Generally speaking, the START+ADDR / RESTART+ADDR is handled automatically 290 * by the controller at the beginning of a command sequence or on a data 291 * direction turn-around, and we only need to tell it when to issue the STOP. 292 */ 293 static int 294 smb_transaction(ig4iic_softc_t *sc, char cmd, int op, 295 char *wbuf, int wcount, char *rbuf, int rcount, int *actualp) 296 { 297 int error; 298 uint32_t last; 299 300 /* 301 * Issue START or RESTART with next data byte, clear any previous 302 * abort condition that may have been holding the txfifo in reset. 303 */ 304 last = IG4_DATA_RESTART; 305 reg_read(sc, IG4_REG_CLR_TX_ABORT); 306 if (actualp) 307 *actualp = 0; 308 309 /* 310 * Issue command if not told otherwise (smbus). 311 */ 312 if ((op & SMB_TRANS_NOCMD) == 0) { 313 error = wait_status(sc, IG4_STATUS_TX_NOTFULL); 314 if (error) 315 goto done; 316 last |= (u_char)cmd; 317 if (wcount == 0 && rcount == 0 && (op & SMB_TRANS_NOSTOP) == 0) 318 last |= IG4_DATA_STOP; 319 reg_write(sc, IG4_REG_DATA_CMD, last); 320 last = 0; 321 322 /* 323 * Clean out any previously received data 324 */ 325 sc->rpos = 0; 326 sc->rnext = 0; 327 } 328 329 /* 330 * If writing and not told otherwise, issue the write count (smbus). 331 */ 332 if (wcount && (op & SMB_TRANS_NOCNT) == 0) { 333 error = wait_status(sc, IG4_STATUS_TX_NOTFULL); 334 if (error) 335 goto done; 336 last |= (u_char)cmd; 337 reg_write(sc, IG4_REG_DATA_CMD, last); 338 last = 0; 339 } 340 341 /* 342 * Bulk write (i2c) 343 */ 344 while (wcount) { 345 error = wait_status(sc, IG4_STATUS_TX_NOTFULL); 346 if (error) 347 goto done; 348 last |= (u_char)*wbuf; 349 if (wcount == 1 && rcount == 0 && (op & SMB_TRANS_NOSTOP) == 0) 350 last |= IG4_DATA_STOP; 351 reg_write(sc, IG4_REG_DATA_CMD, last); 352 --wcount; 353 ++wbuf; 354 last = 0; 355 } 356 357 /* 358 * Issue reads to xmit FIFO (strange, I know) to tell the controller 359 * to clock in data. At the moment just issue one read ahead to 360 * pipeline the incoming data. 361 * 362 * NOTE: In the case of NOCMD and wcount == 0 we still issue a 363 * RESTART here, even if the data direction has not changed 364 * from the previous CHAINing call. This we force the RESTART. 365 * (A new START is issued automatically by the controller in 366 * the other nominal cases such as a data direction change or 367 * a previous STOP was issued). 368 * 369 * If this will be the last byte read we must also issue the STOP 370 * at the end of the read. 371 */ 372 if (rcount) { 373 last = IG4_DATA_RESTART | IG4_DATA_COMMAND_RD; 374 if (rcount == 1 && 375 (op & (SMB_TRANS_NOSTOP | SMB_TRANS_NOCNT)) == 376 SMB_TRANS_NOCNT) { 377 last |= IG4_DATA_STOP; 378 } 379 reg_write(sc, IG4_REG_DATA_CMD, last); 380 last = IG4_DATA_COMMAND_RD; 381 } 382 383 /* 384 * Bulk read (i2c) and count field handling (smbus) 385 */ 386 while (rcount) { 387 /* 388 * Maintain a pipeline by queueing the allowance for the next 389 * read before waiting for the current read. 390 */ 391 if (rcount > 1) { 392 if (op & SMB_TRANS_NOCNT) 393 last = (rcount == 2) ? IG4_DATA_STOP : 0; 394 else 395 last = 0; 396 reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_COMMAND_RD | 397 last); 398 } 399 error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY); 400 if (error) 401 goto done; 402 last = data_read(sc); 403 404 if (op & SMB_TRANS_NOCNT) { 405 *rbuf = (u_char)last; 406 ++rbuf; 407 --rcount; 408 if (actualp) 409 ++*actualp; 410 } else { 411 /* 412 * Handle count field (smbus), which is not part of 413 * the rcount'ed buffer. The first read data in a 414 * bulk transfer is the count. 415 * 416 * XXX if rcount is loaded as 0 how do I generate a 417 * STOP now without issuing another RD or WR? 418 */ 419 if (rcount > (u_char)last) 420 rcount = (u_char)last; 421 op |= SMB_TRANS_NOCNT; 422 } 423 } 424 error = 0; 425 done: 426 /* XXX wait for xmit buffer to become empty */ 427 last = reg_read(sc, IG4_REG_TX_ABRT_SOURCE); 428 429 return error; 430 } 431 432 /* 433 * SMBUS API FUNCTIONS 434 * 435 * Called from ig4iic_pci_attach/detach() 436 */ 437 int 438 ig4iic_attach(ig4iic_softc_t *sc) 439 { 440 int error; 441 uint32_t v; 442 443 lockmgr(&sc->lk, LK_EXCLUSIVE); 444 445 v = reg_read(sc, IG4_REG_COMP_TYPE); 446 kprintf("type %08x\n", v); 447 v = reg_read(sc, IG4_REG_COMP_PARAM1); 448 kprintf("params %08x\n", v); 449 v = reg_read(sc, IG4_REG_COMP_VER); 450 kprintf("version %08x\n", v); 451 if (v != IG4_COMP_VER) { 452 error = ENXIO; 453 goto done; 454 } 455 #if 1 456 v = reg_read(sc, IG4_REG_SS_SCL_HCNT); 457 kprintf("SS_SCL_HCNT %08x\n", v); 458 v = reg_read(sc, IG4_REG_SS_SCL_LCNT); 459 kprintf("SS_SCL_LCNT %08x\n", v); 460 v = reg_read(sc, IG4_REG_FS_SCL_HCNT); 461 kprintf("FS_SCL_HCNT %08x\n", v); 462 v = reg_read(sc, IG4_REG_FS_SCL_LCNT); 463 kprintf("FS_SCL_LCNT %08x\n", v); 464 v = reg_read(sc, IG4_REG_SDA_HOLD); 465 kprintf("HOLD %08x\n", v); 466 467 v = reg_read(sc, IG4_REG_SS_SCL_HCNT); 468 reg_write(sc, IG4_REG_FS_SCL_HCNT, v); 469 v = reg_read(sc, IG4_REG_SS_SCL_LCNT); 470 reg_write(sc, IG4_REG_FS_SCL_LCNT, v); 471 #endif 472 /* 473 * Program based on a 25000 Hz clock. This is a bit of a 474 * hack (obviously). The defaults are 400 and 470 for standard 475 * and 60 and 130 for fast. The defaults for standard fail 476 * utterly (presumably cause an abort) because the clock time 477 * is ~18.8ms by default. This brings it down to ~4ms (for now). 478 */ 479 reg_write(sc, IG4_REG_SS_SCL_HCNT, 100); 480 reg_write(sc, IG4_REG_SS_SCL_LCNT, 125); 481 reg_write(sc, IG4_REG_FS_SCL_HCNT, 100); 482 reg_write(sc, IG4_REG_FS_SCL_LCNT, 125); 483 484 /* 485 * Use a threshold of 1 so we get interrupted on each character, 486 * allowing us to use lksleep() in our poll code. Not perfect 487 * but this is better than using DELAY() for receiving data. 488 */ 489 reg_write(sc, IG4_REG_RX_TL, 1); 490 491 reg_write(sc, IG4_REG_CTL, 492 IG4_CTL_MASTER | 493 IG4_CTL_SLAVE_DISABLE | 494 IG4_CTL_RESTARTEN | 495 IG4_CTL_SPEED_STD); 496 497 sc->smb = device_add_child(sc->dev, "smbus", -1); 498 if (sc->smb == NULL) { 499 device_printf(sc->dev, "smbus driver not found\n"); 500 error = ENXIO; 501 goto done; 502 } 503 504 #if 0 505 /* 506 * Don't do this, it blows up the PCI config 507 */ 508 reg_write(sc, IG4_REG_RESETS, IG4_RESETS_ASSERT); 509 reg_write(sc, IG4_REG_RESETS, IG4_RESETS_DEASSERT); 510 #endif 511 512 /* 513 * Interrupt on STOP detect or receive character ready 514 */ 515 reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET | 516 IG4_INTR_RX_FULL); 517 if (set_controller(sc, 0)) 518 device_printf(sc->dev, "controller error during attach-1\n"); 519 if (set_controller(sc, IG4_I2C_ENABLE)) 520 device_printf(sc->dev, "controller error during attach-2\n"); 521 error = bus_setup_intr(sc->dev, sc->intr_res, 0, 522 ig4iic_intr, sc, &sc->intr_handle, NULL); 523 if (error) { 524 device_printf(sc->dev, 525 "Unable to setup irq: error %d\n", error); 526 goto done; 527 } 528 529 /* Attach us to the smbus */ 530 lockmgr(&sc->lk, LK_RELEASE); 531 error = bus_generic_attach(sc->dev); 532 lockmgr(&sc->lk, LK_EXCLUSIVE); 533 if (error) { 534 device_printf(sc->dev, 535 "failed to attach child: error %d\n", error); 536 goto done; 537 } 538 sc->generic_attached = 1; 539 540 done: 541 lockmgr(&sc->lk, LK_RELEASE); 542 return error; 543 } 544 545 int 546 ig4iic_detach(ig4iic_softc_t *sc) 547 { 548 int error; 549 550 lockmgr(&sc->lk, LK_EXCLUSIVE); 551 552 reg_write(sc, IG4_REG_INTR_MASK, 0); 553 reg_read(sc, IG4_REG_CLR_INTR); 554 set_controller(sc, 0); 555 556 if (sc->generic_attached) { 557 error = bus_generic_detach(sc->dev); 558 if (error) 559 goto done; 560 sc->generic_attached = 0; 561 } 562 if (sc->smb) { 563 device_delete_child(sc->dev, sc->smb); 564 sc->smb = NULL; 565 } 566 if (sc->intr_handle) { 567 bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle); 568 sc->intr_handle = NULL; 569 } 570 571 error = 0; 572 done: 573 lockmgr(&sc->lk, LK_RELEASE); 574 return error; 575 } 576 577 int 578 ig4iic_smb_callback(device_t dev, int index, void *data) 579 { 580 ig4iic_softc_t *sc = device_get_softc(dev); 581 int error; 582 583 lockmgr(&sc->lk, LK_EXCLUSIVE); 584 585 switch (index) { 586 case SMB_REQUEST_BUS: 587 error = 0; 588 break; 589 case SMB_RELEASE_BUS: 590 error = 0; 591 break; 592 default: 593 error = SMB_EABORT; 594 break; 595 } 596 597 lockmgr(&sc->lk, LK_RELEASE); 598 599 return error; 600 } 601 602 /* 603 * Quick command. i.e. START + cmd + R/W + STOP and no data. It is 604 * unclear to me how I could implement this with the intel i2c controller 605 * because the controler sends STARTs and STOPs automatically with data. 606 */ 607 int 608 ig4iic_smb_quick(device_t dev, u_char slave, int how) 609 { 610 ig4iic_softc_t *sc = device_get_softc(dev); 611 int error; 612 613 lockmgr(&sc->lk, LK_EXCLUSIVE); 614 615 switch (how) { 616 case SMB_QREAD: 617 error = SMB_ENOTSUPP; 618 break; 619 case SMB_QWRITE: 620 error = SMB_ENOTSUPP; 621 break; 622 default: 623 error = SMB_ENOTSUPP; 624 break; 625 } 626 lockmgr(&sc->lk, LK_RELEASE); 627 628 return error; 629 } 630 631 /* 632 * Incremental send byte without stop (?). It is unclear why the slave 633 * address is specified if this presumably is used in combination with 634 * ig4iic_smb_quick(). 635 * 636 * (Also, how would this work anyway? Issue the last byte with writeb()?) 637 */ 638 int 639 ig4iic_smb_sendb(device_t dev, u_char slave, char byte) 640 { 641 ig4iic_softc_t *sc = device_get_softc(dev); 642 uint32_t cmd; 643 int error; 644 645 lockmgr(&sc->lk, LK_EXCLUSIVE); 646 647 set_slave_addr(sc, slave, 0); 648 cmd = byte; 649 if (wait_status(sc, IG4_STATUS_TX_NOTFULL) == 0) { 650 reg_write(sc, IG4_REG_DATA_CMD, cmd); 651 error = 0; 652 } else { 653 error = SMB_ETIMEOUT; 654 } 655 656 lockmgr(&sc->lk, LK_RELEASE); 657 return error; 658 } 659 660 /* 661 * Incremental receive byte without stop (?). It is unclear why the slave 662 * address is specified if this presumably is used in combination with 663 * ig4iic_smb_quick(). 664 */ 665 int 666 ig4iic_smb_recvb(device_t dev, u_char slave, char *byte) 667 { 668 ig4iic_softc_t *sc = device_get_softc(dev); 669 int error; 670 671 lockmgr(&sc->lk, LK_EXCLUSIVE); 672 673 set_slave_addr(sc, slave, 0); 674 reg_write(sc, IG4_REG_DATA_CMD, IG4_DATA_COMMAND_RD); 675 if (wait_status(sc, IG4_STATUS_RX_NOTEMPTY) == 0) { 676 *byte = data_read(sc); 677 error = 0; 678 } else { 679 *byte = 0; 680 error = SMB_ETIMEOUT; 681 } 682 683 lockmgr(&sc->lk, LK_RELEASE); 684 return error; 685 } 686 687 /* 688 * Write command and single byte in transaction. 689 */ 690 int 691 ig4iic_smb_writeb(device_t dev, u_char slave, char cmd, char byte) 692 { 693 ig4iic_softc_t *sc = device_get_softc(dev); 694 int error; 695 696 lockmgr(&sc->lk, LK_EXCLUSIVE); 697 698 set_slave_addr(sc, slave, 0); 699 error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT, 700 &byte, 1, NULL, 0, NULL); 701 702 lockmgr(&sc->lk, LK_RELEASE); 703 return error; 704 } 705 706 /* 707 * Write command and single word in transaction. 708 */ 709 int 710 ig4iic_smb_writew(device_t dev, u_char slave, char cmd, short word) 711 { 712 ig4iic_softc_t *sc = device_get_softc(dev); 713 char buf[2]; 714 int error; 715 716 lockmgr(&sc->lk, LK_EXCLUSIVE); 717 718 set_slave_addr(sc, slave, 0); 719 buf[0] = word & 0xFF; 720 buf[1] = word >> 8; 721 error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT, 722 buf, 2, NULL, 0, NULL); 723 724 lockmgr(&sc->lk, LK_RELEASE); 725 return error; 726 } 727 728 /* 729 * write command and read single byte in transaction. 730 */ 731 int 732 ig4iic_smb_readb(device_t dev, u_char slave, char cmd, char *byte) 733 { 734 ig4iic_softc_t *sc = device_get_softc(dev); 735 int error; 736 737 lockmgr(&sc->lk, LK_EXCLUSIVE); 738 739 set_slave_addr(sc, slave, 0); 740 error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT, 741 NULL, 0, byte, 1, NULL); 742 743 lockmgr(&sc->lk, LK_RELEASE); 744 return error; 745 } 746 747 /* 748 * write command and read word in transaction. 749 */ 750 int 751 ig4iic_smb_readw(device_t dev, u_char slave, char cmd, short *word) 752 { 753 ig4iic_softc_t *sc = device_get_softc(dev); 754 char buf[2]; 755 int error; 756 757 lockmgr(&sc->lk, LK_EXCLUSIVE); 758 759 set_slave_addr(sc, slave, 0); 760 if ((error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT, 761 NULL, 0, buf, 2, NULL)) == 0) { 762 *word = (u_char)buf[0] | ((u_char)buf[1] << 8); 763 } 764 765 lockmgr(&sc->lk, LK_RELEASE); 766 return error; 767 } 768 769 /* 770 * write command and word and read word in transaction 771 */ 772 int 773 ig4iic_smb_pcall(device_t dev, u_char slave, char cmd, 774 short sdata, short *rdata) 775 { 776 ig4iic_softc_t *sc = device_get_softc(dev); 777 char rbuf[2]; 778 char wbuf[2]; 779 int error; 780 781 lockmgr(&sc->lk, LK_EXCLUSIVE); 782 783 set_slave_addr(sc, slave, 0); 784 wbuf[0] = sdata & 0xFF; 785 wbuf[1] = sdata >> 8; 786 if ((error = smb_transaction(sc, cmd, SMB_TRANS_NOCNT, 787 wbuf, 2, rbuf, 2, NULL)) == 0) { 788 *rdata = (u_char)rbuf[0] | ((u_char)rbuf[1] << 8); 789 } 790 791 lockmgr(&sc->lk, LK_RELEASE); 792 return error; 793 } 794 795 int 796 ig4iic_smb_bwrite(device_t dev, u_char slave, char cmd, 797 u_char wcount, char *buf) 798 { 799 ig4iic_softc_t *sc = device_get_softc(dev); 800 int error; 801 802 lockmgr(&sc->lk, LK_EXCLUSIVE); 803 804 set_slave_addr(sc, slave, 0); 805 error = smb_transaction(sc, cmd, 0, 806 buf, wcount, NULL, 0, NULL); 807 808 lockmgr(&sc->lk, LK_RELEASE); 809 return error; 810 } 811 812 int 813 ig4iic_smb_bread(device_t dev, u_char slave, char cmd, 814 u_char *countp_char, char *buf) 815 { 816 ig4iic_softc_t *sc = device_get_softc(dev); 817 int rcount = *countp_char; 818 int error; 819 820 lockmgr(&sc->lk, LK_EXCLUSIVE); 821 822 set_slave_addr(sc, slave, 0); 823 error = smb_transaction(sc, cmd, 0, 824 NULL, 0, buf, rcount, &rcount); 825 *countp_char = rcount; 826 827 lockmgr(&sc->lk, LK_RELEASE); 828 return error; 829 } 830 831 int 832 ig4iic_smb_trans(device_t dev, int slave, char cmd, int op, 833 char *wbuf, int wcount, char *rbuf, int rcount, 834 int *actualp) 835 { 836 ig4iic_softc_t *sc = device_get_softc(dev); 837 int error; 838 839 lockmgr(&sc->lk, LK_EXCLUSIVE); 840 841 set_slave_addr(sc, slave, op); 842 error = smb_transaction(sc, cmd, op, 843 wbuf, wcount, rbuf, rcount, actualp); 844 845 lockmgr(&sc->lk, LK_RELEASE); 846 return error; 847 } 848 849 /* 850 * Interrupt Operation 851 */ 852 static 853 void 854 ig4iic_intr(void *cookie) 855 { 856 ig4iic_softc_t *sc = cookie; 857 uint32_t status; 858 859 lockmgr(&sc->lk, LK_EXCLUSIVE); 860 /* reg_write(sc, IG4_REG_INTR_MASK, IG4_INTR_STOP_DET);*/ 861 status = reg_read(sc, IG4_REG_I2C_STA); 862 if (status & IG4_STATUS_RX_NOTEMPTY) { 863 sc->rbuf[sc->rnext & IG4_RBUFMASK] = 864 (uint8_t)reg_read(sc, IG4_REG_DATA_CMD); 865 ++sc->rnext; 866 } 867 reg_read(sc, IG4_REG_CLR_INTR); 868 wakeup(sc); 869 lockmgr(&sc->lk, LK_RELEASE); 870 } 871 872 DRIVER_MODULE(smbus, ig4iic, smbus_driver, smbus_devclass, NULL, NULL); 873