From 2f529f9b558ca1c1bd74be7437a84e4711743404 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 01 Nov 2024 02:11:33 +0000 Subject: [PATCH] add xenomai --- kernel/drivers/spi/spi-bcm2835.c | 99 ++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 88 insertions(+), 11 deletions(-) diff --git a/kernel/drivers/spi/spi-bcm2835.c b/kernel/drivers/spi/spi-bcm2835.c index bb9d838..4a3dbc0 100644 --- a/kernel/drivers/spi/spi-bcm2835.c +++ b/kernel/drivers/spi/spi-bcm2835.c @@ -1079,17 +1079,10 @@ return 0; } -static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, - struct spi_device *spi, - struct spi_transfer *tfr) +static unsigned long bcm2835_get_clkdiv(struct bcm2835_spi *bs, u32 spi_hz, + u32 *effective_speed_hz) { - struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); - unsigned long spi_hz, cdiv; - unsigned long hz_per_byte, byte_limit; - u32 cs = bs->prepare_cs[spi->chip_select]; - - /* set clock */ - spi_hz = tfr->speed_hz; + unsigned long cdiv; if (spi_hz >= bs->clk_hz / 2) { cdiv = 2; /* clk_hz/2 is the fastest we can go */ @@ -1103,7 +1096,25 @@ } else { cdiv = 0; /* 0 is the slowest we can go */ } - tfr->effective_speed_hz = cdiv ? (bs->clk_hz / cdiv) : (bs->clk_hz / 65536); + + *effective_speed_hz = cdiv ? (bs->clk_hz / cdiv) : (bs->clk_hz / 65536); + + return cdiv; +} + +static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, + struct spi_device *spi, + struct spi_transfer *tfr) +{ + struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); + unsigned long spi_hz, cdiv; + unsigned long hz_per_byte, byte_limit; + u32 cs = bs->prepare_cs[spi->chip_select]; + + /* set clock */ + spi_hz = tfr->speed_hz; + + cdiv = bcm2835_get_clkdiv(bs, spi_hz, &tfr->effective_speed_hz); bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); /* handle all the 3-wire mode */ @@ -1283,6 +1294,68 @@ return 0; } +#ifdef CONFIG_SPI_BCM2835_OOB + +static int bcm2835_spi_prepare_oob_transfer(struct spi_controller *ctlr, + struct spi_oob_transfer *xfer) +{ + /* + * The size of a transfer is limited by DLEN which is 16-bit + * wide, and we don't want to scatter transfers in out-of-band + * mode, so cap the frame size accordingly. + */ + if (xfer->setup.frame_len > 65532) + return -EINVAL; + + return 0; +} + +static void bcm2835_spi_start_oob_transfer(struct spi_controller *ctlr, + struct spi_oob_transfer *xfer) +{ + struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); + struct spi_device *spi = xfer->spi; + u32 cs = bs->prepare_cs[spi->chip_select], effective_speed_hz; + unsigned long cdiv; + + /* See bcm2835_spi_prepare_message(). */ + bcm2835_wr(bs, BCM2835_SPI_CS, cs); + + cdiv = bcm2835_get_clkdiv(bs, xfer->setup.speed_hz, &effective_speed_hz); + xfer->effective_speed_hz = effective_speed_hz; + bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); + bcm2835_wr(bs, BCM2835_SPI_DLEN, xfer->setup.frame_len); + + if (spi->mode & SPI_3WIRE) + cs |= BCM2835_SPI_CS_REN; + bcm2835_wr(bs, BCM2835_SPI_CS, + cs | BCM2835_SPI_CS_TA | BCM2835_SPI_CS_DMAEN); +} + +static void bcm2835_spi_pulse_oob_transfer(struct spi_controller *ctlr, + struct spi_oob_transfer *xfer) +{ + struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); + + /* Reload DLEN for the next pulse. */ + bcm2835_wr(bs, BCM2835_SPI_DLEN, xfer->setup.frame_len); +} + +static void bcm2835_spi_terminate_oob_transfer(struct spi_controller *ctlr, + struct spi_oob_transfer *xfer) +{ + struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); + + bcm2835_spi_reset_hw(bs); +} + +#else +#define bcm2835_spi_prepare_oob_transfer NULL +#define bcm2835_spi_start_oob_transfer NULL +#define bcm2835_spi_pulse_oob_transfer NULL +#define bcm2835_spi_terminate_oob_transfer NULL +#endif + static int bcm2835_spi_probe(struct platform_device *pdev) { struct spi_controller *ctlr; @@ -1304,6 +1377,10 @@ ctlr->transfer_one = bcm2835_spi_transfer_one; ctlr->handle_err = bcm2835_spi_handle_err; ctlr->prepare_message = bcm2835_spi_prepare_message; + ctlr->prepare_oob_transfer = bcm2835_spi_prepare_oob_transfer; + ctlr->start_oob_transfer = bcm2835_spi_start_oob_transfer; + ctlr->pulse_oob_transfer = bcm2835_spi_pulse_oob_transfer; + ctlr->terminate_oob_transfer = bcm2835_spi_terminate_oob_transfer; ctlr->dev.of_node = pdev->dev.of_node; bs = spi_controller_get_devdata(ctlr); -- Gitblit v1.6.2