From: freddy2_es@yahoo.com (Alfredo Quesada Sánchez)
To: linux-arm-kernel@lists.infradead.org
Subject: Using SPI in a kernel module
Date: Sun, 27 Jun 2010 13:55:51 -0700 (PDT) [thread overview]
Message-ID: <189502.64100.qm@web33802.mail.mud.yahoo.com> (raw)
In-Reply-To: <4C27B013.4010400@softerra.com>
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 prev parent reply other threads:[~2010-06-27 20:55 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-27 18:25 Using SPI in a kernel module Alfredo Quesada Sánchez
2010-06-27 20:09 ` Mykhail Lodygin
2010-06-27 20:55 ` Alfredo Quesada Sánchez [this message]
2010-06-27 21:26 ` Mykhail Lodygin
2010-06-27 21:47 ` Alfredo Quesada Sánchez
2010-06-27 22:30 ` Mykhail Lodygin
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=189502.64100.qm@web33802.mail.mud.yahoo.com \
--to=freddy2_es@yahoo.com \
--cc=linux-arm-kernel@lists.infradead.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