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; }
uint8_t SoftwareWire::endTransmission(boolean sendStop) { if(sendStop) i2c_stop(); else i2c_repstart(); return(_transmission); // return the transmission status that was set during writing address and data }
// // The requestFrom() read the data from the I2C bus and stores it in a buffer. // uint8_t SoftwareWire::requestFrom(uint8_t address, uint8_t size, boolean sendStop) { uint8_t n=0; // number of valid received bytes. Start with 0 bytes. // The stransmission status is set, allthough it is not returned. // Start with the status : no error _transmission = SOFTWAREWIRE_NO_ERROR; // Clear the RX buffer rxBufPut = 0; rxBufGet = 0; boolean bus_okay = i2c_start(); if(bus_okay) { uint8_t rc = i2c_write((address << 1) | 1); // The r/w bit is '1' to read if( rc == 0) // a sda zero from Slave for the 9th bit is ack { _transmission = SOFTWAREWIRE_NO_ERROR; // TODO: check if the Slave returns less bytes than requested. for(; n<size; n++) { if( n < (size - 1)) rxBuf[n] = i2c_read(true); // read with ack else rxBuf[n] = i2c_read(false); // last byte, read with nack } rxBufPut = n; } else { _transmission = SOFTWAREWIRE_ADDRESS_NACK; } } else { // There was a bus error. _transmission = SOFTWAREWIRE_OTHER; } if(sendStop || _transmission != SOFTWAREWIRE_NO_ERROR) i2c_stop(); else i2c_repstart(); return( n); }
static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count, int last) { int i, status; struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; int wfp; /* increment number of bytes to read by one -- read dummy byte */ for (i = 0; i <= count; i++) { if ((wfp = wait_for_pin(adap, &status))) { if (wfp == -EINTR) { /* arbitration lost */ return -EINTR; } i2c_stop(adap); dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n"); return (-1); } #ifndef STUB_I2C if ((status & I2C_PCF_LRB) && (i != count)) { i2c_stop(adap); dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n"); return (-1); } #endif if (i == count - 1) { set_pcf(adap, 1, I2C_PCF_ESO); } else if (i == count) { if (last) { i2c_stop(adap); } else { i2c_repstart(adap); } }; if (i) { buf[i - 1] = i2c_inb(adap); } else { i2c_inb(adap); /* dummy read */ } } return (i - 1); }
/* * 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 pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count, int last) { int i, status; struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; int wfp; /* */ for (i = 0; i <= count; i++) { if ((wfp = wait_for_pin(adap, &status))) { if (wfp == -EINTR) return -EINTR; /* */ i2c_stop(adap); dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n"); return -1; } if ((status & I2C_PCF_LRB) && (i != count)) { i2c_stop(adap); dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n"); return -1; } if (i == count - 1) { set_pcf(adap, 1, I2C_PCF_ESO); } else if (i == count) { if (last) i2c_stop(adap); else i2c_repstart(adap); } if (i) buf[i - 1] = i2c_inb(adap); else i2c_inb(adap); /* */ } return i - 1; }
static uchar i2c_do(struct i2c_cmd *cmd) { uchar addr; LED_PORT |= LED_BV DEBUGF("i2c %s at 0x%02x, len = %d\n", (cmd->flags&I2C_M_RD)?"rd":"wr", cmd->addr, cmd->len); /* normal 7bit address */ addr = ( cmd->addr << 1 ); if (cmd->flags & I2C_M_RD ) addr |= 1; if(cmd->cmd & CMD_I2C_BEGIN) i2c_start(); else i2c_repstart(); // send DEVICE address if(!i2c_put_u08(addr)) { DEBUGF("I2C read: address error @ %x\n", addr); status = STATUS_ADDRESS_NAK; expected = 0; i2c_stop(); } else { status = STATUS_ADDRESS_ACK; expected = cmd->len; saved_cmd = cmd->cmd; /* check if transfer is already done (or failed) */ if((cmd->cmd & CMD_I2C_END) && !expected) i2c_stop(); } /* more data to be expected? */ LED_PORT &= ~LED_BV; return(cmd->len?0xff:0x00); }
static uchar i2c_do(struct i2c_cmd *cmd) { uchar addr; /* normal 7bit address */ addr = ( cmd->addr << 1 ); if (cmd->flags & I2C_M_RD ) addr |= 1; if(cmd->cmd & CMD_I2C_BEGIN) i2c_start(); else i2c_repstart(); // send DEVICE address if(!i2c_write_byte(addr)) { status = STATUS_ADDRESS_NAK; expected = 0; i2c_stop(); } else { status = STATUS_ADDRESS_ACK; expected = cmd->len; saved_cmd = cmd->cmd; /* check if transfer is already done (or failed) */ if((cmd->cmd & CMD_I2C_END) && !expected) i2c_stop(); } /* more data to be expected? */ #ifndef USBTINY return(cmd->len?0xff:0x00); #else return(((cmd->flags & I2C_M_RD) && cmd->len)?0xff:0x00); #endif }