/* Set CS/SCK Delays and Inactive Time to defaults */
sifive_spi_write(spi, SIFIVE_SPI_REG_DELAY0,
SIFIVE_SPI_DELAY0_CSSCK(1) |
SIFIVE_SPI_DELAY0_SCKCS(1));
sifive_spi_write(spi, SIFIVE_SPI_REG_DELAY1,
SIFIVE_SPI_DELAY1_INTERCS(1) |
SIFIVE_SPI_DELAY1_INTERXFR(0));
/* Set frame format */
cr = SIFIVE_SPI_FMT_LEN(t->bits_per_word); switch (mode) { case SPI_NBITS_QUAD:
cr |= SIFIVE_SPI_FMT_PROTO_QUAD; break; case SPI_NBITS_DUAL:
cr |= SIFIVE_SPI_FMT_PROTO_DUAL; break; default:
cr |= SIFIVE_SPI_FMT_PROTO_SINGLE; break;
} if (device->mode & SPI_LSB_FIRST)
cr |= SIFIVE_SPI_FMT_ENDIAN; if (!t->rx_buf)
cr |= SIFIVE_SPI_FMT_DIR;
sifive_spi_write(spi, SIFIVE_SPI_REG_FMT, cr);
/* We will want to poll if the time we need to wait is * less than the context switching time. * Let's call that threshold 5us. The operation will take: * (8/mode) * fifo_depth / hz <= 5 * 10^-6 * 1600000 * fifo_depth <= hz * mode
*/ return 1600000 * spi->fifo_depth <= t->speed_hz * mode;
}
while (remaining_words) { unsignedint n_words = min(remaining_words, spi->fifo_depth); unsignedint i;
/* Enqueue n_words for transmission */ for (i = 0; i < n_words; i++)
sifive_spi_tx(spi, tx_ptr++);
if (rx_ptr) { /* Wait for transmission + reception to complete */
sifive_spi_write(spi, SIFIVE_SPI_REG_RXMARK,
n_words - 1);
sifive_spi_wait(spi, SIFIVE_SPI_IP_RXWM, poll);
/* Read out all the data from the RX FIFO */ for (i = 0; i < n_words; i++)
sifive_spi_rx(spi, rx_ptr++);
} else { /* Wait for transmission to complete */
sifive_spi_wait(spi, SIFIVE_SPI_IP_TXWM, poll);
}
spi->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(spi->regs)) {
ret = PTR_ERR(spi->regs); goto put_host;
}
spi->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(spi->clk)) {
dev_err(&pdev->dev, "Unable to find bus clock\n");
ret = PTR_ERR(spi->clk); goto put_host;
}
irq = platform_get_irq(pdev, 0); if (irq < 0) {
ret = irq; goto put_host;
}
/* Optional parameters */
ret =
of_property_read_u32(pdev->dev.of_node, "sifive,fifo-depth",
&spi->fifo_depth); if (ret < 0)
spi->fifo_depth = SIFIVE_SPI_DEFAULT_DEPTH;
ret =
of_property_read_u32(pdev->dev.of_node, "sifive,max-bits-per-word",
&max_bits_per_word);
if (!ret && max_bits_per_word < 8) {
dev_err(&pdev->dev, "Only 8bit SPI words supported by the driver\n");
ret = -EINVAL; goto put_host;
}
/* Spin up the bus clock before hitting registers */
ret = clk_prepare_enable(spi->clk); if (ret) {
dev_err(&pdev->dev, "Unable to enable bus clock\n"); goto put_host;
}
/* probe the number of CS lines */
spi->cs_inactive = sifive_spi_read(spi, SIFIVE_SPI_REG_CSDEF);
sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, 0xffffffffU);
cs_bits = sifive_spi_read(spi, SIFIVE_SPI_REG_CSDEF);
sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, spi->cs_inactive); if (!cs_bits) {
dev_err(&pdev->dev, "Could not auto probe CS lines\n");
ret = -EINVAL; goto disable_clk;
}
num_cs = ilog2(cs_bits) + 1; if (num_cs > SIFIVE_SPI_MAX_CS) {
dev_err(&pdev->dev, "Invalid number of spi targets\n");
ret = -EINVAL; goto disable_clk;
}
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.