Problem with SPI on S3C2412

José Miguel Gonçalves jose.goncalves at inov.pt
Wed Nov 18 13:30:14 EST 2009


Ben Dooks wrote:
> On Wed, Nov 04, 2009 at 03:24:37PM +0000, José Miguel Gonçalves wrote:
>>
>> Meanwhile I think I've spotted the (first) problem. In  
>> arch/arm/mach-s3c2412/s3c2412.c the SPI device is renamed "s3c2412-spi"  
>> (it was set in arch/arm/plat-s3c24xx/devs.c with "s3c2410-spi") but the  
>> spi_s3c24xx driver expects a platform driver named "s3c2410-spi", so it  
>> fails to initialize. Commenting the driving renaming I get a little bit  
>> further:
>
> Hmm, I think I was looking at adding some basic support for the s3c2412's
> FIFO facility to the SPI driver and forgot to actually finish and submit
> it. I'll look into fixing the spi driver in my latest updates.
>
>> s3c2410-spi s3c2410-spi.0: No platform data supplied
>> s3c2410-spi: probe of s3c2410-spi.0 failed with error -2
>> modprobe: failed to load module spi_s3c24xx: No such device
>>
>> Now it seems I need some architecture dependent initialization, correct?
>
> Yes, you need to give it some platform data to control behaviour.
>

I've finally succeeded on accessing a device using the SPI bus on the 
S3C2412.
First I've set-up my platform data as following:

static struct spi_board_info sx560_spi_devs[] __initdata = {
    /* Microchip TC72 Temperature Sensor */
    {
        .modalias = "spidev",
        .max_speed_hz = 7500000,
        .bus_num = 0,
        .chip_select = 0,
        .mode = SPI_CS_HIGH | SPI_MODE_1,
    },
};

static void sx560_spi_cs(struct s3c2410_spi_info *spi, int cs, int pol)
{
    s3c2410_gpio_setpin(S3C2410_GPF3, pol);
}

static struct s3c2410_spi_info sx560_spi0_platdata = {
    .num_cs = 1,
    .bus_num = 0,
    .set_cs = sx560_spi_cs,
};

static void __init sx560_machine_init(void)
{
    ...
    s3c_device_spi0.dev.platform_data = &sx560_spi0_platdata;
    spi_register_board_info(sx560_spi_devs, ARRAY_SIZE(sx560_spi_devs));
}

Then I've made a simple program using spidev I/F to access the device.
Executing it, I've found that I could not read the correct data.
I've probed the SPI signals with a scope and everything seemed OK.
I dig into the driver sources and on the S3C2412 datasheet to find that 
this device can not use the same S3C2410 driver's code because of the 
added FIFOs, even if not used. The following patch is needed to make the 
driver to work on the S3C2412 chip (and probably on the S3C2413):

diff -Naurp linux-2.6.27.39.original/drivers/spi/spi_s3c24xx.c 
linux-2.6.27.39/drivers/spi/spi_s3c24xx.c
--- linux-2.6.27.39.original/drivers/spi/spi_s3c24xx.c    2009-11-10 
00:59:38.000000000 +0000
+++ linux-2.6.27.39/drivers/spi/spi_s3c24xx.c    2009-11-18 
16:46:40.963533686 +0000
@@ -202,6 +199,12 @@ static int s3c24xx_spi_txrx(struct spi_d
     return hw->count;
 }
 
+#ifdef CONFIG_CPU_S3C2412
+#define SPRDAT S3C2412_SPRDATB
+#else
+#define SPRDAT S3C2410_SPRDAT
+#endif
+
 static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
 {
     struct s3c24xx_spi *hw = dev;
@@ -223,7 +226,7 @@ static irqreturn_t s3c24xx_spi_irq(int i
     hw->count++;
 
     if (hw->rx)
-        hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT);
+        hw->rx[count] = readb(hw->regs + SPRDAT);
 
     count++;
 
diff -Naurp 
linux-2.6.27.39.original/include/asm-arm/plat-s3c24xx/regs-spi.h 
linux-2.6.27.39/include/asm-arm/plat-s3c24xx/regs-spi.h
--- linux-2.6.27.39.original/include/asm-arm/plat-s3c24xx/regs-spi.h    
2009-11-10 00:59:38.000000000 +0000
+++ linux-2.6.27.39/include/asm-arm/plat-s3c24xx/regs-spi.h    
2009-11-18 16:46:32.474660359 +0000
@@ -75,7 +75,8 @@
 #define S3C2410_SPRDAT     (0x14)
 
 #define S3C2412_TXFIFO     (0x18)
-#define S3C2412_RXFIFO     (0x18)
+#define S3C2412_RXFIFO     (0x1C)
+#define S3C2412_SPRDATB     (0x20)
 #define S3C2412_SPFIC     (0x24)






More information about the linux-arm mailing list