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



      

  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