Loading drivers/i2c/busses/i2c-octeon.c +63 −63 Original line number Diff line number Diff line Loading @@ -214,6 +214,69 @@ static int octeon_i2c_wait(struct octeon_i2c *i2c) return 0; } /* calculate and set clock divisors */ static void octeon_i2c_set_clock(struct octeon_i2c *i2c) { int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff; int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000; for (ndiv_idx = 0; ndiv_idx < 8 && delta_hz != 0; ndiv_idx++) { /* * An mdiv value of less than 2 seems to not work well * with ds1337 RTCs, so we constrain it to larger values. */ for (mdiv_idx = 15; mdiv_idx >= 2 && delta_hz != 0; mdiv_idx--) { /* * For given ndiv and mdiv values check the * two closest thp values. */ tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10; tclk *= (1 << ndiv_idx); thp_base = (i2c->sys_freq / (tclk * 2)) - 1; for (inc = 0; inc <= 1; inc++) { thp_idx = thp_base + inc; if (thp_idx < 5 || thp_idx > 0xff) continue; foscl = i2c->sys_freq / (2 * (thp_idx + 1)); foscl = foscl / (1 << ndiv_idx); foscl = foscl / (mdiv_idx + 1) / 10; diff = abs(foscl - i2c->twsi_freq); if (diff < delta_hz) { delta_hz = diff; thp = thp_idx; mdiv = mdiv_idx; ndiv = ndiv_idx; } } } } octeon_i2c_write_sw(i2c, SW_TWSI_OP_TWSI_CLK, thp); octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv); } static int octeon_i2c_init_lowlevel(struct octeon_i2c *i2c) { u8 status; int tries; /* disable high level controller, enable bus access */ octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); /* reset controller */ octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_RST, 0); for (tries = 10; tries; tries--) { udelay(1); status = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); if (status == STAT_IDLE) return 0; } dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n", __func__, status); return -EIO; } /** * octeon_i2c_start - send START to the bus * @i2c: The struct octeon_i2c Loading Loading @@ -428,69 +491,6 @@ static struct i2c_adapter octeon_i2c_ops = { .algo = &octeon_i2c_algo, }; /* calculate and set clock divisors */ static void octeon_i2c_set_clock(struct octeon_i2c *i2c) { int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff; int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000; for (ndiv_idx = 0; ndiv_idx < 8 && delta_hz != 0; ndiv_idx++) { /* * An mdiv value of less than 2 seems to not work well * with ds1337 RTCs, so we constrain it to larger values. */ for (mdiv_idx = 15; mdiv_idx >= 2 && delta_hz != 0; mdiv_idx--) { /* * For given ndiv and mdiv values check the * two closest thp values. */ tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10; tclk *= (1 << ndiv_idx); thp_base = (i2c->sys_freq / (tclk * 2)) - 1; for (inc = 0; inc <= 1; inc++) { thp_idx = thp_base + inc; if (thp_idx < 5 || thp_idx > 0xff) continue; foscl = i2c->sys_freq / (2 * (thp_idx + 1)); foscl = foscl / (1 << ndiv_idx); foscl = foscl / (mdiv_idx + 1) / 10; diff = abs(foscl - i2c->twsi_freq); if (diff < delta_hz) { delta_hz = diff; thp = thp_idx; mdiv = mdiv_idx; ndiv = ndiv_idx; } } } } octeon_i2c_write_sw(i2c, SW_TWSI_OP_TWSI_CLK, thp); octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv); } static int octeon_i2c_init_lowlevel(struct octeon_i2c *i2c) { u8 status; int tries; /* disable high level controller, enable bus access */ octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); /* reset controller */ octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_RST, 0); for (tries = 10; tries; tries--) { udelay(1); status = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); if (status == STAT_IDLE) return 0; } dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n", __func__, status); return -EIO; } static int octeon_i2c_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; Loading Loading
drivers/i2c/busses/i2c-octeon.c +63 −63 Original line number Diff line number Diff line Loading @@ -214,6 +214,69 @@ static int octeon_i2c_wait(struct octeon_i2c *i2c) return 0; } /* calculate and set clock divisors */ static void octeon_i2c_set_clock(struct octeon_i2c *i2c) { int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff; int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000; for (ndiv_idx = 0; ndiv_idx < 8 && delta_hz != 0; ndiv_idx++) { /* * An mdiv value of less than 2 seems to not work well * with ds1337 RTCs, so we constrain it to larger values. */ for (mdiv_idx = 15; mdiv_idx >= 2 && delta_hz != 0; mdiv_idx--) { /* * For given ndiv and mdiv values check the * two closest thp values. */ tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10; tclk *= (1 << ndiv_idx); thp_base = (i2c->sys_freq / (tclk * 2)) - 1; for (inc = 0; inc <= 1; inc++) { thp_idx = thp_base + inc; if (thp_idx < 5 || thp_idx > 0xff) continue; foscl = i2c->sys_freq / (2 * (thp_idx + 1)); foscl = foscl / (1 << ndiv_idx); foscl = foscl / (mdiv_idx + 1) / 10; diff = abs(foscl - i2c->twsi_freq); if (diff < delta_hz) { delta_hz = diff; thp = thp_idx; mdiv = mdiv_idx; ndiv = ndiv_idx; } } } } octeon_i2c_write_sw(i2c, SW_TWSI_OP_TWSI_CLK, thp); octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv); } static int octeon_i2c_init_lowlevel(struct octeon_i2c *i2c) { u8 status; int tries; /* disable high level controller, enable bus access */ octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); /* reset controller */ octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_RST, 0); for (tries = 10; tries; tries--) { udelay(1); status = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); if (status == STAT_IDLE) return 0; } dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n", __func__, status); return -EIO; } /** * octeon_i2c_start - send START to the bus * @i2c: The struct octeon_i2c Loading Loading @@ -428,69 +491,6 @@ static struct i2c_adapter octeon_i2c_ops = { .algo = &octeon_i2c_algo, }; /* calculate and set clock divisors */ static void octeon_i2c_set_clock(struct octeon_i2c *i2c) { int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff; int thp = 0x18, mdiv = 2, ndiv = 0, delta_hz = 1000000; for (ndiv_idx = 0; ndiv_idx < 8 && delta_hz != 0; ndiv_idx++) { /* * An mdiv value of less than 2 seems to not work well * with ds1337 RTCs, so we constrain it to larger values. */ for (mdiv_idx = 15; mdiv_idx >= 2 && delta_hz != 0; mdiv_idx--) { /* * For given ndiv and mdiv values check the * two closest thp values. */ tclk = i2c->twsi_freq * (mdiv_idx + 1) * 10; tclk *= (1 << ndiv_idx); thp_base = (i2c->sys_freq / (tclk * 2)) - 1; for (inc = 0; inc <= 1; inc++) { thp_idx = thp_base + inc; if (thp_idx < 5 || thp_idx > 0xff) continue; foscl = i2c->sys_freq / (2 * (thp_idx + 1)); foscl = foscl / (1 << ndiv_idx); foscl = foscl / (mdiv_idx + 1) / 10; diff = abs(foscl - i2c->twsi_freq); if (diff < delta_hz) { delta_hz = diff; thp = thp_idx; mdiv = mdiv_idx; ndiv = ndiv_idx; } } } } octeon_i2c_write_sw(i2c, SW_TWSI_OP_TWSI_CLK, thp); octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CLKCTL, (mdiv << 3) | ndiv); } static int octeon_i2c_init_lowlevel(struct octeon_i2c *i2c) { u8 status; int tries; /* disable high level controller, enable bus access */ octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_CTL, TWSI_CTL_ENAB); /* reset controller */ octeon_i2c_write_sw(i2c, SW_TWSI_EOP_TWSI_RST, 0); for (tries = 10; tries; tries--) { udelay(1); status = octeon_i2c_read_sw(i2c, SW_TWSI_EOP_TWSI_STAT); if (status == STAT_IDLE) return 0; } dev_err(i2c->dev, "%s: TWSI_RST failed! (0x%x)\n", __func__, status); return -EIO; } static int octeon_i2c_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; Loading