staticint mxl111sf_i2c_bitbang_sendbyte(struct mxl111sf_state *state,
u8 byte)
{ int i, ret;
u8 data = 0;
mxl_i2c("(0x%02x)", byte);
ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data); if (mxl_fail(ret)) goto fail;
for (i = 0; i < 8; i++) {
data = (byte & (0x80 >> i)) ? SW_SDA_OUT : 0;
ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
0x10 | SW_I2C_EN | data); if (mxl_fail(ret)) goto fail;
ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
0x10 | SW_I2C_EN | data | SW_SCL_OUT); if (mxl_fail(ret)) goto fail;
ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
0x10 | SW_I2C_EN | data); if (mxl_fail(ret)) goto fail;
}
/* last bit was 0 so we need to release SDA */ if (!(byte & 1)) {
ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
0x10 | SW_I2C_EN | SW_SDA_OUT); if (mxl_fail(ret)) goto fail;
}
/* CLK high for ACK readback */
ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT); if (mxl_fail(ret)) goto fail;
ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data); if (mxl_fail(ret)) goto fail;
/* drop the CLK after getting ACK, SDA will go high right away */
ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
0x10 | SW_I2C_EN | SW_SDA_OUT); if (mxl_fail(ret)) goto fail;
if (data & SW_SDA_IN)
ret = -EIO;
fail: return ret;
}
staticint mxl111sf_i2c_bitbang_recvbyte(struct mxl111sf_state *state,
u8 *pbyte)
{ int i, ret;
u8 byte = 0;
u8 data = 0;
mxl_i2c("()");
*pbyte = 0;
ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
0x10 | SW_I2C_EN | SW_SDA_OUT); if (mxl_fail(ret)) goto fail;
for (i = 0; i < 8; i++) {
ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
0x10 | SW_I2C_EN |
SW_SCL_OUT | SW_SDA_OUT); if (mxl_fail(ret)) goto fail;
ret = mxl111sf_read_reg(state, SW_I2C_BUSY_ADDR, &data); if (mxl_fail(ret)) goto fail;
staticint mxl111sf_i2c_nack(struct mxl111sf_state *state)
{ int ret;
mxl_i2c("()");
/* SDA high to signal last byte read from slave */
ret = mxl111sf_write_reg(state, SW_I2C_ADDR,
0x10 | SW_I2C_EN | SW_SCL_OUT | SW_SDA_OUT); if (mxl_fail(ret)) goto fail;
staticint mxl111sf_i2c_sw_xfer_msg(struct mxl111sf_state *state, struct i2c_msg *msg)
{ int i, ret;
mxl_i2c("()");
if (msg->flags & I2C_M_RD) {
ret = mxl111sf_i2c_start(state); if (mxl_fail(ret)) goto fail;
ret = mxl111sf_i2c_bitbang_sendbyte(state,
(msg->addr << 1) | 0x01); if (mxl_fail(ret)) {
mxl111sf_i2c_stop(state); goto fail;
}
for (i = 0; i < msg->len; i++) {
ret = mxl111sf_i2c_bitbang_recvbyte(state,
&msg->buf[i]); if (mxl_fail(ret)) {
mxl111sf_i2c_stop(state); goto fail;
}
if (i < msg->len - 1)
mxl111sf_i2c_ack(state);
}
mxl111sf_i2c_nack(state);
ret = mxl111sf_i2c_stop(state); if (mxl_fail(ret)) goto fail;
} else {
ret = mxl111sf_i2c_start(state); if (mxl_fail(ret)) goto fail;
ret = mxl111sf_i2c_bitbang_sendbyte(state,
(msg->addr << 1) & 0xfe); if (mxl_fail(ret)) {
mxl111sf_i2c_stop(state); goto fail;
}
for (i = 0; i < msg->len; i++) {
ret = mxl111sf_i2c_bitbang_sendbyte(state,
msg->buf[i]); if (mxl_fail(ret)) {
mxl111sf_i2c_stop(state); goto fail;
}
}
/* FIXME: we only want to do this on the last transaction */
mxl111sf_i2c_stop(state);
}
fail: return ret;
}
/* check for slave device status */ if (mxl111sf_i2c_check_status(state) == 1) {
mxl_i2c("NACK writing slave address %02x",
msg->addr); /* if NACK, stop I2C bus and exit */
buf[2] = I2C_CONTROL_REG;
buf[3] = 0x4E;
buf[4] = (HWI2C400) ? 0x03 : 0x0D;
ret = -EIO; gotoexit;
}
/* I2C interface can do I2C operations in block of 8 bytes of I2C data. calculation to figure out number of blocks of i2c
data required to program */
block_len = (msg->len / 8);
left_over_len = (msg->len % 8);
for (index = 0; index < block_len; index++) { for (i = 0; i < 8; i++) { /* write data on I2C interface */
buf[2+(i*3)] = I2C_DATA_REG;
buf[3+(i*3)] = msg->buf[(index*8)+i];
buf[4+(i*3)] = 0x00;
}
ret = mxl111sf_i2c_send_data(state, 0, buf);
/* check for I2C NACK status */ if (mxl111sf_i2c_check_status(state) == 1) {
mxl_i2c("NACK writing slave address %02x",
msg->addr);
/* if NACK, stop I2C bus and exit */
buf[2] = I2C_CONTROL_REG;
buf[3] = 0x4E;
buf[4] = (HWI2C400) ? 0x03 : 0x0D;
ret = -EIO; gotoexit;
}
}
if (left_over_len) { for (k = 0; k < 26; k++)
buf[k] = USB_END_I2C_CMD;
buf[0] = 0x99;
buf[1] = 0x00;
for (i = 0; i < left_over_len; i++) {
buf[2+(i*3)] = I2C_DATA_REG;
buf[3+(i*3)] = msg->buf[(index*8)+i];
mxl_i2c("index = %d %d data %d",
index, i, msg->buf[(index*8)+i]);
buf[4+(i*3)] = 0x00;
}
ret = mxl111sf_i2c_send_data(state, 0, buf);
/* check for I2C NACK status */ if (mxl111sf_i2c_check_status(state) == 1) {
mxl_i2c("NACK writing slave address %02x",
msg->addr);
/* if NACK, stop I2C bus and exit */
buf[2] = I2C_CONTROL_REG;
buf[3] = 0x4E;
buf[4] = (HWI2C400) ? 0x03 : 0x0D;
ret = -EIO; gotoexit;
}
/* check for I2C NACK status */ if (mxl111sf_i2c_check_status(state) == 1) {
mxl_i2c("NACK reading slave address %02x",
msg->addr);
/* if NACK, stop I2C bus and exit */
buf[2] = I2C_CONTROL_REG;
buf[3] = 0xC7;
buf[4] = (HWI2C400) ? 0x03 : 0x0D;
ret = -EIO; gotoexit;
}
/* I2C interface can do I2C operations in block of 8 bytes of I2C data. calculation to figure out number of blocks of
i2c data required to program */
block_len = ((msg->len) / 8);
left_over_len = ((msg->len) % 8);
index = 0;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.