Re: [PATCH] spi: Add PXA2xx SSP SPI Driver

From: David Vrabel
Date: Tue Feb 07 2006 - 10:03:30 EST


David Vrabel wrote:
> stephen@xxxxxxxxxxxxxxxxxxx wrote:
>
>>From: Stephen Street <stephen@xxxxxxxxxxxxxxxxxxx>
>>
>>The driver turns a PXA2xx synchronous serial port (SSP) into a SPI master
>>controller (see Documentation/spi/spi_summary). The driver has the following
>>features:
>
>
> I've not tested this on my PXA27x platform yet (I'll try and get this
> done this tomorrow) but a few comments.

Found time to test it today.

I needed to use DMA for all transfers (not just ones >= dma_burst_size)
since at high clock rates (> ~5 MHz) PIO just can't keep up.

David Vrabel
--
David Vrabel, Design Engineer

Arcom, Clifton Road Tel: +44 (0)1223 411200 ext. 3233
Cambridge CB1 7EA, UK Web: http://www.arcom.com/
Index: linux-2.6-working/drivers/spi/pxa2xx_spi.c
===================================================================
--- linux-2.6-working.orig/drivers/spi/pxa2xx_spi.c 2006-02-07 12:43:32.000000000 +0000
+++ linux-2.6-working/drivers/spi/pxa2xx_spi.c 2006-02-07 14:13:47.000000000 +0000
@@ -43,7 +43,11 @@
MODULE_DESCRIPTION("PXA2xx SSP SPI Contoller");
MODULE_LICENSE("GPL");

-#define CLOCK_SPEED_HZ 3686400
+#if defined(CONFIG_PXA25x)
+# define CLOCK_SPEED_HZ 3686400
+#elif defined(CONFIG_PXA27x)
+# define CLOCK_SPEED_HZ 13000000
+#endif
#define MAX_BUSES 3

#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
@@ -429,9 +433,6 @@
if (!IS_DMA_ALIGNED(drv_data->rx) || !IS_DMA_ALIGNED(drv_data->tx))
return 0;

- if (drv_data->len < drv_data->cur_chip->dma_burst_size)
- return 0;
-
/* Modify setup if rx buffer is null */
if (drv_data->rx == NULL) {
*(u32 *)(drv_data->null_dma_buf) = 0;
@@ -1014,7 +1015,7 @@
chip->cr1 = SSCR1_LBM;
}

- chip->cr0 = SSCR0_SerClkDiv((CLOCK_SPEED_HZ / spi->max_speed_hz) + 2)
+ chip->cr0 = SSCR0_SerClkDiv(CLOCK_SPEED_HZ / (spi->max_speed_hz + 1) + 1)
| SSCR0_Motorola
| SSCR0_DataSize(spi->bits_per_word & 0x0f)
| SSCR0_SSE
@@ -1218,7 +1219,7 @@

/* Attach to IRQ */
irq = platform_get_irq(pdev, 0);
- if (irq == 0) {
+ if (irq < 0) {
dev_err(&pdev->dev, "irq resource not defined\n");
status = -ENODEV;
goto out_error_master_alloc;
@@ -1378,7 +1379,7 @@

/* Release IRQ */
irq = platform_get_irq(pdev, 0);
- if (irq != 0)
+ if (irq >= 0)
free_irq(irq, drv_data);

/* Disconnect from the SPI framework */