diff options
-rw-r--r-- | drivers/spi/spi_imx.c | 73 |
1 files changed, 53 insertions, 20 deletions
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 20cdee3b5a2e..60a52d173d8f 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c | |||
@@ -75,6 +75,7 @@ struct spi_imx_devtype_data { | |||
75 | int (*config)(struct spi_imx_data *, struct spi_imx_config *); | 75 | int (*config)(struct spi_imx_data *, struct spi_imx_config *); |
76 | void (*trigger)(struct spi_imx_data *); | 76 | void (*trigger)(struct spi_imx_data *); |
77 | int (*rx_available)(struct spi_imx_data *); | 77 | int (*rx_available)(struct spi_imx_data *); |
78 | void (*reset)(struct spi_imx_data *); | ||
78 | }; | 79 | }; |
79 | 80 | ||
80 | struct spi_imx_data { | 81 | struct spi_imx_data { |
@@ -213,7 +214,7 @@ static void __maybe_unused mx31_trigger(struct spi_imx_data *spi_imx) | |||
213 | writel(reg, spi_imx->base + MXC_CSPICTRL); | 214 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
214 | } | 215 | } |
215 | 216 | ||
216 | static int __maybe_unused mx31_config(struct spi_imx_data *spi_imx, | 217 | static int __maybe_unused spi_imx0_4_config(struct spi_imx_data *spi_imx, |
217 | struct spi_imx_config *config) | 218 | struct spi_imx_config *config) |
218 | { | 219 | { |
219 | unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; | 220 | unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; |
@@ -221,12 +222,7 @@ static int __maybe_unused mx31_config(struct spi_imx_data *spi_imx, | |||
221 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << | 222 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << |
222 | MX31_CSPICTRL_DR_SHIFT; | 223 | MX31_CSPICTRL_DR_SHIFT; |
223 | 224 | ||
224 | if (cpu_is_mx31()) | 225 | reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT; |
225 | reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT; | ||
226 | else if (cpu_is_mx25() || cpu_is_mx35()) { | ||
227 | reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; | ||
228 | reg |= MX31_CSPICTRL_SSCTL; | ||
229 | } | ||
230 | 226 | ||
231 | if (config->mode & SPI_CPHA) | 227 | if (config->mode & SPI_CPHA) |
232 | reg |= MX31_CSPICTRL_PHA; | 228 | reg |= MX31_CSPICTRL_PHA; |
@@ -235,10 +231,7 @@ static int __maybe_unused mx31_config(struct spi_imx_data *spi_imx, | |||
235 | if (config->mode & SPI_CS_HIGH) | 231 | if (config->mode & SPI_CS_HIGH) |
236 | reg |= MX31_CSPICTRL_SSPOL; | 232 | reg |= MX31_CSPICTRL_SSPOL; |
237 | if (config->cs < 0) { | 233 | if (config->cs < 0) { |
238 | if (cpu_is_mx31()) | 234 | reg |= (config->cs + 32) << MX31_CSPICTRL_CS_SHIFT; |
239 | reg |= (config->cs + 32) << MX31_CSPICTRL_CS_SHIFT; | ||
240 | else if (cpu_is_mx25() || cpu_is_mx35()) | ||
241 | reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT; | ||
242 | } | 235 | } |
243 | 236 | ||
244 | writel(reg, spi_imx->base + MXC_CSPICTRL); | 237 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
@@ -246,11 +239,43 @@ static int __maybe_unused mx31_config(struct spi_imx_data *spi_imx, | |||
246 | return 0; | 239 | return 0; |
247 | } | 240 | } |
248 | 241 | ||
242 | static int __maybe_unused spi_imx0_7_config(struct spi_imx_data *spi_imx, | ||
243 | struct spi_imx_config *config) | ||
244 | { | ||
245 | unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; | ||
246 | |||
247 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << | ||
248 | MX31_CSPICTRL_DR_SHIFT; | ||
249 | |||
250 | reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; | ||
251 | reg |= MX31_CSPICTRL_SSCTL; | ||
252 | |||
253 | if (config->mode & SPI_CPHA) | ||
254 | reg |= MX31_CSPICTRL_PHA; | ||
255 | if (config->mode & SPI_CPOL) | ||
256 | reg |= MX31_CSPICTRL_POL; | ||
257 | if (config->mode & SPI_CS_HIGH) | ||
258 | reg |= MX31_CSPICTRL_SSPOL; | ||
259 | if (config->cs < 0) | ||
260 | reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT; | ||
261 | |||
262 | writel(reg, spi_imx->base + MXC_CSPICTRL); | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
249 | static int __maybe_unused mx31_rx_available(struct spi_imx_data *spi_imx) | 267 | static int __maybe_unused mx31_rx_available(struct spi_imx_data *spi_imx) |
250 | { | 268 | { |
251 | return readl(spi_imx->base + MX31_CSPISTATUS) & MX31_STATUS_RR; | 269 | return readl(spi_imx->base + MX31_CSPISTATUS) & MX31_STATUS_RR; |
252 | } | 270 | } |
253 | 271 | ||
272 | static void __maybe_unused spi_imx0_4_reset(struct spi_imx_data *spi_imx) | ||
273 | { | ||
274 | /* drain receive buffer */ | ||
275 | while (readl(spi_imx->base + MX3_CSPISTAT) & MX3_CSPISTAT_RR) | ||
276 | readl(spi_imx->base + MXC_CSPIRXDATA); | ||
277 | } | ||
278 | |||
254 | #define MX27_INTREG_RR (1 << 4) | 279 | #define MX27_INTREG_RR (1 << 4) |
255 | #define MX27_INTREG_TEEN (1 << 9) | 280 | #define MX27_INTREG_TEEN (1 << 9) |
256 | #define MX27_INTREG_RREN (1 << 13) | 281 | #define MX27_INTREG_RREN (1 << 13) |
@@ -313,6 +338,11 @@ static int __maybe_unused mx27_rx_available(struct spi_imx_data *spi_imx) | |||
313 | return readl(spi_imx->base + MXC_CSPIINT) & MX27_INTREG_RR; | 338 | return readl(spi_imx->base + MXC_CSPIINT) & MX27_INTREG_RR; |
314 | } | 339 | } |
315 | 340 | ||
341 | static void __maybe_unused spi_imx0_0_reset(struct spi_imx_data *spi_imx) | ||
342 | { | ||
343 | writel(1, spi_imx->base + MXC_RESET); | ||
344 | } | ||
345 | |||
316 | #define MX1_INTREG_RR (1 << 3) | 346 | #define MX1_INTREG_RR (1 << 3) |
317 | #define MX1_INTREG_TEEN (1 << 8) | 347 | #define MX1_INTREG_TEEN (1 << 8) |
318 | #define MX1_INTREG_RREN (1 << 11) | 348 | #define MX1_INTREG_RREN (1 << 11) |
@@ -369,6 +399,11 @@ static int __maybe_unused mx1_rx_available(struct spi_imx_data *spi_imx) | |||
369 | return readl(spi_imx->base + MXC_CSPIINT) & MX1_INTREG_RR; | 399 | return readl(spi_imx->base + MXC_CSPIINT) & MX1_INTREG_RR; |
370 | } | 400 | } |
371 | 401 | ||
402 | static void __maybe_unused mx1_reset(struct spi_imx_data *spi_imx) | ||
403 | { | ||
404 | writel(1, spi_imx->base + MXC_RESET); | ||
405 | } | ||
406 | |||
372 | /* | 407 | /* |
373 | * These version numbers are taken from the Freescale driver. Unfortunately it | 408 | * These version numbers are taken from the Freescale driver. Unfortunately it |
374 | * doesn't support i.MX1, so this entry doesn't match the scheme. :-( | 409 | * doesn't support i.MX1, so this entry doesn't match the scheme. :-( |
@@ -380,6 +415,7 @@ static struct spi_imx_devtype_data spi_imx_devtype_data[] __devinitdata = { | |||
380 | .config = mx1_config, | 415 | .config = mx1_config, |
381 | .trigger = mx1_trigger, | 416 | .trigger = mx1_trigger, |
382 | .rx_available = mx1_rx_available, | 417 | .rx_available = mx1_rx_available, |
418 | .reset = mx1_reset, | ||
383 | }, | 419 | }, |
384 | #endif | 420 | #endif |
385 | #ifdef CONFIG_SPI_IMX_VER_0_0 | 421 | #ifdef CONFIG_SPI_IMX_VER_0_0 |
@@ -388,22 +424,25 @@ static struct spi_imx_devtype_data spi_imx_devtype_data[] __devinitdata = { | |||
388 | .config = mx27_config, | 424 | .config = mx27_config, |
389 | .trigger = mx27_trigger, | 425 | .trigger = mx27_trigger, |
390 | .rx_available = mx27_rx_available, | 426 | .rx_available = mx27_rx_available, |
427 | .reset = spi_imx0_0_reset, | ||
391 | }, | 428 | }, |
392 | #endif | 429 | #endif |
393 | #ifdef CONFIG_SPI_IMX_VER_0_4 | 430 | #ifdef CONFIG_SPI_IMX_VER_0_4 |
394 | [SPI_IMX_VER_0_4] = { | 431 | [SPI_IMX_VER_0_4] = { |
395 | .intctrl = mx31_intctrl, | 432 | .intctrl = mx31_intctrl, |
396 | .config = mx31_config, | 433 | .config = spi_imx0_4_config, |
397 | .trigger = mx31_trigger, | 434 | .trigger = mx31_trigger, |
398 | .rx_available = mx31_rx_available, | 435 | .rx_available = mx31_rx_available, |
436 | .reset = spi_imx0_4_reset, | ||
399 | }, | 437 | }, |
400 | #endif | 438 | #endif |
401 | #ifdef CONFIG_SPI_IMX_VER_0_7 | 439 | #ifdef CONFIG_SPI_IMX_VER_0_7 |
402 | [SPI_IMX_VER_0_7] = { | 440 | [SPI_IMX_VER_0_7] = { |
403 | .intctrl = mx31_intctrl, | 441 | .intctrl = mx31_intctrl, |
404 | .config = mx31_config, | 442 | .config = spi_imx0_7_config, |
405 | .trigger = mx31_trigger, | 443 | .trigger = mx31_trigger, |
406 | .rx_available = mx31_rx_available, | 444 | .rx_available = mx31_rx_available, |
445 | .reset = spi_imx0_4_reset, | ||
407 | }, | 446 | }, |
408 | #endif | 447 | #endif |
409 | }; | 448 | }; |
@@ -683,13 +722,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) | |||
683 | clk_enable(spi_imx->clk); | 722 | clk_enable(spi_imx->clk); |
684 | spi_imx->spi_clk = clk_get_rate(spi_imx->clk); | 723 | spi_imx->spi_clk = clk_get_rate(spi_imx->clk); |
685 | 724 | ||
686 | if (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) | 725 | spi_imx->devtype_data.reset(spi_imx); |
687 | writel(1, spi_imx->base + MXC_RESET); | ||
688 | |||
689 | /* drain receive buffer */ | ||
690 | if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35()) | ||
691 | while (readl(spi_imx->base + MX3_CSPISTAT) & MX3_CSPISTAT_RR) | ||
692 | readl(spi_imx->base + MXC_CSPIRXDATA); | ||
693 | 726 | ||
694 | spi_imx->devtype_data.intctrl(spi_imx, 0); | 727 | spi_imx->devtype_data.intctrl(spi_imx, 0); |
695 | 728 | ||