Lines Matching +full:riic +full:- +full:rz
1 // SPDX-License-Identifier: GPL-2.0
3 * Renesas RIIC driver
5 * Copyright (C) 2013 Wolfram Sang <wsa@sang-engineering.com>
89 #define RIIC_INIT_MSG -1
114 static inline void riic_clear_set_bit(struct riic_dev *riic, u8 clear, u8 set, u8 reg) in riic_clear_set_bit() argument
116 writeb((readb(riic->base + reg) & ~clear) | set, riic->base + reg); in riic_clear_set_bit()
121 struct riic_dev *riic = i2c_get_adapdata(adap); in riic_xfer() local
126 pm_runtime_get_sync(adap->dev.parent); in riic_xfer()
128 if (readb(riic->base + RIIC_ICCR2) & ICCR2_BBSY) { in riic_xfer()
129 riic->err = -EBUSY; in riic_xfer()
133 reinit_completion(&riic->msg_done); in riic_xfer()
134 riic->err = 0; in riic_xfer()
136 writeb(0, riic->base + RIIC_ICSR2); in riic_xfer()
139 riic->bytes_left = RIIC_INIT_MSG; in riic_xfer()
140 riic->buf = msgs[i].buf; in riic_xfer()
141 riic->msg = &msgs[i]; in riic_xfer()
142 riic->is_last = (i == num - 1); in riic_xfer()
144 writeb(ICIER_NAKIE | ICIER_TIE, riic->base + RIIC_ICIER); in riic_xfer()
146 writeb(start_bit, riic->base + RIIC_ICCR2); in riic_xfer()
148 time_left = wait_for_completion_timeout(&riic->msg_done, riic->adapter.timeout); in riic_xfer()
150 riic->err = -ETIMEDOUT; in riic_xfer()
152 if (riic->err) in riic_xfer()
159 pm_runtime_put(adap->dev.parent); in riic_xfer()
161 return riic->err ?: num; in riic_xfer()
166 struct riic_dev *riic = data; in riic_tdre_isr() local
169 if (!riic->bytes_left) in riic_tdre_isr()
172 if (riic->bytes_left == RIIC_INIT_MSG) { in riic_tdre_isr()
173 if (riic->msg->flags & I2C_M_RD) in riic_tdre_isr()
175 riic_clear_set_bit(riic, ICIER_TIE, ICIER_RIE, RIIC_ICIER); in riic_tdre_isr()
178 riic->bytes_left = riic->msg->len; in riic_tdre_isr()
180 val = i2c_8bit_addr_from_msg(riic->msg); in riic_tdre_isr()
182 val = *riic->buf; in riic_tdre_isr()
183 riic->buf++; in riic_tdre_isr()
184 riic->bytes_left--; in riic_tdre_isr()
192 if (riic->bytes_left == 0) in riic_tdre_isr()
193 riic_clear_set_bit(riic, ICIER_TIE, ICIER_TEIE, RIIC_ICIER); in riic_tdre_isr()
200 writeb(val, riic->base + RIIC_ICDRT); in riic_tdre_isr()
207 struct riic_dev *riic = data; in riic_tend_isr() local
209 if (readb(riic->base + RIIC_ICSR2) & ICSR2_NACKF) { in riic_tend_isr()
211 readb(riic->base + RIIC_ICDRR); /* dummy read */ in riic_tend_isr()
212 riic_clear_set_bit(riic, ICSR2_NACKF, 0, RIIC_ICSR2); in riic_tend_isr()
213 riic->err = -ENXIO; in riic_tend_isr()
214 } else if (riic->bytes_left) { in riic_tend_isr()
218 if (riic->is_last || riic->err) { in riic_tend_isr()
219 riic_clear_set_bit(riic, ICIER_TEIE, ICIER_SPIE, RIIC_ICIER); in riic_tend_isr()
220 writeb(ICCR2_SP, riic->base + RIIC_ICCR2); in riic_tend_isr()
223 riic_clear_set_bit(riic, ICIER_TEIE, 0, RIIC_ICIER); in riic_tend_isr()
224 complete(&riic->msg_done); in riic_tend_isr()
232 struct riic_dev *riic = data; in riic_rdrf_isr() local
234 if (!riic->bytes_left) in riic_rdrf_isr()
237 if (riic->bytes_left == RIIC_INIT_MSG) { in riic_rdrf_isr()
238 riic->bytes_left = riic->msg->len; in riic_rdrf_isr()
239 readb(riic->base + RIIC_ICDRR); /* dummy read */ in riic_rdrf_isr()
243 if (riic->bytes_left == 1) { in riic_rdrf_isr()
245 if (riic->is_last) { in riic_rdrf_isr()
246 riic_clear_set_bit(riic, 0, ICIER_SPIE, RIIC_ICIER); in riic_rdrf_isr()
247 writeb(ICCR2_SP, riic->base + RIIC_ICCR2); in riic_rdrf_isr()
250 riic_clear_set_bit(riic, 0, ICMR3_ACKBT, RIIC_ICMR3); in riic_rdrf_isr()
253 riic_clear_set_bit(riic, ICMR3_ACKBT, 0, RIIC_ICMR3); in riic_rdrf_isr()
257 *riic->buf = readb(riic->base + RIIC_ICDRR); in riic_rdrf_isr()
258 riic->buf++; in riic_rdrf_isr()
259 riic->bytes_left--; in riic_rdrf_isr()
266 struct riic_dev *riic = data; in riic_stop_isr() local
269 writeb(0, riic->base + RIIC_ICSR2); in riic_stop_isr()
270 readb(riic->base + RIIC_ICSR2); in riic_stop_isr()
271 writeb(0, riic->base + RIIC_ICIER); in riic_stop_isr()
272 readb(riic->base + RIIC_ICIER); in riic_stop_isr()
274 complete(&riic->msg_done); in riic_stop_isr()
289 static int riic_init_hw(struct riic_dev *riic, struct i2c_timings *t) in riic_init_hw() argument
295 pm_runtime_get_sync(riic->adapter.dev.parent); in riic_init_hw()
297 if (t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ) { in riic_init_hw()
298 dev_err(&riic->adapter.dev, in riic_init_hw()
300 t->bus_freq_hz, I2C_MAX_FAST_MODE_FREQ); in riic_init_hw()
301 ret = -EINVAL; in riic_init_hw()
305 rate = clk_get_rate(riic->clk); in riic_init_hw()
322 total_ticks = DIV_ROUND_UP(rate, t->bus_freq_hz); in riic_init_hw()
338 dev_err(&riic->adapter.dev, "invalid speed (%lu). Too slow.\n", in riic_init_hw()
339 (unsigned long)t->bus_freq_hz); in riic_init_hw()
340 ret = -EINVAL; in riic_init_hw()
344 brh = total_ticks - brl; in riic_init_hw()
348 brl -= 4; in riic_init_hw()
349 brh -= 4; in riic_init_hw()
351 brl -= 3; in riic_init_hw()
352 brh -= 3; in riic_init_hw()
359 brl -= t->scl_fall_ns / (1000000000 / rate); in riic_init_hw()
360 brh -= t->scl_rise_ns / (1000000000 / rate); in riic_init_hw()
368 pr_debug("i2c-riic: freq=%lu, duty=%d, fall=%lu, rise=%lu, cks=%d, brl=%d, brh=%d\n", in riic_init_hw()
370 t->scl_fall_ns / (1000000000 / rate), in riic_init_hw()
371 t->scl_rise_ns / (1000000000 / rate), cks, brl, brh); in riic_init_hw()
374 writeb(ICCR1_IICRST | ICCR1_SOWP, riic->base + RIIC_ICCR1); in riic_init_hw()
375 riic_clear_set_bit(riic, 0, ICCR1_ICE, RIIC_ICCR1); in riic_init_hw()
377 writeb(ICMR1_CKS(cks), riic->base + RIIC_ICMR1); in riic_init_hw()
378 writeb(brh | ICBR_RESERVED, riic->base + RIIC_ICBRH); in riic_init_hw()
379 writeb(brl | ICBR_RESERVED, riic->base + RIIC_ICBRL); in riic_init_hw()
381 writeb(0, riic->base + RIIC_ICSER); in riic_init_hw()
382 writeb(ICMR3_ACKWP | ICMR3_RDRFS, riic->base + RIIC_ICMR3); in riic_init_hw()
384 riic_clear_set_bit(riic, ICCR1_IICRST, 0, RIIC_ICCR1); in riic_init_hw()
387 pm_runtime_put(riic->adapter.dev.parent); in riic_init_hw()
392 { .res_num = 0, .isr = riic_tend_isr, .name = "riic-tend" },
393 { .res_num = 1, .isr = riic_rdrf_isr, .name = "riic-rdrf" },
394 { .res_num = 2, .isr = riic_tdre_isr, .name = "riic-tdre" },
395 { .res_num = 3, .isr = riic_stop_isr, .name = "riic-stop" },
396 { .res_num = 5, .isr = riic_tend_isr, .name = "riic-nack" },
401 struct riic_dev *riic; in riic_i2c_probe() local
409 riic = devm_kzalloc(&pdev->dev, sizeof(*riic), GFP_KERNEL); in riic_i2c_probe()
410 if (!riic) in riic_i2c_probe()
411 return -ENOMEM; in riic_i2c_probe()
414 riic->base = devm_ioremap_resource(&pdev->dev, res); in riic_i2c_probe()
415 if (IS_ERR(riic->base)) in riic_i2c_probe()
416 return PTR_ERR(riic->base); in riic_i2c_probe()
418 riic->clk = devm_clk_get(&pdev->dev, NULL); in riic_i2c_probe()
419 if (IS_ERR(riic->clk)) { in riic_i2c_probe()
420 dev_err(&pdev->dev, "missing controller clock"); in riic_i2c_probe()
421 return PTR_ERR(riic->clk); in riic_i2c_probe()
424 type = (enum riic_type)of_device_get_match_data(&pdev->dev); in riic_i2c_probe()
426 rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); in riic_i2c_probe()
428 dev_err(&pdev->dev, "Error: missing reset ctrl\n"); in riic_i2c_probe()
438 return -ENODEV; in riic_i2c_probe()
440 ret = devm_request_irq(&pdev->dev, res->start, riic_irqs[i].isr, in riic_i2c_probe()
441 0, riic_irqs[i].name, riic); in riic_i2c_probe()
443 dev_err(&pdev->dev, "failed to request irq %s\n", riic_irqs[i].name); in riic_i2c_probe()
448 adap = &riic->adapter; in riic_i2c_probe()
449 i2c_set_adapdata(adap, riic); in riic_i2c_probe()
450 strlcpy(adap->name, "Renesas RIIC adapter", sizeof(adap->name)); in riic_i2c_probe()
451 adap->owner = THIS_MODULE; in riic_i2c_probe()
452 adap->algo = &riic_algo; in riic_i2c_probe()
453 adap->dev.parent = &pdev->dev; in riic_i2c_probe()
454 adap->dev.of_node = pdev->dev.of_node; in riic_i2c_probe()
456 init_completion(&riic->msg_done); in riic_i2c_probe()
458 i2c_parse_fw_timings(&pdev->dev, &i2c_t, true); in riic_i2c_probe()
460 pm_runtime_enable(&pdev->dev); in riic_i2c_probe()
462 ret = riic_init_hw(riic, &i2c_t); in riic_i2c_probe()
470 platform_set_drvdata(pdev, riic); in riic_i2c_probe()
472 dev_info(&pdev->dev, "registered with %dHz bus speed\n", in riic_i2c_probe()
477 pm_runtime_disable(&pdev->dev); in riic_i2c_probe()
483 struct riic_dev *riic = platform_get_drvdata(pdev); in riic_i2c_remove() local
485 pm_runtime_get_sync(&pdev->dev); in riic_i2c_remove()
486 writeb(0, riic->base + RIIC_ICIER); in riic_i2c_remove()
487 pm_runtime_put(&pdev->dev); in riic_i2c_remove()
488 i2c_del_adapter(&riic->adapter); in riic_i2c_remove()
489 pm_runtime_disable(&pdev->dev); in riic_i2c_remove()
495 { .compatible = "renesas,riic-r9a07g044", .data = (void *)RIIC_RZ_G2L },
496 { .compatible = "renesas,riic-rz", .data = (void *)RIIC_RZ_A },
504 .name = "i2c-riic",
511 MODULE_DESCRIPTION("Renesas RIIC adapter");
512 MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>");