Exemplo n.º 1
0
static int bcm1161_i2c_inb(void *base, int no_ack, struct bcm1161_i2c *i2c)
{
	u8 cs = REG_I2C_CS(base);
	u8 data;

	I2C_DEBUG(DBG_TRACE, "%d\n", no_ack);

	/* Wait for controller to be done with last command */
	if (bcm1161_check_cmdbusy(base) < 0) {
		I2C_DEBUG(DBG_ERROR, "cmdbusy always high\n");
		return -EIO;
	}
	/* Initiate data read with ACK low */
	REG_I2C_CS(base) =
	    REG_I2C_CS_SDA | REG_I2C_CS_SCL |
	    REG_I2C_CS_CMDREAD | REG_I2C_CS_EN | (no_ack ? REG_I2C_CS_ACK : 0);

	/* Wait for command to be done */
	if (bcm1161_wait_sesdone(base, 1, i2c) < 0) {
		I2C_DEBUG(DBG_ERROR, "sesdone timed out, cs = 0x%02x\n", cs);
		return -ETIMEDOUT;
	}
	/* Read data */
	data = REG_I2C_DAT(base);

	udelay(5);
	return (int)data;
}
Exemplo n.º 2
0
bool I2C_MultipleWrite(alt_u32 clk_base, alt_u32 data_base, alt_8 DeviceAddr, alt_u8 ControlAddr, alt_u8 *pData, alt_u16 len){
    bool bSuccess = TRUE;
    int i;

    i2c_start(clk_base, data_base);
    if (!i2c_write(clk_base, data_base, DeviceAddr)){  // send ID
        bSuccess = FALSE;
        I2C_DEBUG(("I2C HMB_E2 Fail: Address NACK!\n"));
    }
    if (bSuccess && !i2c_write(clk_base, data_base, ControlAddr)){ // send sub-address
        bSuccess = FALSE;
        I2C_DEBUG(("I2C HMB_E2 Fail: SubAddress NACK!\n"));
    }            
    if (bSuccess){
        for(i=0;i<len && bSuccess;i++){
            bSuccess = i2c_write(clk_base, data_base, *pData);
            pData++;
        }
        if (!bSuccess)         
            I2C_DEBUG(("I2C HMB_E2 Fail: write NACK!\n"));
    }
    i2c_stop(clk_base, data_base);
    
    usleep(7*1000); // delay to wait EE2 ready (at least 5 ms delay is required)
    
    return bSuccess;

    
}
Exemplo n.º 3
0
/* returns:
 * 1 if the device acknowledged
 * 0 if the device did not ack
 * -ETIMEDOUT if an error occurred (while raising the scl line)
 */
