/** * Initialize the TSB I2 controller */ static void tsb_i2c_init(void) { /* Disable the adapter */ tsb_i2c_disable(); /* Set timings for Standard and Fast Speed mode */ i2c_write(TSB_I2C_SS_SCL_HCNT, 28); i2c_write(TSB_I2C_SS_SCL_LCNT, 52); i2c_write(TSB_I2C_FS_SCL_HCNT, 47); i2c_write(TSB_I2C_FS_SCL_LCNT, 65); /* Configure Tx/Rx FIFO threshold levels */ i2c_write(TSB_I2C_TX_TL, TSB_I2C_TX_FIFO_DEPTH - 1); i2c_write(TSB_I2C_RX_TL, 0); /* configure the i2c master */ i2c_write(TSB_I2C_CON, TSB_I2C_CONFIG); }
static void tsb_i2c_start_transfer(void) { i2cvdbg("\n"); /* Disable the adapter */ tsb_i2c_disable(); /* write target address */ i2c_write(TSB_I2C_TAR, g_msgs[g_tx_index].addr); /* Disable the interrupts */ tsb_i2c_disable_int(); /* Enable the adapter */ tsb_i2c_enable(); /* Clear interrupts */ tsb_i2c_clear_int(); /* Enable interrupts */ i2c_write(TSB_I2C_INTR_MASK, TSB_I2C_INTR_DEFAULT_MASK); }
/** * Initialize the TSB I2 controller */ static void tsb_i2c_init(void) { /* Disable the adapter */ tsb_i2c_disable(); /* * Set timings for Standard and Fast Speed mode: * Values taken from ARA_ES2_GPBridge_AppendixA and tweaked for * 98.4 kHz in standard mode and 396.7 kHz in full speed mode */ i2c_write(TSB_I2C_SS_SCL_HCNT, 205); i2c_write(TSB_I2C_SS_SCL_LCNT, 270); i2c_write(TSB_I2C_FS_SCL_HCNT, 45); i2c_write(TSB_I2C_FS_SCL_LCNT, 63); /* Configure Tx/Rx FIFO threshold levels */ i2c_write(TSB_I2C_TX_TL, TSB_I2C_TX_FIFO_DEPTH - 1); i2c_write(TSB_I2C_RX_TL, 0); /* configure the i2c master */ i2c_write(TSB_I2C_CON, TSB_I2C_CONFIG); }
/* Perform a sequence of I2C transfers */ static int up_i2c_transfer(struct i2c_dev_s *idev, struct i2c_msg_s *msgs, int num) { int ret; i2cvdbg("msgs: %d\n", num); sem_wait(&g_mutex); g_msgs = msgs; g_msgs_count = num; g_tx_index = 0; g_rx_index = 0; g_rx_outstanding = 0; g_cmd_err = 0; g_msg_err = 0; g_status = TSB_I2C_STATUS_IDLE; g_abort_source = 0; ret = tsb_i2c_wait_bus_ready(); if (ret < 0) goto done; /* * start a watchdog to timeout the transfer if * the bus is locked up... */ wd_start(g_timeout, TSB_I2C_TIMEOUT, i2c_timeout, 1, 0); /* start the transfers */ tsb_i2c_start_transfer(); sem_wait(&g_wait); wd_cancel(g_timeout); if (g_status == TSB_I2C_STATUS_TIMEOUT) { i2cdbg("controller timed out\n"); /* Re-init the adapter */ tsb_i2c_init(); ret = -ETIMEDOUT; goto done; } tsb_i2c_disable(); if (g_msg_err) { ret = g_msg_err; i2cdbg("error msg_err %x\n", g_msg_err); goto done; } if (!g_cmd_err) { ret = 0; i2cvdbg("no error %d\n", num); goto done; } /* Handle abort errors */ if (g_cmd_err == TSB_I2C_ERR_TX_ABRT) { ret = tsb_i2c_handle_tx_abort(); goto done; } /* default error code */ ret = -EIO; i2cdbg("unknown error %x\n", ret); done: sem_post(&g_mutex); return ret; }