Using SPI in a kernel module

Mykhail Lodygin mishal at softerra.com
Sun Jun 27 17:26:53 EDT 2010


Invocation sequence is the same as described  in  ek_spi_devices. So since there is no YOUR driver in ek_spi_devices - i can't say when it would be called - for now - never.
which device? - you define it by setting .chip_select, i believe.

You could see all calls -  just set verbosity to debug function in the 
configuration.
On 06/27/2010 11:55 PM, Alfredo Quesada Sánchez wrote:
> There are a few compiled files in that directory (more preciselly is arch/arm/mach-at91), including:
>
> - board-XXX.c (well, the name of the board)
>
> MACHINE_START(AT91SAM9G45EKES, "Atmel AT91SAM9G45-EKES")
> 	/* Maintainer: Atmel */
> 	.phys_io	= AT91_BASE_SYS,
> 	.io_pg_offst	= (AT91_VA_BASE_SYS>>  18)&  0xfffc,
> 	.boot_params	= AT91_SDRAM_BASE + 0x100,
> 	.timer		=&at91sam926x_timer,
> 	.map_io		= ek_map_io,
> 	.init_irq	= ek_init_irq,
> 	.init_machine	= ek_board_init,
> MACHINE_END
>
> In this file there is:
>
> /*
>   * SPI devices.
>   */
> static struct spi_board_info ek_spi_devices[] = {
> 	{	/* DataFlash chip */
> 		.modalias	= "mtd_dataflash",
> 		.chip_select	= 0,
> 		.max_speed_hz	= 15 * 1000 * 1000,
> 		.bus_num	= 0,
> 	},
> };
>
> And in ek_board_init I can see a call to:
>
> /* SPI */
> at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
>
>
> This function is in at91sam9g45_devices.c (also compiled), also having:
>
> static struct resource spi0_resources[] = {
> 	[0] = {
> 		.start	= AT91SAM9G45_BASE_SPI0,
> 		.end	= AT91SAM9G45_BASE_SPI0 + SZ_16K - 1,
> 		.flags	= IORESOURCE_MEM,
> 	},
> 	[1] = {
> 		.start	= AT91SAM9G45_ID_SPI0,
> 		.end	= AT91SAM9G45_ID_SPI0,
> 		.flags	= IORESOURCE_IRQ,
> 	},
> };
>
> static struct platform_device at91sam9g45_spi0_device = {
> 	.name		= "atmel_spi",
> 	.id		= 0,
> 	.dev		= {
> 				.dma_mask		=&spi_dmamask,
> 				.coherent_dma_mask	= DMA_BIT_MASK(32),
> 	},
> 	.resource	= spi0_resources,
> 	.num_resources	= ARRAY_SIZE(spi0_resources),
> };
>
> static const unsigned spi0_standard_cs[4] = { AT91_PIN_PB3, AT91_PIN_PB18, AT91_PIN_PB19, AT91_PIN_PD27 };
>
> static struct resource spi1_resources[] = {
> 	[0] = {
> 		.start	= AT91SAM9G45_BASE_SPI1,
> 		.end	= AT91SAM9G45_BASE_SPI1 + SZ_16K - 1,
> 		.flags	= IORESOURCE_MEM,
> 	},
> 	[1] = {
> 		.start	= AT91SAM9G45_ID_SPI1,
> 		.end	= AT91SAM9G45_ID_SPI1,
> 		.flags	= IORESOURCE_IRQ,
> 	},
> };
>
> static struct platform_device at91sam9g45_spi1_device = {
> 	.name		= "atmel_spi",
> 	.id		= 1,
> 	.dev		= {
> 				.dma_mask		=&spi_dmamask,
> 				.coherent_dma_mask	= DMA_BIT_MASK(32),
> 	},
> 	.resource	= spi1_resources,
> 	.num_resources	= ARRAY_SIZE(spi1_resources),
> };
>
> static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB17, AT91_PIN_PD28, AT91_PIN_PD18, AT91_PIN_PD19 };
>
> void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
> {
> 	int i;
> 	unsigned long cs_pin;
> 	short enable_spi0 = 0;
> 	short enable_spi1 = 0;
>
> 	/* Choose SPI chip-selects */
> 	for (i = 0; i<  nr_devices; i++) {
> 		if (devices[i].controller_data)
> 			cs_pin = (unsigned long) devices[i].controller_data;
> 		else if (devices[i].bus_num == 0)
> 			cs_pin = spi0_standard_cs[devices[i].chip_select];
> 		else
> 			cs_pin = spi1_standard_cs[devices[i].chip_select];
>
> 		if (devices[i].bus_num == 0)
> 			enable_spi0 = 1;
> 		else
> 			enable_spi1 = 1;
>
> 		/* enable chip-select pin */
> 		at91_set_gpio_output(cs_pin, 1);
>
> 		/* pass chip-select pin to driver */
> 		devices[i].controller_data = (void *) cs_pin;
> 	}
>
> 	spi_register_board_info(devices, nr_devices);
>
> 	/* Configure SPI bus(es) */
> 	if (enable_spi0) {
> 		at91_set_A_periph(AT91_PIN_PB0, 0);	/* SPI0_MISO */
> 		at91_set_A_periph(AT91_PIN_PB1, 0);	/* SPI0_MOSI */
> 		at91_set_A_periph(AT91_PIN_PB2, 0);	/* SPI0_SPCK */
>
> 		at91_clock_associate("spi0_clk",&at91sam9g45_spi0_device.dev, "spi_clk");
> 		platform_device_register(&at91sam9g45_spi0_device);
> 	}
> 	if (enable_spi1) {
> 		at91_set_A_periph(AT91_PIN_PB14, 0);	/* SPI1_MISO */
> 		at91_set_A_periph(AT91_PIN_PB15, 0);	/* SPI1_MOSI */
> 		at91_set_A_periph(AT91_PIN_PB16, 0);	/* SPI1_SPCK */
>
> 		at91_clock_associate("spi1_clk",&at91sam9g45_spi1_device.dev, "spi_clk");
> 		platform_device_register(&at91sam9g45_spi1_device);
> 	}
> }
>
> To summarize, in the end platform_device_register should be called for SPI 0 (as you can see the board has 2 SPI channels).
>
>
> So.. assuming this is working as expected, when should i see a call to my driver's probe function? and.. which spi_device will be passed as parameter? (there is only 1 registered, but for this question let's assume that i have more spi devices registered).
>
> Regards
>
>    
>> Hello
>> How about specifying correct data (for your particular
>> board) in the
>> machine-specific
>> code?(arch/your_arch/mach-your_machine/your_machine.c)
>> Basically it is enough for the system to invoke proper
>> probes.
>> Mikhail
>>      
>
>
>
>    

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20100628/edc6638e/attachment-0001.html>


More information about the linux-arm-kernel mailing list