/* define polling limits */ staticunsignedint polling_limit_us = 30;
module_param(polling_limit_us, uint, 0664);
MODULE_PARM_DESC(polling_limit_us, "time in us to run a transfer in polling mode - if zero no polling is used\n");
staticinlinevoid bcm2835aux_wr_fifo(struct bcm2835aux_spi *bs)
{
u32 data;
u8 byte; int count; int i;
/* gather up to 3 bytes to write to the FIFO */
count = min(bs->tx_len, 3);
data = 0; for (i = 0; i < count; i++) {
byte = bs->tx_buf ? *bs->tx_buf++ : 0;
data |= byte << (8 * (2 - i));
}
/* and set the variable bit-length */
data |= (count * 8) << 24;
staticvoid bcm2835aux_spi_transfer_helper(struct bcm2835aux_spi *bs)
{
u32 stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT);
/* check if we have data to read */ for (; bs->rx_len && (stat & BCM2835_AUX_SPI_STAT_RX_LVL);
stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT))
bcm2835aux_rd_fifo(bs);
/* check if we have data to write */ while (bs->tx_len &&
(bs->pending < 12) &&
(!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
BCM2835_AUX_SPI_STAT_TX_FULL))) {
bcm2835aux_wr_fifo(bs);
}
}
/* IRQ may be shared, so return if our interrupts are disabled */ if (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_CNTL1) &
(BCM2835_AUX_SPI_CNTL1_TXEMPTY | BCM2835_AUX_SPI_CNTL1_IDLE))) return IRQ_NONE;
/* do common fifo handling */
bcm2835aux_spi_transfer_helper(bs);
/* and if rx_len is 0 then disable interrupts and wake up completion */ if (!bs->rx_len) {
bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
spi_finalize_current_transfer(host);
}
/* fill in registers and fifos before enabling interrupts */
bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]);
/* fill in tx fifo with data before enabling interrupts */ while ((bs->tx_len) &&
(bs->pending < 12) &&
(!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
BCM2835_AUX_SPI_STAT_TX_FULL))) {
bcm2835aux_wr_fifo(bs);
}
/* now run the interrupt mode */ return __bcm2835aux_spi_transfer_one_irq(host, spi, tfr);
}
/* set the timeout to at least 2 jiffies */
timeout = jiffies + 2 + HZ * polling_limit_us / 1000000;
/* loop until finished the transfer */ while (bs->rx_len) {
/* do common fifo handling */
bcm2835aux_spi_transfer_helper(bs);
/* there is still data pending to read check the timeout */ if (bs->rx_len && time_after(jiffies, timeout)) {
dev_dbg_ratelimited(&spi->dev, "timeout period reached: jiffies: %lu remaining tx/rx: %d/%d - falling back to interrupt mode\n",
jiffies - timeout,
bs->tx_len, bs->rx_len); /* forward to interrupt handler */
bs->count_transfer_irq_after_poll++; return __bcm2835aux_spi_transfer_one_irq(host,
spi, tfr);
}
}
/* and return without waiting for completion */ return0;
}
staticint bcm2835aux_spi_setup(struct spi_device *spi)
{ /* sanity check for native cs */ if (spi->mode & SPI_NO_CS) return0;
if (spi_get_csgpiod(spi, 0)) return0;
/* for dt-backwards compatibility: only support native on CS0 *knownthingsnotsupportedwithbrokennativeCS: **multiplechip-selects:cs0-cs2areall *simultaniouslyassertedwheneverthereisatransfer *thisevenincludesSPI_NO_CS **SPI_CS_HIGH:csarealwaysassertedlow **cs_change:csisdeassertedaftereachspi_transfer **cs_delay_usec:csisalwaysdeassertedoneSCKcycle *afterthelasttransfer *probablymore...
*/
dev_warn(&spi->dev, "Native CS is not supported - please configure cs-gpio in device-tree\n");
if (spi_get_chipselect(spi, 0) == 0) return0;
dev_warn(&spi->dev, "Native CS is not working for cs > 0\n");
/* the main area */
bs->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(bs->regs)) return PTR_ERR(bs->regs);
bs->clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(bs->clk)) {
err = PTR_ERR(bs->clk);
dev_err(&pdev->dev, "could not get clk: %d\n", err); return err;
}
bs->irq = platform_get_irq(pdev, 0); if (bs->irq < 0) return bs->irq;
/* just checking if the clock returns a sane value */
clk_hz = clk_get_rate(bs->clk); if (!clk_hz) {
dev_err(&pdev->dev, "clock returns 0 Hz\n"); return -ENODEV;
}
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.