public inbox for linux-spi@vger.kernel.org
 help / color / mirror / Atom feed
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

  parent reply	other threads:[~2016-01-05  0:19 UTC|newest]

Thread overview: 13+ 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
     [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
     [not found]     ` <1441970527-2403-2-git-send-email-kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
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
     [not found]     ` <1441970527-2403-3-git-send-email-kernel-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
2015-10-06 11:23       ` Mark Brown
     [not found]         ` <20151006112320.GP12635-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2015-10-06 11:38           ` Martin Sperl
     [not found]             ` <5613B2A2.9020309-TqfNSX0MhmxHKSADF0wUEw@public.gmane.org>
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   ` [PATCH v6 4/4] ARM: bcm2835: enable auxiliary spi driver in defconfig kernel-TqfNSX0MhmxHKSADF0wUEw

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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox