|
@@ -50,6 +50,9 @@
|
|
|
#define BCM2835_I2C_S_CLKT BIT(9)
|
|
|
#define BCM2835_I2C_S_LEN BIT(10) /* Fake bit for SW error reporting */
|
|
|
|
|
|
+#define BCM2835_I2C_FEDL_SHIFT 16
|
|
|
+#define BCM2835_I2C_REDL_SHIFT 0
|
|
|
+
|
|
|
#define BCM2835_I2C_CDIV_MIN 0x0002
|
|
|
#define BCM2835_I2C_CDIV_MAX 0xFFFE
|
|
|
|
|
@@ -81,7 +84,7 @@ static inline u32 bcm2835_i2c_readl(struct bcm2835_i2c_dev *i2c_dev, u32 reg)
|
|
|
|
|
|
static int bcm2835_i2c_set_divider(struct bcm2835_i2c_dev *i2c_dev)
|
|
|
{
|
|
|
- u32 divider;
|
|
|
+ u32 divider, redl, fedl;
|
|
|
|
|
|
divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk),
|
|
|
i2c_dev->bus_clk_rate);
|
|
@@ -100,6 +103,22 @@ static int bcm2835_i2c_set_divider(struct bcm2835_i2c_dev *i2c_dev)
|
|
|
|
|
|
bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider);
|
|
|
|
|
|
+ /*
|
|
|
+ * Number of core clocks to wait after falling edge before
|
|
|
+ * outputting the next data bit. Note that both FEDL and REDL
|
|
|
+ * can't be greater than CDIV/2.
|
|
|
+ */
|
|
|
+ fedl = max(divider / 16, 1u);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Number of core clocks to wait after rising edge before
|
|
|
+ * sampling the next incoming data bit.
|
|
|
+ */
|
|
|
+ redl = max(divider / 4, 1u);
|
|
|
+
|
|
|
+ bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DEL,
|
|
|
+ (fedl << BCM2835_I2C_FEDL_SHIFT) |
|
|
|
+ (redl << BCM2835_I2C_REDL_SHIFT));
|
|
|
return 0;
|
|
|
}
|
|
|
|