Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: ep93xx: simone: support for SPI-based MMC/SD cards

This includes setting up EGPIOs 0 and 9 for card detection and
chip select respectively. This patch is needed to mount a root
filesystem on the SPI-based MMC card reader found on the Sim.One.

Signed-off-by: Mika Westerberg <mika.westerberg@iki.fi>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Kevin Hilman <khilman@linaro.org>

authored by

Mika Westerberg and committed by
Kevin Hilman
d50bfa47 259413af

+134 -1
+134 -1
arch/arm/mach-ep93xx/simone.c
··· 20 20 #include <linux/platform_device.h> 21 21 #include <linux/i2c.h> 22 22 #include <linux/i2c-gpio.h> 23 + #include <linux/mmc/host.h> 24 + #include <linux/spi/spi.h> 25 + #include <linux/spi/mmc_spi.h> 26 + #include <linux/platform_data/video-ep93xx.h> 27 + #include <linux/platform_data/spi-ep93xx.h> 28 + #include <linux/gpio.h> 23 29 24 30 #include <mach/hardware.h> 25 - #include <linux/platform_data/video-ep93xx.h> 26 31 #include <mach/gpio-ep93xx.h> 27 32 28 33 #include <asm/mach-types.h> ··· 43 38 .num_modes = EP93XXFB_USE_MODEDB, 44 39 .bpp = 16, 45 40 .flags = EP93XXFB_USE_SDCSN0 | EP93XXFB_PCLK_FALLING, 41 + }; 42 + 43 + /* 44 + * GPIO lines used for MMC card detection. 45 + */ 46 + #define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0 47 + 48 + /* 49 + * Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes 50 + * low between multi-message command blocks. From v1.4, it uses a GPIO instead. 51 + * v1.3 parts will still work, since the signal on SFRMOUT is automatic. 52 + */ 53 + #define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO1 54 + 55 + /* 56 + * MMC SPI chip select GPIO handling. If you are using SFRMOUT (SFRM1) signal, 57 + * you can leave these empty and pass NULL as .controller_data. 58 + */ 59 + 60 + static int simone_mmc_spi_setup(struct spi_device *spi) 61 + { 62 + unsigned int gpio = MMC_CHIP_SELECT_GPIO; 63 + int err; 64 + 65 + err = gpio_request(gpio, spi->modalias); 66 + if (err) 67 + return err; 68 + 69 + err = gpio_direction_output(gpio, 1); 70 + if (err) { 71 + gpio_free(gpio); 72 + return err; 73 + } 74 + 75 + return 0; 76 + } 77 + 78 + static void simone_mmc_spi_cleanup(struct spi_device *spi) 79 + { 80 + unsigned int gpio = MMC_CHIP_SELECT_GPIO; 81 + 82 + gpio_set_value(gpio, 1); 83 + gpio_direction_input(gpio); 84 + gpio_free(gpio); 85 + } 86 + 87 + static void simone_mmc_spi_cs_control(struct spi_device *spi, int value) 88 + { 89 + gpio_set_value(MMC_CHIP_SELECT_GPIO, value); 90 + } 91 + 92 + static struct ep93xx_spi_chip_ops simone_mmc_spi_ops = { 93 + .setup = simone_mmc_spi_setup, 94 + .cleanup = simone_mmc_spi_cleanup, 95 + .cs_control = simone_mmc_spi_cs_control, 96 + }; 97 + 98 + /* 99 + * MMC card detection GPIO setup. 100 + */ 101 + 102 + static int simone_mmc_spi_init(struct device *dev, 103 + irqreturn_t (*irq_handler)(int, void *), void *mmc) 104 + { 105 + unsigned int gpio = MMC_CARD_DETECT_GPIO; 106 + int irq, err; 107 + 108 + err = gpio_request(gpio, dev_name(dev)); 109 + if (err) 110 + return err; 111 + 112 + err = gpio_direction_input(gpio); 113 + if (err) 114 + goto fail; 115 + 116 + irq = gpio_to_irq(gpio); 117 + if (irq < 0) 118 + goto fail; 119 + 120 + err = request_irq(irq, irq_handler, IRQF_TRIGGER_FALLING, 121 + "MMC card detect", mmc); 122 + if (err) 123 + goto fail; 124 + 125 + printk(KERN_INFO "%s: using irq %d for MMC card detection\n", 126 + dev_name(dev), irq); 127 + 128 + return 0; 129 + fail: 130 + gpio_free(gpio); 131 + return err; 132 + } 133 + 134 + static void simone_mmc_spi_exit(struct device *dev, void *mmc) 135 + { 136 + unsigned int gpio = MMC_CARD_DETECT_GPIO; 137 + 138 + free_irq(gpio_to_irq(gpio), mmc); 139 + gpio_free(gpio); 140 + } 141 + 142 + static struct mmc_spi_platform_data simone_mmc_spi_data = { 143 + .init = simone_mmc_spi_init, 144 + .exit = simone_mmc_spi_exit, 145 + .detect_delay = 500, 146 + .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, 147 + }; 148 + 149 + static struct spi_board_info simone_spi_devices[] __initdata = { 150 + { 151 + .modalias = "mmc_spi", 152 + .controller_data = &simone_mmc_spi_ops, 153 + .platform_data = &simone_mmc_spi_data, 154 + /* 155 + * We use 10 MHz even though the maximum is 3.7 MHz. The driver 156 + * will limit it automatically to max. frequency. 157 + */ 158 + .max_speed_hz = 10 * 1000 * 1000, 159 + .bus_num = 0, 160 + .chip_select = 0, 161 + .mode = SPI_MODE_3, 162 + }, 163 + }; 164 + 165 + static struct ep93xx_spi_info simone_spi_info __initdata = { 166 + .num_chipselect = ARRAY_SIZE(simone_spi_devices), 46 167 }; 47 168 48 169 static struct i2c_gpio_platform_data __initdata simone_i2c_gpio_data = { ··· 205 74 ep93xx_register_fb(&simone_fb_info); 206 75 ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info, 207 76 ARRAY_SIZE(simone_i2c_board_info)); 77 + ep93xx_register_spi(&simone_spi_info, simone_spi_devices, 78 + ARRAY_SIZE(simone_spi_devices)); 208 79 simone_register_audio(); 209 80 } 210 81