These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / arm / mach-ep93xx / simone.c
index 36f22c1..7bb540c 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/i2c-gpio.h>
+#include <linux/mmc/host.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/mmc_spi.h>
+#include <linux/platform_data/video-ep93xx.h>
+#include <linux/platform_data/spi-ep93xx.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
-#include <linux/platform_data/video-ep93xx.h>
 #include <mach/gpio-ep93xx.h>
 
 #include <asm/mach-types.h>
@@ -35,11 +40,136 @@ static struct ep93xx_eth_data __initdata simone_eth_data = {
 };
 
 static struct ep93xxfb_mach_info __initdata simone_fb_info = {
-       .num_modes      = EP93XXFB_USE_MODEDB,
-       .bpp            = 16,
        .flags          = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING,
 };
 
+/*
+ * GPIO lines used for MMC card detection.
+ */
+#define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0
+
+/*
+ * Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes
+ * low between multi-message command blocks. From v1.4, it uses a GPIO instead.
+ * v1.3 parts will still work, since the signal on SFRMOUT is automatic.
+ */
+#define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO1
+
+/*
+ * MMC SPI chip select GPIO handling. If you are using SFRMOUT (SFRM1) signal,
+ * you can leave these empty and pass NULL as .controller_data.
+ */
+
+static int simone_mmc_spi_setup(struct spi_device *spi)
+{
+       unsigned int gpio = MMC_CHIP_SELECT_GPIO;
+       int err;
+
+       err = gpio_request(gpio, spi->modalias);
+       if (err)
+               return err;
+
+       err = gpio_direction_output(gpio, 1);
+       if (err) {
+               gpio_free(gpio);
+               return err;
+       }
+
+       return 0;
+}
+
+static void simone_mmc_spi_cleanup(struct spi_device *spi)
+{
+       unsigned int gpio = MMC_CHIP_SELECT_GPIO;
+
+       gpio_set_value(gpio, 1);
+       gpio_direction_input(gpio);
+       gpio_free(gpio);
+}
+
+static void simone_mmc_spi_cs_control(struct spi_device *spi, int value)
+{
+       gpio_set_value(MMC_CHIP_SELECT_GPIO, value);
+}
+
+static struct ep93xx_spi_chip_ops simone_mmc_spi_ops = {
+       .setup          = simone_mmc_spi_setup,
+       .cleanup        = simone_mmc_spi_cleanup,
+       .cs_control     = simone_mmc_spi_cs_control,
+};
+
+/*
+ * MMC card detection GPIO setup.
+ */
+
+static int simone_mmc_spi_init(struct device *dev,
+       irqreturn_t (*irq_handler)(int, void *), void *mmc)
+{
+       unsigned int gpio = MMC_CARD_DETECT_GPIO;
+       int irq, err;
+
+       err = gpio_request(gpio, dev_name(dev));
+       if (err)
+               return err;
+
+       err = gpio_direction_input(gpio);
+       if (err)
+               goto fail;
+
+       irq = gpio_to_irq(gpio);
+       if (irq < 0)
+               goto fail;
+
+       err = request_irq(irq, irq_handler, IRQF_TRIGGER_FALLING,
+                         "MMC card detect", mmc);
+       if (err)
+               goto fail;
+
+       printk(KERN_INFO "%s: using irq %d for MMC card detection\n",
+              dev_name(dev), irq);
+
+       return 0;
+fail:
+       gpio_free(gpio);
+       return err;
+}
+
+static void simone_mmc_spi_exit(struct device *dev, void *mmc)
+{
+       unsigned int gpio = MMC_CARD_DETECT_GPIO;
+
+       free_irq(gpio_to_irq(gpio), mmc);
+       gpio_free(gpio);
+}
+
+static struct mmc_spi_platform_data simone_mmc_spi_data = {
+       .init           = simone_mmc_spi_init,
+       .exit           = simone_mmc_spi_exit,
+       .detect_delay   = 500,
+       .ocr_mask       = MMC_VDD_32_33 | MMC_VDD_33_34,
+};
+
+static struct spi_board_info simone_spi_devices[] __initdata = {
+       {
+               .modalias               = "mmc_spi",
+               .controller_data        = &simone_mmc_spi_ops,
+               .platform_data          = &simone_mmc_spi_data,
+               /*
+                * We use 10 MHz even though the maximum is 3.7 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_3,
+       },
+};
+
+static struct ep93xx_spi_info simone_spi_info __initdata = {
+       .num_chipselect = ARRAY_SIZE(simone_spi_devices),
+       .use_dma = 1,
+};
+
 static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = {
        .sda_pin                = EP93XX_GPIO_LINE_EEDAT,
        .sda_is_open_drain      = 0,
@@ -74,6 +204,8 @@ static void __init simone_init_machine(void)
        ep93xx_register_fb(&simone_fb_info);
        ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
                            ARRAY_SIZE(simone_i2c_board_info));
+       ep93xx_register_spi(&simone_spi_info, simone_spi_devices,
+                           ARRAY_SIZE(simone_spi_devices));
        simone_register_audio();
 }