Skip to content

Commit

Permalink
spi/ep93xx: implemented driver for Cirrus EP93xx SPI controller
Browse files Browse the repository at this point in the history
This patch adds an SPI master driver for the Cirrus EP93xx SPI controller found
in EP93xx chips.

Signed-off-by: Mika Westerberg <[email protected]>
Signed-off-by: H Hartley Sweeten <[email protected]>
Acked-by: H Hartley Sweeten <[email protected]>
Signed-off-by: Grant Likely <[email protected]>
  • Loading branch information
Mika Westerberg authored and glikely committed May 25, 2010
1 parent 1dcf57c commit 011f23a
Show file tree
Hide file tree
Showing 5 changed files with 1,071 additions and 0 deletions.
95 changes: 95 additions & 0 deletions Documentation/spi/ep93xx_spi
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
Cirrus EP93xx SPI controller driver HOWTO
=========================================

ep93xx_spi driver brings SPI master support for EP93xx SPI controller. Chip
selects are implemented with GPIO lines.

NOTE: If possible, don't use SFRMOUT (SFRM1) signal as a chip select. It will
not work correctly (it cannot be controlled by software). Use GPIO lines
instead.

Sample configuration
====================

Typically driver configuration is done in platform board files (the files under
arch/arm/mach-ep93xx/*.c). In this example we configure MMC over SPI through
this driver on TS-7260 board. You can adapt the code to suit your needs.

This example uses EGPIO9 as SD/MMC card chip select (this is wired in DIO1
header on the board).

You need to select CONFIG_MMC_SPI to use mmc_spi driver.

arch/arm/mach-ep93xx/ts72xx.c:

...
#include <linux/gpio.h>
#include <linux/spi/spi.h>

#include <mach/ep93xx_spi.h>

/* this is our GPIO line used for chip select */
#define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO9

static int ts72xx_mmc_spi_setup(struct spi_device *spi)
{
int err;

err = gpio_request(MMC_CHIP_SELECT_GPIO, spi->modalias);
if (err)
return err;

gpio_direction_output(MMC_CHIP_SELECT_GPIO, 1);

return 0;
}

static void ts72xx_mmc_spi_cleanup(struct spi_device *spi)
{
gpio_set_value(MMC_CHIP_SELECT_GPIO, 1);
gpio_direction_input(MMC_CHIP_SELECT_GPIO);
gpio_free(MMC_CHIP_SELECT_GPIO);
}

static void ts72xx_mmc_spi_cs_control(struct spi_device *spi, int value)
{
gpio_set_value(MMC_CHIP_SELECT_GPIO, value);
}

static struct ep93xx_spi_chip_ops ts72xx_mmc_spi_ops = {
.setup = ts72xx_mmc_spi_setup,
.cleanup = ts72xx_mmc_spi_cleanup,
.cs_control = ts72xx_mmc_spi_cs_control,
};

static struct spi_board_info ts72xx_spi_devices[] __initdata = {
{
.modalias = "mmc_spi",
.controller_data = &ts72xx_mmc_spi_ops,
/*
* We use 10 MHz even though the maximum is 7.4 MHz. The driver
* will limit it automatically to max. frequency.
*/
.max_speed_hz = 10 * 1000 * 1000,
.bus_num = 0,
.chip_select = 0,
.mode = SPI_MODE_0,
},
};

static struct ep93xx_spi_info ts72xx_spi_info = {
.num_chipselect = ARRAY_SIZE(ts72xx_spi_devices),
};

static void __init ts72xx_init_machine(void)
{
...
ep93xx_register_spi(&ts72xx_spi_info, ts72xx_spi_devices,
ARRAY_SIZE(ts72xx_spi_devices));
}

Thanks to
=========
Martin Guy, H. Hartley Sweeten and others who helped me during development of
the driver. Simplemachines.it donated me a Sim.One board which I used testing
the driver on EP9307.
27 changes: 27 additions & 0 deletions arch/arm/mach-ep93xx/include/mach/ep93xx_spi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef __ASM_MACH_EP93XX_SPI_H
#define __ASM_MACH_EP93XX_SPI_H

struct spi_device;

/**
* struct ep93xx_spi_info - EP93xx specific SPI descriptor
* @num_chipselect: number of chip selects on this board, must be
* at least one
*/
struct ep93xx_spi_info {
int num_chipselect;
};

/**
* struct ep93xx_spi_chip_ops - operation callbacks for SPI slave device
* @setup: setup the chip select mechanism
* @cleanup: cleanup the chip select mechanism
* @cs_control: control the device chip select
*/
struct ep93xx_spi_chip_ops {
int (*setup)(struct spi_device *spi);
void (*cleanup)(struct spi_device *spi);
void (*cs_control)(struct spi_device *spi, int value);
};

#endif /* __ASM_MACH_EP93XX_SPI_H */
10 changes: 10 additions & 0 deletions drivers/spi/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,16 @@ config SPI_DAVINCI
help
SPI master controller for DaVinci and DA8xx SPI modules.

config SPI_EP93XX
tristate "Cirrus Logic EP93xx SPI controller"
depends on ARCH_EP93XX
help
This enables using the Cirrus EP93xx SPI controller in master
mode.

To compile this driver as a module, choose M here. The module will be
called ep93xx_spi.

config SPI_GPIO
tristate "GPIO-based bitbanging SPI Master"
depends on GENERIC_GPIO
Expand Down
1 change: 1 addition & 0 deletions drivers/spi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ obj-$(CONFIG_SPI_DAVINCI) += davinci_spi.o
obj-$(CONFIG_SPI_DESIGNWARE) += dw_spi.o
obj-$(CONFIG_SPI_DW_PCI) += dw_spi_pci.o
obj-$(CONFIG_SPI_DW_MMIO) += dw_spi_mmio.o
obj-$(CONFIG_SPI_EP93XX) += ep93xx_spi.o
obj-$(CONFIG_SPI_GPIO) += spi_gpio.o
obj-$(CONFIG_SPI_IMX) += spi_imx.o
obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o
Expand Down
Loading

0 comments on commit 011f23a

Please sign in to comment.