diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/Kconfig | 12 | ||||
-rw-r--r-- | drivers/spi/spi-imx.c | 208 |
2 files changed, 109 insertions, 111 deletions
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index c327cf3d8174..52e2900d9d8e 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -154,18 +154,6 @@ config SPI_GPIO | |||
154 | GPIO operations, you should be able to leverage that for better | 154 | GPIO operations, you should be able to leverage that for better |
155 | speed with a custom version of this driver; see the source code. | 155 | speed with a custom version of this driver; see the source code. |
156 | 156 | ||
157 | config SPI_IMX_VER_IMX1 | ||
158 | def_bool y if SOC_IMX1 | ||
159 | |||
160 | config SPI_IMX_VER_0_0 | ||
161 | def_bool y if SOC_IMX21 || SOC_IMX27 | ||
162 | |||
163 | config SPI_IMX_VER_0_4 | ||
164 | def_bool y if ARCH_MX25 || SOC_IMX31 || SOC_IMX35 || SOC_IMX51 || SOC_IMX53 | ||
165 | |||
166 | config SPI_IMX_VER_2_3 | ||
167 | def_bool y if SOC_IMX51 || SOC_IMX53 | ||
168 | |||
169 | config SPI_IMX | 157 | config SPI_IMX |
170 | tristate "Freescale i.MX SPI controllers" | 158 | tristate "Freescale i.MX SPI controllers" |
171 | depends on ARCH_MXC | 159 | depends on ARCH_MXC |
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 615a84c8ccda..87981b417967 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
@@ -57,10 +57,12 @@ struct spi_imx_config { | |||
57 | }; | 57 | }; |
58 | 58 | ||
59 | enum spi_imx_devtype { | 59 | enum spi_imx_devtype { |
60 | SPI_IMX_VER_IMX1, | 60 | IMX1_CSPI, |
61 | SPI_IMX_VER_0_0, | 61 | IMX21_CSPI, |
62 | SPI_IMX_VER_0_4, | 62 | IMX27_CSPI, |
63 | SPI_IMX_VER_2_3, | 63 | IMX31_CSPI, |
64 | IMX35_CSPI, /* CSPI on all i.mx except above */ | ||
65 | IMX51_ECSPI, /* ECSPI on i.mx51 and later */ | ||
64 | }; | 66 | }; |
65 | 67 | ||
66 | struct spi_imx_data; | 68 | struct spi_imx_data; |
@@ -71,7 +73,7 @@ struct spi_imx_devtype_data { | |||
71 | void (*trigger)(struct spi_imx_data *); | 73 | void (*trigger)(struct spi_imx_data *); |
72 | int (*rx_available)(struct spi_imx_data *); | 74 | int (*rx_available)(struct spi_imx_data *); |
73 | void (*reset)(struct spi_imx_data *); | 75 | void (*reset)(struct spi_imx_data *); |
74 | unsigned int fifosize; | 76 | enum spi_imx_devtype devtype; |
75 | }; | 77 | }; |
76 | 78 | ||
77 | struct spi_imx_data { | 79 | struct spi_imx_data { |
@@ -94,6 +96,21 @@ struct spi_imx_data { | |||
94 | struct spi_imx_devtype_data *devtype_data; | 96 | struct spi_imx_devtype_data *devtype_data; |
95 | }; | 97 | }; |
96 | 98 | ||
99 | static inline int is_imx27_cspi(struct spi_imx_data *d) | ||
100 | { | ||
101 | return d->devtype_data->devtype == IMX27_CSPI; | ||
102 | } | ||
103 | |||
104 | static inline int is_imx35_cspi(struct spi_imx_data *d) | ||
105 | { | ||
106 | return d->devtype_data->devtype == IMX35_CSPI; | ||
107 | } | ||
108 | |||
109 | static inline unsigned spi_imx_get_fifosize(struct spi_imx_data *d) | ||
110 | { | ||
111 | return (d->devtype_data->devtype == IMX51_ECSPI) ? 64 : 8; | ||
112 | } | ||
113 | |||
97 | #define MXC_SPI_BUF_RX(type) \ | 114 | #define MXC_SPI_BUF_RX(type) \ |
98 | static void spi_imx_buf_rx_##type(struct spi_imx_data *spi_imx) \ | 115 | static void spi_imx_buf_rx_##type(struct spi_imx_data *spi_imx) \ |
99 | { \ | 116 | { \ |
@@ -135,14 +152,9 @@ static int mxc_clkdivs[] = {0, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, | |||
135 | 152 | ||
136 | /* MX21, MX27 */ | 153 | /* MX21, MX27 */ |
137 | static unsigned int spi_imx_clkdiv_1(unsigned int fin, | 154 | static unsigned int spi_imx_clkdiv_1(unsigned int fin, |
138 | unsigned int fspi) | 155 | unsigned int fspi, unsigned int max) |
139 | { | 156 | { |
140 | int i, max; | 157 | int i; |
141 | |||
142 | if (cpu_is_mx21()) | ||
143 | max = 18; | ||
144 | else | ||
145 | max = 16; | ||
146 | 158 | ||
147 | for (i = 2; i < max; i++) | 159 | for (i = 2; i < max; i++) |
148 | if (fspi * mxc_clkdivs[i] >= fin) | 160 | if (fspi * mxc_clkdivs[i] >= fin) |
@@ -347,7 +359,7 @@ static int __maybe_unused mx31_config(struct spi_imx_data *spi_imx, | |||
347 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << | 359 | reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << |
348 | MX31_CSPICTRL_DR_SHIFT; | 360 | MX31_CSPICTRL_DR_SHIFT; |
349 | 361 | ||
350 | if (cpu_is_mx35()) { | 362 | if (is_imx35_cspi(spi_imx)) { |
351 | reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; | 363 | reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT; |
352 | reg |= MX31_CSPICTRL_SSCTL; | 364 | reg |= MX31_CSPICTRL_SSCTL; |
353 | } else { | 365 | } else { |
@@ -362,8 +374,8 @@ static int __maybe_unused mx31_config(struct spi_imx_data *spi_imx, | |||
362 | reg |= MX31_CSPICTRL_SSPOL; | 374 | reg |= MX31_CSPICTRL_SSPOL; |
363 | if (cs < 0) | 375 | if (cs < 0) |
364 | reg |= (cs + 32) << | 376 | reg |= (cs + 32) << |
365 | (cpu_is_mx35() ? MX35_CSPICTRL_CS_SHIFT : | 377 | (is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT : |
366 | MX31_CSPICTRL_CS_SHIFT); | 378 | MX31_CSPICTRL_CS_SHIFT); |
367 | 379 | ||
368 | writel(reg, spi_imx->base + MXC_CSPICTRL); | 380 | writel(reg, spi_imx->base + MXC_CSPICTRL); |
369 | 381 | ||
@@ -421,8 +433,9 @@ static int __maybe_unused mx21_config(struct spi_imx_data *spi_imx, | |||
421 | { | 433 | { |
422 | unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_MASTER; | 434 | unsigned int reg = MX21_CSPICTRL_ENABLE | MX21_CSPICTRL_MASTER; |
423 | int cs = spi_imx->chipselect[config->cs]; | 435 | int cs = spi_imx->chipselect[config->cs]; |
436 | unsigned int max = is_imx27_cspi(spi_imx) ? 16 : 18; | ||
424 | 437 | ||
425 | reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz) << | 438 | reg |= spi_imx_clkdiv_1(spi_imx->spi_clk, config->speed_hz, max) << |
426 | MX21_CSPICTRL_DR_SHIFT; | 439 | MX21_CSPICTRL_DR_SHIFT; |
427 | reg |= config->bpw - 1; | 440 | reg |= config->bpw - 1; |
428 | 441 | ||
@@ -511,51 +524,84 @@ static void __maybe_unused mx1_reset(struct spi_imx_data *spi_imx) | |||
511 | writel(1, spi_imx->base + MXC_RESET); | 524 | writel(1, spi_imx->base + MXC_RESET); |
512 | } | 525 | } |
513 | 526 | ||
514 | /* | 527 | static struct spi_imx_devtype_data imx1_cspi_devtype_data = { |
515 | * These version numbers are taken from the Freescale driver. Unfortunately it | 528 | .intctrl = mx1_intctrl, |
516 | * doesn't support i.MX1, so this entry doesn't match the scheme. :-( | 529 | .config = mx1_config, |
517 | */ | 530 | .trigger = mx1_trigger, |
518 | static struct spi_imx_devtype_data spi_imx_devtype_data[] = { | 531 | .rx_available = mx1_rx_available, |
519 | #ifdef CONFIG_SPI_IMX_VER_IMX1 | 532 | .reset = mx1_reset, |
520 | [SPI_IMX_VER_IMX1] = { | 533 | .devtype = IMX1_CSPI, |
521 | .intctrl = mx1_intctrl, | 534 | }; |
522 | .config = mx1_config, | 535 | |
523 | .trigger = mx1_trigger, | 536 | static struct spi_imx_devtype_data imx21_cspi_devtype_data = { |
524 | .rx_available = mx1_rx_available, | 537 | .intctrl = mx21_intctrl, |
525 | .reset = mx1_reset, | 538 | .config = mx21_config, |
526 | .fifosize = 8, | 539 | .trigger = mx21_trigger, |
527 | }, | 540 | .rx_available = mx21_rx_available, |
528 | #endif | 541 | .reset = mx21_reset, |
529 | #ifdef CONFIG_SPI_IMX_VER_0_0 | 542 | .devtype = IMX21_CSPI, |
530 | [SPI_IMX_VER_0_0] = { | 543 | }; |
531 | .intctrl = mx21_intctrl, | 544 | |
532 | .config = mx21_config, | 545 | static struct spi_imx_devtype_data imx27_cspi_devtype_data = { |
533 | .trigger = mx21_trigger, | 546 | /* i.mx27 cspi shares the functions with i.mx21 one */ |
534 | .rx_available = mx21_rx_available, | 547 | .intctrl = mx21_intctrl, |
535 | .reset = mx21_reset, | 548 | .config = mx21_config, |
536 | .fifosize = 8, | 549 | .trigger = mx21_trigger, |
537 | }, | 550 | .rx_available = mx21_rx_available, |
538 | #endif | 551 | .reset = mx21_reset, |
539 | #ifdef CONFIG_SPI_IMX_VER_0_4 | 552 | .devtype = IMX27_CSPI, |
540 | [SPI_IMX_VER_0_4] = { | 553 | }; |
541 | .intctrl = mx31_intctrl, | 554 | |
542 | .config = mx31_config, | 555 | static struct spi_imx_devtype_data imx31_cspi_devtype_data = { |
543 | .trigger = mx31_trigger, | 556 | .intctrl = mx31_intctrl, |
544 | .rx_available = mx31_rx_available, | 557 | .config = mx31_config, |
545 | .reset = mx31_reset, | 558 | .trigger = mx31_trigger, |
546 | .fifosize = 8, | 559 | .rx_available = mx31_rx_available, |
547 | }, | 560 | .reset = mx31_reset, |
548 | #endif | 561 | .devtype = IMX31_CSPI, |
549 | #ifdef CONFIG_SPI_IMX_VER_2_3 | 562 | }; |
550 | [SPI_IMX_VER_2_3] = { | 563 | |
551 | .intctrl = mx51_ecspi_intctrl, | 564 | static struct spi_imx_devtype_data imx35_cspi_devtype_data = { |
552 | .config = mx51_ecspi_config, | 565 | /* i.mx35 and later cspi shares the functions with i.mx31 one */ |
553 | .trigger = mx51_ecspi_trigger, | 566 | .intctrl = mx31_intctrl, |
554 | .rx_available = mx51_ecspi_rx_available, | 567 | .config = mx31_config, |
555 | .reset = mx51_ecspi_reset, | 568 | .trigger = mx31_trigger, |
556 | .fifosize = 64, | 569 | .rx_available = mx31_rx_available, |
557 | }, | 570 | .reset = mx31_reset, |
558 | #endif | 571 | .devtype = IMX35_CSPI, |
572 | }; | ||
573 | |||
574 | static struct spi_imx_devtype_data imx51_ecspi_devtype_data = { | ||
575 | .intctrl = mx51_ecspi_intctrl, | ||
576 | .config = mx51_ecspi_config, | ||
577 | .trigger = mx51_ecspi_trigger, | ||
578 | .rx_available = mx51_ecspi_rx_available, | ||
579 | .reset = mx51_ecspi_reset, | ||
580 | .devtype = IMX51_ECSPI, | ||
581 | }; | ||
582 | |||
583 | static struct platform_device_id spi_imx_devtype[] = { | ||
584 | { | ||
585 | .name = "imx1-cspi", | ||
586 | .driver_data = (kernel_ulong_t) &imx1_cspi_devtype_data, | ||
587 | }, { | ||
588 | .name = "imx21-cspi", | ||
589 | .driver_data = (kernel_ulong_t) &imx21_cspi_devtype_data, | ||
590 | }, { | ||
591 | .name = "imx27-cspi", | ||
592 | .driver_data = (kernel_ulong_t) &imx27_cspi_devtype_data, | ||
593 | }, { | ||
594 | .name = "imx31-cspi", | ||
595 | .driver_data = (kernel_ulong_t) &imx31_cspi_devtype_data, | ||
596 | }, { | ||
597 | .name = "imx35-cspi", | ||
598 | .driver_data = (kernel_ulong_t) &imx35_cspi_devtype_data, | ||
599 | }, { | ||
600 | .name = "imx51-ecspi", | ||
601 | .driver_data = (kernel_ulong_t) &imx51_ecspi_devtype_data, | ||
602 | }, { | ||
603 | /* sentinel */ | ||
604 | } | ||
559 | }; | 605 | }; |
560 | 606 | ||
561 | static void spi_imx_chipselect(struct spi_device *spi, int is_active) | 607 | static void spi_imx_chipselect(struct spi_device *spi, int is_active) |
@@ -573,7 +619,7 @@ static void spi_imx_chipselect(struct spi_device *spi, int is_active) | |||
573 | 619 | ||
574 | static void spi_imx_push(struct spi_imx_data *spi_imx) | 620 | static void spi_imx_push(struct spi_imx_data *spi_imx) |
575 | { | 621 | { |
576 | while (spi_imx->txfifo < spi_imx->devtype_data->fifosize) { | 622 | while (spi_imx->txfifo < spi_imx_get_fifosize(spi_imx)) { |
577 | if (!spi_imx->count) | 623 | if (!spi_imx->count) |
578 | break; | 624 | break; |
579 | spi_imx->tx(spi_imx); | 625 | spi_imx->tx(spi_imx); |
@@ -689,42 +735,6 @@ static void spi_imx_cleanup(struct spi_device *spi) | |||
689 | { | 735 | { |
690 | } | 736 | } |
691 | 737 | ||
692 | static struct platform_device_id spi_imx_devtype[] = { | ||
693 | { | ||
694 | .name = "imx1-cspi", | ||
695 | .driver_data = SPI_IMX_VER_IMX1, | ||
696 | }, { | ||
697 | .name = "imx21-cspi", | ||
698 | .driver_data = SPI_IMX_VER_0_0, | ||
699 | }, { | ||
700 | .name = "imx25-cspi", | ||
701 | .driver_data = SPI_IMX_VER_0_4, | ||
702 | }, { | ||
703 | .name = "imx27-cspi", | ||
704 | .driver_data = SPI_IMX_VER_0_0, | ||
705 | }, { | ||
706 | .name = "imx31-cspi", | ||
707 | .driver_data = SPI_IMX_VER_0_4, | ||
708 | }, { | ||
709 | .name = "imx35-cspi", | ||
710 | .driver_data = SPI_IMX_VER_0_4, | ||
711 | }, { | ||
712 | .name = "imx51-cspi", | ||
713 | .driver_data = SPI_IMX_VER_0_4, | ||
714 | }, { | ||
715 | .name = "imx51-ecspi", | ||
716 | .driver_data = SPI_IMX_VER_2_3, | ||
717 | }, { | ||
718 | .name = "imx53-cspi", | ||
719 | .driver_data = SPI_IMX_VER_0_4, | ||
720 | }, { | ||
721 | .name = "imx53-ecspi", | ||
722 | .driver_data = SPI_IMX_VER_2_3, | ||
723 | }, { | ||
724 | /* sentinel */ | ||
725 | } | ||
726 | }; | ||
727 | |||
728 | static int __devinit spi_imx_probe(struct platform_device *pdev) | 738 | static int __devinit spi_imx_probe(struct platform_device *pdev) |
729 | { | 739 | { |
730 | struct spi_imx_master *mxc_platform_info; | 740 | struct spi_imx_master *mxc_platform_info; |
@@ -777,7 +787,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev) | |||
777 | init_completion(&spi_imx->xfer_done); | 787 | init_completion(&spi_imx->xfer_done); |
778 | 788 | ||
779 | spi_imx->devtype_data = | 789 | spi_imx->devtype_data = |
780 | &spi_imx_devtype_data[pdev->id_entry->driver_data]; | 790 | (struct spi_imx_devtype_data *) pdev->id_entry->driver_data; |
781 | 791 | ||
782 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 792 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
783 | if (!res) { | 793 | if (!res) { |