pcf.c revision 46573
1/*- 2 * Copyright (c) 1998 Nicolas Souchu, Marc Bouget 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 * $Id: pcf.c,v 1.7 1999/05/02 21:51:17 peter Exp $ 27 * 28 */ 29#include <sys/param.h> 30#include <sys/systm.h> 31#include <sys/kernel.h> 32#include <sys/module.h> 33#include <sys/bus.h> 34#include <sys/conf.h> 35#include <sys/malloc.h> 36 37#include <machine/clock.h> 38 39#include <i386/isa/isa_device.h> 40 41#include <dev/iicbus/iiconf.h> 42#include "iicbus_if.h" 43 44#define TIMEOUT 9999 /* XXX */ 45 46/* Status bits of S1 register (read only) */ 47#define nBB 0x01 /* busy when low set/reset by STOP/START*/ 48#define LAB 0x02 /* lost arbitration bit in multi-master mode */ 49#define AAS 0x04 /* addressed as slave */ 50#define LRB 0x08 /* last received byte when not AAS */ 51#define AD0 0x08 /* general call received when AAS */ 52#define BER 0x10 /* bus error, misplaced START or STOP */ 53#define STS 0x20 /* STOP detected in slave receiver mode */ 54#define PIN 0x80 /* pending interrupt not (r/w) */ 55 56/* Control bits of S1 register (write only) */ 57#define ACK 0x01 58#define STO 0x02 59#define STA 0x04 60#define ENI 0x08 61#define ES2 0x10 62#define ES1 0x20 63#define ES0 0x40 64 65#define BUFSIZE 2048 66 67#define SLAVE_TRANSMITTER 0x1 68#define SLAVE_RECEIVER 0x2 69 70#define PCF_DEFAULT_ADDR 0xaa 71 72struct pcf_softc { 73 74 int pcf_base; /* isa port */ 75 u_char pcf_addr; /* interface I2C address */ 76 77 int pcf_slave_mode; /* receiver or transmitter */ 78 int pcf_started; /* 1 if start condition sent */ 79 80 device_t iicbus; /* the corresponding iicbus */ 81}; 82 83struct pcf_isa_softc { 84 85 int pcf_unit; /* unit of the isa device */ 86 int pcf_base; /* isa port */ 87 int pcf_irq; /* isa irq or null if polled */ 88 89 unsigned int pcf_flags; /* boot flags */ 90}; 91 92#define MAXPCF 2 93 94static struct pcf_isa_softc *pcfdata[MAXPCF]; 95static int npcf = 0; 96 97static int pcfprobe_isa(struct isa_device *); 98static int pcfattach_isa(struct isa_device *); 99 100struct isa_driver pcfdriver = { 101 pcfprobe_isa, pcfattach_isa, "pcf" 102}; 103 104static int pcf_probe(device_t); 105static int pcf_attach(device_t); 106static void pcf_print_child(device_t, device_t); 107 108static int pcf_repeated_start(device_t, u_char, int); 109static int pcf_start(device_t, u_char, int); 110static int pcf_stop(device_t); 111static int pcf_write(device_t, char *, int, int *, int); 112static int pcf_read(device_t, char *, int, int *, int, int); 113static ointhand2_t pcfintr; 114static int pcf_rst_card(device_t, u_char, u_char, u_char *); 115 116static device_method_t pcf_methods[] = { 117 /* device interface */ 118 DEVMETHOD(device_probe, pcf_probe), 119 DEVMETHOD(device_attach, pcf_attach), 120 121 /* bus interface */ 122 DEVMETHOD(bus_print_child, pcf_print_child), 123 124 /* iicbus interface */ 125 DEVMETHOD(iicbus_callback, iicbus_null_callback), 126 DEVMETHOD(iicbus_repeated_start, pcf_repeated_start), 127 DEVMETHOD(iicbus_start, pcf_start), 128 DEVMETHOD(iicbus_stop, pcf_stop), 129 DEVMETHOD(iicbus_write, pcf_write), 130 DEVMETHOD(iicbus_read, pcf_read), 131 DEVMETHOD(iicbus_reset, pcf_rst_card), 132 133 { 0, 0 } 134}; 135 136static driver_t pcf_driver = { 137 "pcf", 138 pcf_methods, 139 DRIVER_TYPE_MISC, 140 sizeof(struct pcf_softc), 141}; 142 143static devclass_t pcf_devclass; 144 145#define DEVTOSOFTC(dev) ((struct pcf_softc *)device_get_softc(dev)) 146 147static int 148pcfprobe_isa(struct isa_device *dvp) 149{ 150 device_t pcfdev; 151 struct pcf_isa_softc *pcf; 152 153 if (npcf >= MAXPCF) 154 return (0); 155 156 if ((pcf = (struct pcf_isa_softc *)malloc(sizeof(struct pcf_isa_softc), 157 M_DEVBUF, M_NOWAIT)) == NULL) 158 return (0); 159 160 pcf->pcf_base = dvp->id_iobase; /* XXX should be ivars */ 161 pcf->pcf_unit = dvp->id_unit; 162 163 if (!(dvp->id_flags & IIC_POLLED)) 164 pcf->pcf_irq = (dvp->id_irq); 165 166 pcfdata[npcf++] = pcf; 167 168 /* XXX add the pcf device to the root_bus until isa bus exists */ 169 pcfdev = device_add_child(root_bus, "pcf", pcf->pcf_unit, NULL); 170 171 if (!pcfdev) 172 goto error; 173 174 return (1); 175 176error: 177 free(pcf, M_DEVBUF); 178 return (0); 179} 180 181static int 182pcfattach_isa(struct isa_device *isdp) 183{ 184 isdp->id_ointr = pcfintr; 185 return (1); /* ok */ 186} 187 188static int 189pcf_probe(device_t pcfdev) 190{ 191 struct pcf_softc *pcf = (struct pcf_softc *)device_get_softc(pcfdev); 192 int unit = device_get_unit(pcfdev); 193 194 /* retrieve base address from isa initialization 195 * 196 * XXX should use ivars with isabus 197 */ 198 pcf->pcf_base = pcfdata[unit]->pcf_base; 199 200 /* reset the chip */ 201 pcf_rst_card(pcfdev, IIC_FASTEST, PCF_DEFAULT_ADDR, NULL); 202 203 /* XXX try do detect chipset */ 204 205 device_set_desc(pcfdev, "PCF8584 I2C bus controller"); 206 207 return (0); 208} 209 210static int 211pcf_attach(device_t pcfdev) 212{ 213 struct pcf_softc *pcf = (struct pcf_softc *)device_get_softc(pcfdev); 214 215 pcf->iicbus = iicbus_alloc_bus(pcfdev); 216 217 /* probe and attach the iicbus */ 218 device_probe_and_attach(pcf->iicbus); 219 220 return (0); 221} 222 223static void 224pcf_print_child(device_t bus, device_t dev) 225{ 226 struct pcf_softc *pcf = (struct pcf_softc *)device_get_softc(bus); 227 228 printf(" on %s%d addr 0x%x", device_get_name(bus), 229 device_get_unit(bus), (int)pcf->pcf_addr); 230 231 return; 232} 233 234/* 235 * PCF8584 datasheet : when operate at 8 MHz or more, a minimun time of 236 * 6 clocks cycles must be left between two consecutives access 237 */ 238#define pcf_nops() DELAY(10) 239 240#define dummy_read(pcf) PCF_GET_S0(pcf) 241#define dummy_write(pcf) PCF_SET_S0(pcf, 0) 242 243/* 244 * Specific register access to PCF8584 245 */ 246static void PCF_SET_S0(struct pcf_softc *pcf, int data) 247{ 248 outb(pcf->pcf_base, data); 249 pcf_nops(); 250} 251 252static void PCF_SET_S1(struct pcf_softc *pcf, int data) 253{ 254 outb(pcf->pcf_base+1, data); 255 pcf_nops(); 256} 257 258static char PCF_GET_S0(struct pcf_softc *pcf) 259{ 260 char data; 261 262 data = inb(pcf->pcf_base); 263 pcf_nops(); 264 265 return (data); 266} 267 268static char PCF_GET_S1(struct pcf_softc *pcf) 269{ 270 char data; 271 272 data = inb(pcf->pcf_base+1); 273 pcf_nops(); 274 275 return (data); 276} 277 278/* 279 * Polling mode for master operations wait for a new 280 * byte incomming or outgoing 281 */ 282static int pcf_wait_byte(struct pcf_softc *pcf) 283{ 284 int counter = TIMEOUT; 285 286 while (counter--) { 287 288 if ((PCF_GET_S1(pcf) & PIN) == 0) 289 return (0); 290 } 291 292 return (IIC_ETIMEOUT); 293} 294 295static int pcf_stop(device_t pcfdev) 296{ 297 struct pcf_softc *pcf = DEVTOSOFTC(pcfdev); 298 299 /* 300 * Send STOP condition iff the START condition was previously sent. 301 * STOP is sent only once even if a iicbus_stop() is called after 302 * an iicbus_read()... see pcf_read(): the pcf needs to send the stop 303 * before the last char is read. 304 */ 305 if (pcf->pcf_started) { 306 /* set stop condition and enable IT */ 307 PCF_SET_S1(pcf, PIN|ES0|ENI|STO|ACK); 308 309 pcf->pcf_started = 0; 310 } 311 312 return (0); 313} 314 315 316static int pcf_noack(struct pcf_softc *pcf, int timeout) 317{ 318 int noack; 319 int k = timeout/10; 320 321 do { 322 noack = PCF_GET_S1(pcf) & LRB; 323 if (!noack) 324 break; 325 DELAY(10); /* XXX wait 10 us */ 326 } while (k--); 327 328 return (noack); 329} 330 331static int pcf_repeated_start(device_t pcfdev, u_char slave, int timeout) 332{ 333 struct pcf_softc *pcf = DEVTOSOFTC(pcfdev); 334 int error = 0; 335 336 /* repeated start */ 337 PCF_SET_S1(pcf, ES0|STA|STO|ACK); 338 339 /* set slave address to PCF. Last bit (LSB) must be set correctly 340 * according to transfer direction */ 341 PCF_SET_S0(pcf, slave); 342 343 /* wait for address sent, polling */ 344 if ((error = pcf_wait_byte(pcf))) 345 goto error; 346 347 /* check for ack */ 348 if (pcf_noack(pcf, timeout)) { 349 error = IIC_ENOACK; 350 goto error; 351 } 352 353 return (0); 354 355error: 356 pcf_stop(pcfdev); 357 return (error); 358} 359 360static int pcf_start(device_t pcfdev, u_char slave, int timeout) 361{ 362 struct pcf_softc *pcf = DEVTOSOFTC(pcfdev); 363 int error = 0; 364 365 if ((PCF_GET_S1(pcf) & nBB) == 0) 366 return (IIC_EBUSBSY); 367 368 /* set slave address to PCF. Last bit (LSB) must be set correctly 369 * according to transfer direction */ 370 PCF_SET_S0(pcf, slave); 371 372 /* START only */ 373 PCF_SET_S1(pcf, PIN|ES0|STA|ACK); 374 375 pcf->pcf_started = 1; 376 377 /* wait for address sent, polling */ 378 if ((error = pcf_wait_byte(pcf))) 379 goto error; 380 381 /* check for ACK */ 382 if (pcf_noack(pcf, timeout)) { 383 error = IIC_ENOACK; 384 goto error; 385 } 386 387 return (0); 388 389error: 390 pcf_stop(pcfdev); 391 return (error); 392} 393 394static void 395pcfintr(unit) 396{ 397 struct pcf_softc *pcf = 398 (struct pcf_softc *)devclass_get_softc(pcf_devclass, unit); 399 400 char data, status, addr; 401 char error = 0; 402 403 status = PCF_GET_S1(pcf); 404 405 if (status & PIN) { 406 printf("pcf%d: spurious interrupt, status=0x%x\n", unit, 407 status & 0xff); 408 409 goto error; 410 } 411 412 if (status & LAB) 413 printf("pcf%d: bus arbitration lost!\n", unit); 414 415 if (status & BER) { 416 error = IIC_EBUSERR; 417 iicbus_intr(pcf->iicbus, INTR_ERROR, &error); 418 419 goto error; 420 } 421 422 do { 423 status = PCF_GET_S1(pcf); 424 425 switch(pcf->pcf_slave_mode) { 426 427 case SLAVE_TRANSMITTER: 428 if (status & LRB) { 429 /* ack interrupt line */ 430 dummy_write(pcf); 431 432 /* no ack, don't send anymore */ 433 pcf->pcf_slave_mode = SLAVE_RECEIVER; 434 435 iicbus_intr(pcf->iicbus, INTR_NOACK, NULL); 436 break; 437 } 438 439 /* get data from upper code */ 440 iicbus_intr(pcf->iicbus, INTR_TRANSMIT, &data); 441 442 PCF_SET_S0(pcf, data); 443 break; 444 445 case SLAVE_RECEIVER: 446 if (status & AAS) { 447 addr = PCF_GET_S0(pcf); 448 449 if (status & AD0) 450 iicbus_intr(pcf->iicbus, INTR_GENERAL, &addr); 451 else 452 iicbus_intr(pcf->iicbus, INTR_START, &addr); 453 454 if (addr & LSB) { 455 pcf->pcf_slave_mode = SLAVE_TRANSMITTER; 456 457 /* get the first char from upper code */ 458 iicbus_intr(pcf->iicbus, INTR_TRANSMIT, &data); 459 460 /* send first data byte */ 461 PCF_SET_S0(pcf, data); 462 } 463 464 break; 465 } 466 467 /* stop condition received? */ 468 if (status & STS) { 469 /* ack interrupt line */ 470 dummy_read(pcf); 471 472 /* emulate intr stop condition */ 473 iicbus_intr(pcf->iicbus, INTR_STOP, NULL); 474 475 } else { 476 /* get data, ack interrupt line */ 477 data = PCF_GET_S0(pcf); 478 479 /* deliver the character */ 480 iicbus_intr(pcf->iicbus, INTR_RECEIVE, &data); 481 } 482 break; 483 484 default: 485 panic("%s: unknown slave mode (%d)!", __FUNCTION__, 486 pcf->pcf_slave_mode); 487 } 488 489 } while ((PCF_GET_S1(pcf) & PIN) == 0); 490 491 return; 492 493error: 494 /* unknown event on bus...reset PCF */ 495 PCF_SET_S1(pcf, PIN|ES0|ENI|ACK); 496 497 pcf->pcf_slave_mode = SLAVE_RECEIVER; 498 499 return; 500} 501 502static int pcf_rst_card(device_t pcfdev, u_char speed, u_char addr, u_char *oldaddr) 503{ 504 struct pcf_softc *pcf = DEVTOSOFTC(pcfdev); 505 506 if (oldaddr) 507 *oldaddr = pcf->pcf_addr; 508 509 /* retrieve own address from bus level */ 510 if (!addr) 511 pcf->pcf_addr = PCF_DEFAULT_ADDR; 512 else 513 pcf->pcf_addr = addr; 514 515 PCF_SET_S1(pcf, PIN); /* initialize S1 */ 516 517 /* own address S'O<>0 */ 518 PCF_SET_S0(pcf, pcf->pcf_addr >> 1); 519 520 /* select clock register */ 521 PCF_SET_S1(pcf, PIN|ES1); 522 523 /* select bus speed : 18=90kb, 19=45kb, 1A=11kb, 1B=1.5kb */ 524 switch (speed) { 525 case IIC_SLOW: 526 PCF_SET_S0(pcf, 0x1b); 527 break; 528 529 case IIC_FAST: 530 PCF_SET_S0(pcf, 0x19); 531 break; 532 533 case IIC_UNKNOWN: 534 case IIC_FASTEST: 535 default: 536 PCF_SET_S0(pcf, 0x18); 537 break; 538 } 539 540 /* set bus on, ack=yes, INT=yes */ 541 PCF_SET_S1(pcf, PIN|ES0|ENI|ACK); 542 543 pcf->pcf_slave_mode = SLAVE_RECEIVER; 544 545 return (0); 546} 547 548static int 549pcf_write(device_t pcfdev, char *buf, int len, int *sent, int timeout /* us */) 550{ 551 struct pcf_softc *pcf = DEVTOSOFTC(pcfdev); 552 int bytes, error = 0; 553 554#ifdef PCFDEBUG 555 printf("pcf%d: >> writing %d bytes\n", device_get_unit(pcfdev), len); 556#endif 557 558 bytes = 0; 559 while (len) { 560 561 PCF_SET_S0(pcf, *buf++); 562 563 /* wait for the byte to be send */ 564 if ((error = pcf_wait_byte(pcf))) 565 goto error; 566 567 /* check if ack received */ 568 if (pcf_noack(pcf, timeout)) { 569 error = IIC_ENOACK; 570 goto error; 571 } 572 573 len --; 574 bytes ++; 575 } 576 577error: 578 *sent = bytes; 579 580#ifdef PCFDEBUG 581 printf("pcf%d: >> %d bytes written (%d)\n", 582 device_get_unit(pcfdev), bytes, error); 583#endif 584 585 return (error); 586} 587 588static int 589pcf_read(device_t pcfdev, char *buf, int len, int *read, int last, 590 int delay /* us */) 591{ 592 struct pcf_softc *pcf = DEVTOSOFTC(pcfdev); 593 int bytes, error = 0; 594 595#ifdef PCFDEBUG 596 printf("pcf%d: << reading %d bytes\n", device_get_unit(pcfdev), len); 597#endif 598 599 /* trig the bus to get the first data byte in S0 */ 600 if (len) { 601 if (len == 1 && last) 602 /* just one byte to read */ 603 PCF_SET_S1(pcf, ES0); /* no ack */ 604 605 dummy_read(pcf); 606 } 607 608 bytes = 0; 609 while (len) { 610 611 /* XXX delay needed here */ 612 613 /* wait for trigged byte */ 614 if ((error = pcf_wait_byte(pcf))) { 615 pcf_stop(pcfdev); 616 goto error; 617 } 618 619 if (len == 1 && last) 620 /* ok, last data byte already in S0, no I2C activity 621 * on next PCF_GET_S0() */ 622 pcf_stop(pcfdev); 623 624 else if (len == 2 && last) 625 /* next trigged byte with no ack */ 626 PCF_SET_S1(pcf, ES0); 627 628 /* receive byte, trig next byte */ 629 *buf++ = PCF_GET_S0(pcf); 630 631 len --; 632 bytes ++; 633 }; 634 635error: 636 *read = bytes; 637 638#ifdef PCFDEBUG 639 printf("pcf%d: << %d bytes read (%d)\n", 640 device_get_unit(pcfdev), bytes, error); 641#endif 642 643 return (error); 644} 645 646DRIVER_MODULE(pcf, root, pcf_driver, pcf_devclass, 0, 0); 647