Beispiel #1
0
void i2c_slave_end_listening(void)
{
    _i2c_state.listening = false;
    if(!i2c_is_busy()){
        i2c_do_listen();
    }
}
Beispiel #2
0
void i2c_slave_listen(void)
{
    _i2c_state.listening = true;
    if(!i2c_is_busy()){
        i2c_do_listen();
    }
}
Beispiel #3
0
static int i2c_is_busy_wait(struct saa7134_dev *dev)
{
	enum i2c_status status;
	int count;

	for (count = 0; count < I2C_WAIT_RETRY; count++) {
		status = i2c_get_status(dev);
		if (!i2c_is_busy(status))
			break;
		saa_wait(I2C_WAIT_DELAY);
	}
	if (I2C_WAIT_RETRY == count)
		return FALSE;
	return TRUE;
}
Beispiel #4
0
static int i2c_wait_done(struct i2c_adapter *i2c_adap)
{
    int count;

    for (count = 0; count < I2C_WAIT_RETRY; count++) {
        if (!i2c_is_busy(i2c_adap))
            break;
        udelay(I2C_WAIT_DELAY);
    }

    if (I2C_WAIT_RETRY == count)
        return 0;

    return 1;
}
Beispiel #5
0
/**
 * Настраивает шину i2c в режим мастер.
 * @param device адрес устройства.
 * @param page_address адрес в устройстве.
 * @param data данные.
 * @param data_size размер данных.
 * @return Код ошибки.
 */
err_t i2c_master_setup_rw(i2c_address_t device, void* page_address, size_t page_address_size, void* data, i2c_size_t data_size)
{
    if(i2c_is_busy()) return E_BUSY;
    if(data == NULL) return E_NULL_POINTER;
    if(data_size == 0) return E_INVALID_VALUE;
    
    if(page_address == NULL){
        page_address_size = 0;
    }else{
        if(page_address_size == 0) return E_INVALID_VALUE;
    }
    
    i2c_data_init(&_i2c_state.master.data, page_address, page_address_size, data, data_size);
    
    _i2c_state.master.device = device;
    
    _i2c_state.has_transfer = true;
    
    return E_NO_ERROR;
}
Beispiel #6
0
int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size,
	     uint8_t *in, int in_size, int flags)
{
	struct i2c_port_data *pd = pdata + port;
	uint32_t events = 0;

	if (out_size == 0 && in_size == 0)
		return EC_SUCCESS;

	if (pd->i2ccs) {
		if ((flags & I2C_XFER_SINGLE) == I2C_XFER_SINGLE)
			flags &= ~I2C_XFER_START;
	}

	/* Copy data to port struct */
	pd->out = out;
	pd->out_size = out_size;
	pd->in = in;
	pd->in_size = in_size;
	pd->flags = flags;
	pd->widx = 0;
	pd->ridx = 0;
	pd->err = 0;
	pd->addr = slave_addr;

	if (port < I2C_STANDARD_PORT_COUNT) {
		/* Make sure we're in a good state to start */
		if ((flags & I2C_XFER_START) && (i2c_is_busy(port)
			|| (IT83XX_SMB_HOSTA(port) & HOSTA_ALL_WC_BIT)
			|| (i2c_get_line_levels(port) != I2C_LINE_IDLE))) {

			/* Attempt to unwedge the port. */
			i2c_unwedge(port);
			/* reset i2c port */
			i2c_reset(port, I2C_RC_NO_IDLE_FOR_START);
		}
	} else {
		/* Make sure we're in a good state to start */
		if ((flags & I2C_XFER_START) && (i2c_is_busy(port)
			|| (i2c_get_line_levels(port) != I2C_LINE_IDLE))) {
			/* Attempt to unwedge the port. */
			i2c_unwedge(port);
			/* reset i2c port */
			i2c_reset(port, I2C_RC_NO_IDLE_FOR_START);
		}
	}

	pd->task_waiting = task_get_current();
	if (pd->flags & I2C_XFER_START) {
		pd->i2ccs = I2C_CH_NORMAL;
		/* enable i2c interrupt */
		task_clear_pending_irq(i2c_ctrl_regs[port].irq);
		task_enable_irq(i2c_ctrl_regs[port].irq);
	}
	/* Start transaction */
	i2c_transaction(port);
	/* Wait for transfer complete or timeout */
	events = task_wait_event_mask(TASK_EVENT_I2C_IDLE, pd->timeout_us);
	/* disable i2c interrupt */
	task_disable_irq(i2c_ctrl_regs[port].irq);
	pd->task_waiting = TASK_ID_INVALID;

	/* Handle timeout */
	if (!(events & TASK_EVENT_I2C_IDLE)) {
		pd->err = EC_ERROR_TIMEOUT;
		/* reset i2c port */
		i2c_reset(port, I2C_RC_TIMEOUT);
	}

	/* reset i2c channel status */
	if (pd->err)
		pd->i2ccs = I2C_CH_NORMAL;

	return pd->err;
}