void i2c_write_read(i2c_package * package_write, i2c_package * package_read) { package_write->write_read = 1; package_read->write_read = 1; i2c_op(package_write); // I2C wirite operation first i2c_op(package_read); // just followed by I2C read operation return; }
static int sh_mobile_i2c_isr_tx(struct sh_mobile_i2c_data *pd) { unsigned char data; if (pd->pos == pd->msg->len) { i2c_op(pd, OP_TX_STOP, 0); return 1; } sh_mobile_i2c_get_data(pd, &data); i2c_op(pd, sh_mobile_i2c_is_first_byte(pd) ? OP_TX_FIRST : OP_TX, data); pd->pos++; return 0; }
static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) { struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter); struct i2c_msg *msg; int err = 0; int i; long timeout; /* Wake up device and enable clock */ pm_runtime_get_sync(pd->dev); /* Process all messages */ for (i = 0; i < num; i++) { bool do_start = pd->send_stop || !i; msg = &msgs[i]; pd->send_stop = i == num - 1 || msg->flags & I2C_M_STOP; pd->stop_after_dma = false; start_ch(pd, msg, do_start); if (do_start) i2c_op(pd, OP_START, 0); /* The interrupt handler takes care of the rest... */ timeout = wait_event_timeout(pd->wait, pd->sr & (ICSR_TACK | SW_DONE), adapter->timeout); /* 'stop_after_dma' tells if DMA transfer was complete */ i2c_put_dma_safe_msg_buf(pd->dma_buf, pd->msg, pd->stop_after_dma); if (!timeout) { dev_err(pd->dev, "Transfer request timed out\n"); if (pd->dma_direction != DMA_NONE) sh_mobile_i2c_cleanup_dma(pd); err = -ETIMEDOUT; break; } if (pd->send_stop) err = poll_busy(pd); else err = poll_dte(pd); if (err < 0) break; } /* Disable channel */ iic_wr(pd, ICCR, ICCR_SCP); /* Disable clock and mark device as idle */ pm_runtime_put_sync(pd->dev); return err ?: num; }
static int sh_mobile_i2c_isr_tx(struct sh_mobile_i2c_data *pd) { unsigned char data; if (pd->pos == pd->msg->len) return 1; sh_mobile_i2c_get_data(pd, &data); if (sh_mobile_i2c_is_last_byte(pd)) i2c_op(pd, OP_TX_STOP, data); else if (sh_mobile_i2c_is_first_byte(pd)) i2c_op(pd, OP_TX_FIRST, data); else i2c_op(pd, OP_TX, data); pd->pos++; return 0; }
void motor_i2c_set_pwm(uint8_t mot_i2c_dev_addr, uint8_t pwm) { i2c_package package; package.data[0] = pwm; // PWM value to be set package.length = 1; // 1 bytes for PWM setting package.direction = I2C_WRITE; // I2C write operation package.slave_address = mot_i2c_dev_addr; // I2C slave address of selected motor controller package.bus_number = MOT_I2C_BUS_NUMBER; // number of the I2C bus, that the motor controller is connected to package.write_read = 0; // no repeated start condition package.i2c_done_handler = NULL; // nothing to be done at I2C completion i2c_op(&package); }
static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) { struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter); struct i2c_msg *msg; int err = 0; int i, k; activate_ch(pd); /* Process all messages */ for (i = 0; i < num; i++) { bool do_start = pd->send_stop || !i; msg = &msgs[i]; pd->send_stop = i == num - 1 || msg->flags & I2C_M_STOP; err = start_ch(pd, msg, do_start); if (err) break; if (do_start) i2c_op(pd, OP_START, 0); /* The interrupt handler takes care of the rest... */ k = wait_event_timeout(pd->wait, pd->sr & (ICSR_TACK | SW_DONE), 5 * HZ); if (!k) { dev_err(pd->dev, "Transfer request timed out\n"); err = -ETIMEDOUT; break; } if (pd->send_stop) err = poll_busy(pd); else err = poll_dte(pd); if (err < 0) break; } deactivate_ch(pd); if (!err) err = num; return err; }
static int sh_mobile_i2c_isr_rx(struct sh_mobile_i2c_data *pd) { unsigned char data; int real_pos; do { if (pd->pos <= -1) { sh_mobile_i2c_get_data(pd, &data); if (sh_mobile_i2c_is_first_byte(pd)) i2c_op(pd, OP_TX_FIRST, data); else i2c_op(pd, OP_TX, data); break; } if (pd->pos == 0) { i2c_op(pd, OP_TX_TO_RX, 0); break; } real_pos = pd->pos - 2; if (pd->pos == pd->msg->len) { if (pd->stop_after_dma) { /* Simulate PIO end condition after DMA transfer */ i2c_op(pd, OP_RX_STOP, 0); pd->pos++; break; } if (real_pos < 0) { i2c_op(pd, OP_RX_STOP, 0); break; } data = i2c_op(pd, OP_RX_STOP_DATA, 0); } else if (real_pos >= 0) { data = i2c_op(pd, OP_RX, 0); } if (real_pos >= 0) pd->msg->buf[real_pos] = data; } while (0); pd->pos++; return pd->pos == (pd->msg->len + 2); }
static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) { struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter); struct i2c_msg *msg; int err = 0; u_int8_t val; int i, k, retry_count; activate_ch(pd); /* Process all messages */ for (i = 0; i < num; i++) { msg = &msgs[i]; err = start_ch(pd, msg); if (err) break; i2c_op(pd, OP_START, 0); /* The interrupt handler takes care of the rest... */ k = wait_event_timeout(pd->wait, pd->sr & (ICSR_TACK | SW_DONE), 5 * HZ); if (!k) dev_err(pd->dev, "Transfer request timed out\n"); retry_count = 1000; again: val = iic_rd(pd, ICSR); dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr); /* the interrupt handler may wake us up before the * transfer is finished, so poll the hardware * until we're done. */ if (val & ICSR_BUSY) { udelay(10); if (retry_count--) goto again; err = -EIO; dev_err(pd->dev, "Polling timed out\n"); break; } /* handle missing acknowledge and arbitration lost */ if ((val | pd->sr) & (ICSR_TACK | ICSR_AL)) { err = -EIO; break; } } deactivate_ch(pd); if (!err) err = num; return err; }