From: Stephan Olbrich <stephanolbrich-Mmb7MZpHnFY@public.gmane.org>
To: linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Cc: Martin Sperl <kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>,
linux-spi <linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Subject: Re: [PATCH v6 2/4] spi: bcm2835: add bcm2835 auxiliary spi device driver
Date: Tue, 05 Jan 2016 01:19:32 +0100 [thread overview]
Message-ID: <1994637.DU4i3KELDi@chaos-desktop> (raw)
In-Reply-To: <36C84129-0322-41C5-B01A-AF6F002E001E-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
Am Montag, 4. Januar 2016, 15:23:52 schrieb Martin Sperl:
> > On 04.01.2016, at 14:51, Stephan Olbrich <stephanolbrich-Mmb7MZpHnFY@public.gmane.org> wrote:
> >
> > According to the spi documentation [1]: "CPHA indicates the clock phase
> > used to sample data; CPHA=0 says sample on the leading edge, CPHA=1 means
> > the trailing edge."
> > Which is from my understanding different from what the BMC2835 ARM
> > Peripherals [2] says for BCM2835_AUX_SPI_CNTL0_CPHA_IN:
> > "If 1 data is clocked in on the rising edge of the SPI clock
> > If 0 data is clocked in on the falling edge of the SPI clock"
> >
> > I would expect the bits to be set dependant on the clock polarity (CPOL).
>
> I am only having “typical” devices with do Mode 0,0 or 1,1 for which it
> works.
Are you only writing to your devices or reading as well? From what I think how
this works, reading should not have worked with Mode 0,0
> > The other issue I have, is that the chip select is set before the clock
> > polarity and the polarity is reset and set again between each transfers of
> > a message. If CPOL is set to 1 this leads to additional rising and
> > falling edges of the clock while chip select is active, where no data is
> > sampled.
> This is something I have seen before with the main spi HW.
> We may need to port the same thing there.
>
> The corresponding patch for spi-bcm2835.c is this:
> acace73df2c1913a526c1b41e4741a4a6704c863
Thanks for the hint. I tried to implement a similar solution. Could you test
if this works for you?
It also contains a fix for the IRQ defines, a hopefully correct solution to
the CPHA issue and reduces the number of unnecessary interrupts.
---
drivers/spi/spi-bcm2835aux.c | 70
++++++++++++++++++++++++++++++++------------
1 file changed, 52 insertions(+), 18 deletions(-)
diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c
index 7de6f84..d8be445 100644
--- a/drivers/spi/spi-bcm2835aux.c
+++ b/drivers/spi/spi-bcm2835aux.c
@@ -73,8 +73,8 @@
/* Bitfields in CNTL1 */
#define BCM2835_AUX_SPI_CNTL1_CSHIGH 0x00000700
-#define BCM2835_AUX_SPI_CNTL1_IDLE 0x00000080
-#define BCM2835_AUX_SPI_CNTL1_TXEMPTY 0x00000040
+#define BCM2835_AUX_SPI_CNTL1_TXEMPTY 0x00000080
+#define BCM2835_AUX_SPI_CNTL1_IDLE 0x00000040
#define BCM2835_AUX_SPI_CNTL1_MSBF_IN 0x00000002
#define BCM2835_AUX_SPI_CNTL1_KEEP_IN 0x00000001
@@ -212,9 +212,15 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void
*dev_id)
ret = IRQ_HANDLED;
}
- /* and if rx_len is 0 then wake up completion and disable spi */
+ if (!bs->tx_len) {
+ /* disable tx fifo empty interrupt */
+ bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1] |
+ BCM2835_AUX_SPI_CNTL1_IDLE);
+ }
+
+ /* and if rx_len is 0 then disable interrupts and wake up completion */
if (!bs->rx_len) {
- bcm2835aux_spi_reset_hw(bs);
+ bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
complete(&master->xfer_completion);
}
@@ -307,9 +313,6 @@ static int bcm2835aux_spi_transfer_one_poll(struct
spi_master *master,
}
}
- /* Transfer complete - reset SPI HW */
- bcm2835aux_spi_reset_hw(bs);
-
/* and return without waiting for completion */
return 0;
}
@@ -330,10 +333,6 @@ static int bcm2835aux_spi_transfer_one(struct spi_master
*master,
* resulting (potentially) in more interrupts when transferring
* more than 12 bytes
*/
- bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE |
- BCM2835_AUX_SPI_CNTL0_VAR_WIDTH |
- BCM2835_AUX_SPI_CNTL0_MSBF_OUT;
- bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN;
/* set clock */
spi_hz = tfr->speed_hz;
@@ -352,13 +351,6 @@ static int bcm2835aux_spi_transfer_one(struct spi_master
*master,
spi_used_hz = clk_hz / (2 * (speed + 1));
- /* handle all the modes */
- if (spi->mode & SPI_CPOL)
- bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL;
- if (spi->mode & SPI_CPHA)
- bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_OUT |
- BCM2835_AUX_SPI_CNTL0_CPHA_IN;
-
/* set transmit buffers and length */
bs->tx_buf = tfr->tx_buf;
bs->rx_buf = tfr->rx_buf;
@@ -382,6 +374,46 @@ static int bcm2835aux_spi_transfer_one(struct spi_master
*master,
return bcm2835aux_spi_transfer_one_irq(master, spi, tfr);
}
+static int bcm2835aux_spi_prepare_message(struct spi_master *master,
+ struct spi_message *msg)
+{
+ struct spi_device *spi = msg->spi;
+ struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+
+ bs->cntl[0] = BCM2835_AUX_SPI_CNTL0_ENABLE |
+ BCM2835_AUX_SPI_CNTL0_VAR_WIDTH |
+ BCM2835_AUX_SPI_CNTL0_MSBF_OUT;
+ bs->cntl[1] = BCM2835_AUX_SPI_CNTL1_MSBF_IN;
+
+ /* handle all the modes */
+ if (spi->mode & SPI_CPOL) {
+ bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPOL;
+ if (spi->mode & SPI_CPHA)
+ bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_IN;
+ else
+ bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_OUT;
+ } else {
+ if (spi->mode & SPI_CPHA)
+ bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_OUT;
+ else
+ bs->cntl[0] |= BCM2835_AUX_SPI_CNTL0_CPHA_IN;
+ }
+ bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
+ bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL0, bs->cntl[0]);
+
+ return 0;
+}
+
+static int bcm2835aux_spi_unprepare_message(struct spi_master *master,
+ struct spi_message *msg)
+{
+ struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
+
+ bcm2835aux_spi_reset_hw(bs);
+
+ return 0;
+}
+
static void bcm2835aux_spi_handle_err(struct spi_master *master,
struct spi_message *msg)
{
@@ -410,6 +442,8 @@ static int bcm2835aux_spi_probe(struct platform_device
*pdev)
master->num_chipselect = -1;
master->transfer_one = bcm2835aux_spi_transfer_one;
master->handle_err = bcm2835aux_spi_handle_err;
+ master->prepare_message = bcm2835aux_spi_prepare_message;
+ master->unprepare_message = bcm2835aux_spi_unprepare_message;
master->dev.of_node = pdev->dev.of_node;
bs = spi_master_get_devdata(master);
--
2.1.4
--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2016-01-05 0:19 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-11 11:22 [PATCH v6 0/4] spi: bcm2835: add spi-bcm2835aux driver kernel-TqfNSX0MhmxHKSADF0wUEw
2015-09-11 11:22 ` kernel at martin.sperl.org
[not found] ` <1441970527-2403-1-git-send-email-kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2015-09-11 11:22 ` [PATCH v6 1/4] dt/bindings: bcm2835: spi: add bindings for the bcm2835 auxiliary spi devices kernel-TqfNSX0MhmxHKSADF0wUEw
2015-09-11 11:22 ` kernel at martin.sperl.org
[not found] ` <1441970527-2403-2-git-send-email-kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2015-09-22 2:25 ` Stephen Warren
2015-09-22 2:25 ` Stephen Warren
2015-10-07 10:43 ` Applied "spi: bcm2835aux: spi: add bindings for the bcm2835 auxiliary spi devices" to the spi tree Mark Brown
2015-09-11 11:22 ` [PATCH v6 2/4] spi: bcm2835: add bcm2835 auxiliary spi device driver kernel-TqfNSX0MhmxHKSADF0wUEw
2015-09-11 11:22 ` kernel at martin.sperl.org
[not found] ` <1441970527-2403-3-git-send-email-kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2015-10-06 11:23 ` Mark Brown
2015-10-06 11:23 ` Mark Brown
[not found] ` <20151006112320.GP12635-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2015-10-06 11:38 ` Martin Sperl
2015-10-06 11:38 ` Martin Sperl
[not found] ` <5613B2A2.9020309-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2015-10-07 10:41 ` Mark Brown
2015-10-07 10:41 ` Mark Brown
2016-01-04 13:51 ` Stephan Olbrich
2016-01-04 14:23 ` Martin Sperl
[not found] ` <36C84129-0322-41C5-B01A-AF6F002E001E-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2016-01-05 0:19 ` Stephan Olbrich [this message]
2015-09-11 11:22 ` [PATCH v6 3/4] spi: bcm2835: add the auxiliary spi1 and spi2 to the device tree kernel-TqfNSX0MhmxHKSADF0wUEw
2015-09-11 11:22 ` kernel at martin.sperl.org
2015-09-11 11:22 ` [PATCH v6 4/4] ARM: bcm2835: enable auxiliary spi driver in defconfig kernel-TqfNSX0MhmxHKSADF0wUEw
2015-09-11 11:22 ` kernel at martin.sperl.org
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1994637.DU4i3KELDi@chaos-desktop \
--to=stephanolbrich-mmb7mzphnfy@public.gmane.org \
--cc=broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org \
--cc=linux-rpi-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.