summaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorWolfram Sang <wsa+renesas@sang-engineering.com>2017-12-18 22:58:00 +0100
committerWolfram Sang <wsa@the-dreams.de>2018-01-15 18:01:03 +0100
commitc3449f73a80b2b04a3f7ff69be871c153ea1a9fa (patch)
tree01599dd9e2d89720de417e23d59c053337864c74 /drivers/i2c
parent023c22fd82ce0c62d7490ace6388191375ef4133 (diff)
downloadlinux-c3449f73a80b2b04a3f7ff69be871c153ea1a9fa.tar.bz2
i2c: sh_mobile: add helper to check frequency calculations
Because we will add a second formula soon, put the sanity checks for the computed results into a separate function. Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c49
1 files changed, 27 insertions, 22 deletions
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index f1a9b971e2c1..b111191a449a 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -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,