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