|
@@ -246,11 +246,36 @@ static u32 sh_mobile_i2c_icch(unsigned long count_khz, u32 tHIGH, u32 tf)
|
|
|
return (((count_khz * (tHIGH + tf)) + 5000) / 10000);
|
|
|
}
|
|
|
|
|
|
+static int sh_mobile_i2c_check_timing(struct sh_mobile_i2c_data *pd)
|
|
|
+{
|
|
|
+ u16 max_val = pd->flags & IIC_FLAG_HAS_ICIC67 ? 0x1ff : 0xff;
|
|
|
+
|
|
|
+ if (pd->iccl > max_val || pd->icch > max_val) {
|
|
|
+ dev_err(pd->dev, "timing values out of range: L/H=0x%x/0x%x\n",
|
|
|
+ pd->iccl, pd->icch);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* one more bit of ICCL in ICIC */
|
|
|
+ if (pd->iccl & 0x100)
|
|
|
+ pd->icic |= ICIC_ICCLB8;
|
|
|
+ else
|
|
|
+ pd->icic &= ~ICIC_ICCLB8;
|
|
|
+
|
|
|
+ /* one more bit of ICCH in ICIC */
|
|
|
+ if (pd->icch & 0x100)
|
|
|
+ pd->icic |= ICIC_ICCHB8;
|
|
|
+ else
|
|
|
+ pd->icic &= ~ICIC_ICCHB8;
|
|
|
+
|
|
|
+ dev_dbg(pd->dev, "timing values: L/H=0x%x/0x%x\n", pd->iccl, pd->icch);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd)
|
|
|
{
|
|
|
unsigned long i2c_clk_khz;
|
|
|
u32 tHIGH, tLOW, tf;
|
|
|
- uint16_t max_val;
|
|
|
|
|
|
i2c_clk_khz = clk_get_rate(pd->clk) / 1000 / pd->clks_per_count;
|
|
|
|
|
@@ -271,27 +296,7 @@ static int sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd)
|
|
|
pd->iccl = sh_mobile_i2c_iccl(i2c_clk_khz, tLOW, tf);
|
|
|
pd->icch = sh_mobile_i2c_icch(i2c_clk_khz, tHIGH, tf);
|
|
|
|
|
|
- max_val = pd->flags & IIC_FLAG_HAS_ICIC67 ? 0x1ff : 0xff;
|
|
|
- if (pd->iccl > max_val || pd->icch > max_val) {
|
|
|
- dev_err(pd->dev, "timing values out of range: L/H=0x%x/0x%x\n",
|
|
|
- pd->iccl, pd->icch);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- /* one more bit of ICCL in ICIC */
|
|
|
- if (pd->iccl & 0x100)
|
|
|
- pd->icic |= ICIC_ICCLB8;
|
|
|
- else
|
|
|
- pd->icic &= ~ICIC_ICCLB8;
|
|
|
-
|
|
|
- /* one more bit of ICCH in ICIC */
|
|
|
- if (pd->icch & 0x100)
|
|
|
- pd->icic |= ICIC_ICCHB8;
|
|
|
- else
|
|
|
- pd->icic &= ~ICIC_ICCHB8;
|
|
|
-
|
|
|
- dev_dbg(pd->dev, "timing values: L/H=0x%x/0x%x\n", pd->iccl, pd->icch);
|
|
|
- return 0;
|
|
|
+ return sh_mobile_i2c_check_timing(pd);
|
|
|
}
|
|
|
|
|
|
static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
|