diff options
-rw-r--r-- | drivers/spi/pxa2xx_spi.c | 93 | ||||
-rw-r--r-- | include/linux/pxa2xx_ssp.h | 2 |
2 files changed, 70 insertions, 25 deletions
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 81cfbbc58e94..a54685bb7e53 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -163,7 +163,10 @@ struct chip_data { | |||
163 | u8 enable_dma; | 163 | u8 enable_dma; |
164 | u8 bits_per_word; | 164 | u8 bits_per_word; |
165 | u32 speed_hz; | 165 | u32 speed_hz; |
166 | int gpio_cs; | 166 | union { |
167 | int gpio_cs; | ||
168 | unsigned int frm; | ||
169 | }; | ||
167 | int gpio_cs_inverted; | 170 | int gpio_cs_inverted; |
168 | int (*write)(struct driver_data *drv_data); | 171 | int (*write)(struct driver_data *drv_data); |
169 | int (*read)(struct driver_data *drv_data); | 172 | int (*read)(struct driver_data *drv_data); |
@@ -176,6 +179,11 @@ static void cs_assert(struct driver_data *drv_data) | |||
176 | { | 179 | { |
177 | struct chip_data *chip = drv_data->cur_chip; | 180 | struct chip_data *chip = drv_data->cur_chip; |
178 | 181 | ||
182 | if (drv_data->ssp_type == CE4100_SSP) { | ||
183 | write_SSSR(drv_data->cur_chip->frm, drv_data->ioaddr); | ||
184 | return; | ||
185 | } | ||
186 | |||
179 | if (chip->cs_control) { | 187 | if (chip->cs_control) { |
180 | chip->cs_control(PXA2XX_CS_ASSERT); | 188 | chip->cs_control(PXA2XX_CS_ASSERT); |
181 | return; | 189 | return; |
@@ -189,6 +197,9 @@ static void cs_deassert(struct driver_data *drv_data) | |||
189 | { | 197 | { |
190 | struct chip_data *chip = drv_data->cur_chip; | 198 | struct chip_data *chip = drv_data->cur_chip; |
191 | 199 | ||
200 | if (drv_data->ssp_type == CE4100_SSP) | ||
201 | return; | ||
202 | |||
192 | if (chip->cs_control) { | 203 | if (chip->cs_control) { |
193 | chip->cs_control(PXA2XX_CS_DEASSERT); | 204 | chip->cs_control(PXA2XX_CS_DEASSERT); |
194 | return; | 205 | return; |
@@ -198,6 +209,25 @@ static void cs_deassert(struct driver_data *drv_data) | |||
198 | gpio_set_value(chip->gpio_cs, !chip->gpio_cs_inverted); | 209 | gpio_set_value(chip->gpio_cs, !chip->gpio_cs_inverted); |
199 | } | 210 | } |
200 | 211 | ||
212 | static void write_SSSR_CS(struct driver_data *drv_data, u32 val) | ||
213 | { | ||
214 | void __iomem *reg = drv_data->ioaddr; | ||
215 | |||
216 | if (drv_data->ssp_type == CE4100_SSP) | ||
217 | val |= read_SSSR(reg) & SSSR_ALT_FRM_MASK; | ||
218 | |||
219 | write_SSSR(val, reg); | ||
220 | } | ||
221 | |||
222 | static int pxa25x_ssp_comp(struct driver_data *drv_data) | ||
223 | { | ||
224 | if (drv_data->ssp_type == PXA25x_SSP) | ||
225 | return 1; | ||
226 | if (drv_data->ssp_type == CE4100_SSP) | ||
227 | return 1; | ||
228 | return 0; | ||
229 | } | ||
230 | |||
201 | static int flush(struct driver_data *drv_data) | 231 | static int flush(struct driver_data *drv_data) |
202 | { | 232 | { |
203 | unsigned long limit = loops_per_jiffy << 1; | 233 | unsigned long limit = loops_per_jiffy << 1; |
@@ -209,7 +239,7 @@ static int flush(struct driver_data *drv_data) | |||
209 | read_SSDR(reg); | 239 | read_SSDR(reg); |
210 | } | 240 | } |
211 | } while ((read_SSSR(reg) & SSSR_BSY) && --limit); | 241 | } while ((read_SSSR(reg) & SSSR_BSY) && --limit); |
212 | write_SSSR(SSSR_ROR, reg); | 242 | write_SSSR_CS(drv_data, SSSR_ROR); |
213 | 243 | ||
214 | return limit; | 244 | return limit; |
215 | } | 245 | } |
@@ -502,9 +532,9 @@ static void dma_error_stop(struct driver_data *drv_data, const char *msg) | |||
502 | /* Stop and reset */ | 532 | /* Stop and reset */ |
503 | DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; | 533 | DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; |
504 | DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; | 534 | DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; |
505 | write_SSSR(drv_data->clear_sr, reg); | 535 | write_SSSR_CS(drv_data, drv_data->clear_sr); |
506 | write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); | 536 | write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); |
507 | if (drv_data->ssp_type != PXA25x_SSP) | 537 | if (!pxa25x_ssp_comp(drv_data)) |
508 | write_SSTO(0, reg); | 538 | write_SSTO(0, reg); |
509 | flush(drv_data); | 539 | flush(drv_data); |
510 | write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); | 540 | write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); |
@@ -524,7 +554,7 @@ static void dma_transfer_complete(struct driver_data *drv_data) | |||
524 | 554 | ||
525 | /* Clear and disable interrupts on SSP and DMA channels*/ | 555 | /* Clear and disable interrupts on SSP and DMA channels*/ |
526 | write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); | 556 | write_SSCR1(read_SSCR1(reg) & ~drv_data->dma_cr1, reg); |
527 | write_SSSR(drv_data->clear_sr, reg); | 557 | write_SSSR_CS(drv_data, drv_data->clear_sr); |
528 | DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; | 558 | DCSR(drv_data->tx_channel) = RESET_DMA_CHANNEL; |
529 | DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; | 559 | DCSR(drv_data->rx_channel) = RESET_DMA_CHANNEL; |
530 | 560 | ||
@@ -617,7 +647,7 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data) | |||
617 | 647 | ||
618 | /* Clear and disable timeout interrupt, do the rest in | 648 | /* Clear and disable timeout interrupt, do the rest in |
619 | * dma_transfer_complete */ | 649 | * dma_transfer_complete */ |
620 | if (drv_data->ssp_type != PXA25x_SSP) | 650 | if (!pxa25x_ssp_comp(drv_data)) |
621 | write_SSTO(0, reg); | 651 | write_SSTO(0, reg); |
622 | 652 | ||
623 | /* finish this transfer, start the next */ | 653 | /* finish this transfer, start the next */ |
@@ -635,9 +665,9 @@ static void int_error_stop(struct driver_data *drv_data, const char* msg) | |||
635 | void __iomem *reg = drv_data->ioaddr; | 665 | void __iomem *reg = drv_data->ioaddr; |
636 | 666 | ||
637 | /* Stop and reset SSP */ | 667 | /* Stop and reset SSP */ |
638 | write_SSSR(drv_data->clear_sr, reg); | 668 | write_SSSR_CS(drv_data, drv_data->clear_sr); |
639 | write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); | 669 | write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); |
640 | if (drv_data->ssp_type != PXA25x_SSP) | 670 | if (!pxa25x_ssp_comp(drv_data)) |
641 | write_SSTO(0, reg); | 671 | write_SSTO(0, reg); |
642 | flush(drv_data); | 672 | flush(drv_data); |
643 | write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); | 673 | write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); |
@@ -653,9 +683,9 @@ static void int_transfer_complete(struct driver_data *drv_data) | |||
653 | void __iomem *reg = drv_data->ioaddr; | 683 | void __iomem *reg = drv_data->ioaddr; |
654 | 684 | ||
655 | /* Stop SSP */ | 685 | /* Stop SSP */ |
656 | write_SSSR(drv_data->clear_sr, reg); | 686 | write_SSSR_CS(drv_data, drv_data->clear_sr); |
657 | write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); | 687 | write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); |
658 | if (drv_data->ssp_type != PXA25x_SSP) | 688 | if (!pxa25x_ssp_comp(drv_data)) |
659 | write_SSTO(0, reg); | 689 | write_SSTO(0, reg); |
660 | 690 | ||
661 | /* Update total byte transfered return count actual bytes read */ | 691 | /* Update total byte transfered return count actual bytes read */ |
@@ -711,7 +741,7 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data) | |||
711 | if (drv_data->tx == drv_data->tx_end) { | 741 | if (drv_data->tx == drv_data->tx_end) { |
712 | write_SSCR1(read_SSCR1(reg) & ~SSCR1_TIE, reg); | 742 | write_SSCR1(read_SSCR1(reg) & ~SSCR1_TIE, reg); |
713 | /* PXA25x_SSP has no timeout, read trailing bytes */ | 743 | /* PXA25x_SSP has no timeout, read trailing bytes */ |
714 | if (drv_data->ssp_type == PXA25x_SSP) { | 744 | if (pxa25x_ssp_comp(drv_data)) { |
715 | if (!wait_ssp_rx_stall(reg)) | 745 | if (!wait_ssp_rx_stall(reg)) |
716 | { | 746 | { |
717 | int_error_stop(drv_data, "interrupt_transfer: " | 747 | int_error_stop(drv_data, "interrupt_transfer: " |
@@ -754,9 +784,9 @@ static irqreturn_t ssp_int(int irq, void *dev_id) | |||
754 | 784 | ||
755 | write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); | 785 | write_SSCR0(read_SSCR0(reg) & ~SSCR0_SSE, reg); |
756 | write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); | 786 | write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); |
757 | if (drv_data->ssp_type != PXA25x_SSP) | 787 | if (!pxa25x_ssp_comp(drv_data)) |
758 | write_SSTO(0, reg); | 788 | write_SSTO(0, reg); |
759 | write_SSSR(drv_data->clear_sr, reg); | 789 | write_SSSR_CS(drv_data, drv_data->clear_sr); |
760 | 790 | ||
761 | dev_err(&drv_data->pdev->dev, "bad message state " | 791 | dev_err(&drv_data->pdev->dev, "bad message state " |
762 | "in interrupt handler\n"); | 792 | "in interrupt handler\n"); |
@@ -869,7 +899,7 @@ static unsigned int ssp_get_clk_div(struct ssp_device *ssp, int rate) | |||
869 | { | 899 | { |
870 | unsigned long ssp_clk = clk_get_rate(ssp->clk); | 900 | unsigned long ssp_clk = clk_get_rate(ssp->clk); |
871 | 901 | ||
872 | if (ssp->type == PXA25x_SSP) | 902 | if (ssp->type == PXA25x_SSP || ssp->type == CE4100_SSP) |
873 | return ((ssp_clk / (2 * rate) - 1) & 0xff) << 8; | 903 | return ((ssp_clk / (2 * rate) - 1) & 0xff) << 8; |
874 | else | 904 | else |
875 | return ((ssp_clk / rate - 1) & 0xfff) << 8; | 905 | return ((ssp_clk / rate - 1) & 0xfff) << 8; |
@@ -1095,7 +1125,7 @@ static void pump_transfers(unsigned long data) | |||
1095 | 1125 | ||
1096 | /* Clear status */ | 1126 | /* Clear status */ |
1097 | cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1; | 1127 | cr1 = chip->cr1 | chip->threshold | drv_data->int_cr1; |
1098 | write_SSSR(drv_data->clear_sr, reg); | 1128 | write_SSSR_CS(drv_data, drv_data->clear_sr); |
1099 | } | 1129 | } |
1100 | 1130 | ||
1101 | /* see if we need to reload the config registers */ | 1131 | /* see if we need to reload the config registers */ |
@@ -1105,7 +1135,7 @@ static void pump_transfers(unsigned long data) | |||
1105 | 1135 | ||
1106 | /* stop the SSP, and update the other bits */ | 1136 | /* stop the SSP, and update the other bits */ |
1107 | write_SSCR0(cr0 & ~SSCR0_SSE, reg); | 1137 | write_SSCR0(cr0 & ~SSCR0_SSE, reg); |
1108 | if (drv_data->ssp_type != PXA25x_SSP) | 1138 | if (!pxa25x_ssp_comp(drv_data)) |
1109 | write_SSTO(chip->timeout, reg); | 1139 | write_SSTO(chip->timeout, reg); |
1110 | /* first set CR1 without interrupt and service enables */ | 1140 | /* first set CR1 without interrupt and service enables */ |
1111 | write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg); | 1141 | write_SSCR1(cr1 & SSCR1_CHANGE_MASK, reg); |
@@ -1113,7 +1143,7 @@ static void pump_transfers(unsigned long data) | |||
1113 | write_SSCR0(cr0, reg); | 1143 | write_SSCR0(cr0, reg); |
1114 | 1144 | ||
1115 | } else { | 1145 | } else { |
1116 | if (drv_data->ssp_type != PXA25x_SSP) | 1146 | if (!pxa25x_ssp_comp(drv_data)) |
1117 | write_SSTO(chip->timeout, reg); | 1147 | write_SSTO(chip->timeout, reg); |
1118 | } | 1148 | } |
1119 | 1149 | ||
@@ -1240,14 +1270,13 @@ static int setup(struct spi_device *spi) | |||
1240 | uint tx_thres = TX_THRESH_DFLT; | 1270 | uint tx_thres = TX_THRESH_DFLT; |
1241 | uint rx_thres = RX_THRESH_DFLT; | 1271 | uint rx_thres = RX_THRESH_DFLT; |
1242 | 1272 | ||
1243 | if (drv_data->ssp_type != PXA25x_SSP | 1273 | if (!pxa25x_ssp_comp(drv_data) |
1244 | && (spi->bits_per_word < 4 || spi->bits_per_word > 32)) { | 1274 | && (spi->bits_per_word < 4 || spi->bits_per_word > 32)) { |
1245 | dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d " | 1275 | dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d " |
1246 | "b/w not 4-32 for type non-PXA25x_SSP\n", | 1276 | "b/w not 4-32 for type non-PXA25x_SSP\n", |
1247 | drv_data->ssp_type, spi->bits_per_word); | 1277 | drv_data->ssp_type, spi->bits_per_word); |
1248 | return -EINVAL; | 1278 | return -EINVAL; |
1249 | } | 1279 | } else if (pxa25x_ssp_comp(drv_data) |
1250 | else if (drv_data->ssp_type == PXA25x_SSP | ||
1251 | && (spi->bits_per_word < 4 | 1280 | && (spi->bits_per_word < 4 |
1252 | || spi->bits_per_word > 16)) { | 1281 | || spi->bits_per_word > 16)) { |
1253 | dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d " | 1282 | dev_err(&spi->dev, "failed setup: ssp_type=%d, bits/wrd=%d " |
@@ -1266,7 +1295,17 @@ static int setup(struct spi_device *spi) | |||
1266 | return -ENOMEM; | 1295 | return -ENOMEM; |
1267 | } | 1296 | } |
1268 | 1297 | ||
1269 | chip->gpio_cs = -1; | 1298 | if (drv_data->ssp_type == CE4100_SSP) { |
1299 | if (spi->chip_select > 4) { | ||
1300 | dev_err(&spi->dev, "failed setup: " | ||
1301 | "cs number must not be > 4.\n"); | ||
1302 | kfree(chip); | ||
1303 | return -EINVAL; | ||
1304 | } | ||
1305 | |||
1306 | chip->frm = spi->chip_select; | ||
1307 | } else | ||
1308 | chip->gpio_cs = -1; | ||
1270 | chip->enable_dma = 0; | 1309 | chip->enable_dma = 0; |
1271 | chip->timeout = TIMOUT_DFLT; | 1310 | chip->timeout = TIMOUT_DFLT; |
1272 | chip->dma_burst_size = drv_data->master_info->enable_dma ? | 1311 | chip->dma_burst_size = drv_data->master_info->enable_dma ? |
@@ -1322,7 +1361,7 @@ static int setup(struct spi_device *spi) | |||
1322 | | (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0); | 1361 | | (((spi->mode & SPI_CPOL) != 0) ? SSCR1_SPO : 0); |
1323 | 1362 | ||
1324 | /* NOTE: PXA25x_SSP _could_ use external clocking ... */ | 1363 | /* NOTE: PXA25x_SSP _could_ use external clocking ... */ |
1325 | if (drv_data->ssp_type != PXA25x_SSP) | 1364 | if (!pxa25x_ssp_comp(drv_data)) |
1326 | dev_dbg(&spi->dev, "%ld Hz actual, %s\n", | 1365 | dev_dbg(&spi->dev, "%ld Hz actual, %s\n", |
1327 | clk_get_rate(ssp->clk) | 1366 | clk_get_rate(ssp->clk) |
1328 | / (1 + ((chip->cr0 & SSCR0_SCR(0xfff)) >> 8)), | 1367 | / (1 + ((chip->cr0 & SSCR0_SCR(0xfff)) >> 8)), |
@@ -1357,17 +1396,21 @@ static int setup(struct spi_device *spi) | |||
1357 | 1396 | ||
1358 | spi_set_ctldata(spi, chip); | 1397 | spi_set_ctldata(spi, chip); |
1359 | 1398 | ||
1399 | if (drv_data->ssp_type == CE4100_SSP) | ||
1400 | return 0; | ||
1401 | |||
1360 | return setup_cs(spi, chip, chip_info); | 1402 | return setup_cs(spi, chip, chip_info); |
1361 | } | 1403 | } |
1362 | 1404 | ||
1363 | static void cleanup(struct spi_device *spi) | 1405 | static void cleanup(struct spi_device *spi) |
1364 | { | 1406 | { |
1365 | struct chip_data *chip = spi_get_ctldata(spi); | 1407 | struct chip_data *chip = spi_get_ctldata(spi); |
1408 | struct driver_data *drv_data = spi_master_get_devdata(spi->master); | ||
1366 | 1409 | ||
1367 | if (!chip) | 1410 | if (!chip) |
1368 | return; | 1411 | return; |
1369 | 1412 | ||
1370 | if (gpio_is_valid(chip->gpio_cs)) | 1413 | if (drv_data->ssp_type != CE4100_SSP && gpio_is_valid(chip->gpio_cs)) |
1371 | gpio_free(chip->gpio_cs); | 1414 | gpio_free(chip->gpio_cs); |
1372 | 1415 | ||
1373 | kfree(chip); | 1416 | kfree(chip); |
@@ -1507,7 +1550,7 @@ static int __devinit pxa2xx_spi_probe(struct platform_device *pdev) | |||
1507 | 1550 | ||
1508 | drv_data->ioaddr = ssp->mmio_base; | 1551 | drv_data->ioaddr = ssp->mmio_base; |
1509 | drv_data->ssdr_physical = ssp->phys_base + SSDR; | 1552 | drv_data->ssdr_physical = ssp->phys_base + SSDR; |
1510 | if (ssp->type == PXA25x_SSP) { | 1553 | if (pxa25x_ssp_comp(drv_data)) { |
1511 | drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE; | 1554 | drv_data->int_cr1 = SSCR1_TIE | SSCR1_RIE; |
1512 | drv_data->dma_cr1 = 0; | 1555 | drv_data->dma_cr1 = 0; |
1513 | drv_data->clear_sr = SSSR_ROR; | 1556 | drv_data->clear_sr = SSSR_ROR; |
@@ -1569,7 +1612,7 @@ static int __devinit pxa2xx_spi_probe(struct platform_device *pdev) | |||
1569 | | SSCR0_Motorola | 1612 | | SSCR0_Motorola |
1570 | | SSCR0_DataSize(8), | 1613 | | SSCR0_DataSize(8), |
1571 | drv_data->ioaddr); | 1614 | drv_data->ioaddr); |
1572 | if (drv_data->ssp_type != PXA25x_SSP) | 1615 | if (!pxa25x_ssp_comp(drv_data)) |
1573 | write_SSTO(0, drv_data->ioaddr); | 1616 | write_SSTO(0, drv_data->ioaddr); |
1574 | write_SSPSP(0, drv_data->ioaddr); | 1617 | write_SSPSP(0, drv_data->ioaddr); |
1575 | 1618 | ||
diff --git a/include/linux/pxa2xx_ssp.h b/include/linux/pxa2xx_ssp.h index c3aa334cbb9b..2f691e4e6222 100644 --- a/include/linux/pxa2xx_ssp.h +++ b/include/linux/pxa2xx_ssp.h | |||
@@ -72,6 +72,7 @@ | |||
72 | #define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */ | 72 | #define SSCR1_SPH (1 << 4) /* Motorola SPI SSPSCLK phase setting */ |
73 | #define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */ | 73 | #define SSCR1_MWDS (1 << 5) /* Microwire Transmit Data Size */ |
74 | 74 | ||
75 | #define SSSR_ALT_FRM_MASK 3 /* Masks the SFRM signal number */ | ||
75 | #define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */ | 76 | #define SSSR_TNF (1 << 2) /* Transmit FIFO Not Full */ |
76 | #define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */ | 77 | #define SSSR_RNE (1 << 3) /* Receive FIFO Not Empty */ |
77 | #define SSSR_BSY (1 << 4) /* SSP Busy */ | 78 | #define SSSR_BSY (1 << 4) /* SSP Busy */ |
@@ -160,6 +161,7 @@ enum pxa_ssp_type { | |||
160 | PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ | 161 | PXA25x_NSSP, /* pxa 255, 26x (including ASSP) */ |
161 | PXA27x_SSP, | 162 | PXA27x_SSP, |
162 | PXA168_SSP, | 163 | PXA168_SSP, |
164 | CE4100_SSP, | ||
163 | }; | 165 | }; |
164 | 166 | ||
165 | struct ssp_device { | 167 | struct ssp_device { |