static void send_and_receive(void) { uint8_t cmd[3]; uint8_t resp[2]; cmd[0] = TMP105_REG_TEMPERATURE; i2c_send(i2c, addr, cmd, 1); i2c_recv(i2c, addr, resp, 2); g_assert_cmpuint(((uint16_t)resp[0] << 8) | resp[1], ==, 0); cmd[0] = TMP105_REG_CONFIG; cmd[1] = 0x0; /* matches the reset value */ i2c_send(i2c, addr, cmd, 2); i2c_recv(i2c, addr, resp, 1); g_assert_cmphex(resp[0], ==, cmd[1]); cmd[0] = TMP105_REG_T_LOW; cmd[1] = 0x12; cmd[2] = 0x34; i2c_send(i2c, addr, cmd, 3); i2c_recv(i2c, addr, resp, 2); g_assert_cmphex(resp[0], ==, cmd[1]); g_assert_cmphex(resp[1], ==, cmd[2]); cmd[0] = TMP105_REG_T_HIGH; cmd[1] = 0x42; cmd[2] = 0x31; i2c_send(i2c, addr, cmd, 3); i2c_recv(i2c, addr, resp, 2); g_assert_cmphex(resp[0], ==, cmd[1]); g_assert_cmphex(resp[1], ==, cmd[2]); }
uint16_t smbus_read_word(i2c_bus *bus, int addr, uint8_t command) { uint16_t data; i2c_start_transfer(bus, addr, 0); i2c_send(bus, command); i2c_start_transfer(bus, addr, 1); data = i2c_recv(bus); data |= i2c_recv(bus) << 8; i2c_nack(bus); i2c_end_transfer(bus); return data; }
int smbus_read_block(i2c_bus *bus, int addr, uint8_t command, uint8_t *data) { int len; int i; i2c_start_transfer(bus, addr, 0); i2c_send(bus, command); i2c_start_transfer(bus, addr, 1); len = i2c_recv(bus); if (len > 32) len = 0; for (i = 0; i < len; i++) data[i] = i2c_recv(bus); i2c_nack(bus); i2c_end_transfer(bus); return len; }
uint8_t smbus_receive_byte(i2c_bus *bus, int addr) { uint8_t data; i2c_start_transfer(bus, addr, 1); data = i2c_recv(bus); i2c_nack(bus); i2c_end_transfer(bus); return data; }
uint8_t smbus_read_byte(i2c_bus *bus, uint8_t addr, uint8_t command) { uint8_t data; i2c_start_transfer(bus, addr, 0); i2c_send(bus, command); i2c_start_transfer(bus, addr, 1); data = i2c_recv(bus); i2c_nack(bus); i2c_end_transfer(bus); return data; }
static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus) { uint8_t ret; aspeed_i2c_set_state(bus, I2CD_MRXD); ret = i2c_recv(bus->bus); bus->intr_status |= I2CD_INTR_RX_DONE; bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT; if (bus->cmd & I2CD_M_S_RX_CMD_LAST) { i2c_nack(bus->bus); } bus->cmd &= ~(I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST); aspeed_i2c_set_state(bus, I2CD_MACTIVE); }
char I2CSendReceive(char addr, char tx_count, char rx_count) { if (I2CSendStop(addr, tx_count, 0)) { /* If send fails, abort but don't send a stop condition if we lost arbitration */ if (i2cError != I2CERR_LOST) I2CStop(); return 1; } SDA_HIGH; /* One of these may be low now, in which case the next */ SCL_HIGH; /* start condition wouldn't be detected so make */ I2CDelay(I2CDELAY); /* sure that they're up and wait for one delay slot */ if (i2c_recv((char)(addr|0x01), rx_count)) return 1; return (i2cError ? 1 : 0); }
static int pca954x_recv(I2CSlave *i2c) { PCA954XState *s = PCA954X(i2c); int i; int ret = 0; if (s->control_decoded) { ret |= s->control_reg; DB_PRINT("returning control register: %x\n", ret); } else { for (i = 0; i < s->lanes; ++i) { if (s->active_lanes & (1 << i)) { ret |= i2c_recv(s->busses[i]); DB_PRINT("recieving from active bus %d:%x\n", i, ret); } } } return ret; }
int i2c_init_clk() { // We only need the I2C device for the clock setup, so just move it all here instead XIicPs i2c_dev; int rv = 0; XIicPs_Config* cfg = XIicPs_LookupConfig(I2C_DEV); if(cfg == NULL) { printf("Could not lookup config for device %d\r\n", I2C_DEV); return -1; } rv = XIicPs_CfgInitialize(&i2c_dev, cfg, cfg->BaseAddress); if(rv != XST_SUCCESS) { printf("Could not init I2C device\r\n"); return -1; } rv = XIicPs_SelfTest(&i2c_dev); if(rv != XST_SUCCESS) { printf("I2C Self-test failed\r\n"); return -1; } XIicPs_SetSClk(&i2c_dev, I2C_CLK); // Ok, try and read from the bus switch uint8_t val = 0; rv = i2c_recv(&i2c_dev, I2C_BUS_SWITCH, &val, 1); if(rv != XST_SUCCESS) { printf("i2c_recv failed with code %d\r\n", rv); return -1; } val = I2C_BUS_SWITCH_DIR_SI5324; rv = i2c_write_await(&i2c_dev, I2C_BUS_SWITCH, &val, 1); if(rv != XST_SUCCESS) { printf("i2c_send failed with code %d\r\n", rv); return -1; } rv = i2c_recv(&i2c_dev, I2C_BUS_SWITCH, &val, 1); if(rv != XST_SUCCESS) { printf("i2c_read failed with code %d\r\n", rv); return -1; } i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x0, 0x54); // FREE_RUN i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x1, 0xE4); // CK_PRIOR2,CK_PRIOR1 i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2, 0x12); // BWSEL was 32 i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x3, 0x15); // CKSEL_REG i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x4, 0x92); // AUTOSEL_REG i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0xa, 0x08); // DSBL2_REG i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0xb, 0x40); // PD_CK2 i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x19, 0xA0); // N1_HS i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x1f, 0x00); // NC1_LS[19:16] i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x20, 0x00); // NC1_LS[15:8] i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x21, 0x03); // NC1_LS[7:0] i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x28, 0xC2); // N2_HS, N2_LS[19:16] i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x29, 0x49); // N2_LS[15:8] i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2a, 0xEF); // N2_LS[7:0] i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2b, 0x00); // N31[18:16] i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2c, 0x77); // N31[15:8] i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2d, 0x0B); // N31[7:0] i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2e, 0x00); // N32[18:16] i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x2f, 0x77); // N32[15:8] i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x30, 0x0B); // N32[7:0] i2c_write_single_reg(&i2c_dev, I2C_SI5324, 0x88, 0x40); // RST_REG,ICAL return XST_SUCCESS; }
static void i2c_state_update(i2c_interface *i2c, int data, int clock) { if (!i2c) return; switch (i2c->state) { case STOPPED: if (data == 0 && i2c->last_data == 1 && clock == 1) i2c->state = INITIALIZING; break; case INITIALIZING: if (clock == 0 && i2c->last_clock == 1 && data == 0) i2c->state = SENDING_BIT7; else i2c_enter_stop(i2c); break; case SENDING_BIT7 ... SENDING_BIT0: if (clock == 0 && i2c->last_clock == 1) { i2c->buffer = (i2c->buffer << 1) | data; i2c->state++; /* will end up in WAITING_FOR_ACK */ } else if (data == 1 && i2c->last_data == 0 && clock == 1) i2c_enter_stop(i2c); break; case WAITING_FOR_ACK: if (clock == 0 && i2c->last_clock == 1) { if (i2c->current_addr < 0) { i2c->current_addr = i2c->buffer; i2c_start_transfer(i2c->bus, i2c->current_addr & 0xfe, i2c->buffer & 1); } else i2c_send(i2c->bus, i2c->buffer); if (i2c->current_addr & 1) { i2c->state = RECEIVING_BIT7; i2c->buffer = i2c_recv(i2c->bus); } else i2c->state = SENDING_BIT7; } else if (data == 1 && i2c->last_data == 0 && clock == 1) i2c_enter_stop(i2c); break; case RECEIVING_BIT7 ... RECEIVING_BIT0: if (clock == 0 && i2c->last_clock == 1) { i2c->state++; /* will end up in SENDING_ACK */ i2c->buffer <<= 1; } else if (data == 1 && i2c->last_data == 0 && clock == 1) i2c_enter_stop(i2c); break; case SENDING_ACK: if (clock == 0 && i2c->last_clock == 1) { i2c->state = RECEIVING_BIT7; if (data == 0) i2c->buffer = i2c_recv(i2c->bus); else i2c_nack(i2c->bus); } else if (data == 1 && i2c->last_data == 0 && clock == 1) i2c_enter_stop(i2c); break; } i2c->last_data = data; i2c->last_clock = clock; }
static uint64_t imx_i2c_read(void *opaque, hwaddr offset, unsigned size) { uint16_t value; IMXI2CState *s = IMX_I2C(opaque); switch (offset) { case IADR_ADDR: value = s->iadr; break; case IFDR_ADDR: value = s->ifdr; break; case I2CR_ADDR: value = s->i2cr; break; case I2SR_ADDR: value = s->i2sr; break; case I2DR_ADDR: value = s->i2dr_read; if (imx_i2c_is_master(s)) { int ret = 0xff; if (s->address == ADDR_RESET) { /* something is wrong as the address is not set */ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read " "without specifying the slave address\n", TYPE_IMX_I2C, __func__); } else if (s->i2cr & I2CR_MTX) { qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read " "but MTX is set\n", TYPE_IMX_I2C, __func__); } else { /* get the next byte */ ret = i2c_recv(s->bus); if (ret >= 0) { imx_i2c_raise_interrupt(s); } else { qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: read failed " "for device 0x%02x\n", TYPE_IMX_I2C, __func__, s->address); ret = 0xff; } } s->i2dr_read = ret; } else { qemu_log_mask(LOG_UNIMP, "[%s]%s: slave mode not implemented\n", TYPE_IMX_I2C, __func__); } break; default: qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%" HWADDR_PRIx "\n", TYPE_IMX_I2C, __func__, offset); value = 0; break; } DPRINTF("read %s [0x%" HWADDR_PRIx "] -> 0x%02x\n", imx_i2c_get_regname(offset), offset, value); return (uint64_t)value; }