10
10
* Rewritten for mainline by Binbin Zhou <[email protected] >
11
11
*/
12
12
13
+ #include <linux/bitfield.h>
13
14
#include <linux/bits.h>
14
15
#include <linux/completion.h>
15
16
#include <linux/device.h>
26
27
#include <linux/units.h>
27
28
28
29
/* I2C Registers */
29
- #define I2C_LS2X_PRER 0x0 /* Freq Division Register(16 bits) */
30
+ #define I2C_LS2X_PRER_LO 0x0 /* Freq Division Low Byte Register */
31
+ #define I2C_LS2X_PRER_HI 0x1 /* Freq Division High Byte Register */
30
32
#define I2C_LS2X_CTR 0x2 /* Control Register */
31
33
#define I2C_LS2X_TXR 0x3 /* Transport Data Register */
32
34
#define I2C_LS2X_RXR 0x3 /* Receive Data Register */
@@ -93,6 +95,7 @@ static irqreturn_t ls2x_i2c_isr(int this_irq, void *dev_id)
93
95
*/
94
96
static void ls2x_i2c_adjust_bus_speed (struct ls2x_i2c_priv * priv )
95
97
{
98
+ u16 val ;
96
99
struct i2c_timings * t = & priv -> i2c_t ;
97
100
struct device * dev = priv -> adapter .dev .parent ;
98
101
u32 acpi_speed = i2c_acpi_find_bus_speed (dev );
@@ -104,9 +107,14 @@ static void ls2x_i2c_adjust_bus_speed(struct ls2x_i2c_priv *priv)
104
107
else
105
108
t -> bus_freq_hz = LS2X_I2C_FREQ_STD ;
106
109
107
- /* Calculate and set i2c frequency. */
108
- writew (LS2X_I2C_PCLK_FREQ / (5 * t -> bus_freq_hz ) - 1 ,
109
- priv -> base + I2C_LS2X_PRER );
110
+ /*
111
+ * According to the chip manual, we can only access the registers as bytes,
112
+ * otherwise the high bits will be truncated.
113
+ * So set the I2C frequency with a sequential writeb() instead of writew().
114
+ */
115
+ val = LS2X_I2C_PCLK_FREQ / (5 * t -> bus_freq_hz ) - 1 ;
116
+ writeb (FIELD_GET (GENMASK (7 , 0 ), val ), priv -> base + I2C_LS2X_PRER_LO );
117
+ writeb (FIELD_GET (GENMASK (15 , 8 ), val ), priv -> base + I2C_LS2X_PRER_HI );
110
118
}
111
119
112
120
static void ls2x_i2c_init (struct ls2x_i2c_priv * priv )
0 commit comments