mirror of
				https://github.com/Ysurac/openmptcprouter.git
				synced 2025-03-09 15:40:20 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			47 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			47 lines
		
	
	
	
		
			1.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From fd423e36e23c3c5d85f2af457ac92368c3416967 Mon Sep 17 00:00:00 2001
 | 
						|
From: Phil Elwell <phil@raspberrypi.org>
 | 
						|
Date: Fri, 12 Jul 2019 15:38:35 +0100
 | 
						|
Subject: [PATCH] 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: https://github.com/raspberrypi/linux/issues/3064
 | 
						|
 | 
						|
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
 | 
						|
---
 | 
						|
 drivers/i2c/busses/i2c-bcm2835.c | 12 ++++++++++++
 | 
						|
 1 file changed, 12 insertions(+)
 | 
						|
 | 
						|
--- a/drivers/i2c/busses/i2c-bcm2835.c
 | 
						|
+++ b/drivers/i2c/busses/i2c-bcm2835.c
 | 
						|
@@ -193,6 +193,7 @@ static int clk_bcm2835_i2c_set_rate(stru
 | 
						|
 {
 | 
						|
 	struct clk_bcm2835_i2c *div = to_clk_bcm2835_i2c(hw);
 | 
						|
 	u32 redl, fedl;
 | 
						|
+	u32 clk_tout;
 | 
						|
 	u32 divider = clk_bcm2835_i2c_calc_divider(rate, parent_rate);
 | 
						|
 
 | 
						|
 	if (divider == -EINVAL)
 | 
						|
@@ -216,6 +217,17 @@ static int clk_bcm2835_i2c_set_rate(stru
 | 
						|
 	bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_DEL,
 | 
						|
 			   (fedl << BCM2835_I2C_FEDL_SHIFT) |
 | 
						|
 			   (redl << BCM2835_I2C_REDL_SHIFT));
 | 
						|
+
 | 
						|
+	/*
 | 
						|
+	 * Set the clock stretch timeout to the SMBUs-recommended 35ms.
 | 
						|
+	 */
 | 
						|
+	if (rate > 0xffff*1000/35)
 | 
						|
+	    clk_tout = 0xffff;
 | 
						|
+	else
 | 
						|
+	    clk_tout = 35*rate/1000;
 | 
						|
+
 | 
						|
+	bcm2835_i2c_writel(div->i2c_dev, BCM2835_I2C_CLKT, clk_tout);
 | 
						|
+
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
 
 |