Lines Matching +full:tie +full:- +full:off

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2013 Wolfram Sang <wsa@sang-engineering.com>
13 * 1) The main xfer routine kicks off a transmission by putting the start bit
14 * (or repeated start) on the bus and enabling the transmit interrupt (TIE)
17 * 2) TIE sends target address + RW bit and selects how to continue.
19 * 3a) Write case: We keep utilizing TIE as long as we have data to send. If we
78 #define RIIC_INIT_MSG -1
124 writeb(val, riic->base + riic->info->regs[offset]); in riic_writeb()
129 return readb(riic->base + riic->info->regs[offset]); in riic_readb()
140 struct device *dev = adap->dev.parent; in riic_xfer()
150 riic->err = -EBUSY; in riic_xfer()
154 reinit_completion(&riic->msg_done); in riic_xfer()
155 riic->err = 0; in riic_xfer()
160 riic->bytes_left = RIIC_INIT_MSG; in riic_xfer()
161 riic->buf = msgs[i].buf; in riic_xfer()
162 riic->msg = &msgs[i]; in riic_xfer()
163 riic->is_last = (i == num - 1); in riic_xfer()
169 time_left = wait_for_completion_timeout(&riic->msg_done, riic->adapter.timeout); in riic_xfer()
171 riic->err = -ETIMEDOUT; in riic_xfer()
173 if (riic->err) in riic_xfer()
183 return riic->err ?: num; in riic_xfer()
191 if (!riic->bytes_left) in riic_tdre_isr()
194 if (riic->bytes_left == RIIC_INIT_MSG) { in riic_tdre_isr()
195 if (riic->msg->flags & I2C_M_RD) in riic_tdre_isr()
200 riic->bytes_left = riic->msg->len; in riic_tdre_isr()
202 val = i2c_8bit_addr_from_msg(riic->msg); in riic_tdre_isr()
204 val = *riic->buf; in riic_tdre_isr()
205 riic->buf++; in riic_tdre_isr()
206 riic->bytes_left--; in riic_tdre_isr()
214 if (riic->bytes_left == 0) in riic_tdre_isr()
218 * This acks the TIE interrupt. We get another TIE immediately if our in riic_tdre_isr()
220 * this must be after updates to ICIER (where we want to disable TIE)! in riic_tdre_isr()
235 riic->err = -ENXIO; in riic_tend_isr()
236 } else if (riic->bytes_left) { in riic_tend_isr()
240 if (riic->is_last || riic->err) { in riic_tend_isr()
246 complete(&riic->msg_done); in riic_tend_isr()
256 if (!riic->bytes_left) in riic_rdrf_isr()
259 if (riic->bytes_left == RIIC_INIT_MSG) { in riic_rdrf_isr()
260 riic->bytes_left = riic->msg->len; in riic_rdrf_isr()
265 if (riic->bytes_left == 1) { in riic_rdrf_isr()
267 if (riic->is_last) { in riic_rdrf_isr()
279 *riic->buf = riic_readb(riic, RIIC_ICDRR); in riic_rdrf_isr()
280 riic->buf++; in riic_rdrf_isr()
281 riic->bytes_left--; in riic_rdrf_isr()
296 complete(&riic->msg_done); in riic_stop_isr()
316 struct i2c_timings *t = &riic->i2c_t; in riic_init_hw()
317 struct device *dev = riic->adapter.dev.parent; in riic_init_hw()
318 bool fast_mode_plus = riic->info->fast_mode_plus; in riic_init_hw()
322 if (t->bus_freq_hz > max_freq) in riic_init_hw()
323 return dev_err_probe(&riic->adapter.dev, -EINVAL, in riic_init_hw()
325 t->bus_freq_hz, max_freq); in riic_init_hw()
327 rate = clk_get_rate(riic->clk); in riic_init_hw()
344 total_ticks = DIV_ROUND_UP(rate, t->bus_freq_hz ?: 1); in riic_init_hw()
360 dev_err(&riic->adapter.dev, "invalid speed (%lu). Too slow.\n", in riic_init_hw()
361 (unsigned long)t->bus_freq_hz); in riic_init_hw()
362 return -EINVAL; in riic_init_hw()
365 brh = total_ticks - brl; in riic_init_hw()
369 brl -= 4; in riic_init_hw()
370 brh -= 4; in riic_init_hw()
372 brl -= 3; in riic_init_hw()
373 brh -= 3; in riic_init_hw()
380 brl -= t->scl_fall_ns / (1000000000 / rate); in riic_init_hw()
381 brh -= t->scl_rise_ns / (1000000000 / rate); in riic_init_hw()
389 pr_debug("i2c-riic: freq=%lu, duty=%d, fall=%lu, rise=%lu, cks=%d, brl=%d, brh=%d\n", in riic_init_hw()
391 t->scl_fall_ns / (1000000000 / rate), in riic_init_hw()
392 t->scl_rise_ns / (1000000000 / rate), cks, brl, brh); in riic_init_hw()
409 if (fast_mode_plus && t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ) in riic_init_hw()
420 { .res_num = 0, .isr = riic_tend_isr, .name = "riic-tend" },
421 { .res_num = 1, .isr = riic_rdrf_isr, .name = "riic-rdrf" },
422 { .res_num = 2, .isr = riic_tdre_isr, .name = "riic-tdre" },
423 { .res_num = 3, .isr = riic_stop_isr, .name = "riic-stop" },
424 { .res_num = 5, .isr = riic_tend_isr, .name = "riic-nack" },
434 struct device *dev = &pdev->dev; in riic_i2c_probe()
441 return -ENOMEM; in riic_i2c_probe()
443 riic->base = devm_platform_ioremap_resource(pdev, 0); in riic_i2c_probe()
444 if (IS_ERR(riic->base)) in riic_i2c_probe()
445 return PTR_ERR(riic->base); in riic_i2c_probe()
447 riic->clk = devm_clk_get(dev, NULL); in riic_i2c_probe()
448 if (IS_ERR(riic->clk)) { in riic_i2c_probe()
450 return PTR_ERR(riic->clk); in riic_i2c_probe()
453 riic->rstc = devm_reset_control_get_optional_exclusive(dev, NULL); in riic_i2c_probe()
454 if (IS_ERR(riic->rstc)) in riic_i2c_probe()
455 return dev_err_probe(dev, PTR_ERR(riic->rstc), in riic_i2c_probe()
458 ret = reset_control_deassert(riic->rstc); in riic_i2c_probe()
462 ret = devm_add_action_or_reset(dev, riic_reset_control_assert, riic->rstc); in riic_i2c_probe()
479 riic->info = of_device_get_match_data(dev); in riic_i2c_probe()
481 adap = &riic->adapter; in riic_i2c_probe()
483 strscpy(adap->name, "Renesas RIIC adapter", sizeof(adap->name)); in riic_i2c_probe()
484 adap->owner = THIS_MODULE; in riic_i2c_probe()
485 adap->algo = &riic_algo; in riic_i2c_probe()
486 adap->dev.parent = dev; in riic_i2c_probe()
487 adap->dev.of_node = dev->of_node; in riic_i2c_probe()
489 init_completion(&riic->msg_done); in riic_i2c_probe()
491 i2c_parse_fw_timings(dev, &riic->i2c_t, true); in riic_i2c_probe()
508 dev_info(dev, "registered with %dHz bus speed\n", riic->i2c_t.bus_freq_hz); in riic_i2c_probe()
520 struct device *dev = &pdev->dev; in riic_i2c_remove()
528 i2c_del_adapter(&riic->adapter); in riic_i2c_remove()
586 i2c_mark_adapter_suspended(&riic->adapter); in riic_i2c_suspend()
594 return reset_control_assert(riic->rstc); in riic_i2c_suspend()
602 ret = reset_control_deassert(riic->rstc); in riic_i2c_resume()
611 * keeping the reset line de-asserted for no reason. in riic_i2c_resume()
613 reset_control_assert(riic->rstc); in riic_i2c_resume()
617 i2c_mark_adapter_resumed(&riic->adapter); in riic_i2c_resume()
627 { .compatible = "renesas,riic-rz", .data = &riic_rz_a_info },
628 { .compatible = "renesas,riic-r7s72100", .data = &riic_rz_a1h_info, },
629 { .compatible = "renesas,riic-r9a09g057", .data = &riic_rz_v2h_info },
637 .name = "i2c-riic",
646 MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>");