static void i2c_init_controller(struct i2c_bus *i2c_bus, u32 clock_khz) { /* TODO: Fix bug which makes us need to do this */ clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_OSC, clock_khz * 1000 * (8 * 2 - 1)); /* Reset I2C controller. */ i2c_reset_controller(i2c_bus); /* Configure I2C controller. */ if (i2c_bus->use_dvc_ctlr) { /* only for DVC I2C CONTROLLER */ struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs; bf_writel(DVC_CTRL_REG3_I2C_HW_SW_PROG, 1, &dvc->ctrl3); } #if defined(CONFIG_TEGRA2) i2c_pin_mux_select(i2c_bus, i2c_bus->pinmux_config); i2c_pin_mux_tristate(i2c_bus, i2c_bus->pinmux_config, 0); #endif }
static void i2c_init_controller(struct i2c_bus *i2c_bus) { /* * Use PLLP - DP-04508-001_v06 datasheet indicates a divisor of 8 * here, in section 23.3.1, but in fact we seem to need a factor of * 16 to get the right frequency. */ clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH, i2c_bus->speed * 2 * 8); /* Reset I2C controller. */ i2c_reset_controller(i2c_bus); /* Configure I2C controller. */ if (i2c_bus->is_dvc) { /* only for DVC I2C */ struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs; setbits_le32(&dvc->ctrl3, DVC_CTRL_REG3_I2C_HW_SW_PROG_MASK); } funcmux_select(i2c_bus->periph_id, i2c_bus->pinmux_config); }
static int send_recv_packets( struct i2c_bus *i2c_bus, struct i2c_trans_info *trans) { struct i2c_control *control = i2c_bus->control; u32 int_status; u32 words; u8 *dptr; u32 local; uchar last_bytes; int error = 0; int is_write = trans->flags & I2C_IS_WRITE; /* clear status from previous transaction, XFER_COMPLETE, NOACK, etc. */ int_status = readl(&control->int_status); writel(int_status, &control->int_status); send_packet_headers(i2c_bus, trans, 1); words = BYTES_TO_WORDS(trans->num_bytes); last_bytes = trans->num_bytes & 3; dptr = trans->buf; while (words) { if (is_write) { /* deal with word alignment */ if ((unsigned)dptr & 3) { memcpy(&local, dptr, sizeof(u32)); writel(local, &control->tx_fifo); debug("pkt data sent (0x%x)\n", local); } else { writel(*(u32 *)dptr, &control->tx_fifo); debug("pkt data sent (0x%x)\n", *(u32 *)dptr); } if (!wait_for_tx_fifo_empty(control)) { error = -1; goto exit; } } else { if (!wait_for_rx_fifo_notempty(control)) { error = -1; goto exit; } /* * for the last word, we read into our local buffer, * in case that caller did not provide enough buffer. */ local = readl(&control->rx_fifo); if ((words == 1) && last_bytes) memcpy(dptr, (char *)&local, last_bytes); else if ((unsigned)dptr & 3) memcpy(dptr, &local, sizeof(u32)); else *(u32 *)dptr = local; debug("pkt data received (0x%x)\n", local); } words--; dptr += sizeof(u32); } if (wait_for_transfer_complete(control)) { error = -1; goto exit; } return 0; exit: /* error, reset the controller. */ i2c_reset_controller(i2c_bus); return error; }