/** * struct st_i2c_timings - per-Mode tuning parameters * @rate: I2C bus rate * @rep_start_hold: I2C repeated start hold time requirement * @rep_start_setup: I2C repeated start set up time requirement * @start_hold: I2C start hold time requirement * @data_setup_time: I2C data set up time requirement * @stop_setup_time: I2C stop set up time requirement * @bus_free_time: I2C bus free time requirement * @sda_pulse_min_limit: I2C SDA pulse mini width limit
*/ struct st_i2c_timings {
u32 rate;
u32 rep_start_hold;
u32 rep_start_setup;
u32 start_hold;
u32 data_setup_time;
u32 stop_setup_time;
u32 bus_free_time;
u32 sda_pulse_min_limit;
};
/** * struct st_i2c_client - client specific data * @addr: 8-bit target addr, including r/w bit * @count: number of bytes to be transfered * @xfered: number of bytes already transferred * @buf: data buffer * @result: result of the transfer * @stop: last I2C msg to be sent, i.e. STOP to be generated
*/ struct st_i2c_client {
u8 addr;
u32 count;
u32 xfered;
u8 *buf; int result; bool stop;
};
/** * struct st_i2c_dev - private data of the controller * @adap: I2C adapter for this controller * @dev: device for this controller * @base: virtual memory area * @complete: completion of I2C message * @irq: interrupt line for th controller * @clk: hw ssc block clock * @mode: I2C mode of the controller. Standard or Fast only supported * @scl_min_width_us: SCL line minimum pulse width in us * @sda_min_width_us: SDA line minimum pulse width in us * @client: I2C transfert information * @busy: I2C transfer on-going
*/ struct st_i2c_dev { struct i2c_adapter adap; struct device *dev; void __iomem *base; struct completion complete; int irq; struct clk *clk; int mode;
u32 scl_min_width_us;
u32 sda_min_width_us; struct st_i2c_client client; bool busy;
};
/* * From I2C Specifications v0.5. * * All the values below have +10% margin added to be * compatible with some out-of-spec devices, * like HDMI link of the Toshiba 19AV600 TV.
*/ staticstruct st_i2c_timings i2c_timings[] = {
[I2C_MODE_STANDARD] = {
.rate = I2C_MAX_STANDARD_MODE_FREQ,
.rep_start_hold = 4400,
.rep_start_setup = 5170,
.start_hold = 4400,
.data_setup_time = 275,
.stop_setup_time = 4400,
.bus_free_time = 5170,
},
[I2C_MODE_FAST] = {
.rate = I2C_MAX_FAST_MODE_FREQ,
.rep_start_hold = 660,
.rep_start_setup = 660,
.start_hold = 660,
.data_setup_time = 110,
.stop_setup_time = 660,
.bus_free_time = 1430,
},
};
staticvoid st_i2c_flush_rx_fifo(struct st_i2c_dev *i2c_dev)
{ int count, i;
/* * Counter only counts up to 7 but fifo size is 8... * When fifo is full, counter is 0 and RIR bit of status register is * set
*/ if (readl_relaxed(i2c_dev->base + SSC_STA) & SSC_STA_RIR)
count = SSC_RXFIFO_SIZE; else
count = readl_relaxed(i2c_dev->base + SSC_RX_FSTAT) &
SSC_RX_FSTAT_STATUS;
for (i = 0; i < count; i++)
readl_relaxed(i2c_dev->base + SSC_RBUF);
}
staticvoid st_i2c_soft_reset(struct st_i2c_dev *i2c_dev)
{ /* * FIFO needs to be emptied before reseting the IP, * else the controller raises a BUSY error.
*/
st_i2c_flush_rx_fifo(i2c_dev);
/* * SSP IP is dual role SPI/I2C to generate 9 clock pulses * we switch to SPI node, 9 bit words and write a 0. This * has been validate with a oscilloscope and is easier * than switching to GPIO mode.
*/
staticint st_i2c_wait_free_bus(struct st_i2c_dev *i2c_dev)
{
u32 sta; int i, ret;
for (i = 0; i < 10; i++) {
sta = readl_relaxed(i2c_dev->base + SSC_STA); if (!(sta & SSC_STA_BUSY)) return 0;
usleep_range(2000, 4000);
}
dev_err(i2c_dev->dev, "bus not free (status = 0x%08x)\n", sta);
ret = i2c_recover_bus(&i2c_dev->adap); if (ret) {
dev_err(i2c_dev->dev, "Failed to recover the bus (%d)\n", ret); return ret;
}
return -EBUSY;
}
/** * st_i2c_write_tx_fifo() - Write a byte in the Tx FIFO * @i2c_dev: Controller's private data * @byte: Data to write in the Tx FIFO
*/ staticinlinevoid st_i2c_write_tx_fifo(struct st_i2c_dev *i2c_dev, u8 byte)
{
u16 tbuf = byte << 1;
/** * st_i2c_wr_fill_tx_fifo() - Fill the Tx FIFO in write mode * @i2c_dev: Controller's private data * * This functions fills the Tx FIFO with I2C transfert buffer when * in write mode.
*/ staticvoid st_i2c_wr_fill_tx_fifo(struct st_i2c_dev *i2c_dev)
{ struct st_i2c_client *c = &i2c_dev->client;
u32 tx_fstat, sta; int i;
sta = readl_relaxed(i2c_dev->base + SSC_STA); if (sta & SSC_STA_TX_FIFO_FULL) return;
for (i = min(c->count, SSC_TXFIFO_SIZE - tx_fstat);
i > 0; i--, c->count--, c->buf++)
st_i2c_write_tx_fifo(i2c_dev, *c->buf);
}
/** * st_i2c_rd_fill_tx_fifo() - Fill the Tx FIFO in read mode * @i2c_dev: Controller's private data * @max: Maximum amount of data to fill into the Tx FIFO * * This functions fills the Tx FIFO with fixed pattern when * in read mode to trigger clock.
*/ staticvoid st_i2c_rd_fill_tx_fifo(struct st_i2c_dev *i2c_dev, u32 max)
{ struct st_i2c_client *c = &i2c_dev->client;
u32 tx_fstat, sta; int i;
sta = readl_relaxed(i2c_dev->base + SSC_STA); if (sta & SSC_STA_TX_FIFO_FULL) return;
sta = readl_relaxed(i2c_dev->base + SSC_STA); if (sta & SSC_STA_RIR) {
i = SSC_RXFIFO_SIZE;
} else {
i = readl_relaxed(i2c_dev->base + SSC_RX_FSTAT);
i &= SSC_RX_FSTAT_STATUS;
}
ien = readl_relaxed(i2c_dev->base + SSC_IEN);
sta = readl_relaxed(i2c_dev->base + SSC_STA);
/* Use __fls() to check error bits first */
it = __fls(sta & ien); if (it < 0) {
dev_dbg(i2c_dev->dev, "spurious it (sta=0x%04x, ien=0x%04x)\n",
sta, ien); return IRQ_NONE;
}
switch (1 << it) { case SSC_STA_TE: if (c->addr & I2C_M_RD)
st_i2c_handle_read(i2c_dev); else
st_i2c_handle_write(i2c_dev); break;
case SSC_STA_STOP: case SSC_STA_REPSTRT:
writel_relaxed(0, i2c_dev->base + SSC_IEN);
complete(&i2c_dev->complete); break;
case SSC_STA_NACK:
writel_relaxed(SSC_CLR_NACK, i2c_dev->base + SSC_CLR);
/* Last received byte handled by NACK interrupt */ if ((c->addr & I2C_M_RD) && (c->count == 1) && (c->xfered)) {
st_i2c_handle_read(i2c_dev); break;
}
it = SSC_IEN_STOPEN | SSC_IEN_ARBLEN;
writel_relaxed(it, i2c_dev->base + SSC_IEN);
/* * Read IEN register to ensure interrupt mask write is effective * before re-enabling interrupt at GIC level, and thus avoid spurious * interrupts.
*/
readl(i2c_dev->base + SSC_IEN);
return IRQ_HANDLED;
}
/** * st_i2c_xfer_msg() - Transfer a single I2C message * @i2c_dev: Controller's private data * @msg: I2C message to transfer * @is_first: first message of the sequence * @is_last: last message of the sequence
*/ staticint st_i2c_xfer_msg(struct st_i2c_dev *i2c_dev, struct i2c_msg *msg, bool is_first, bool is_last)
{ struct st_i2c_client *c = &i2c_dev->client;
u32 ctl, i2c, it; unsignedlong time_left; int ret;
/** * st_i2c_xfer() - Transfer a single I2C message * @i2c_adap: Adapter pointer to the controller * @msgs: Pointer to data to be written. * @num: Number of messages to be executed
*/ staticint st_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
{ struct st_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap); int ret, i;
i2c_dev->busy = true;
ret = clk_prepare_enable(i2c_dev->clk); if (ret) {
dev_err(i2c_dev->dev, "Failed to prepare_enable clock\n"); return ret;
}
pinctrl_pm_select_default_state(i2c_dev->dev);
st_i2c_hw_config(i2c_dev);
for (i = 0; (i < num) && !ret; i++)
ret = st_i2c_xfer_msg(i2c_dev, &msgs[i], i == 0, i == num - 1);
staticint st_i2c_resume(struct device *dev)
{
pinctrl_pm_select_default_state(dev); /* Go in idle state if available */
pinctrl_pm_select_idle_state(dev);
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.