- 09 12月, 2009 17 次提交
-
-
由 Shinya Kuribayashi 提交于
Currently we process the first i2c_dw_xfer_msg() in i2c_dw_xfer(), but in this case there is a possibility to be interrupted by certain interrupts. As described before in this patchset, we need to keep providing new transmit data within a given time period, otherwise Tx FIFO underrun takes place and STOP condition will be generated on the bus, even if we have more bytes to be written. In order to exclude all such possibilities, change TX_EMPTY interrupt usage as below: * DW_IC_INTR_DEFAULT_MASK: Define a default interrupt mask set, and put TX_EMPTY there. * i2c_dw_xfer_init: Enable DW_IC_INTR_DEFAULT_MASK prior to initiating a new I2C transaction. The first TX_EMPTY will be triggered shortly. With the help of it, we can make the first call to i2c_dw_xfer_msg() in the interrupt handler. * i2c_dw_xfer_msg: Fixup intr_mask operation accordingly. Make sure that TX_EMPTY operations need to be reversed. * request_irq: Set IRQF_DISABLED so that we could load transmit data into Tx FIFO without being distracted by other interrupts. * Remove i2c_dw_xfer_msg() in i2c_dw_xfer(). Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
I2c_dw_xfer_msg() also has the same target address inconsistency check, and furthermore it checks across all i2c_msg messages, while i2c_dw_read() walks through i2c_msg messages only with_ I2C_M_RD flag. That is, target address check in i2c_dw_read() is redundant and useless. Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
Set proper I2C_FUNC_SMBUS_* bits so that the driver could be used with some utilities requiring SMBus functionalities, such as i2c-tools. Note that DW I2C core doesn't support I2C_FUNC_SMBUS_QUICK, as it's not capable of zero-length data transactions. Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
As the driver and hardware always process the given data in parallel, then it would be better to initialize tx_limit, rx_limit and rx_valid variables just prior to being used. This will help us to send / receive as much data as possible. Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Acked-by: NBaruch Siach <baruch@tkos.co.il> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
While we have a local variable "buf_len" for dev->tx_buf_len, we don't have such local variable for dev->tx_buf pointer. While "buf_len" is restored at first then updated when we start processing a new i2c_msg (determined by STATUS_WRITE_IN_PROGRESS flag), ->tx_buf is different. Such inconsistency makes the code slightly hard to follow. Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Acked-by: NBaruch Siach <baruch@tkos.co.il> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
We have some steps at the top of i2c_dw_xfer_msg() to set up a slave address and enable DW I2C core. And it's executed only when we don't have STATUS_WRITE_IN_PROGRESS. But we need to make sure that STATUS_WRITE_IN_PROGRESS only indicates that we have a pending i2c_msg to process. In other words, even if STATUS_WRITE_IN_PROGRESS is not set, that doesn't mean we're at initial state in the I2C transaction. Since i2c_dw_xfer_msg() will be invoked again and again during a transaction, those init steps have a possibility to be re-processed needlessly. For example, this issue easily takes place when processing a combined transaction with a certain condition (the number of tx bytes in the first i2c_msg, equals to the Tx FIFO depth). Consequently we should not use STATUS_WRITE_IN_PROGRESS to determine where we're at in an I2C transaction. It would be better to separate those initialization steps from i2c_dw_xfer_msg(). Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Acked-by: NBaruch Siach <baruch@tkos.co.il> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
Enable RX_FULL interrupt mask by default, and hook it in the interrupt handler. If requested amount of rx data (defined by IC_RX_TL) is not available, we don't have to process i2c_dw_read(). Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Acked-by: NBaruch Siach <baruch@tkos.co.il> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
As a hardware feature, DW I2C core generates a STOP condition whenever the Tx FIFO becomes empty (strictly speaking, whenever the last byte in the Tx FIFO is sent out), even if we have more bytes to be written. In other words, we must never make "Tx FIFO underrun" happen during a transaction, except for the last byte. For the safety's sake, we'd make TX_EMPTY interrupt get triggered every time one byte is processed. The Rx FIFO threshold needs to be set as well. Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Acked-by: NBaruch Siach <baruch@tkos.co.il> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
Symptom: -------- When we're going to send/receive the longer size of data than the Tx FIFO length, the I2C transaction will be divided into several separated transactions, limited by the Tx FIFO length. Details: -------- As a hardware feature, DW I2C core generates a STOP condition whenever the Tx FIFO becomes empty (strictly speaking, whenever the last byte in the Tx FIFO is sent out), even if we have more bytes to be written. Then, once a new transmit data is written to the Tx FIFO, DW I2C core will initiate a new transaction, which leads to another START condition. This explains how the transaction in question goes, and implies that current tasklet-based dw_i2c_pump_msg() strategy couldn't meet the timing constraint required for avoiding Tx FIFO underrun. To avoid this scenario, we must keep providing new transmit data within a given time period. In case of Fast-mode + 32-byte Tx FIFO, for instance, it takes about 22.5[us] to process single byte, and 720[us] in total. This patch removes the existing tasklet-based "pump" system, and move its jobs into the interrupt handler. Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Acked-by: NBaruch Siach <baruch@tkos.co.il> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
In case a work-in-progress i2c_msg has more bytes to be written, we need to set STATUS_WRITE_IN_PROGRESS and exit from the msg_write_idx- searching loop. Otherwise, we will overtake the current msg_write_idx without waiting for its transmission to be processed. Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
* Calculate with accurate conditional expressions from DW manuals. * Round ic_clk by adding 0.5 as it's important at high ic_clk rate. * Take into account "tHD;STA" issue for _HCNT calculation. * Take into account "tf" for _LCNT calculation. * Add "cond" and "offset" fot further correction requirements. For _HCNT calculation, there's one issue needs to be carefully considered; DesignWare I2C core doesn't seem to have solid strategy to meet the tHD;STA timing spec. If you configure _HCNT based on the tHIGH timing spec, it easily results in violation of the tHD;STA spec. After many trials, we came to the conclusion that the tHD;STA period is proportional to (_HCNT + 3). For the safety's sake, this should be selected by default. As for _LCNT calculation, DW I2C core has one characteristic behavior; he starts counting the SCL CNTs for the LOW period of the SCL clock (tLOW) as soon as it pulls the SCL line. At that time, he doesn't take into account the fall time of SCL signal (tf), IOW, he starts counting CNTs without confirming the SCL input voltage has dropped to below VIL. This characteristics becomes a problem on some platforms where tf is considerably long, and results in violation of the tLOW timing spec. To make the driver configurable as much as possible for various cases, we'd have separated arguments "tf" and "offset", and for safety default values should be 0.3 us and 0, respectively. Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Acked-by: NBaruch Siach <baruch@tkos.co.il> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
We couldn't know the original intent for this variable, but at this point it's useless. Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Acked-by: NBaruch Siach <baruch@tkos.co.il> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
We don't have to use "struct i2c_adapter" pointer here. Let's use a local "struct dw_i2c_dev" pointer, instead. Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Acked-by: NBaruch Siach <baruch@tkos.co.il> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
We don't have to use "struct i2c_adapter" pointer here. Let's use a local "struct dw_i2c_dev" pointer, instead. Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Acked-by: NBaruch Siach <baruch@tkos.co.il> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Acked-by: NBaruch Siach <baruch@tkos.co.il> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
We're strongly discouraged from using the IC_CLR_INTR register because it clears all software-clearable interrupts asserted at the moment. stat = readl(IC_INTR_STAT); : : <=== Interrupts asserted during this period will be lost : readl(IC_CLR_INTR); Instead, use the separately-prepared IC_CLR_* registers. At the same time, this patch adds all remaining interrupt definitions available in the DesignWare I2C hardware. Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
由 Shinya Kuribayashi 提交于
This driver looks originally meant for armel machines where readw()/ writew() works perfectly fine with this hardware. But that doens't work for big-endian systems. This patch converts all 8/16-bit-aware usages to 32-bit variants. Signed-off-by: NShinya Kuribayashi <shinya.kuribayashi@necel.com> Acked-by: NBaruch Siach <baruch@tkos.co.il> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-
- 24 6月, 2009 1 次提交
-
-
由 Baruch Siach 提交于
The i2c Linux driver for the DesignWare i2c block of Synopsys, which is meant for AMBA Peripheral Bus. This i2c block is used on SoC chips like the ARM9 based PVG610. Signed-off-by: NBaruch Siach <baruch@tkos.co.il> Signed-off-by: NBen Dooks <ben-linux@fluff.org>
-