Lines Matching +full:auto +full:- +full:i2c

7  * SPDX-License-Identifier:	GPL-2.0+
12 #include <i2c.h>
20 /* HSI2C-specific register description */
97 * @param i2c: pointer to the appropriate register bank
103 static int hsi2c_wait_for_trx(struct exynos5_hsi2c *i2c) in hsi2c_wait_for_trx() argument
107 while (i-- > 0) { in hsi2c_wait_for_trx()
108 u32 int_status = readl(&i2c->usi_int_stat); in hsi2c_wait_for_trx()
111 u32 trans_status = readl(&i2c->usi_trans_status); in hsi2c_wait_for_trx()
114 writel(int_status, &i2c->usi_int_stat); in hsi2c_wait_for_trx()
142 struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; in hsi2c_get_clk_details()
144 unsigned int op_clk = i2c_bus->clock_frequency; in hsi2c_get_clk_details()
159 t_ftl_cycle = (readl(&hsregs->usi_conf) >> 16) & 0x7; in hsi2c_get_clk_details()
160 utemp0 = (clkin / op_clk) - 8 - 2 * t_ftl_cycle; in hsi2c_get_clk_details()
166 i2c_bus->clk_cycle = utemp1 - 2; in hsi2c_get_clk_details()
167 i2c_bus->clk_div = i; in hsi2c_get_clk_details()
171 return -EINVAL; in hsi2c_get_clk_details()
176 struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; in hsi2c_ch_init()
188 n_clkdiv = i2c_bus->clk_div; in hsi2c_ch_init()
189 t_scl_l = i2c_bus->clk_cycle / 2; in hsi2c_ch_init()
190 t_scl_h = i2c_bus->clk_cycle / 2; in hsi2c_ch_init()
196 t_sr_release = i2c_bus->clk_cycle; in hsi2c_ch_init()
203 writel(HSI2C_TRAILING_COUNT, &hsregs->usi_trailing_ctl); in hsi2c_ch_init()
206 clrsetbits_le32(&hsregs->usi_timeout, HSI2C_TIMEOUT_EN, 0); in hsi2c_ch_init()
208 /* set AUTO mode */ in hsi2c_ch_init()
209 writel(readl(&hsregs->usi_conf) | HSI2C_AUTO_MODE, &hsregs->usi_conf); in hsi2c_ch_init()
212 writel(HSI2C_INT_I2C_EN, &hsregs->usi_int_en); in hsi2c_ch_init()
215 writel(HSI2C_RXFIFO_EN | HSI2C_TXFIFO_EN, &hsregs->usi_fifo_ctl); in hsi2c_ch_init()
218 writel(i2c_timing_s1, &hsregs->usi_timing_fs1); in hsi2c_ch_init()
219 writel(i2c_timing_s2, &hsregs->usi_timing_fs2); in hsi2c_ch_init()
220 writel(i2c_timing_s3, &hsregs->usi_timing_fs3); in hsi2c_ch_init()
221 writel(i2c_timing_sla, &hsregs->usi_timing_sla); in hsi2c_ch_init()
227 struct exynos5_hsi2c *i2c = i2c_bus->hsregs; in exynos5_i2c_reset() local
231 i2c_ctl = readl(&i2c->usi_ctl); in exynos5_i2c_reset()
233 writel(i2c_ctl, &i2c->usi_ctl); in exynos5_i2c_reset()
235 i2c_ctl = readl(&i2c->usi_ctl); in exynos5_i2c_reset()
237 writel(i2c_ctl, &i2c->usi_ctl); in exynos5_i2c_reset()
254 * met - the function returns I2C_NOK_TOUT;
256 * @param i2c: pointer to the appropriate i2c register bank.
260 static unsigned hsi2c_poll_fifo(struct exynos5_hsi2c *i2c, bool rx_transfer) in hsi2c_poll_fifo() argument
265 while (readl(&i2c->usi_fifo_stat) & fifo_bit) { in hsi2c_poll_fifo()
266 if (readl(&i2c->usi_int_stat) & HSI2C_INT_I2C_EN) { in hsi2c_poll_fifo()
276 !(readl(&i2c->usi_fifo_stat) & fifo_bit)) in hsi2c_poll_fifo()
280 if (!i--) { in hsi2c_poll_fifo()
292 * Set up transfer as described in section 27.5.1.2 'I2C Channel Auto Mode' of
295 * @param i2c: pointer to the appropriate i2c register bank.
296 * @param chip: slave address on the i2c bus (with read/write bit exlcuded)
299 * @param: issue_stop: set to true if i2c stop condition should be generated
304 static int hsi2c_prepare_transaction(struct exynos5_hsi2c *i2c, in hsi2c_prepare_transaction() argument
318 writel(readl(&i2c->usi_timeout) & ~HSI2C_TIMEOUT_EN, &i2c->usi_timeout); in hsi2c_prepare_transaction()
321 writel(HSI2C_SLV_ADDR_MAS(chip), &i2c->i2c_addr); in hsi2c_prepare_transaction()
324 /* i2c master, read transaction */ in hsi2c_prepare_transaction()
326 &i2c->usi_ctl); in hsi2c_prepare_transaction()
329 writel(conf | HSI2C_READ_WRITE, &i2c->usi_auto_conf); in hsi2c_prepare_transaction()
331 /* i2c master, write transaction */ in hsi2c_prepare_transaction()
333 &i2c->usi_ctl); in hsi2c_prepare_transaction()
336 writel(conf, &i2c->usi_auto_conf); in hsi2c_prepare_transaction()
340 writel(HSI2C_INT_I2C_EN, &i2c->usi_int_stat); in hsi2c_prepare_transaction()
346 * Wait while i2c bus is settling down (mostly stop gets completed).
348 static int hsi2c_wait_while_busy(struct exynos5_hsi2c *i2c) in hsi2c_wait_while_busy() argument
352 while (readl(&i2c->usi_trans_status) & HSI2C_MASTER_BUSY) { in hsi2c_wait_while_busy()
353 if (!i--) { in hsi2c_wait_while_busy()
362 static int hsi2c_write(struct exynos5_hsi2c *i2c, in hsi2c_write() argument
373 /* Writes of zero length not supported in auto mode. */ in hsi2c_write()
379 (i2c, chip, len + alen, false, issue_stop); in hsi2c_write()
385 rv = hsi2c_poll_fifo(i2c, false); in hsi2c_write()
390 writel(addr[i], &i2c->usi_txdata); in hsi2c_write()
394 rv = hsi2c_poll_fifo(i2c, false); in hsi2c_write()
399 writel(data[i], &i2c->usi_txdata); in hsi2c_write()
402 rv = hsi2c_wait_for_trx(i2c); in hsi2c_write()
406 int tmp_ret = hsi2c_wait_while_busy(i2c); in hsi2c_write()
411 writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */ in hsi2c_write()
415 static int hsi2c_read(struct exynos5_hsi2c *i2c, in hsi2c_read() argument
426 /* Reads of zero length not supported in auto mode. */ in hsi2c_read()
434 rv = hsi2c_write(i2c, chip, addr, alen, NULL, 0, false); in hsi2c_read()
439 rv = hsi2c_prepare_transaction(i2c, chip, len, true, true); in hsi2c_read()
445 rv = hsi2c_poll_fifo(i2c, true); in hsi2c_read()
450 data[i] = readl(&i2c->usi_rxdata); in hsi2c_read()
453 rv = hsi2c_wait_for_trx(i2c); in hsi2c_read()
456 tmp_ret = hsi2c_wait_while_busy(i2c); in hsi2c_read()
460 writel(HSI2C_FUNC_MODE_I2C, &i2c->usi_ctl); /* done */ in hsi2c_read()
468 struct exynos5_hsi2c *hsregs = i2c_bus->hsregs; in exynos_hs_i2c_xfer()
471 for (; nmsgs > 0; nmsgs--, msg++) { in exynos_hs_i2c_xfer()
472 if (msg->flags & I2C_M_RD) { in exynos_hs_i2c_xfer()
473 ret = hsi2c_read(hsregs, msg->addr, 0, 0, msg->buf, in exynos_hs_i2c_xfer()
474 msg->len); in exynos_hs_i2c_xfer()
476 ret = hsi2c_write(hsregs, msg->addr, 0, 0, msg->buf, in exynos_hs_i2c_xfer()
477 msg->len, true); in exynos_hs_i2c_xfer()
481 return -EREMOTEIO; in exynos_hs_i2c_xfer()
492 i2c_bus->clock_frequency = speed; in s3c24x0_i2c_set_bus_speed()
495 return -EFAULT; in s3c24x0_i2c_set_bus_speed()
514 ret = hsi2c_read(i2c_bus->hsregs, chip, 0, 0, buf, 1); in s3c24x0_i2c_probe()
521 const void *blob = gd->fdt_blob; in s3c_i2c_ofdata_to_platdata()
527 i2c_bus->hsregs = (struct exynos5_hsi2c *)devfdt_get_addr(dev); in s3c_i2c_ofdata_to_platdata()
529 i2c_bus->id = pinmux_decode_periph_id(blob, node); in s3c_i2c_ofdata_to_platdata()
531 i2c_bus->clock_frequency = fdtdec_get_int(blob, node, in s3c_i2c_ofdata_to_platdata()
532 "clock-frequency", 100000); in s3c_i2c_ofdata_to_platdata()
533 i2c_bus->node = node; in s3c_i2c_ofdata_to_platdata()
534 i2c_bus->bus_num = dev->seq; in s3c_i2c_ofdata_to_platdata()
536 exynos_pinmux_config(i2c_bus->id, PINMUX_FLAG_HS_MODE); in s3c_i2c_ofdata_to_platdata()
538 i2c_bus->active = true; in s3c_i2c_ofdata_to_platdata()
550 { .compatible = "samsung,exynos5-hsi2c" },