static void pcf_epp_setbyte(void *data, int ctl, int val) { if (ctl) { if (gpe.pe_irq > 0) { DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Write control 0x%x\n", val|I2C_PCF_ENI)); // set A0 pin HIGH outb(inb(CTRL) | PARPORT_CONTROL_INIT, CTRL); // DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: CTRL port = 0x%x\n", inb(CTRL))); // DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: STAT port = 0x%x\n", inb(STAT))); // EPP write data cycle outb(val | I2C_PCF_ENI, EDAT); } else { DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Write control 0x%x\n", val)); // set A0 pin HIGH outb(inb(CTRL) | PARPORT_CONTROL_INIT, CTRL); outb(val, CTRL); } } else { DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Write data 0x%x\n", val)); // set A0 pin LO outb(inb(CTRL) & ~PARPORT_CONTROL_INIT, CTRL); // DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: CTRL port = 0x%x\n", inb(CTRL))); // DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: STAT port = 0x%x\n", inb(STAT))); outb(val, EDAT); } }
static int pcf_epp_init(void *data) { if (check_region(gpe.pe_base, 5) < 0 ) { printk(KERN_WARNING "Could not request port region with base 0x%x\n", gpe.pe_base); return -ENODEV; } else { request_region(gpe.pe_base, 5, "i2c (EPP parallel port adapter)"); } DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: init status port = 0x%x\n", inb(0x379))); if (gpe.pe_irq > 0) { if (request_irq(gpe.pe_irq, pcf_epp_handler, 0, "PCF8584", 0) < 0) { printk(KERN_NOTICE "i2c-pcf-epp.o: Request irq%d failed\n", gpe.pe_irq); gpe.pe_irq = 0; } else disable_irq(gpe.pe_irq); enable_irq(gpe.pe_irq); } // EPP mode initialize // enable interrupt from nINTR pin outb(inb(CTRL)|0x14, CTRL); // clear ERROR bit of STAT outb(inb(STAT)|0x01, STAT); outb(inb(STAT)&~0x01,STAT); return 0; }
static int pcf_epp_getbyte(void *data, int ctl) { int val; if (ctl) { // set A0 pin HIGH outb(inb(CTRL) | PARPORT_CONTROL_INIT, CTRL); val = inb(EDAT); DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Read control 0x%x\n", val)); } else { // set A0 pin LOW outb(inb(CTRL) & ~PARPORT_CONTROL_INIT, CTRL); val = inb(EDAT); DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: Read data 0x%x\n", val)); } return (val); }
static int pcf_isa_getbyte(void *data, int ctl) { int address = ctl ? (base + 1) : base; int val = mmapped ? readb(address) : inb(address); DEB3(printk("i2c-elektor.o: Read 0x%X 0x%02X\n", address, val)); return (val); }
/* * This should perform the 'PCF8584 initialization sequence' as described * in the Philips IC12 data book (1995, Aug 29). * There should be a 30 clock cycle wait after reset, I assume this * has been fulfilled. * There should be a delay at the end equal to the longest I2C message * to synchronize the BB-bit (in multimaster systems). How long is * this? I assume 1 second is always long enough. * * vdovikin: added detect code for PCF8584 */ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) { unsigned char temp; DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1))); /* S1=0x80: S0 selected, serial interface off */ set_pcf(adap, 1, I2C_PCF_PIN); /* * check to see S1 now used as R/W ctrl - * PCF8584 does that when ESO is zero */ if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); return -ENXIO; /* definitely not PCF8584 */ } /* load own address in S0, effective address is (own << 1) */ i2c_outb(adap, get_own(adap)); /* check it's really written */ if ((temp = i2c_inb(adap)) != get_own(adap)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp)); return -ENXIO; } /* S1=0xA0, next byte in S2 */ set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1); /* check to see S2 now selected */ if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp)); return -ENXIO; } /* load clock register S2 */ i2c_outb(adap, get_clock(adap)); /* check it's really written, the only 5 lowest bits does matter */ if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp)); return -ENXIO; } /* Enable serial interface, idle, S0 selected */ set_pcf(adap, 1, I2C_PCF_IDLE); /* check to see PCF is really idled and we can access status register */ if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp)); return -ENXIO; } printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n"); return 0; }
static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) { unsigned char temp; DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1))); /* */ set_pcf(adap, 1, I2C_PCF_PIN); /* */ if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); return -ENXIO; /* */ } /* */ i2c_outb(adap, get_own(adap)); /* */ if ((temp = i2c_inb(adap)) != get_own(adap)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp)); return -ENXIO; } /* */ set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1); /* */ if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp)); return -ENXIO; } /* */ i2c_outb(adap, get_clock(adap)); /* */ if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp)); return -ENXIO; } /* */ set_pcf(adap, 1, I2C_PCF_IDLE); /* */ if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) { DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp)); return -ENXIO; } printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n"); return 0; }
/* Request our * interrupt line and register its associated handler. */ static int iic_hw_resrc_init(void) { if (iic_avalanche_priv_data.iic_irq > 0) { if (request_irq(iic_avalanche_priv_data.iic_irq, iic_avalanche_handler, 0, "TI IIC", 0) < 0) { iic_avalanche_priv_data.iic_irq = 0; } else DEB3(printk("Enabled IIC IRQ %d\n", iic_avalanche_priv_data.iic_irq)); } return 0; }
// // Description: This function is very hardware dependent. First, we lock // the region of memory where out registers exist. Next, we request our // interrupt line and register its associated handler. Our IIC peripheral // uses interrupt number 2, as specified by the 405 reference manual. // static int iic_hw_resrc_init(int instance) { DEB(printk("iic_hw_resrc_init: Physical Base address: 0x%x\n", (u32) IIC_ADDR[instance] )); iic_ibmocp_adaps[instance]->iic_base = (u32)ioremap((unsigned long)IIC_ADDR[instance],PAGE_SIZE); DEB(printk("iic_hw_resrc_init: ioremapped base address: 0x%x\n", iic_ibmocp_adaps[instance]->iic_base)); if (iic_ibmocp_adaps[instance]->iic_irq > 0) { if (request_irq(iic_ibmocp_adaps[instance]->iic_irq, iic_ibmocp_handler, 0, "IBM OCP IIC", iic_ibmocp_adaps[instance]) < 0) { printk(KERN_ERR "iic_hw_resrc_init: Request irq%d failed\n", iic_ibmocp_adaps[instance]->iic_irq); iic_ibmocp_adaps[instance]->iic_irq = 0; } else { DEB3(printk("iic_hw_resrc_init: Enabled interrupt\n")); } } return 0; }
static void pcf_isa_setbyte(void *data, int ctl, int val) { int address = ctl ? (base + 1) : base; if (ctl && irq) { val |= I2C_PCF_ENI; } DEB3(printk("i2c-elektor.o: Write 0x%X 0x%02X\n", address, val & 255)); switch (mmapped) { case 0: /* regular I/O */ outb(val, address); break; case 2: /* double mapped I/O needed for UP2000 board, I don't know why this... */ writeb(val, address); /* fall */ case 1: /* memory mapped I/O */ writeb(val, address); break; } }
static int __init i2c_pcfisa_init(void) { #ifdef __alpha__ /* check to see we have memory mapped PCF8584 connected to the Cypress cy82c693 PCI-ISA bridge as on UP2000 board */ if ((base == 0) && pci_present()) { struct pci_dev *cy693_dev = pci_find_device(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, NULL); if (cy693_dev) { char config; /* yeap, we've found cypress, let's check config */ if (!pci_read_config_byte(cy693_dev, 0x47, &config)) { DEB3(printk("i2c-elektor.o: found cy82c693, config register 0x47 = 0x%02x.\n", config)); /* UP2000 board has this register set to 0xe1, but the most significant bit as seems can be reset during the proper initialisation sequence if guys from API decides to do that (so, we can even enable Tsunami Pchip window for the upper 1 Gb) */ /* so just check for ROMCS at 0xe0000, ROMCS enabled for writes and external XD Bus buffer in use. */ if ((config & 0x7f) == 0x61) { /* seems to be UP2000 like board */ base = 0xe0000; /* I don't know why we need to write twice */ mmapped = 2; /* UP2000 drives ISA with 8.25 MHz (PCI/4) clock (this can be read from cypress) */ clock = I2C_PCF_CLK | I2C_PCF_TRNS90; printk("i2c-elektor.o: found API UP2000 like board, will probe PCF8584 later.\n"); } } } } #endif /* sanity checks for mmapped I/O */ if (mmapped && base < 0xc8000) { printk("i2c-elektor.o: incorrect base address (0x%0X) specified for mmapped I/O.\n", base); return -ENODEV; } printk("i2c-elektor.o: i2c pcf8584-isa adapter module\n"); if (base == 0) { base = DEFAULT_BASE; } #if (LINUX_VERSION_CODE >= 0x020301) init_waitqueue_head(&pcf_wait); #endif if (pcf_isa_init() == 0) { if (i2c_pcf_add_bus(&pcf_isa_ops) < 0) return -ENODEV; } else { return -ENODEV; } printk("i2c-elektor.o: found device at %#x.\n", base); return 0; }
static void pcf_epp_handler(int this_irq, void *dev_id, struct pt_regs *regs) { pcf_pending = 1; wake_up_interruptible(&pcf_wait); DEB3(printk(KERN_DEBUG "i2c-pcf-epp.o: in interrupt handler.\n")); }
static void iic_ite_setiic(void *data, int ctl, short val) { unsigned long j = jiffies + 10; DEB3(printk(" Write 0x%02x to 0x%x\n",(unsigned short)val, ctl&0xff)); DEB3({while (jiffies < j) schedule();})
static int pca_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) { struct i2c_algo_pca_data *adap = i2c_adap->algo_data; struct i2c_msg *msg = NULL; int curmsg; int numbytes = 0; int state; int ret; int completed = 1; unsigned long timeout = jiffies + i2c_adap->timeout; while ((state = pca_status(adap)) != 0xf8) { if (time_before(jiffies, timeout)) { msleep(10); } else { dev_dbg(&i2c_adap->dev, "bus is not idle. status is " "%#04x\n", state); return -EAGAIN; } } DEB1("{{{ XFER %d messages\n", num); if (i2c_debug >= 2) { for (curmsg = 0; curmsg < num; curmsg++) { int addr, i; msg = &msgs[curmsg]; addr = (0x7f & msg->addr) ; if (msg->flags & I2C_M_RD) printk(KERN_INFO " [%02d] RD %d bytes from %#02x [%#02x, ...]\n", curmsg, msg->len, addr, (addr << 1) | 1); else { printk(KERN_INFO " [%02d] WR %d bytes to %#02x [%#02x%s", curmsg, msg->len, addr, addr << 1, msg->len == 0 ? "" : ", "); for (i = 0; i < msg->len; i++) printk("%#04x%s", msg->buf[i], i == msg->len - 1 ? "" : ", "); printk("]\n"); } } } curmsg = 0; ret = -EREMOTEIO; while (curmsg < num) { state = pca_status(adap); DEB3("STATE is 0x%02x\n", state); msg = &msgs[curmsg]; switch (state) { case 0xf8: /* On reset or stop the bus is idle */ completed = pca_start(adap); break; case 0x08: /* A START condition has been transmitted */ case 0x10: /* A repeated start condition has been transmitted */ completed = pca_address(adap, msg); break; case 0x18: /* SLA+W has been transmitted; ACK has been received */ case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */ if (numbytes < msg->len) { completed = pca_tx_byte(adap, msg->buf[numbytes]); numbytes++; break; } curmsg++; numbytes = 0; if (curmsg == num) pca_stop(adap); else completed = pca_repeated_start(adap); break; case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */ DEB2("NOT ACK received after SLA+W\n"); pca_stop(adap); goto out; case 0x40: /* SLA+R has been transmitted; ACK has been received */ completed = pca_rx_ack(adap, msg->len > 1); break; case 0x50: /* Data bytes has been received; ACK has been returned */ if (numbytes < msg->len) { pca_rx_byte(adap, &msg->buf[numbytes], 1); numbytes++; completed = pca_rx_ack(adap, numbytes < msg->len - 1); break; } curmsg++; numbytes = 0; if (curmsg == num) pca_stop(adap); else completed = pca_repeated_start(adap); break; case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */ DEB2("NOT ACK received after SLA+R\n"); pca_stop(adap); goto out; case 0x30: /* Data byte in I2CDAT has been transmitted; NOT ACK has been received */ DEB2("NOT ACK received after data byte\n"); pca_stop(adap); goto out; case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */ DEB2("Arbitration lost\n"); /* * The PCA9564 data sheet (2006-09-01) says "A * START condition will be transmitted when the * bus becomes free (STOP or SCL and SDA high)" * when the STA bit is set (p. 11). * * In case this won't work, try pca_reset() * instead. */ pca_start(adap); goto out; case 0x58: /* Data byte has been received; NOT ACK has been returned */ if (numbytes == msg->len - 1) { pca_rx_byte(adap, &msg->buf[numbytes], 0); curmsg++; numbytes = 0; if (curmsg == num) pca_stop(adap); else completed = pca_repeated_start(adap); } else { DEB2("NOT ACK sent after data byte received. " "Not final byte. numbytes %d. len %d\n", numbytes, msg->len); pca_stop(adap); goto out; } break; case 0x70: /* Bus error - SDA stuck low */ DEB2("BUS ERROR - SDA Stuck low\n"); pca_reset(adap); goto out; case 0x90: /* Bus error - SCL stuck low */ DEB2("BUS ERROR - SCL Stuck low\n"); pca_reset(adap); goto out; case 0x00: /* Bus error during master or slave mode due to illegal START or STOP condition */ DEB2("BUS ERROR - Illegal START or STOP\n"); pca_reset(adap); goto out; default: dev_err(&i2c_adap->dev, "unhandled SIO state 0x%02x\n", state); break; } if (!completed) goto out; } ret = curmsg; out: DEB1("}}} transfered %d/%d messages. " "status is %#04x. control is %#04x\n", curmsg, num, pca_status(adap), pca_get_con(adap)); return ret; }
static int pca_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) { struct i2c_algo_pca_data *adap = i2c_adap->algo_data; struct i2c_msg *msg = NULL; int curmsg; int numbytes = 0; int state; state = pca_status(adap); if ( state != 0xF8 ) { printk(KERN_ERR DRIVER ": bus is not idle. status is %#04x\n", state ); /* FIXME: what to do. Force stop ? */ return -EREMOTEIO; } DEB1("{{{ XFER %d messages\n", num); if (i2c_debug>=2) { for (curmsg = 0; curmsg < num; curmsg++) { int addr, i; msg = &msgs[curmsg]; addr = (0x7f & msg->addr) ; if (msg->flags & I2C_M_RD ) printk(KERN_INFO " [%02d] RD %d bytes from %#02x [%#02x, ...]\n", curmsg, msg->len, addr, (addr<<1) | 1); else { printk(KERN_INFO " [%02d] WR %d bytes to %#02x [%#02x%s", curmsg, msg->len, addr, addr<<1, msg->len == 0 ? "" : ", "); for(i=0; i < msg->len; i++) printk("%#04x%s", msg->buf[i], i == msg->len - 1 ? "" : ", "); printk("]\n"); } } } curmsg = 0; while (curmsg < num) { state = pca_status(adap); DEB3("STATE is 0x%02x\n", state); msg = &msgs[curmsg]; switch (state) { case 0xf8: /* On reset or stop the bus is idle */ pca_start(adap); break; case 0x08: /* A START condition has been transmitted */ case 0x10: /* A repeated start condition has been transmitted */ pca_address(adap, msg); break; case 0x18: /* SLA+W has been transmitted; ACK has been received */ case 0x28: /* Data byte in I2CDAT has been transmitted; ACK has been received */ if (numbytes < msg->len) { pca_tx_byte(adap, msg->buf[numbytes]); numbytes++; break; } curmsg++; numbytes = 0; if (curmsg == num) pca_stop(adap); else pca_repeated_start(adap); break; case 0x20: /* SLA+W has been transmitted; NOT ACK has been received */ DEB2("NOT ACK received after SLA+W\n"); pca_stop(adap); return -EREMOTEIO; case 0x40: /* SLA+R has been transmitted; ACK has been received */ pca_rx_ack(adap, msg->len > 1); break; case 0x50: /* Data bytes has been received; ACK has been returned */ if (numbytes < msg->len) { pca_rx_byte(adap, &msg->buf[numbytes], 1); numbytes++; pca_rx_ack(adap, numbytes < msg->len - 1); break; } curmsg++; numbytes = 0; if (curmsg == num) pca_stop(adap); else pca_repeated_start(adap); break; case 0x48: /* SLA+R has been transmitted; NOT ACK has been received */ DEB2("NOT ACK received after SLA+R\n"); pca_stop(adap); return -EREMOTEIO; case 0x30: /* Data byte in I2CDAT has been transmitted; NOT ACK has been received */ DEB2("NOT ACK received after data byte\n"); return -EREMOTEIO; case 0x38: /* Arbitration lost during SLA+W, SLA+R or data bytes */ DEB2("Arbitration lost\n"); return -EREMOTEIO; case 0x58: /* Data byte has been received; NOT ACK has been returned */ if ( numbytes == msg->len - 1 ) { pca_rx_byte(adap, &msg->buf[numbytes], 0); curmsg++; numbytes = 0; if (curmsg == num) pca_stop(adap); else pca_repeated_start(adap); } else { DEB2("NOT ACK sent after data byte received. " "Not final byte. numbytes %d. len %d\n", numbytes, msg->len); pca_stop(adap); return -EREMOTEIO; } break; case 0x70: /* Bus error - SDA stuck low */ DEB2("BUS ERROR - SDA Stuck low\n"); pca_reset(adap); return -EREMOTEIO; case 0x90: /* Bus error - SCL stuck low */ DEB2("BUS ERROR - SCL Stuck low\n"); pca_reset(adap); return -EREMOTEIO; case 0x00: /* Bus error during master or slave mode due to illegal START or STOP condition */ DEB2("BUS ERROR - Illegal START or STOP\n"); pca_reset(adap); return -EREMOTEIO; default: printk(KERN_ERR DRIVER ": unhandled SIO state 0x%02x\n", state); break; } } DEB1(KERN_CRIT "}}} transfered %d messages. " "status is %#04x. control is %#04x\n", num, pca_status(adap), pca_get_con(adap)); return curmsg; }