static int bcm1161_i2c_outb(void *base, char c, struct bcm1161_i2c *i2c)
{
	int ack;

	I2C_DEBUG(DBG_TRACE, "0x%2x\n", c);

	udelay(5);

	/* Wait for controller to be done with last command */
	if (bcm1161_check_cmdbusy(base) < 0) {
		I2C_DEBUG(DBG_ERROR, "cmdbusy always high\n");
		return -EIO;
	}
	/* Send data */
	REG_I2C_CS(base) = REG_I2C_CS_SDA | REG_I2C_CS_SCL | REG_I2C_CS_EN;
	REG_I2C_DAT(base) = (u8) c;

	/* Wait for command to be done */
	ack = bcm1161_wait_sesdone(base, 0, i2c);
	if (ack < 0) {
		I2C_DEBUG(DBG_ERROR, "sesdone timed out\n");
		return -ETIMEDOUT;
	}

	return ack;
}
Exemplo n.º 4
0
bool I2C_Write(alt_u32 clk_base, alt_u32 data_base, alt_8 DeviceAddr, alt_u8 ControlAddr, alt_u8 ControlData){
    bool bSuccess = TRUE;
    //alt_u8 DeviceAddr;
    
    // device id
    //DeviceAddr = HMB_E2_I2C_ID;

    i2c_start(clk_base, data_base);
    if (!i2c_write(clk_base, data_base, DeviceAddr)){  // send ID
        bSuccess = FALSE;
        I2C_DEBUG(("I2C HMB_E2 Fail: Address NACK!\n"));
    }
    if (bSuccess && !i2c_write(clk_base, data_base, ControlAddr)){ // send sub-address
        bSuccess = FALSE;
        I2C_DEBUG(("I2C HMB_E2 Fail: SubAddress NACK!\n"));
    }            
    if (bSuccess && !i2c_write(clk_base, data_base, ControlData)){  
        bSuccess = FALSE;
        I2C_DEBUG(("I2C HMB_E2 Fail: write NACK!\n"));
    }
    i2c_stop(clk_base, data_base);
    
    usleep(7*1000); // delay to wait EE2 ready (at least 5 ms delay is required)
    
    return bSuccess;

    
}
Exemplo n.º 5
0
bool I2C_Read(alt_u32 clk_base, alt_u32 data_base, alt_8 DeviceAddr, alt_u8 ControlAddr, alt_u8 *pControlData){
    bool bSuccess = TRUE;
    //alt_u8 DeviceAddr;
   
    // device id
    //DeviceAddr = HMB_E2_I2C_ID;

    i2c_start(clk_base, data_base);
    if (!i2c_write(clk_base, data_base, DeviceAddr)){  // send ID
        bSuccess = FALSE;
        I2C_DEBUG(("I2C HMB_E2 Fail: Address NACK!\n"));
    }
    if (bSuccess && !i2c_write(clk_base, data_base, ControlAddr)){ // send sub-address
        bSuccess = FALSE;
        I2C_DEBUG(("I2C HMB_E2 Fail: SubAddress NACK!\n"));
    }            
    i2c_start(clk_base, data_base);  // restart
    DeviceAddr |= 1; // Read
    if (bSuccess && !i2c_write(clk_base, data_base, DeviceAddr)){  // send id
        bSuccess = FALSE;
        I2C_DEBUG(("I2C HMB_E2 Fail: Address+1 NACK!\n"));
    }
    
    if (bSuccess){
        i2c_read(clk_base, data_base, pControlData, FALSE);  // read
    }        
    i2c_stop(clk_base, data_base);
    
    return bSuccess;
}
Exemplo n.º 6
0
static int bcm1161_readbytes(struct i2c_adapter *i2c_adap,
			     struct i2c_msg *msg, struct bcm1161_i2c *i2c)
{
	int inval;
	int rdcount = 0;	/* counts bytes read */
	char *temp = msg->buf;
	int count = msg->len;

	while (count > 0) {
		inval = bcm1161_i2c_inb(i2c_adap->algo_data,
					(msg->flags & I2C_M_NO_RD_ACK)
					|| (count == 1), i2c);

		if (inval >= 0) {
			I2C_DEBUG(DBG_TRACE2, "reading %2.2X\n", inval & 0xff);
			*temp = inval;
			rdcount++;
		} else {	/* read timed out */
			i2c_errors++;
			I2C_DEBUG(DBG_ERROR, "timed out.\n");
			break;
		}

		temp++;
		count--;
	}
	return rdcount;
}
Exemplo n.º 7
0
static int bcm1161_sendbytes(struct i2c_adapter *i2c_adap,
			     struct i2c_msg *msg, struct bcm1161_i2c *i2c)
{
	char c;
	const char *temp = msg->buf;
	int count = msg->len;
	unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
	int retval;
	int wrcount = 0;

	while (count > 0) {
		c = *temp;
		I2C_DEBUG(DBG_TRACE2, "writing %2.2X\n", c & 0xff);
		retval = bcm1161_i2c_outb(i2c_adap->algo_data, c, i2c);

		if ((retval > 0) || (nak_ok && (retval == 0))) {
			/* ok or ignored NAK */
			count--;
			temp++;
			wrcount++;
		} else {	/* arbitration or no acknowledge */
			I2C_DEBUG(DBG_ERROR, "error %d/%d.\n", wrcount,
				  msg->len);
			i2c_errors++;
			bcm1161_i2c_stop(i2c_adap->algo_data, i2c);
			return (retval < 0) ? retval : -EFAULT;
			/* got a better one ?? */
		}
	}
	return wrcount;
}
Exemplo n.º 8
0
static int
iicbb_stop(device_t dev)
{
	struct iicbb_softc *sc = device_get_softc(dev);

	I2C_SET(sc,dev,0,0);
	I2C_SET(sc,dev,1,0);
	I2C_SET(sc,dev,1,1);
	I2C_DEBUG(printf(">"));
	I2C_DEBUG(printf("\n"));
	return (0);
}
Exemplo n.º 9
0
/* doAddress initiates the transfer by generating the start condition (in
 * try_address) and transmits the address in the necessary format to handle
 * reads, writes as well as 10bit-addresses.
 * returns:
 *  0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set
 * -x an error occurred (like: -EREMOTEIO if the device did not answer, or
 *  -ETIMEDOUT, for example if the lines are stuck...)
 */
