#define CSI_FIFO_SIZE_BYTES 32U #define CSI_FIFO_HALF_SIZE 16U #define CSI_EN_DIS_TIMEOUT_US 100 /* * Clock "csiclk" gets divided by 2 * CSI_CLKSEL_CKS in order to generate the * serial clock (output from master), with CSI_CLKSEL_CKS ranging from 0x1 (that * means "csiclk" is divided by 2) to 0x3FFF ("csiclk" is divided by 32766).
*/ #define CSI_CKS_MAX GENMASK(13, 0)
if (csi->txbuf) /* * Leaving a little bit of headroom in the FIFOs makes it very * hard to raise an overflow error (which is only possible * when IP transmits and receives at the same time).
*/
to_transfer = min(CSI_FIFO_HALF_SIZE, bytes_remaining); else
to_transfer = min(CSI_FIFO_SIZE_BYTES, bytes_remaining);
if (csi->bytes_per_word == 2)
to_transfer >>= 1;
/* * We can only choose a trigger level from a predefined set of values. * This will pick a value that is the greatest possible integer that's * less than or equal to the number of bytes we need to transfer. * This may result in multiple smaller transfers.
*/
csi->words_to_transfer = rounddown_pow_of_two(to_transfer);
/* * There is a restriction on the frequency of CSICLK, it has to be <= * PCLK / 2.
*/ if (csiclk_rate > csiclk_rate_limit) {
clk_set_rate(csi->csiclk, csiclk_rate >> 1);
csiclk_rate = clk_get_rate(csi->csiclk);
} elseif ((csiclk_rate << 1) <= csiclk_rate_limit) {
clk_set_rate(csi->csiclk, csiclk_rate << 1);
csiclk_rate = clk_get_rate(csi->csiclk);
}
/* Setup serial data order */
rzv2m_csi_reg_write_bit(csi, CSI_MODE, CSI_MODE_DIR,
!!(spi->mode & SPI_LSB_FIRST));
/* Set the role, 1 for target and 0 for host */
rzv2m_csi_reg_write_bit(csi, CSI_CLKSEL, CSI_CLKSEL_SLAVE,
!!spi_controller_is_target(csi->controller));
/* Give the IP a SW reset */
ret = rzv2m_csi_sw_reset(csi, 1); if (ret) return ret;
rzv2m_csi_sw_reset(csi, 0);
/* * We need to enable the communication so that the clock will settle * for the right polarity before enabling the CS.
*/
rzv2m_csi_start_stop_operation(csi, 1, false);
udelay(10);
rzv2m_csi_start_stop_operation(csi, 0, false);
return0;
}
staticint rzv2m_csi_pio_transfer(struct rzv2m_csi_priv *csi)
{ bool tx_completed = !csi->txbuf; bool rx_completed = !csi->rxbuf; int ret = 0;
/* Make sure the TX FIFO is empty */
writel(0, csi->base + CSI_OFIFOL);
/* Make sure the RX FIFO is empty */
writel(0, csi->base + CSI_IFIFOL);
while (!tx_completed || !rx_completed) { /* * Decide how many words we are going to transfer during * this cycle (for both TX and RX), then set the RX FIFO trigger * level accordingly. No need to set a trigger level for the * TX FIFO, as this IP comes with an interrupt that fires when * the TX FIFO is empty.
*/
rzv2m_csi_calc_current_transfer(csi);
rzv2m_csi_set_rx_fifo_trigger_level(csi);
/* TX */ if (csi->txbuf) {
ret = rzv2m_csi_fill_txfifo(csi); if (ret) break;
if (csi->bytes_sent == csi->buffer_len)
tx_completed = true;
}
rzv2m_csi_start_stop_operation(csi, 1, false);
/* * Make sure the RX FIFO contains the desired number of words. * We then either flush its content, or we copy it onto * csi->rxbuf.
*/
ret = rzv2m_csi_wait_for_rx_ready(csi); if (ret) break;
if (!spi_controller_is_target(csi->controller))
rzv2m_csi_start_stop_operation(csi, 0, false);
/* RX */ if (csi->rxbuf) {
ret = rzv2m_csi_read_rxfifo(csi); if (ret) break;
ret = devm_request_irq(dev, irq, rzv2m_csi_irq_handler, 0,
dev_name(dev), csi); if (ret) return dev_err_probe(dev, ret, "cannot request IRQ\n");
/* * The reset also affects other HW that is not under the control * of Linux. Therefore, all we can do is make sure the reset is * deasserted.
*/
reset_control_deassert(rstc);
/* Make sure the IP is in SW reset state */
ret = rzv2m_csi_sw_reset(csi, 1); if (ret) return ret;
ret = clk_prepare_enable(csi->csiclk); if (ret) return dev_err_probe(dev, ret, "could not enable csiclk\n");
ret = spi_register_controller(controller); if (ret) {
clk_disable_unprepare(csi->csiclk); return dev_err_probe(dev, ret, "register controller failed\n");
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Fabrizio Castro <castro.fabrizio.jz@renesas.com>");
MODULE_DESCRIPTION("Clocked Serial Interface Driver");
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.16Bemerkung:
(vorverarbeitet am 2026-06-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.