Skip to content

Commit b9af312

Browse files
Phil Elwellpopcornmix
Phil Elwell
authored andcommitted
i2c: bcm2835: Set clock-stretch timeout to 35ms
The BCM2835 I2C blocks have a register to set the clock-stretch timeout - how long the device is allowed to hold SCL low - in bus cycles. The current driver doesn't write to the register, therefore the default value of 64 cycles is being used for all devices. Set the timeout to the value recommended for SMBus - 35ms. See: #3064 Signed-off-by: Phil Elwell <[email protected]> i2c: bcm2835: Make clock-stretch timeout configurable The default clock-stretch timeout is 35 mS, which works well for SMBus, but there are some I2C devices which can stretch the clock even longer. Rather than trying to prescribe a safe default for everyone, allow the timeout to be configured. Signed-off-by: Alex Crawford <raspberrypi/[email protected]> i2c-bcm2835: Flush FIFOs cleanly on error On error condition, note the error return code, but still handle the FIFOs in the normal way rather than relying on C_CLEAR flushing everything cleanly. Signed-off-by: Dave Stevenson <[email protected]> i2c-bcm2835: Do not abort transfers on ERR if still active If a transaction is aborted immediately on ERR being reported, then the bus is not returned to the STOP condition, and devices generally get very upset. Handle the ERR and CLKT conditions only when TA is not set. Signed-off-by: Dave Stevenson <[email protected]> i2c-bcm2835: Implement I2C_M_IGNORE_NAK Now that transfers aren't aborted immediately (and uncleanly) on errors, and the FIFOs are always drained after all transfers, we can implement I2C_M_IGNORE_NAK by ignoring the returned error value. Signed-off-by: Dave Stevenson <[email protected]>
1 parent 0ca3571 commit b9af312

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

drivers/i2c/busses/i2c-bcm2835.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ static unsigned int debug;
6060
module_param(debug, uint, 0644);
6161
MODULE_PARM_DESC(debug, "1=err, 2=isr, 3=xfer");
6262

63+
static unsigned int clk_tout_ms = 35; /* SMBUs-recommended 35ms */
64+
module_param(clk_tout_ms, uint, 0644);
65+
MODULE_PARM_DESC(clk_tout_ms, "clock-stretch timeout (mS)");
66+
6367
#define BCM2835_DEBUG_MAX 512
6468
struct bcm2835_debug {
6569
struct i2c_msg *msg;
@@ -193,6 +197,7 @@ static int clk_bcm2835_i2c_set_rate(struct clk_hw *hw, unsigned long rate,
193197
{
194198
struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw);
195199
u32 redl, fedl;
200+
u32 clk_tout;
196201
u32 divider = clk_bcm2835_i2c_calc_divider(rate, parent_rate);
197202

198203
if (divider == -EINVAL)
@@ -216,6 +221,17 @@ static int clk_bcm2835_i2c_set_rate(struct clk_hw *hw, unsigned long rate,
216221
bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DEL,
217222
(fedl << BCM2835_I2C_FEDL_SHIFT) |
218223
(redl << BCM2835_I2C_REDL_SHIFT));
224+
225+
/*
226+
* Set the clock stretch timeout.
227+
*/
228+
if (rate > 0xffff*1000/clk_tout_ms)
229+
clk_tout = 0xffff;
230+
else
231+
clk_tout = clk_tout_ms*rate/1000;
232+
233+
bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_CLKT, clk_tout);
234+
219235
return 0;
220236
}
221237

@@ -369,10 +385,8 @@ static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data)
369385
bcm2835_debug_add(i2c_dev, val);
370386

371387
err = val & (BCM2835_I2C_S_CLKT | BCM2835_I2C_S_ERR);
372-
if (err) {
388+
if (err && !(val & BCM2835_I2C_S_TA))
373389
i2c_dev->msg_err = err;
374-
goto complete;
375-
}
376390

377391
if (val & BCM2835_I2C_S_DONE) {
378392
if (!i2c_dev->curr_msg) {
@@ -384,8 +398,6 @@ static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data)
384398

385399
if ((val & BCM2835_I2C_S_RXD) || i2c_dev->msg_buf_remaining)
386400
i2c_dev->msg_err = BCM2835_I2C_S_LEN;
387-
else
388-
i2c_dev->msg_err = 0;
389401
goto complete;
390402
}
391403

@@ -431,6 +443,7 @@ static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
431443
{
432444
struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
433445
unsigned long time_left;
446+
bool ignore_nak = false;
434447
int i;
435448

436449
if (debug)
@@ -440,15 +453,19 @@ static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
440453
for (i = 0; i < num; i++)
441454
bcm2835_debug_print_msg(i2c_dev, &msgs[i], i + 1, num, __func__);
442455

443-
for (i = 0; i < (num - 1); i++)
456+
for (i = 0; i < (num - 1); i++) {
444457
if (msgs[i].flags & I2C_M_RD) {
445458
dev_warn_once(i2c_dev->dev,
446459
"only one read message supported, has to be last\n");
447460
return -EOPNOTSUPP;
448461
}
462+
if (msgs[i].flags & I2C_M_IGNORE_NAK)
463+
ignore_nak = true;
464+
}
449465

450466
i2c_dev->curr_msg = msgs;
451467
i2c_dev->num_msgs = num;
468+
i2c_dev->msg_err = 0;
452469
reinit_completion(&i2c_dev->completion);
453470

454471
bcm2835_i2c_start_transfer(i2c_dev);
@@ -458,6 +475,9 @@ static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
458475

459476
bcm2835_i2c_finish_transfer(i2c_dev);
460477

478+
if (ignore_nak)
479+
i2c_dev->msg_err &= ~BCM2835_I2C_S_ERR;
480+
461481
if (debug > 1 || (debug && (!time_left || i2c_dev->msg_err)))
462482
bcm2835_debug_print(i2c_dev);
463483
i2c_dev->debug_num_msgs = 0;
@@ -483,7 +503,7 @@ static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
483503

484504
static u32 bcm2835_i2c_func(struct i2c_adapter *adap)
485505
{
486-
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
506+
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
487507
}
488508

489509
static const struct i2c_algorithm bcm2835_i2c_algo = {

0 commit comments

Comments
 (0)