static int bcm1161_doAddress(struct i2c_adapter *i2c_adap,
			     struct i2c_msg *msg, struct bcm1161_i2c *i2c)
{
	unsigned short flags = msg->flags;
	unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;

	unsigned char addr;
	int ret, retries;

	retries = nak_ok ? 0 : i2c_adap->retries;

	if ((flags & I2C_M_TEN)) {
		/* a ten bit address */
		addr = 0xf0 | ((msg->addr >> 7) & 0x03);
		I2C_DEBUG(DBG_TRACE2, "addr: %d\n", addr);
		/* try extended address code... */
		ret = bcm1161_try_address(i2c_adap, addr, retries, i2c);

		if ((ret != 1) && !nak_ok) {
			I2C_DEBUG(DBG_ERROR,
				  "died at extended address code.\n");
			return -EREMOTEIO;
		}
		/* the remaining 8 bit address */
		ret = bcm1161_i2c_outb(i2c_adap->algo_data,
				       msg->addr & 0x7f, i2c);

		if ((ret != 1) && !nak_ok) {
			/* the chip did not ack / xmission error occurred */
			I2C_DEBUG(DBG_ERROR, "died at 2nd address code.\n");
			return -EREMOTEIO;
		}

		if (flags & I2C_M_RD) {
			ret = bcm1161_i2c_repstart(i2c_adap->algo_data, i2c);

			if (ret < 0)
				return -EIO;
			/* okay, now switch into reading mode */
			addr |= 0x01;
			ret = bcm1161_try_address(i2c_adap, addr, retries, i2c);

			if ((ret != 1) && !nak_ok) {
				I2C_DEBUG(DBG_ERROR,
					  "died at extended address code.\n");
				return -EREMOTEIO;
			}
		}
	} else {		/* normal 7bit address  */
Exemplo n.º 10
0
static int bcm1161_wait_sesdone(int *base, int clear_cmd,
				struct bcm1161_i2c *i2c)
{
	int ret;
	u8 isr;
	u8 cs = REG_I2C_CS(base);

#if !I2C_POLL_COMMAND_DONE
	ret = bcm1161_wait_interrupt(i2c);
#else
	ret = bcm1161_wait_interrupt(base, i2c);
#endif
	if (ret < 0) {
		I2C_DEBUG(DBG_ERROR,
			  "wait interrupt timed out %d cs = 0x%02X\n", ret, cs);
		i2c_errors++;
		bcm1161_i2c_reset_controller(base);
		return ret;
	}
	/* Get status from interrupt status register */
	isr = ret;

	/* Clear command */
	cs = REG_I2C_CS(base);
	if (clear_cmd) {
		REG_I2C_CS(base) = (cs & ~REG_I2C_CS_CMDMASK);
	}

	if (isr & REG_I2C_ISR_I2CERR) {
		I2C_DEBUG(DBG_ERROR, "bus error detected, slave addr = 0x%04X\n",
								i2c->addr);
		i2c_errors++;
		return -EIO;
	}

	if (isr & REG_I2C_ISR_NOACK) {
		I2C_DEBUG(DBG_ERROR, "no ack, slave addr = 0x%04X\n",
								i2c->addr);
		i2c_errors++;
	}

	if (!(isr & REG_I2C_ISR_SES_DONE)) {
		I2C_DEBUG(DBG_ERROR, "ses done timedout\n");
		i2c_errors++;
		return -EIO;
	}

	return (cs & REG_I2C_CS_ACK) ? 0 : 1;
}
Exemplo n.º 11
0
void i2c_stop(struct i2c_bus *bus)
{
	I2C_SET(bus,0,0);
	I2C_SET(bus,1,0);
	I2C_SET(bus,1,1);
	I2C_DEBUG(printk(">\n"));
}
Exemplo n.º 12
0
/* try_address tries to contact a chip for a number of
 * times before it gives up.
 * return values:
 * 1 chip answered
 * 0 chip did not answer
 * -x transmission error
 */
static int bcm1161_try_address(struct i2c_adapter *i2c_adap,
			       unsigned char addr, int retries,
			       struct bcm1161_i2c *i2c)
{
	int i, ret = -1;

	I2C_DEBUG(DBG_TRACE, "0x%02x, %d\n", addr, retries);

	for (i = 0; i <= retries; i++) {
		ret = bcm1161_i2c_outb(i2c_adap->algo_data, addr, i2c);
		if (ret == 1)
			break;	/* success! */
		bcm1161_i2c_stop(i2c_adap->algo_data, i2c);
		udelay(5);
		if (i == retries)	/* no success */
			break;
		bcm1161_i2c_start(i2c_adap->algo_data, i2c);
		udelay(100);
	}
	udelay(5);
	if (i) {
		I2C_DEBUG(DBG_INFO,
			  "Used %d tries to %s client at 0x%02x : %s\n",
			  i + 1, addr & 1 ? "read" : "write", addr >> 1,
			  ret == 1 ? "success" : ret == 0 ? "no ack" :
			  "failed, timeout?");
	}
	return ret;
}
Exemplo n.º 13
0
static int bcm1161_wait_interrupt(void *base, struct bcm1161 *i2c)
{
	/* wait for I2C Controller Interrupt */
	unsigned int i = 0;
#if defined (CONFIG_ARCH_BCM116X)
	timer_tick_count_t clk;
	timer_tick_count_t clk2;
#endif
	int isr;

#if defined (CONFIG_ARCH_BCM116X)
	clk = timer_get_tick_count();
#endif
	while ((REG_I2C_ISR(base) & I2C_ISR_MASK_ALL) == 0) {
		i++;
		if (i == (unsigned int)(-1)) {
			I2C_DEBUG(DBG_ERROR, "wait timed out, %d\n", clk);
			return -ETIMEDOUT;
		}
	}

#if defined (CONFIG_ARCH_BCM116X)
	clk2 = timer_get_tick_count();
	clk = clk2 - clk;
	if (clk > i2c_max_irq_wait) {
		i2c_max_irq_wait = clk;
	}
#endif
	isr = REG_I2C_ISR(base);
	REG_I2C_ISR(base) = isr;

	return isr;
}
Exemplo n.º 14
0
static int
iicbb_start(device_t dev, u_char slave, int timeout)
{
	int error;

	I2C_DEBUG(printf("<"));

	I2C_SET(dev,1,1);
	I2C_SET(dev,1,0);
	I2C_SET(dev,0,0);

	/* send address */
	iicbb_sendbyte(dev, slave, timeout);

	/* check for ack */
	if (iicbb_ack(dev, timeout)) {
		error = IIC_ENOACK;
		goto error;
	}

	return(0);

error:
	iicbb_stop(dev);
	return (error);
}
Exemplo n.º 15
0
void i2c_start(struct i2c_bus *bus)
{
	I2C_SET(bus,0,1);
	I2C_SET(bus,1,1);
	I2C_SET(bus,1,0);
	I2C_SET(bus,0,0);
	I2C_DEBUG(printk("%s: < ",bus->name));
}
Exemplo n.º 16
0
static int
iicbb_stop(device_t dev)
{
	I2C_SET(dev,0,0);
	I2C_SET(dev,1,0);
	I2C_SET(dev,1,1);
	I2C_DEBUG(printf(">"));
	return (0);
}
Exemplo n.º 17
0
static int bcm1161_i2c_start(void *base, struct bcm1161_i2c *i2c)
{
	u8 cs;
	int i = 0;
	I2C_DEBUG(DBG_TRACE, "\n");

#if ADD_TURNAROUND_DELAY
	udelay(TURN_AROUND_DELAY);
#endif

	while (((cs = REG_I2C_CS(base)) &
		(REG_I2C_CS_SDA | REG_I2C_CS_SCL)) !=
	       (REG_I2C_CS_SDA | REG_I2C_CS_SCL)) {
		if ((i % 100) == 0) {
			i2c_errors++;
			I2C_DEBUG(DBG_ERROR,
				  "waiting for cs = 0x%2x [i = %d] base = 0x%p\n",
				  cs, i, (unsigned int)base);
			bcm1161_i2c_reset_controller(base);
		}
		i++;
	}

	/* Wait for controller to be done with last command */
	if (bcm1161_check_cmdbusy(base) < 0) {
		I2C_DEBUG(DBG_ERROR, "cmdbusy always high\n");
		return -EIO;
	}

	/* Send normal start condition */
	REG_I2C_CS(base) = REG_I2C_CS_SDA | REG_I2C_CS_SCL |
	    REG_I2C_CS_CMDSTART | REG_I2C_CS_EN;

	/* Wait for command to be done */
	if (bcm1161_wait_sesdone(base, 1, i2c) < 0) {
		I2C_DEBUG(DBG_ERROR, "sesdone timed out\n");
		return -ETIMEDOUT;
	}

	return 0;
}
Exemplo n.º 18
0
static int bcm1161_i2c_repstart(void *base, struct bcm1161_i2c *i2c)
{
	I2C_DEBUG(DBG_TRACE, "\n");

	/* Wait for controller to be done with last command */
	if (bcm1161_check_cmdbusy(base) < 0) {
		I2C_DEBUG(DBG_ERROR, "cmdbusy always high\n");
		return -EIO;
	}
	/* Send repeated start condition */
	REG_I2C_CS(base) = REG_I2C_CS_SDA | REG_I2C_CS_SCL |
	    REG_I2C_CS_CMDRESTART | REG_I2C_CS_EN;

	/* Wait for command to be done */
	if (bcm1161_wait_sesdone(base, 1, i2c) < 0) {
		I2C_DEBUG(DBG_ERROR, "sesdone timed out\n");
		return -ETIMEDOUT;
	}

	return 0;
}
Exemplo n.º 19
0
int i2c_sendbyte(struct i2c_bus *bus,unsigned char data,int wait_for_ack)
{
	int i, ack;
    
	I2C_SET(bus,0,0);
	for (i=7; i>=0; i--)
		(data&(1<<i)) ? i2c_one(bus) : i2c_zero(bus);
	if (wait_for_ack)
		udelay(wait_for_ack);
	ack=i2c_ack(bus);
	I2C_DEBUG(printk("%02x%c ",(int)data,ack?'-':'+'));
	return ack;
}
Exemplo n.º 20
0
bool I2C_MultipleRead(alt_u32 clk_base, alt_u32 data_base, alt_8 DeviceAddr, alt_u8 szData[], alt_u16 len){
    int i;
    bool bSuccess = TRUE;
    //alt_u8 DeviceAddr, 
    alt_u8 ControlAddr = 0;
    
   
    // device id
    //DeviceAddr = HMB_E2_I2C_ID;

    i2c_start(clk_base, data_base);
    if (!i2c_write(clk_base, data_base, DeviceAddr)){  // send ID
        bSuccess = FALSE;
        I2C_DEBUG(("I2C HMB_E2 Fail: Address NACK!\n"));
    }
    if (bSuccess && !i2c_write(clk_base, data_base, ControlAddr)){ // send sub-address
        bSuccess = FALSE;
        I2C_DEBUG(("I2C HMB_E2 Fail: SubAddress NACK!\n"));
    }    
    if (bSuccess)        
        i2c_start(clk_base, data_base);  // restart
    DeviceAddr |= 1; // Read
    if (bSuccess && !i2c_write(clk_base, data_base, DeviceAddr)){  // send id
        bSuccess = FALSE;
        I2C_DEBUG(("I2C HMB_E2 Fail: Address+1 NACK!\n"));
    }
    
    if (bSuccess){
        for(i=0;i<len && bSuccess;i++){
            i2c_read(clk_base, data_base, &szData[i], (i==(len-1))?FALSE:TRUE);  // read
        }            
    }        
    i2c_stop(clk_base, data_base);
    
    return bSuccess;    
    
}
Exemplo n.º 21
0
static void
iicbb_sendbyte(device_t dev, u_char data, int timeout)
{
	int i;
    
	for (i=7; i>=0; i--) {
		if (data&(1<<i)) {
			iicbb_one(dev, timeout);
		} else {
			iicbb_zero(dev, timeout);
		}
	}
	I2C_DEBUG(printf("w%02x",(int)data));
	return;
}
Exemplo n.º 22
0
static int bcm1161_i2c_stop(void *base, struct bcm1161_i2c *i2c)
{
	u8 cs = REG_I2C_CS(base);

	I2C_DEBUG(DBG_TRACE, "\n");

	/* Wait for controller to be done with last command */
	if (bcm1161_check_cmdbusy(base) < 0) {
		I2C_DEBUG(DBG_ERROR, "cmdbusy always high\n");
		return -EIO;
	}

	/* Send stop condition */
	REG_I2C_CS(base) = REG_I2C_CS_SDA | REG_I2C_CS_SCL |
	    REG_I2C_CS_CMDSTOP | REG_I2C_CS_EN;

	/* Wait for command to be done */
	if (bcm1161_wait_sesdone(base, 1, i2c) < 0) {
		I2C_DEBUG(DBG_ERROR, "sesdone timed out, cs = 0x%02x\n", cs);
		return -ETIMEDOUT;
	}

	return 0;
}
Exemplo n.º 23
0
/* compute the clock period required for the delay between i2c transactions */
static unsigned long bcm1161_i2c_bus_clk_period(struct bcm1161_i2c *i2c)
{
	u8 tim, div, p;

	tim = REG_I2C_TIM(i2c->adapter.algo_data);
	div = tim & REG_I2C_TIM_DIVMSK;
	p = (tim & REG_I2C_TIM_PMSK) >> BSC_TIM_P_VAL_BIT_SHIFT;

	I2C_DEBUG(DBG_INFO, " tim[%d]\t div[%d]\t p[%d]\n", tim, div, p);

	div = 1 << (4 - div);
	p = 2 * (p + 1) + 1 + 2 * (p + 1) + 2;

	return (div * p * 1000000 + (clk_get_rate(i2c->clk) >> 1) - 1) /
	    BSC_MASTER_CLK_FREQ;
}
Exemplo n.º 24
0
unsigned char i2c_readbyte(struct i2c_bus *bus,int last)
{
	int i;
	unsigned char data=0;
    
	I2C_SET(bus,0,1);
	for (i=7; i>=0; i--) 
	{
		I2C_SET(bus,1,1);
		if (I2C_GET(bus))
			data |= (1<<i);
		I2C_SET(bus,0,1);
	}
	last ? i2c_one(bus) : i2c_zero(bus);
	I2C_DEBUG(printk("=%02x%c ",(int)data,last?'-':'+'));
	return data;
}
Exemplo n.º 25
0
/*
 * Waiting for ACKNOWLEDGE.
 *
 * When a chip is being addressed or has received data it will issue an
 * ACKNOWLEDGE pulse. Therefore the MASTER must release the DATA line
 * (set it to high level) and then release the CLOCK line.
 * Now it must wait for the SLAVE to pull the DATA line low.
 * Actually on the bus this looks like a START condition so nothing happens
 * because of the fact that the IC's that have not been addressed are doing
 * nothing.
 *
 * When the SLAVE has pulled this line low the MASTER will take the CLOCK
 * line low and then the SLAVE will release the SDA (data) line.
 */
static int
iicbb_ack(device_t dev, int timeout)
{
	int noack;
	int k = 0;
    
	I2C_SET(dev,0,1);
	I2C_SET(dev,1,1);
	do {
		noack = I2C_GETSDA(dev);
		if (!noack)
			break;
		DELAY(10);
		k += 10;
	} while (k < timeout);

	I2C_SET(dev,0,1);
	I2C_DEBUG(printf("%c ",noack?'-':'+'));

	return (noack);
}
Exemplo n.º 26
0
static u_char
iicbb_readbyte(device_t dev, int last, int timeout)
{
	int i;
	unsigned char data=0;
    
	I2C_SET(dev,0,1);
	for (i=7; i>=0; i--) 
	{
		I2C_SET(dev,1,1);
		if (I2C_GETSDA(dev))
			data |= (1<<i);
		I2C_SET(dev,0,1);
	}
	if (last) {
		iicbb_one(dev, timeout);
	} else {
		iicbb_zero(dev, timeout);
	}
	I2C_DEBUG(printf("r%02x%c ",(int)data,last?'-':'+'));
	return data;
}
Exemplo n.º 27
0
/*
 * Waiting for ACKNOWLEDGE.
 *
 * When a chip is being addressed or has received data it will issue an
 * ACKNOWLEDGE pulse. Therefore the MASTER must release the DATA line
 * (set it to high level) and then release the CLOCK line.
 * Now it must wait for the SLAVE to pull the DATA line low.
 * Actually on the bus this looks like a START condition so nothing happens
 * because of the fact that the IC's that have not been addressed are doing
 * nothing.
 *
 * When the SLAVE has pulled this line low the MASTER will take the CLOCK
 * line low and then the SLAVE will release the SDA (data) line.
 */
static int
iicbb_ack(device_t dev, int timeout)
{
	struct iicbb_softc *sc = device_get_softc(dev);
	int noack;
	int k = 0;

	I2C_SET(sc,dev,0,1);
	I2C_SET(sc,dev,1,1);
	do {
		noack = I2C_GETSDA(dev);
		if (!noack)
			break;
		DELAY(1);
		k++;
	} while (k < timeout);

	I2C_SET(sc,dev,0,1);
	I2C_DEBUG(printf("%c ",noack?'-':'+'));

	return (noack);
}