@@ -14,11 +14,15 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/gpio.h>
#include <linux/m48t86.h>
#include <linux/mtd/physmap.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/eeprom.h>
#include <mach/hardware.h>
#include <mach/ts72xx.h>
+#include <mach/ep93xx_spi.h>
#include <asm/mach-types.h>
#include <asm/mach/map.h>
@@ -190,6 +194,105 @@ static struct ep93xx_eth_data ts72xx_eth_data = {
.phy_id = 1,
};
+static const struct spi_board_info ts72xx_spi_devices[] __initconst = {
+ {
+ .modalias = "mmc_spi",
+ .max_speed_hz = 10 * 1000 * 1000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ },
+};
+
+/*
+ * Mapping of SPI chip selects to GPIO pins. In TS-72xx we have GPIO lines
+ * 8-15 wired into DIO1 header which can be used as chip selects.
+ */
+static const unsigned ts72xx_spi_chip_selects[] = {
+ [0] = EP93XX_GPIO_LINE_EGPIO8,
+ [1] = EP93XX_GPIO_LINE_EGPIO9,
+ /*
+ * Add more here as needed.
+ */
+};
+
+static inline unsigned cs_to_gpio(unsigned cs)
+{
+ BUG_ON(cs >= ARRAY_SIZE(ts72xx_spi_chip_selects));
+ return ts72xx_spi_chip_selects[cs];
+}
+
+static void ts72xx_spi_cs_control(unsigned cs, unsigned value, void *data)
+{
+ (void)data;
+ gpio_set_value(cs_to_gpio(cs), value);
+}
+
+static struct ep93xx_spi_info ts72xx_spi_info = {
+ .num_chipselect = ARRAY_SIZE(ts72xx_spi_chip_selects),
+ .cs_control = ts72xx_spi_cs_control,
+};
+
+/**
+ * ts72xx_init_spi() - initializes board SPI devices
+ *
+ * This function initializes all the SPI devices declared in ts72xx_spi_devices
+ * array. It also allocates GPIO line as chip selects for each device. Chip
+ * selects are declared in ts72xx_spi_chip_selects array.
+ */
+static void __init ts72xx_init_spi(void)
+{
+ unsigned gpio;
+ int i, err;
+
+ /*
+ * Now go through all SPI peripherals that board wants to register
+ * and acquire gpio for every chip select.
+ */
+ for (i = 0; i < ARRAY_SIZE(ts72xx_spi_devices); i++) {
+ gpio = cs_to_gpio(ts72xx_spi_devices[i].chip_select);
+
+ err = gpio_request(gpio, "ep93xx-spi");
+ if (err) {
+ pr_err("failed to allocate GPIO%d\n", gpio);
+ goto fail;
+ }
+
+ /*
+ * We default chip selects to be active low. This can be
+ * changed by the protocol drivers passing SPI_CS_HIGH flag
+ * to ep93xx-spi driver. The driver then changes the value
+ * by using info->cs_control().
+ */
+ err = gpio_direction_output(gpio, 1);
+ if (err) {
+ pr_err("failed to configure GPIO%d\n", gpio);
+ goto fail;
+ }
+ }
+
+ err = spi_register_board_info(ts72xx_spi_devices,
+ ARRAY_SIZE(ts72xx_spi_devices));
+ if (err) {
+ pr_err("failed to register SPI devices\n");
+ goto fail;
+ }
+
+ err = ep93xx_register_spi(&ts72xx_spi_info);
+ if (err) {
+ pr_err("failed to register SPI platform device\n");
+ goto fail;
+ }
+
+ return;
+
+fail:
+ while (--i >= 0) {
+ gpio = cs_to_gpio(ts72xx_spi_devices[i].chip_select);
+ gpio_free(gpio);
+ }
+}
+
static void __init ts72xx_init_machine(void)
{
ep93xx_init_devices();
@@ -198,6 +301,7 @@ static void __init ts72xx_init_machine(void)
platform_device_register(&ts72xx_wdt_device);
ep93xx_register_eth(&ts72xx_eth_data, 1);
+ ts72xx_init_spi();
}
MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC")