diff options
| -rw-r--r-- | Documentation/spi/ep93xx_spi | 105 | ||||
| -rw-r--r-- | arch/arm/mach-ep93xx/edb93xx.c | 31 | ||||
| -rw-r--r-- | arch/arm/mach-ep93xx/simone.c | 63 | ||||
| -rw-r--r-- | arch/arm/mach-ep93xx/vision_ep9307.c | 88 | ||||
| -rw-r--r-- | drivers/spi/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/spi/spi-dw.c | 8 | ||||
| -rw-r--r-- | drivers/spi/spi-dw.h | 1 | ||||
| -rw-r--r-- | drivers/spi/spi-ep93xx.c | 139 | ||||
| -rw-r--r-- | drivers/spi/spi-fsl-lpspi.c | 8 | ||||
| -rw-r--r-- | include/linux/platform_data/spi-ep93xx.h | 17 |
10 files changed, 83 insertions, 379 deletions
diff --git a/Documentation/spi/ep93xx_spi b/Documentation/spi/ep93xx_spi deleted file mode 100644 index 832ddce6e5fb..000000000000 --- a/Documentation/spi/ep93xx_spi +++ /dev/null | |||
| @@ -1,105 +0,0 @@ | |||
| 1 | Cirrus EP93xx SPI controller driver HOWTO | ||
| 2 | ========================================= | ||
| 3 | |||
| 4 | ep93xx_spi driver brings SPI master support for EP93xx SPI controller. Chip | ||
| 5 | selects are implemented with GPIO lines. | ||
| 6 | |||
| 7 | NOTE: If possible, don't use SFRMOUT (SFRM1) signal as a chip select. It will | ||
| 8 | not work correctly (it cannot be controlled by software). Use GPIO lines | ||
| 9 | instead. | ||
| 10 | |||
| 11 | Sample configuration | ||
| 12 | ==================== | ||
| 13 | |||
| 14 | Typically driver configuration is done in platform board files (the files under | ||
| 15 | arch/arm/mach-ep93xx/*.c). In this example we configure MMC over SPI through | ||
| 16 | this driver on TS-7260 board. You can adapt the code to suit your needs. | ||
| 17 | |||
| 18 | This example uses EGPIO9 as SD/MMC card chip select (this is wired in DIO1 | ||
| 19 | header on the board). | ||
| 20 | |||
| 21 | You need to select CONFIG_MMC_SPI to use mmc_spi driver. | ||
| 22 | |||
| 23 | arch/arm/mach-ep93xx/ts72xx.c: | ||
| 24 | |||
| 25 | ... | ||
| 26 | #include <linux/gpio.h> | ||
| 27 | #include <linux/spi/spi.h> | ||
| 28 | |||
| 29 | #include <linux/platform_data/spi-ep93xx.h> | ||
| 30 | |||
| 31 | /* this is our GPIO line used for chip select */ | ||
| 32 | #define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO9 | ||
| 33 | |||
| 34 | static int ts72xx_mmc_spi_setup(struct spi_device *spi) | ||
| 35 | { | ||
| 36 | int err; | ||
| 37 | |||
| 38 | err = gpio_request(MMC_CHIP_SELECT_GPIO, spi->modalias); | ||
| 39 | if (err) | ||
| 40 | return err; | ||
| 41 | |||
| 42 | gpio_direction_output(MMC_CHIP_SELECT_GPIO, 1); | ||
| 43 | |||
| 44 | return 0; | ||
| 45 | } | ||
| 46 | |||
| 47 | static void ts72xx_mmc_spi_cleanup(struct spi_device *spi) | ||
| 48 | { | ||
| 49 | gpio_set_value(MMC_CHIP_SELECT_GPIO, 1); | ||
| 50 | gpio_direction_input(MMC_CHIP_SELECT_GPIO); | ||
| 51 | gpio_free(MMC_CHIP_SELECT_GPIO); | ||
| 52 | } | ||
| 53 | |||
| 54 | static void ts72xx_mmc_spi_cs_control(struct spi_device *spi, int value) | ||
| 55 | { | ||
| 56 | gpio_set_value(MMC_CHIP_SELECT_GPIO, value); | ||
| 57 | } | ||
| 58 | |||
| 59 | static struct ep93xx_spi_chip_ops ts72xx_mmc_spi_ops = { | ||
| 60 | .setup = ts72xx_mmc_spi_setup, | ||
| 61 | .cleanup = ts72xx_mmc_spi_cleanup, | ||
| 62 | .cs_control = ts72xx_mmc_spi_cs_control, | ||
| 63 | }; | ||
| 64 | |||
| 65 | static struct spi_board_info ts72xx_spi_devices[] __initdata = { | ||
| 66 | { | ||
| 67 | .modalias = "mmc_spi", | ||
| 68 | .controller_data = &ts72xx_mmc_spi_ops, | ||
| 69 | /* | ||
| 70 | * We use 10 MHz even though the maximum is 7.4 MHz. The driver | ||
| 71 | * will limit it automatically to max. frequency. | ||
| 72 | */ | ||
| 73 | .max_speed_hz = 10 * 1000 * 1000, | ||
| 74 | .bus_num = 0, | ||
| 75 | .chip_select = 0, | ||
| 76 | .mode = SPI_MODE_0, | ||
| 77 | }, | ||
| 78 | }; | ||
| 79 | |||
| 80 | static struct ep93xx_spi_info ts72xx_spi_info = { | ||
| 81 | .num_chipselect = ARRAY_SIZE(ts72xx_spi_devices), | ||
| 82 | }; | ||
| 83 | |||
| 84 | static void __init ts72xx_init_machine(void) | ||
| 85 | { | ||
| 86 | ... | ||
| 87 | ep93xx_register_spi(&ts72xx_spi_info, ts72xx_spi_devices, | ||
| 88 | ARRAY_SIZE(ts72xx_spi_devices)); | ||
| 89 | } | ||
| 90 | |||
| 91 | The driver can use DMA for the transfers also. In this case ts72xx_spi_info | ||
| 92 | becomes: | ||
| 93 | |||
| 94 | static struct ep93xx_spi_info ts72xx_spi_info = { | ||
| 95 | .num_chipselect = ARRAY_SIZE(ts72xx_spi_devices), | ||
| 96 | .use_dma = true; | ||
| 97 | }; | ||
| 98 | |||
| 99 | Note that CONFIG_EP93XX_DMA should be enabled as well. | ||
| 100 | |||
| 101 | Thanks to | ||
| 102 | ========= | ||
| 103 | Martin Guy, H. Hartley Sweeten and others who helped me during development of | ||
| 104 | the driver. Simplemachines.it donated me a Sim.One board which I used testing | ||
| 105 | the driver on EP9307. | ||
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index ad92d9f7e4df..0ac176386789 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
| 28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
| 29 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
| 30 | #include <linux/gpio.h> | ||
| 31 | #include <linux/i2c.h> | 30 | #include <linux/i2c.h> |
| 32 | #include <linux/i2c-gpio.h> | 31 | #include <linux/i2c-gpio.h> |
| 33 | #include <linux/spi/spi.h> | 32 | #include <linux/spi/spi.h> |
| @@ -106,33 +105,10 @@ static struct cs4271_platform_data edb93xx_cs4271_data = { | |||
| 106 | .gpio_nreset = -EINVAL, /* filled in later */ | 105 | .gpio_nreset = -EINVAL, /* filled in later */ |
| 107 | }; | 106 | }; |
| 108 | 107 | ||
| 109 | static int edb93xx_cs4271_hw_setup(struct spi_device *spi) | ||
| 110 | { | ||
| 111 | return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6, | ||
| 112 | GPIOF_OUT_INIT_HIGH, spi->modalias); | ||
| 113 | } | ||
| 114 | |||
| 115 | static void edb93xx_cs4271_hw_cleanup(struct spi_device *spi) | ||
| 116 | { | ||
| 117 | gpio_free(EP93XX_GPIO_LINE_EGPIO6); | ||
| 118 | } | ||
| 119 | |||
| 120 | static void edb93xx_cs4271_hw_cs_control(struct spi_device *spi, int value) | ||
| 121 | { | ||
| 122 | gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value); | ||
| 123 | } | ||
| 124 | |||
| 125 | static struct ep93xx_spi_chip_ops edb93xx_cs4271_hw = { | ||
| 126 | .setup = edb93xx_cs4271_hw_setup, | ||
| 127 | .cleanup = edb93xx_cs4271_hw_cleanup, | ||
| 128 | .cs_control = edb93xx_cs4271_hw_cs_control, | ||
| 129 | }; | ||
| 130 | |||
| 131 | static struct spi_board_info edb93xx_spi_board_info[] __initdata = { | 108 | static struct spi_board_info edb93xx_spi_board_info[] __initdata = { |
| 132 | { | 109 | { |
| 133 | .modalias = "cs4271", | 110 | .modalias = "cs4271", |
| 134 | .platform_data = &edb93xx_cs4271_data, | 111 | .platform_data = &edb93xx_cs4271_data, |
| 135 | .controller_data = &edb93xx_cs4271_hw, | ||
| 136 | .max_speed_hz = 6000000, | 112 | .max_speed_hz = 6000000, |
| 137 | .bus_num = 0, | 113 | .bus_num = 0, |
| 138 | .chip_select = 0, | 114 | .chip_select = 0, |
| @@ -140,8 +116,13 @@ static struct spi_board_info edb93xx_spi_board_info[] __initdata = { | |||
| 140 | }, | 116 | }, |
| 141 | }; | 117 | }; |
| 142 | 118 | ||
| 119 | static int edb93xx_spi_chipselects[] __initdata = { | ||
| 120 | EP93XX_GPIO_LINE_EGPIO6, | ||
| 121 | }; | ||
| 122 | |||
| 143 | static struct ep93xx_spi_info edb93xx_spi_info __initdata = { | 123 | static struct ep93xx_spi_info edb93xx_spi_info __initdata = { |
| 144 | .num_chipselect = ARRAY_SIZE(edb93xx_spi_board_info), | 124 | .chipselect = edb93xx_spi_chipselects, |
| 125 | .num_chipselect = ARRAY_SIZE(edb93xx_spi_chipselects), | ||
| 145 | }; | 126 | }; |
| 146 | 127 | ||
| 147 | static void __init edb93xx_register_spi(void) | 128 | static void __init edb93xx_register_spi(void) |
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c index 7bb540c421ee..c7a40f245892 100644 --- a/arch/arm/mach-ep93xx/simone.c +++ b/arch/arm/mach-ep93xx/simone.c | |||
| @@ -49,56 +49,6 @@ static struct ep93xxfb_mach_info __initdata simone_fb_info = { | |||
| 49 | #define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0 | 49 | #define MMC_CARD_DETECT_GPIO EP93XX_GPIO_LINE_EGPIO0 |
| 50 | 50 | ||
| 51 | /* | 51 | /* |
| 52 | * Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes | ||
| 53 | * low between multi-message command blocks. From v1.4, it uses a GPIO instead. | ||
| 54 | * v1.3 parts will still work, since the signal on SFRMOUT is automatic. | ||
| 55 | */ | ||
| 56 | #define MMC_CHIP_SELECT_GPIO EP93XX_GPIO_LINE_EGPIO1 | ||
| 57 | |||
| 58 | /* | ||
| 59 | * MMC SPI chip select GPIO handling. If you are using SFRMOUT (SFRM1) signal, | ||
| 60 | * you can leave these empty and pass NULL as .controller_data. | ||
| 61 | */ | ||
| 62 | |||
| 63 | static int simone_mmc_spi_setup(struct spi_device *spi) | ||
| 64 | { | ||
| 65 | unsigned int gpio = MMC_CHIP_SELECT_GPIO; | ||
| 66 | int err; | ||
| 67 | |||
| 68 | err = gpio_request(gpio, spi->modalias); | ||
| 69 | if (err) | ||
| 70 | return err; | ||
| 71 | |||
| 72 | err = gpio_direction_output(gpio, 1); | ||
| 73 | if (err) { | ||
| 74 | gpio_free(gpio); | ||
| 75 | return err; | ||
| 76 | } | ||
| 77 | |||
| 78 | return 0; | ||
| 79 | } | ||
| 80 | |||
| 81 | static void simone_mmc_spi_cleanup(struct spi_device *spi) | ||
| 82 | { | ||
| 83 | unsigned int gpio = MMC_CHIP_SELECT_GPIO; | ||
| 84 | |||
| 85 | gpio_set_value(gpio, 1); | ||
| 86 | gpio_direction_input(gpio); | ||
| 87 | gpio_free(gpio); | ||
| 88 | } | ||
| 89 | |||
| 90 | static void simone_mmc_spi_cs_control(struct spi_device *spi, int value) | ||
| 91 | { | ||
| 92 | gpio_set_value(MMC_CHIP_SELECT_GPIO, value); | ||
| 93 | } | ||
| 94 | |||
| 95 | static struct ep93xx_spi_chip_ops simone_mmc_spi_ops = { | ||
| 96 | .setup = simone_mmc_spi_setup, | ||
| 97 | .cleanup = simone_mmc_spi_cleanup, | ||
| 98 | .cs_control = simone_mmc_spi_cs_control, | ||
| 99 | }; | ||
| 100 | |||
| 101 | /* | ||
| 102 | * MMC card detection GPIO setup. | 52 | * MMC card detection GPIO setup. |
| 103 | */ | 53 | */ |
| 104 | 54 | ||
| @@ -152,7 +102,6 @@ static struct mmc_spi_platform_data simone_mmc_spi_data = { | |||
| 152 | static struct spi_board_info simone_spi_devices[] __initdata = { | 102 | static struct spi_board_info simone_spi_devices[] __initdata = { |
| 153 | { | 103 | { |
| 154 | .modalias = "mmc_spi", | 104 | .modalias = "mmc_spi", |
| 155 | .controller_data = &simone_mmc_spi_ops, | ||
| 156 | .platform_data = &simone_mmc_spi_data, | 105 | .platform_data = &simone_mmc_spi_data, |
| 157 | /* | 106 | /* |
| 158 | * We use 10 MHz even though the maximum is 3.7 MHz. The driver | 107 | * We use 10 MHz even though the maximum is 3.7 MHz. The driver |
| @@ -165,8 +114,18 @@ static struct spi_board_info simone_spi_devices[] __initdata = { | |||
| 165 | }, | 114 | }, |
| 166 | }; | 115 | }; |
| 167 | 116 | ||
| 117 | /* | ||
| 118 | * Up to v1.3, the Sim.One used SFRMOUT as SD card chip select, but this goes | ||
| 119 | * low between multi-message command blocks. From v1.4, it uses a GPIO instead. | ||
| 120 | * v1.3 parts will still work, since the signal on SFRMOUT is automatic. | ||
| 121 | */ | ||
| 122 | static int simone_spi_chipselects[] __initdata = { | ||
| 123 | EP93XX_GPIO_LINE_EGPIO1, | ||
| 124 | }; | ||
| 125 | |||
| 168 | static struct ep93xx_spi_info simone_spi_info __initdata = { | 126 | static struct ep93xx_spi_info simone_spi_info __initdata = { |
| 169 | .num_chipselect = ARRAY_SIZE(simone_spi_devices), | 127 | .chipselect = simone_spi_chipselects, |
| 128 | .num_chipselect = ARRAY_SIZE(simone_spi_chipselects), | ||
| 170 | .use_dma = 1, | 129 | .use_dma = 1, |
| 171 | }; | 130 | }; |
| 172 | 131 | ||
diff --git a/arch/arm/mach-ep93xx/vision_ep9307.c b/arch/arm/mach-ep93xx/vision_ep9307.c index 5cced5988498..1daf9441058c 100644 --- a/arch/arm/mach-ep93xx/vision_ep9307.c +++ b/arch/arm/mach-ep93xx/vision_ep9307.c | |||
| @@ -175,33 +175,9 @@ static struct cs4271_platform_data vision_cs4271_data = { | |||
| 175 | .gpio_nreset = EP93XX_GPIO_LINE_H(2), | 175 | .gpio_nreset = EP93XX_GPIO_LINE_H(2), |
| 176 | }; | 176 | }; |
| 177 | 177 | ||
| 178 | static int vision_cs4271_hw_setup(struct spi_device *spi) | ||
| 179 | { | ||
| 180 | return gpio_request_one(EP93XX_GPIO_LINE_EGPIO6, | ||
| 181 | GPIOF_OUT_INIT_HIGH, spi->modalias); | ||
| 182 | } | ||
| 183 | |||
| 184 | static void vision_cs4271_hw_cleanup(struct spi_device *spi) | ||
| 185 | { | ||
| 186 | gpio_free(EP93XX_GPIO_LINE_EGPIO6); | ||
| 187 | } | ||
| 188 | |||
| 189 | static void vision_cs4271_hw_cs_control(struct spi_device *spi, int value) | ||
| 190 | { | ||
| 191 | gpio_set_value(EP93XX_GPIO_LINE_EGPIO6, value); | ||
| 192 | } | ||
| 193 | |||
| 194 | static struct ep93xx_spi_chip_ops vision_cs4271_hw = { | ||
| 195 | .setup = vision_cs4271_hw_setup, | ||
| 196 | .cleanup = vision_cs4271_hw_cleanup, | ||
| 197 | .cs_control = vision_cs4271_hw_cs_control, | ||
| 198 | }; | ||
| 199 | |||
| 200 | /************************************************************************* | 178 | /************************************************************************* |
| 201 | * SPI Flash | 179 | * SPI Flash |
| 202 | *************************************************************************/ | 180 | *************************************************************************/ |
| 203 | #define VISION_SPI_FLASH_CS EP93XX_GPIO_LINE_EGPIO7 | ||
| 204 | |||
| 205 | static struct mtd_partition vision_spi_flash_partitions[] = { | 181 | static struct mtd_partition vision_spi_flash_partitions[] = { |
| 206 | { | 182 | { |
| 207 | .name = "SPI bootstrap", | 183 | .name = "SPI bootstrap", |
| @@ -224,68 +200,20 @@ static struct flash_platform_data vision_spi_flash_data = { | |||
| 224 | .nr_parts = ARRAY_SIZE(vision_spi_flash_partitions), | 200 | .nr_parts = ARRAY_SIZE(vision_spi_flash_partitions), |
| 225 | }; | 201 | }; |
| 226 | 202 | ||
| 227 | static int vision_spi_flash_hw_setup(struct spi_device *spi) | ||
| 228 | { | ||
| 229 | return gpio_request_one(VISION_SPI_FLASH_CS, GPIOF_INIT_HIGH, | ||
| 230 | spi->modalias); | ||
| 231 | } | ||
| 232 | |||
| 233 | static void vision_spi_flash_hw_cleanup(struct spi_device *spi) | ||
| 234 | { | ||
| 235 | gpio_free(VISION_SPI_FLASH_CS); | ||
| 236 | } | ||
| 237 | |||
| 238 | static void vision_spi_flash_hw_cs_control(struct spi_device *spi, int value) | ||
| 239 | { | ||
| 240 | gpio_set_value(VISION_SPI_FLASH_CS, value); | ||
| 241 | } | ||
| 242 | |||
| 243 | static struct ep93xx_spi_chip_ops vision_spi_flash_hw = { | ||
| 244 | .setup = vision_spi_flash_hw_setup, | ||
| 245 | .cleanup = vision_spi_flash_hw_cleanup, | ||
| 246 | .cs_control = vision_spi_flash_hw_cs_control, | ||
| 247 | }; | ||
| 248 | |||
| 249 | /************************************************************************* | 203 | /************************************************************************* |
| 250 | * SPI SD/MMC host | 204 | * SPI SD/MMC host |
| 251 | *************************************************************************/ | 205 | *************************************************************************/ |
| 252 | #define VISION_SPI_MMC_CS EP93XX_GPIO_LINE_G(2) | ||
| 253 | #define VISION_SPI_MMC_WP EP93XX_GPIO_LINE_F(0) | ||
| 254 | #define VISION_SPI_MMC_CD EP93XX_GPIO_LINE_EGPIO15 | ||
| 255 | |||
| 256 | static struct mmc_spi_platform_data vision_spi_mmc_data = { | 206 | static struct mmc_spi_platform_data vision_spi_mmc_data = { |
| 257 | .detect_delay = 100, | 207 | .detect_delay = 100, |
| 258 | .powerup_msecs = 100, | 208 | .powerup_msecs = 100, |
| 259 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, | 209 | .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, |
| 260 | .flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO, | 210 | .flags = MMC_SPI_USE_CD_GPIO | MMC_SPI_USE_RO_GPIO, |
| 261 | .cd_gpio = VISION_SPI_MMC_CD, | 211 | .cd_gpio = EP93XX_GPIO_LINE_EGPIO15, |
| 262 | .cd_debounce = 1, | 212 | .cd_debounce = 1, |
| 263 | .ro_gpio = VISION_SPI_MMC_WP, | 213 | .ro_gpio = EP93XX_GPIO_LINE_F(0), |
| 264 | .caps2 = MMC_CAP2_RO_ACTIVE_HIGH, | 214 | .caps2 = MMC_CAP2_RO_ACTIVE_HIGH, |
| 265 | }; | 215 | }; |
| 266 | 216 | ||
| 267 | static int vision_spi_mmc_hw_setup(struct spi_device *spi) | ||
| 268 | { | ||
| 269 | return gpio_request_one(VISION_SPI_MMC_CS, GPIOF_INIT_HIGH, | ||
| 270 | spi->modalias); | ||
| 271 | } | ||
| 272 | |||
| 273 | static void vision_spi_mmc_hw_cleanup(struct spi_device *spi) | ||
| 274 | { | ||
| 275 | gpio_free(VISION_SPI_MMC_CS); | ||
| 276 | } | ||
| 277 | |||
| 278 | static void vision_spi_mmc_hw_cs_control(struct spi_device *spi, int value) | ||
| 279 | { | ||
| 280 | gpio_set_value(VISION_SPI_MMC_CS, value); | ||
| 281 | } | ||
| 282 | |||
| 283 | static struct ep93xx_spi_chip_ops vision_spi_mmc_hw = { | ||
| 284 | .setup = vision_spi_mmc_hw_setup, | ||
| 285 | .cleanup = vision_spi_mmc_hw_cleanup, | ||
| 286 | .cs_control = vision_spi_mmc_hw_cs_control, | ||
| 287 | }; | ||
| 288 | |||
| 289 | /************************************************************************* | 217 | /************************************************************************* |
| 290 | * SPI Bus | 218 | * SPI Bus |
| 291 | *************************************************************************/ | 219 | *************************************************************************/ |
| @@ -293,7 +221,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { | |||
| 293 | { | 221 | { |
| 294 | .modalias = "cs4271", | 222 | .modalias = "cs4271", |
| 295 | .platform_data = &vision_cs4271_data, | 223 | .platform_data = &vision_cs4271_data, |
| 296 | .controller_data = &vision_cs4271_hw, | ||
| 297 | .max_speed_hz = 6000000, | 224 | .max_speed_hz = 6000000, |
| 298 | .bus_num = 0, | 225 | .bus_num = 0, |
| 299 | .chip_select = 0, | 226 | .chip_select = 0, |
| @@ -301,7 +228,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { | |||
| 301 | }, { | 228 | }, { |
| 302 | .modalias = "sst25l", | 229 | .modalias = "sst25l", |
| 303 | .platform_data = &vision_spi_flash_data, | 230 | .platform_data = &vision_spi_flash_data, |
| 304 | .controller_data = &vision_spi_flash_hw, | ||
| 305 | .max_speed_hz = 20000000, | 231 | .max_speed_hz = 20000000, |
| 306 | .bus_num = 0, | 232 | .bus_num = 0, |
| 307 | .chip_select = 1, | 233 | .chip_select = 1, |
| @@ -309,7 +235,6 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { | |||
| 309 | }, { | 235 | }, { |
| 310 | .modalias = "mmc_spi", | 236 | .modalias = "mmc_spi", |
| 311 | .platform_data = &vision_spi_mmc_data, | 237 | .platform_data = &vision_spi_mmc_data, |
| 312 | .controller_data = &vision_spi_mmc_hw, | ||
| 313 | .max_speed_hz = 20000000, | 238 | .max_speed_hz = 20000000, |
| 314 | .bus_num = 0, | 239 | .bus_num = 0, |
| 315 | .chip_select = 2, | 240 | .chip_select = 2, |
| @@ -317,8 +242,15 @@ static struct spi_board_info vision_spi_board_info[] __initdata = { | |||
| 317 | }, | 242 | }, |
| 318 | }; | 243 | }; |
| 319 | 244 | ||
| 245 | static int vision_spi_chipselects[] __initdata = { | ||
| 246 | EP93XX_GPIO_LINE_EGPIO6, | ||
| 247 | EP93XX_GPIO_LINE_EGPIO7, | ||
| 248 | EP93XX_GPIO_LINE_G(2), | ||
| 249 | }; | ||
| 250 | |||
| 320 | static struct ep93xx_spi_info vision_spi_master __initdata = { | 251 | static struct ep93xx_spi_info vision_spi_master __initdata = { |
| 321 | .num_chipselect = ARRAY_SIZE(vision_spi_board_info), | 252 | .chipselect = vision_spi_chipselects, |
| 253 | .num_chipselect = ARRAY_SIZE(vision_spi_chipselects), | ||
| 322 | .use_dma = 1, | 254 | .use_dma = 1, |
| 323 | }; | 255 | }; |
| 324 | 256 | ||
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 0f8afeed648e..7415022fa0d7 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
| @@ -264,7 +264,7 @@ config SPI_EP93XX | |||
| 264 | mode. | 264 | mode. |
| 265 | 265 | ||
| 266 | config SPI_FALCON | 266 | config SPI_FALCON |
| 267 | tristate "Falcon SPI controller support" | 267 | bool "Falcon SPI controller support" |
| 268 | depends on SOC_FALCON | 268 | depends on SOC_FALCON |
| 269 | help | 269 | help |
| 270 | The external bus unit (EBU) found on the FALC-ON SoC has SPI | 270 | The external bus unit (EBU) found on the FALC-ON SoC has SPI |
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c index 054012f87567..b217c22ff72f 100644 --- a/drivers/spi/spi-dw.c +++ b/drivers/spi/spi-dw.c | |||
| @@ -107,9 +107,9 @@ static const struct file_operations dw_spi_regs_ops = { | |||
| 107 | 107 | ||
| 108 | static int dw_spi_debugfs_init(struct dw_spi *dws) | 108 | static int dw_spi_debugfs_init(struct dw_spi *dws) |
| 109 | { | 109 | { |
| 110 | char name[128]; | 110 | char name[32]; |
| 111 | 111 | ||
| 112 | snprintf(name, 128, "dw_spi-%s", dev_name(&dws->master->dev)); | 112 | snprintf(name, 32, "dw_spi%d", dws->master->bus_num); |
| 113 | dws->debugfs = debugfs_create_dir(name, NULL); | 113 | dws->debugfs = debugfs_create_dir(name, NULL); |
| 114 | if (!dws->debugfs) | 114 | if (!dws->debugfs) |
| 115 | return -ENOMEM; | 115 | return -ENOMEM; |
| @@ -486,9 +486,9 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws) | |||
| 486 | dws->type = SSI_MOTO_SPI; | 486 | dws->type = SSI_MOTO_SPI; |
| 487 | dws->dma_inited = 0; | 487 | dws->dma_inited = 0; |
| 488 | dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); | 488 | dws->dma_addr = (dma_addr_t)(dws->paddr + DW_SPI_DR); |
| 489 | snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num); | ||
| 490 | 489 | ||
| 491 | ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dws->name, master); | 490 | ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev), |
| 491 | master); | ||
| 492 | if (ret < 0) { | 492 | if (ret < 0) { |
| 493 | dev_err(dev, "can not get IRQ\n"); | 493 | dev_err(dev, "can not get IRQ\n"); |
| 494 | goto err_free_master; | 494 | goto err_free_master; |
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index c21ca02f8ec5..da5eab62df34 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h | |||
| @@ -101,7 +101,6 @@ struct dw_spi_dma_ops { | |||
| 101 | struct dw_spi { | 101 | struct dw_spi { |
| 102 | struct spi_master *master; | 102 | struct spi_master *master; |
| 103 | enum dw_ssi_type type; | 103 | enum dw_ssi_type type; |
| 104 | char name[16]; | ||
| 105 | 104 | ||
| 106 | void __iomem *regs; | 105 | void __iomem *regs; |
| 107 | unsigned long paddr; | 106 | unsigned long paddr; |
diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index 17a6387e20b5..b5d766064b7b 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
| 29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
| 30 | #include <linux/scatterlist.h> | 30 | #include <linux/scatterlist.h> |
| 31 | #include <linux/gpio.h> | ||
| 31 | #include <linux/spi/spi.h> | 32 | #include <linux/spi/spi.h> |
| 32 | 33 | ||
| 33 | #include <linux/platform_data/dma-ep93xx.h> | 34 | #include <linux/platform_data/dma-ep93xx.h> |
| @@ -107,16 +108,6 @@ struct ep93xx_spi { | |||
| 107 | void *zeropage; | 108 | void *zeropage; |
| 108 | }; | 109 | }; |
| 109 | 110 | ||
| 110 | /** | ||
| 111 | * struct ep93xx_spi_chip - SPI device hardware settings | ||
| 112 | * @spi: back pointer to the SPI device | ||
| 113 | * @ops: private chip operations | ||
| 114 | */ | ||
| 115 | struct ep93xx_spi_chip { | ||
| 116 | const struct spi_device *spi; | ||
| 117 | struct ep93xx_spi_chip_ops *ops; | ||
| 118 | }; | ||
| 119 | |||
| 120 | /* converts bits per word to CR0.DSS value */ | 111 | /* converts bits per word to CR0.DSS value */ |
| 121 | #define bits_per_word_to_dss(bpw) ((bpw) - 1) | 112 | #define bits_per_word_to_dss(bpw) ((bpw) - 1) |
| 122 | 113 | ||
| @@ -229,104 +220,36 @@ static int ep93xx_spi_calc_divisors(const struct ep93xx_spi *espi, | |||
| 229 | return -EINVAL; | 220 | return -EINVAL; |
| 230 | } | 221 | } |
| 231 | 222 | ||
| 232 | static void ep93xx_spi_cs_control(struct spi_device *spi, bool control) | 223 | static void ep93xx_spi_cs_control(struct spi_device *spi, bool enable) |
| 233 | { | ||
| 234 | struct ep93xx_spi_chip *chip = spi_get_ctldata(spi); | ||
| 235 | int value = (spi->mode & SPI_CS_HIGH) ? control : !control; | ||
| 236 | |||
| 237 | if (chip->ops && chip->ops->cs_control) | ||
| 238 | chip->ops->cs_control(spi, value); | ||
| 239 | } | ||
| 240 | |||
| 241 | /** | ||
| 242 | * ep93xx_spi_setup() - setup an SPI device | ||
| 243 | * @spi: SPI device to setup | ||
| 244 | * | ||
| 245 | * This function sets up SPI device mode, speed etc. Can be called multiple | ||
| 246 | * times for a single device. Returns %0 in case of success, negative error in | ||
| 247 | * case of failure. When this function returns success, the device is | ||
| 248 | * deselected. | ||
| 249 | */ | ||
| 250 | static int ep93xx_spi_setup(struct spi_device *spi) | ||
| 251 | { | 224 | { |
| 252 | struct ep93xx_spi *espi = spi_master_get_devdata(spi->master); | 225 | if (spi->mode & SPI_CS_HIGH) |
| 253 | struct ep93xx_spi_chip *chip; | 226 | enable = !enable; |
| 254 | 227 | ||
| 255 | chip = spi_get_ctldata(spi); | 228 | if (gpio_is_valid(spi->cs_gpio)) |
| 256 | if (!chip) { | 229 | gpio_set_value(spi->cs_gpio, !enable); |
| 257 | dev_dbg(&espi->pdev->dev, "initial setup for %s\n", | ||
| 258 | spi->modalias); | ||
| 259 | |||
| 260 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
| 261 | if (!chip) | ||
| 262 | return -ENOMEM; | ||
| 263 | |||
| 264 | chip->spi = spi; | ||
| 265 | chip->ops = spi->controller_data; | ||
| 266 | |||
| 267 | if (chip->ops && chip->ops->setup) { | ||
| 268 | int ret = chip->ops->setup(spi); | ||
| 269 | |||
| 270 | if (ret) { | ||
| 271 | kfree(chip); | ||
| 272 | return ret; | ||
| 273 | } | ||
| 274 | } | ||
| 275 | |||
| 276 | spi_set_ctldata(spi, chip); | ||
| 277 | } | ||
| 278 | |||
| 279 | ep93xx_spi_cs_control(spi, false); | ||
| 280 | return 0; | ||
| 281 | } | 230 | } |
| 282 | 231 | ||
| 283 | /** | ||
| 284 | * ep93xx_spi_cleanup() - cleans up master controller specific state | ||
| 285 | * @spi: SPI device to cleanup | ||
| 286 | * | ||
| 287 | * This function releases master controller specific state for given @spi | ||
| 288 | * device. | ||
| 289 | */ | ||
| 290 | static void ep93xx_spi_cleanup(struct spi_device *spi) | ||
| 291 | { | ||
| 292 | struct ep93xx_spi_chip *chip; | ||
| 293 | |||
| 294 | chip = spi_get_ctldata(spi); | ||
| 295 | if (chip) { | ||
| 296 | if (chip->ops && chip->ops->cleanup) | ||
| 297 | chip->ops->cleanup(spi); | ||
| 298 | spi_set_ctldata(spi, NULL); | ||
| 299 | kfree(chip); | ||
| 300 | } | ||
| 301 | } | ||
| 302 | |||
| 303 | /** | ||
| 304 | * ep93xx_spi_chip_setup() - configures hardware according to given @chip | ||
| 305 | * @espi: ep93xx SPI controller struct | ||
| 306 | * @chip: chip specific settings | ||
| 307 | * @speed_hz: transfer speed | ||
| 308 | * @bits_per_word: transfer bits_per_word | ||
| 309 | */ | ||
| 310 | static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi, | 232 | static int ep93xx_spi_chip_setup(const struct ep93xx_spi *espi, |
| 311 | const struct ep93xx_spi_chip *chip, | 233 | struct spi_device *spi, |
| 312 | u32 speed_hz, u8 bits_per_word) | 234 | struct spi_transfer *xfer) |
| 313 | { | 235 | { |
| 314 | u8 dss = bits_per_word_to_dss(bits_per_word); | 236 | u8 dss = bits_per_word_to_dss(xfer->bits_per_word); |
| 315 | u8 div_cpsr = 0; | 237 | u8 div_cpsr = 0; |
| 316 | u8 div_scr = 0; | 238 | u8 div_scr = 0; |
| 317 | u16 cr0; | 239 | u16 cr0; |
| 318 | int err; | 240 | int err; |
| 319 | 241 | ||
| 320 | err = ep93xx_spi_calc_divisors(espi, speed_hz, &div_cpsr, &div_scr); | 242 | err = ep93xx_spi_calc_divisors(espi, xfer->speed_hz, |
| 243 | &div_cpsr, &div_scr); | ||
| 321 | if (err) | 244 | if (err) |
| 322 | return err; | 245 | return err; |
| 323 | 246 | ||
| 324 | cr0 = div_scr << SSPCR0_SCR_SHIFT; | 247 | cr0 = div_scr << SSPCR0_SCR_SHIFT; |
| 325 | cr0 |= (chip->spi->mode & (SPI_CPHA|SPI_CPOL)) << SSPCR0_MODE_SHIFT; | 248 | cr0 |= (spi->mode & (SPI_CPHA | SPI_CPOL)) << SSPCR0_MODE_SHIFT; |
| 326 | cr0 |= dss; | 249 | cr0 |= dss; |
| 327 | 250 | ||
| 328 | dev_dbg(&espi->pdev->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n", | 251 | dev_dbg(&espi->pdev->dev, "setup: mode %d, cpsr %d, scr %d, dss %d\n", |
| 329 | chip->spi->mode, div_cpsr, div_scr, dss); | 252 | spi->mode, div_cpsr, div_scr, dss); |
| 330 | dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", cr0); | 253 | dev_dbg(&espi->pdev->dev, "setup: cr0 %#x\n", cr0); |
| 331 | 254 | ||
| 332 | ep93xx_spi_write_u8(espi, SSPCPSR, div_cpsr); | 255 | ep93xx_spi_write_u8(espi, SSPCPSR, div_cpsr); |
| @@ -603,12 +526,11 @@ static void ep93xx_spi_process_transfer(struct ep93xx_spi *espi, | |||
| 603 | struct spi_message *msg, | 526 | struct spi_message *msg, |
| 604 | struct spi_transfer *t) | 527 | struct spi_transfer *t) |
| 605 | { | 528 | { |
| 606 | struct ep93xx_spi_chip *chip = spi_get_ctldata(msg->spi); | ||
| 607 | int err; | 529 | int err; |
| 608 | 530 | ||
| 609 | msg->state = t; | 531 | msg->state = t; |
| 610 | 532 | ||
| 611 | err = ep93xx_spi_chip_setup(espi, chip, t->speed_hz, t->bits_per_word); | 533 | err = ep93xx_spi_chip_setup(espi, msg->spi, t); |
| 612 | if (err) { | 534 | if (err) { |
| 613 | dev_err(&espi->pdev->dev, | 535 | dev_err(&espi->pdev->dev, |
| 614 | "failed to setup chip for transfer\n"); | 536 | "failed to setup chip for transfer\n"); |
| @@ -863,8 +785,13 @@ static int ep93xx_spi_probe(struct platform_device *pdev) | |||
| 863 | struct resource *res; | 785 | struct resource *res; |
| 864 | int irq; | 786 | int irq; |
| 865 | int error; | 787 | int error; |
| 788 | int i; | ||
| 866 | 789 | ||
| 867 | info = dev_get_platdata(&pdev->dev); | 790 | info = dev_get_platdata(&pdev->dev); |
| 791 | if (!info) { | ||
| 792 | dev_err(&pdev->dev, "missing platform data\n"); | ||
| 793 | return -EINVAL; | ||
| 794 | } | ||
| 868 | 795 | ||
| 869 | irq = platform_get_irq(pdev, 0); | 796 | irq = platform_get_irq(pdev, 0); |
| 870 | if (irq < 0) { | 797 | if (irq < 0) { |
| @@ -882,14 +809,36 @@ static int ep93xx_spi_probe(struct platform_device *pdev) | |||
| 882 | if (!master) | 809 | if (!master) |
| 883 | return -ENOMEM; | 810 | return -ENOMEM; |
| 884 | 811 | ||
| 885 | master->setup = ep93xx_spi_setup; | ||
| 886 | master->transfer_one_message = ep93xx_spi_transfer_one_message; | 812 | master->transfer_one_message = ep93xx_spi_transfer_one_message; |
| 887 | master->cleanup = ep93xx_spi_cleanup; | ||
| 888 | master->bus_num = pdev->id; | 813 | master->bus_num = pdev->id; |
| 889 | master->num_chipselect = info->num_chipselect; | ||
| 890 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; | 814 | master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; |
| 891 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); | 815 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); |
| 892 | 816 | ||
| 817 | master->num_chipselect = info->num_chipselect; | ||
| 818 | master->cs_gpios = devm_kzalloc(&master->dev, | ||
| 819 | sizeof(int) * master->num_chipselect, | ||
| 820 | GFP_KERNEL); | ||
| 821 | if (!master->cs_gpios) { | ||
| 822 | error = -ENOMEM; | ||
| 823 | goto fail_release_master; | ||
| 824 | } | ||
| 825 | |||
| 826 | for (i = 0; i < master->num_chipselect; i++) { | ||
| 827 | master->cs_gpios[i] = info->chipselect[i]; | ||
| 828 | |||
| 829 | if (!gpio_is_valid(master->cs_gpios[i])) | ||
| 830 | continue; | ||
| 831 | |||
| 832 | error = devm_gpio_request_one(&pdev->dev, master->cs_gpios[i], | ||
| 833 | GPIOF_OUT_INIT_HIGH, | ||
| 834 | "ep93xx-spi"); | ||
| 835 | if (error) { | ||
| 836 | dev_err(&pdev->dev, "could not request cs gpio %d\n", | ||
| 837 | master->cs_gpios[i]); | ||
| 838 | goto fail_release_master; | ||
| 839 | } | ||
| 840 | } | ||
| 841 | |||
| 893 | platform_set_drvdata(pdev, master); | 842 | platform_set_drvdata(pdev, master); |
| 894 | 843 | ||
| 895 | espi = spi_master_get_devdata(master); | 844 | espi = spi_master_get_devdata(master); |
diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c index 52551f6d0c7d..cb3c73007ca1 100644 --- a/drivers/spi/spi-fsl-lpspi.c +++ b/drivers/spi/spi-fsl-lpspi.c | |||
| @@ -366,7 +366,7 @@ static int fsl_lpspi_transfer_one_msg(struct spi_master *master, | |||
| 366 | struct spi_transfer *xfer; | 366 | struct spi_transfer *xfer; |
| 367 | bool is_first_xfer = true; | 367 | bool is_first_xfer = true; |
| 368 | u32 temp; | 368 | u32 temp; |
| 369 | int ret; | 369 | int ret = 0; |
| 370 | 370 | ||
| 371 | msg->status = 0; | 371 | msg->status = 0; |
| 372 | msg->actual_length = 0; | 372 | msg->actual_length = 0; |
| @@ -512,9 +512,9 @@ static int fsl_lpspi_remove(struct platform_device *pdev) | |||
| 512 | 512 | ||
| 513 | static struct platform_driver fsl_lpspi_driver = { | 513 | static struct platform_driver fsl_lpspi_driver = { |
| 514 | .driver = { | 514 | .driver = { |
| 515 | .name = DRIVER_NAME, | 515 | .name = DRIVER_NAME, |
| 516 | .of_match_table = fsl_lpspi_dt_ids, | 516 | .of_match_table = fsl_lpspi_dt_ids, |
| 517 | }, | 517 | }, |
| 518 | .probe = fsl_lpspi_probe, | 518 | .probe = fsl_lpspi_probe, |
| 519 | .remove = fsl_lpspi_remove, | 519 | .remove = fsl_lpspi_remove, |
| 520 | }; | 520 | }; |
diff --git a/include/linux/platform_data/spi-ep93xx.h b/include/linux/platform_data/spi-ep93xx.h index 9bb63ac13f04..171a271c2cbd 100644 --- a/include/linux/platform_data/spi-ep93xx.h +++ b/include/linux/platform_data/spi-ep93xx.h | |||
| @@ -5,25 +5,14 @@ struct spi_device; | |||
| 5 | 5 | ||
| 6 | /** | 6 | /** |
| 7 | * struct ep93xx_spi_info - EP93xx specific SPI descriptor | 7 | * struct ep93xx_spi_info - EP93xx specific SPI descriptor |
| 8 | * @num_chipselect: number of chip selects on this board, must be | 8 | * @chipselect: array of gpio numbers to use as chip selects |
| 9 | * at least one | 9 | * @num_chipselect: ARRAY_SIZE(chipselect) |
| 10 | * @use_dma: use DMA for the transfers | 10 | * @use_dma: use DMA for the transfers |
| 11 | */ | 11 | */ |
| 12 | struct ep93xx_spi_info { | 12 | struct ep93xx_spi_info { |
| 13 | int *chipselect; | ||
| 13 | int num_chipselect; | 14 | int num_chipselect; |
| 14 | bool use_dma; | 15 | bool use_dma; |
| 15 | }; | 16 | }; |
| 16 | 17 | ||
| 17 | /** | ||
| 18 | * struct ep93xx_spi_chip_ops - operation callbacks for SPI slave device | ||
| 19 | * @setup: setup the chip select mechanism | ||
| 20 | * @cleanup: cleanup the chip select mechanism | ||
| 21 | * @cs_control: control the device chip select | ||
| 22 | */ | ||
| 23 | struct ep93xx_spi_chip_ops { | ||
| 24 | int (*setup)(struct spi_device *spi); | ||
| 25 | void (*cleanup)(struct spi_device *spi); | ||
| 26 | void (*cs_control)(struct spi_device *spi, int value); | ||
| 27 | }; | ||
| 28 | |||
| 29 | #endif /* __ASM_MACH_EP93XX_SPI_H */ | 18 | #endif /* __ASM_MACH_EP93XX_SPI_H */ |
