static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status) { DEB2(printk(KERN_INFO "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n", *status)); /* Cleanup from LAB -- reset and enable ESO. * This resets the PCF8584; since we've lost the bus, no * further attempts should be made by callers to clean up * (no i2c_stop() etc.) */ set_pcf(adap, 1, I2C_PCF_PIN); set_pcf(adap, 1, I2C_PCF_ESO); /* We pause for a time period sufficient for any running * I2C transaction to complete -- the arbitration logic won't * work properly until the next START is seen. * It is assumed the bus driver or client has set a proper value. * * REVISIT: should probably use msleep instead of mdelay if we * know we can sleep. */ if (adap->lab_mdelay) mdelay(adap->lab_mdelay); DEB2(printk(KERN_INFO "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n", get_pcf(adap, 1))); }
static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status) { DEB2(printk(KERN_INFO "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n", *status)); /* */ set_pcf(adap, 1, I2C_PCF_PIN); set_pcf(adap, 1, I2C_PCF_ESO); /* */ if (adap->lab_mdelay) mdelay(adap->lab_mdelay); DEB2(printk(KERN_INFO "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n", get_pcf(adap, 1))); }
/* Called when the module is loaded. This function starts the * cascade of calls up through the heirarchy of i2c modules (i.e. up to the * algorithm layer and into to the core layer) */ static int __init iic_avalanche_init(void) { struct iic_avalanche *piic = &iic_avalanche_priv_data; DEB2(printk(KERN_INFO "Initialize Avalanche IIC adapter module\n")); iic_avalanche_priv_data.iic_clock = avalanche_get_vbus_freq(); /* Clock frequency on the peripheral bus */ iic_avalanche_data.data = (void *)piic; init_waitqueue_head(&iic_wait); if (iic_hw_resrc_init() == 0) { DEB2(printk("calling add bus\n")); if (i2c_avalanche_add_bus(&iic_avalanche_ops) < 0) return -ENODEV; } else { return -ENODEV; } DEB2(printk(KERN_INFO " found device at %#x irq %d.\n", piic->iic_base, piic->iic_irq)); return 0; }
/* * 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; }
static int mlib_read_mthd (mlib_desc * desc) { char sig[5]; unsigned char hi, lo; int len; if (!mlib_chkdesc (desc)) return 0; if (!mlib_rdstr (desc, sig, 4)) return 0; if (strcmp (sig, "MThd")) { mlib_seterr ("Invalid header signature (!= MThd)"); return 0; } if (mlib_rdint32 (desc, &len)) if (mlib_rdint16 (desc, &desc->hdr.MThd_fmt)) DEB2 (printf ("Header: Format %d\n", desc->hdr.MThd_fmt)); if (mlib_rdint16 (desc, &desc->hdr.MThd_ntrk)) DEB2 (printf ("Header: ntrks %d\n", desc->hdr.MThd_ntrk)); if (mlib_rdbyte (desc, &hi)) if (mlib_rdbyte (desc, &lo)) if (hi & 0x80) /* Negative */ { DEB2 (printf ("SMPTE timing: format = %d, resolution = %d\n", (char) hi, lo)); desc->hdr.time_mode = TIME_SMPTE; desc->hdr.SMPTE_format = (char) hi; desc->hdr.SMPTE_resolution = lo; } else { desc->hdr.time_mode = TIME_MIDI; desc->hdr.division = (hi << 8) + lo; DEB2 (printf ("Midi timing: timebase = %d ppqn\n", desc->hdr.division)); } desc->curr_trk = -1; desc->trk_offs = 0; desc->next_trk_offs = 4 + 4 + len;; return mlib_seek (desc, desc->trk_offs); /* Point to the first track */ }
// // Description: The registered interrupt handler // static void iic_ibmocp_handler(int this_irq, void *dev_id, struct pt_regs *regs) { int ret; struct iic_regs *iic; struct iic_ibm *priv_data = dev_id; iic = (struct iic_regs *) priv_data->iic_base; iic_pending = 1; DEB2(printk("iic_ibmocp_handler: in interrupt handler\n")); // Read status register ret = readb((int) &(iic->sts)); DEB2(printk("iic_ibmocp_handler: status = %x\n", ret)); // Clear status register. See IBM PPC 405 reference manual for details writeb(0x0a, (int) &(iic->sts)); wake_up_interruptible(&(iic_wait[priv_data->index])); }
static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, int count, int last) { struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; int wrcount, status, timeout; for (wrcount=0; wrcount<count; ++wrcount) { DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n", buf[wrcount] & 0xff)); i2c_outb(adap, buf[wrcount]); timeout = wait_for_pin(adap, &status); if (timeout) { if (timeout == -EINTR) return -EINTR; /* arbitration lost */ i2c_stop(adap); dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n"); return -EREMOTEIO; /* got a better one ?? */ } if (status & I2C_PCF_LRB) { i2c_stop(adap); dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n"); return -EREMOTEIO; /* got a better one ?? */ } } if (last) i2c_stop(adap); else i2c_repstart(adap); return wrcount; }
static void iic_avalanche_handler(int this_irq, void *dev_id, struct pt_regs *regs) { iic_pending = 1; DEB2(printk("iic_avalanche_handler: in interrupt handler\n")); wake_up_interruptible(&iic_wait); }
static void pca_stop(struct i2c_algo_pca_data *adap) { int sta = pca_get_con(adap); DEB2("=== STOP\n"); sta |= I2C_PCA_CON_STO; sta &= ~(I2C_PCA_CON_STA|I2C_PCA_CON_SI); pca_set_con(adap, sta); }
static int pca_repeated_start(struct i2c_algo_pca_data *adap) { int sta = pca_get_con(adap); DEB2("=== REPEATED START\n"); sta |= I2C_PCA_CON_STA; sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI); pca_set_con(adap, sta); return pca_wait(adap); }
/* * Generate a start condition on the i2c bus. * * returns after the start condition has occured */ static void pca_start(struct i2c_algo_pca_data *adap) { int sta = pca_get_con(adap); DEB2("=== START\n"); sta |= I2C_PCA_CON_STA; sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_SI); pca_set_con(adap, sta); pca_wait(adap); }
static int pca_tx_byte(struct i2c_algo_pca_data *adap, __u8 b) { int sta = pca_get_con(adap); DEB2("=== WRITE %#04x\n", b); pca_outw(adap, I2C_PCA_DAT, b); sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI); pca_set_con(adap, sta); return pca_wait(adap); }
/* * Description: This performs the IBM PPC 405 IIC initialization sequence * as described in the PPC405GP data book. */ static int iic_init(struct i2c_adapter *adap) { struct iic_regs *iic; unsigned short retval; iic = (struct iic_regs *) ((struct ocp_dev *) adap->data)->vaddr; /* Clear master low master address */ iic_outb(iic->lmadr, 0); /* Clear high master address */ iic_outb(iic->hmadr, 0); /* Clear low slave address */ iic_outb(iic->lsadr, 0); /* Clear high slave address */ iic_outb(iic->hsadr, 0); /* Clear status */ iic_outb(iic->sts, 0x0a); /* Clear extended status */ iic_outb(iic->extsts, 0x8f); /* Set clock division */ iic_outb(iic->clkdiv, 0x04); retval = iic_inb(iic->clkdiv); DEB(printk("iic_init: CLKDIV register = %x\n", retval)); /* Enable interrupts on Requested Master Transfer Complete */ iic_outb(iic->intmsk, 0x01); /* Clear transfer count */ iic_outb(iic->xfrcnt, 0x0); /* Clear extended control and status */ iic_outb(iic->xtcntlss, 0xf0); /* Set mode control (flush master data buf, enable hold SCL, exit */ /* unknown state. */ iic_outb(iic->mdcntl, 0x47); /* Clear control register */ iic_outb(iic->cntl, 0x0); DEB2(printk(KERN_DEBUG "iic_init: Initialized IIC on PPC 405\n")); return 0; }
static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) { int timeout = DEF_TIMEOUT; *status = get_pcf(adap, 1); #ifndef STUB_I2C while (timeout-- && (*status & I2C_PCF_PIN)) { adap->waitforpin(); *status = get_pcf(adap, 1); } if (*status & I2C_PCF_LAB) { DEB2(printk(KERN_INFO "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n", *status)); /* Cleanup from LAB-- reset and enable ESO. * This resets the PCF8584; since we've lost the bus, no * further attempts should be made by callers to clean up * (no i2c_stop() etc.) */ set_pcf(adap, 1, I2C_PCF_PIN); set_pcf(adap, 1, I2C_PCF_ESO); /* TODO: we should pause for a time period sufficient for any * running I2C transaction to complete-- the arbitration * logic won't work properly until the next START is seen. */ DEB2(printk(KERN_INFO "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n", get_pcf(adap,1))); return(-EINTR); } #endif if (timeout <= 0) return(-1); else return(0); }
/* * registering functions to load algorithms at runtime */ int i2c_pcf_add_bus(struct i2c_adapter *adap) { struct i2c_algo_pcf_data *pcf_adap = adap->algo_data; int rval; DEB2(dev_dbg(&adap->dev, "hw routines registered.\n")); /* register new adapter to i2c module... */ adap->algo = &pcf_algo; if ((rval = pcf_init_8584(pcf_adap))) return rval; rval = i2c_add_adapter(adap); return rval; }
/* * Description: Whenever we initiate a transaction, the first byte clocked * onto the bus after the start condition is the address (7 bit) of the * device we want to talk to. This function manipulates the address specified * so that it makes sense to the hardware when written to the IIC peripheral. * * Note: 10 bit addresses are not supported in this driver, although they are * supported by the hardware. This functionality needs to be implemented. */ static inline int iic_doAddress(struct i2c_adapter *adap, struct i2c_msg *msg, int retries) { struct iic_regs *iic; unsigned short flags = msg->flags; unsigned char addr; iic = (struct iic_regs *) IIC_DEV(vaddr); /* * The following segment for 10 bit addresses needs to be ported */ #if 0 /* Ten bit addresses not supported right now */ if ((flags & I2C_M_TEN)) { /* a ten bit address */ addr = 0xf0 | ((msg->addr >> 7) & 0x03); DEB2(printk(KERN_DEBUG "addr0: %d\n", addr)); /* try extended address code... */ ret = try_address(adap, addr, retries); if (ret != 1) { printk(KERN_ERR "iic_doAddress: died at extended address code.\n"); return -EREMOTEIO; } /* the remaining 8 bit address */ iic_outb(msg->addr & 0x7f); /* Status check comes here */ if (ret != 1) { printk(KERN_ERR "iic_doAddress: died at 2nd address code.\n"); return -EREMOTEIO; } if (flags & I2C_M_RD) { i2c_repstart(adap); /* okay, now switch into reading mode */ addr |= 0x01; ret = try_address(adap, addr, retries); if (ret != 1) { printk(KERN_ERR "iic_doAddress: died at extended address code.\n"); return -EREMOTEIO; } } } else
static int pca_address(struct i2c_algo_pca_data *adap, struct i2c_msg *msg) { int sta = pca_get_con(adap); int addr; addr = ((0x7f & msg->addr) << 1); if (msg->flags & I2C_M_RD) addr |= 1; DEB2("=== SLAVE ADDRESS %#04x+%c=%#04x\n", msg->addr, msg->flags & I2C_M_RD ? 'R' : 'W', addr); pca_outw(adap, I2C_PCA_DAT, addr); sta &= ~(I2C_PCA_CON_STO|I2C_PCA_CON_STA|I2C_PCA_CON_SI); pca_set_con(adap, sta); return pca_wait(adap); }
/* * Description: This function implements combined transactions. Combined * transactions consist of combinations of reading and writing blocks of data. * Each transfer (i.e. a read or a write) is separated by a repeated start * condition. */ static int iic_combined_transaction(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) { int i; struct i2c_msg *pmsg; int ret; DEB2(printk(KERN_DEBUG "Beginning combined transaction\n")); for (i = 0; i < num; i++) { pmsg = &msgs[i]; if (pmsg->flags & I2C_M_RD) { /* Last read or write segment needs to be terminated with a stop */ if (i < num - 1) { DEB2(printk(KERN_DEBUG "This one is a read\n")); } else { DEB2(printk (KERN_DEBUG "Doing the last read\n")); } ret = iic_readbytes(i2c_adap, pmsg->buf, pmsg->len, (i < num - 1) ? IIC_COMBINED_XFER : IIC_SINGLE_XFER); if (ret != pmsg->len) { DEB2(printk("i2c-algo-ppc405.o: fail: " "only read %d bytes.\n", ret)); return i; } else { DEB2(printk ("i2c-algo-ppc405.o: read %d bytes.\n", ret)); } } else if (!(pmsg->flags & I2C_M_RD)) { /* Last read or write segment needs to be terminated with a stop */ if (i < num - 1) { DEB2(printk (KERN_DEBUG "This one is a write\n")); } else { DEB2(printk (KERN_DEBUG "Doing the last write\n")); } ret = iic_sendbytes(i2c_adap, pmsg->buf, pmsg->len, (i < num - 1) ? IIC_COMBINED_XFER : IIC_SINGLE_XFER); if (ret != pmsg->len) { DEB2(printk("i2c-algo-ppc405.o: fail: " "only wrote %d bytes.\n", ret)); return i; } else { DEB2(printk ("i2c-algo-ppc405.o: wrote %d bytes.\n", ret)); } } } return num; }
int i2c_del_driver(struct i2c_driver *driver) { int i,j,k,res; DRV_LOCK(); for (i = 0; i < I2C_DRIVER_MAX; i++) if (driver == drivers[i]) break; if (I2C_DRIVER_MAX == i) { printk(KERN_WARNING " i2c-core.o: unregister_driver: " "[%s] not found\n", driver->name); DRV_UNLOCK(); return -ENODEV; } /* Have a look at each adapter, if clients of this driver are still * attached. If so, detach them to be able to kill the driver * afterwards. */ DEB2(printk(KERN_DEBUG "i2c-core.o: unregister_driver - looking for clients.\n")); /* removing clients does not depend on the notify flag, else * invalid operation might (will!) result, when using stale client * pointers. */ ADAP_LOCK(); /* should be moved inside the if statement... */ for (k=0;k<I2C_ADAP_MAX;k++) { struct i2c_adapter *adap = adapters[k]; if (adap == NULL) /* skip empty entries. */ continue; DEB2(printk(KERN_DEBUG "i2c-core.o: examining adapter %s:\n", adap->name)); if (driver->flags & I2C_DF_DUMMY) { /* DUMMY drivers do not register their clients, so we have to * use a trick here: we call driver->attach_adapter to * *detach* it! Of course, each dummy driver should know about * this or hell will break loose... */ if ((res = driver->attach_adapter(adap))) { printk(KERN_WARNING "i2c-core.o: while unregistering " "dummy driver %s, adapter %s could " "not be detached properly; driver " "not unloaded!\n", driver->name, adap->name); ADAP_UNLOCK(); return res; } } else { for (j=0;j<I2C_CLIENT_MAX;j++) { struct i2c_client *client = adap->clients[j]; if (client != NULL && client->driver == driver) { DEB2(printk(KERN_DEBUG "i2c-core.o: " "detaching client %s:\n", client->name)); if ((res = driver-> detach_client(client))) { printk(KERN_ERR "i2c-core.o: while " "unregistering driver " "`%s', the client at " "address %02x of " "adapter `%s' could not " "be detached; driver " "not unloaded!\n", driver->name, client->addr, adap->name); ADAP_UNLOCK(); return res; } } } } } ADAP_UNLOCK(); drivers[i] = NULL; driver_count--; DRV_UNLOCK(); DEB(printk(KERN_DEBUG "i2c-core.o: driver unregistered: %s\n",driver->name)); return 0; }
static int iic_sendbytes(struct i2c_adapter *adap, const char *buf, int count, int xfer_flag) { struct iic_regs *iic; int wrcount, status, timeout; int loops, remainder, i, j; int ret, error_code; iic = (struct iic_regs *) IIC_DEV(vaddr); if (count == 0) return 0; wrcount = 0; loops = count / 4; remainder = count % 4; if ((loops > 1) && (remainder == 0)) { for (i = 0; i < (loops - 1); i++) { /* Write four bytes to master data buffer */ for (j = 0; j < 4; j++) { iic_outb(iic->mdbuf, buf[wrcount++]); } /* Issue command to IICO device to begin transmission */ iic_outb(iic->cntl, 0x35); /* Wait for transmission to complete. When it does, * loop to the top of the for statement and write the * next four bytes. */ timeout = wait_for_pin(adap, &status); if (timeout < 0) { /* Error handling */ return wrcount; } ret = analyze_status(adap, &error_code); if (ret < 0) { if (error_code == IIC_ERR_INCOMPLETE_XFR) { /* Return the number of bytes transferred */ ret = iic_inb(iic->xfrcnt); ret = ret & 0x07; return (wrcount - 4 + ret); } else return error_code; } } } else if ((loops >= 1) && (remainder > 0)) { /*printk(KERN_DEBUG "iic_sendbytes: (loops >= 1)\n"); */ for (i = 0; i < loops; i++) { /* * Write four bytes to master data buffer */ for (j = 0; j < 4; j++) { iic_outb(iic->mdbuf, buf[wrcount++]); } /* * Issue command to IICO device to begin transmission */ iic_outb(iic->cntl, 0x35); /* * Wait for transmission to complete. When it does, * loop to the top of the for statement and write the * next four bytes. */ timeout = wait_for_pin(adap, &status); if (timeout < 0) return wrcount; ret = analyze_status(adap, &error_code); if (ret < 0) { if (error_code == IIC_ERR_INCOMPLETE_XFR) { /* Return the number of bytes transferred */ ret = iic_inb(iic->xfrcnt); ret = ret & 0x07; return (wrcount - 4 + ret); } else return error_code; } } } if (remainder == 0) remainder = 4; /* Write the remaining bytes (less than or equal to 4) */ for (i = 0; i < remainder; i++) iic_outb(iic->mdbuf, buf[wrcount++]); if (xfer_flag == IIC_COMBINED_XFER) { iic_outb(iic->cntl, (0x09 | ((remainder - 1) << 4))); } else { iic_outb(iic->cntl, (0x01 | ((remainder - 1) << 4))); } DEB2(printk(KERN_DEBUG "iic_sendbytes: Waiting for interrupt\n")); timeout = wait_for_pin(adap, &status); if (timeout < 0) return wrcount; ret = analyze_status(adap, &error_code); if (ret < 0) { if (error_code == IIC_ERR_INCOMPLETE_XFR) { /* Return the number of bytes transferred */ ret = iic_inb(iic->xfrcnt); ret = ret & 0x07; return (wrcount - 4 + ret); } else return error_code; } DEB2(printk(KERN_DEBUG "iic_sendbytes: Got interrupt\n")); return wrcount; }
/* * Description: Called by the upper layers to do the grunt work for * a master read transaction. */ static int iic_readbytes(struct i2c_adapter *adap, char *buf, int count, int xfer_type) { struct iic_regs *iic; int rdcount = 0, i, status, timeout; int loops, remainder, j; int ret, error_code; iic = (struct iic_regs *) IIC_DEV(vaddr); if (count == 0) return 0; loops = count / 4; remainder = count % 4; if ((loops > 1) && (remainder == 0)) { for (i = 0; i < (loops - 1); i++) { /* Issue command to begin master read (4 bytes maximum) */ iic_outb(iic->cntl, 0x37); /* * Wait for transmission to complete. When it does, * loop to the top of the for statement and write the * next four bytes. */ timeout = wait_for_pin(adap, &status); if (timeout < 0) return rdcount; ret = analyze_status(adap, &error_code); if (ret < 0) { if (error_code == IIC_ERR_INCOMPLETE_XFR) return rdcount; else return error_code; } for (j = 0; j < 4; j++) { /* Wait for data to shuffle to top of data buffer * This value needs to optimized. */ udelay(1); buf[rdcount] = iic_inb(iic->mdbuf); rdcount++; } } } else if ((loops >= 1) && (remainder > 0)) { for (i = 0; i < loops; i++) { /* Issue command to begin master read (4 bytes maximum) */ iic_outb(iic->cntl, 0x37); /* * Wait for transmission to complete. When it does, * loop to the top of the for statement and write the * next four bytes. */ timeout = wait_for_pin(adap, &status); if (timeout < 0) return rdcount; ret = analyze_status(adap, &error_code); if (ret < 0) { if (error_code == IIC_ERR_INCOMPLETE_XFR) return rdcount; else return error_code; } for (j = 0; j < 4; j++) { /* Wait for data to shuffle to top of data buffer * This value needs to optimized. */ udelay(1); buf[rdcount] = iic_inb(iic->mdbuf); rdcount++; } } } if (remainder == 0) remainder = 4; DEB2(printk (KERN_DEBUG "iic_readbytes: writing %x to IICO_CNTL\n", (0x03 | ((remainder - 1) << 4)))); if (xfer_type == IIC_COMBINED_XFER) { iic_outb(iic->cntl, (0x0b | ((remainder - 1) << 4))); } else { iic_outb(iic->cntl, (0x03 | ((remainder - 1) << 4))); } DEB2(printk(KERN_DEBUG "iic_readbytes: Wait for pin\n")); timeout = wait_for_pin(adap, &status); DEB2(printk(KERN_DEBUG "iic_readbytes: Got the interrupt\n")); if (timeout < 0) return rdcount; ret = analyze_status(adap, &error_code); if (ret < 0) { if (error_code == IIC_ERR_INCOMPLETE_XFR) return rdcount; else return error_code; } for (i = 0; i < remainder; i++) { buf[rdcount] = iic_inb(iic->mdbuf); rdcount++; } return rdcount; }
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; }
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 void pca_rx_byte(struct i2c_algo_pca_data *adap, __u8 *b, int ack) { *b = pca_inw(adap, I2C_PCA_DAT); DEB2("=== READ %#04x %s\n", *b, ack ? "ACK" : "NACK"); }
static int octeon_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int combined) { uint64_t data = 0; int i; int timeout = 0; octeon_mio_tws_sw_twsi_t temp, mio_tws_sw_twsi; octeon_mio_tws_sw_twsi_ext_t mio_tws_sw_twsi_ext; DEB2("addr: 0x%04x, len: %d, flags: 0x%x, buf[0] = %x\n", msg->addr, msg->len, msg->flags, msg->buf[0]); mio_tws_sw_twsi.u64 = 0x0; mio_tws_sw_twsi.s.v = 1; //ten bit address op<1> = 1 if( msg->flags & I2C_M_TEN) mio_tws_sw_twsi.s.op |= 0x2; mio_tws_sw_twsi.s.a = msg->addr & 0x3ff; // check the msg->len 0<=len <8 if( msg->len > 8 ){ printk("%s %d Error len msg->len %d\n", __FILE__, __LINE__, msg->len); return (-1); } mio_tws_sw_twsi.s.sovr = 1; // size override. if ( msg->len == 0 ) mio_tws_sw_twsi.s.size = 0; else mio_tws_sw_twsi.s.size = msg->len-1; // Size: 0 = 1 byte, 1 = 2 bytes, ..., 7 = 8 bytes if( msg->flags & I2C_M_RD ){ mio_tws_sw_twsi.s.r = 1; // Enable Read bit }else{ for(i =0; i <= mio_tws_sw_twsi.s.size; i++){ data = data << 8; data |= msg->buf[i]; } mio_tws_sw_twsi.s.d = data; mio_tws_sw_twsi_ext.s.d = data >> 32; } #ifdef I2C_OCTEON_DEBUG if ( mio_tws_sw_twsi.s.r == 1 ) printk("twsi-read op: data=%llx %llx len=%d\n", mio_tws_sw_twsi.u64, mio_tws_sw_twsi_ext.u64, msg->len); else printk("twsi-write op: data=%llx %llx len=%d\n", mio_tws_sw_twsi.u64, mio_tws_sw_twsi_ext.u64, msg->len); #endif octeon_write_csr(OCTEON_MIO_TWS_SW_TWSI_EXT, mio_tws_sw_twsi_ext.u64); octeon_write_csr(OCTEON_MIO_TWS_SW_TWSI, mio_tws_sw_twsi.u64); //Poll! wait the transfer complete and timeout (10ms). do{ temp.u64 = octeon_read_csr(OCTEON_MIO_TWS_SW_TWSI); udelay(1); }while (temp.s.v && (timeout++ < I2C_MAX_TIMEOUT)); mio_tws_sw_twsi.u64 = octeon_read_csr(OCTEON_MIO_TWS_SW_TWSI); if (timeout >= I2C_MAX_TIMEOUT) { printk("Octeon twsi I2C Timeout!\n"); octeon_i2c_reset(); return -EIO; } //transfer ERROR if (!mio_tws_sw_twsi.s.r){ octeon_i2c_reset(); return -EIO; } if (msg->flags & I2C_M_RD){ mio_tws_sw_twsi_ext.u64 = octeon_read_csr(OCTEON_MIO_TWS_SW_TWSI_EXT); data = ((uint64_t) mio_tws_sw_twsi_ext.s.d << 32) | mio_tws_sw_twsi.s.d; #ifdef I2C_OCTEON_DEBUG printk("twsi-read result: data=%llx %llx len=%d\n", mio_tws_sw_twsi.u64, mio_tws_sw_twsi_ext.u64, msg->len); #endif for(i = mio_tws_sw_twsi.s.size; i >= 0; i--){ msg->buf[i] = data; data = data >> 8; } }