diff options
Diffstat (limited to 'drivers/spi/spi-omap2-mcspi.c')
-rw-r--r-- | drivers/spi/spi-omap2-mcspi.c | 76 |
1 files changed, 41 insertions, 35 deletions
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 3542fdc664b1..b610f522ca44 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/of.h> | 39 | #include <linux/of.h> |
40 | #include <linux/of_device.h> | 40 | #include <linux/of_device.h> |
41 | #include <linux/pinctrl/consumer.h> | 41 | #include <linux/pinctrl/consumer.h> |
42 | #include <linux/err.h> | ||
43 | 42 | ||
44 | #include <linux/spi/spi.h> | 43 | #include <linux/spi/spi.h> |
45 | 44 | ||
@@ -130,6 +129,7 @@ struct omap2_mcspi { | |||
130 | struct omap2_mcspi_dma *dma_channels; | 129 | struct omap2_mcspi_dma *dma_channels; |
131 | struct device *dev; | 130 | struct device *dev; |
132 | struct omap2_mcspi_regs ctx; | 131 | struct omap2_mcspi_regs ctx; |
132 | unsigned int pin_dir:1; | ||
133 | }; | 133 | }; |
134 | 134 | ||
135 | struct omap2_mcspi_cs { | 135 | struct omap2_mcspi_cs { |
@@ -323,19 +323,11 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, | |||
323 | struct omap2_mcspi *mcspi; | 323 | struct omap2_mcspi *mcspi; |
324 | struct omap2_mcspi_dma *mcspi_dma; | 324 | struct omap2_mcspi_dma *mcspi_dma; |
325 | unsigned int count; | 325 | unsigned int count; |
326 | u8 * rx; | ||
327 | const u8 * tx; | ||
328 | void __iomem *chstat_reg; | ||
329 | struct omap2_mcspi_cs *cs = spi->controller_state; | ||
330 | 326 | ||
331 | mcspi = spi_master_get_devdata(spi->master); | 327 | mcspi = spi_master_get_devdata(spi->master); |
332 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 328 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
333 | count = xfer->len; | 329 | count = xfer->len; |
334 | 330 | ||
335 | rx = xfer->rx_buf; | ||
336 | tx = xfer->tx_buf; | ||
337 | chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; | ||
338 | |||
339 | if (mcspi_dma->dma_tx) { | 331 | if (mcspi_dma->dma_tx) { |
340 | struct dma_async_tx_descriptor *tx; | 332 | struct dma_async_tx_descriptor *tx; |
341 | struct scatterlist sg; | 333 | struct scatterlist sg; |
@@ -359,19 +351,6 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, | |||
359 | dma_async_issue_pending(mcspi_dma->dma_tx); | 351 | dma_async_issue_pending(mcspi_dma->dma_tx); |
360 | omap2_mcspi_set_dma_req(spi, 0, 1); | 352 | omap2_mcspi_set_dma_req(spi, 0, 1); |
361 | 353 | ||
362 | wait_for_completion(&mcspi_dma->dma_tx_completion); | ||
363 | dma_unmap_single(mcspi->dev, xfer->tx_dma, count, | ||
364 | DMA_TO_DEVICE); | ||
365 | |||
366 | /* for TX_ONLY mode, be sure all words have shifted out */ | ||
367 | if (rx == NULL) { | ||
368 | if (mcspi_wait_for_reg_bit(chstat_reg, | ||
369 | OMAP2_MCSPI_CHSTAT_TXS) < 0) | ||
370 | dev_err(&spi->dev, "TXS timed out\n"); | ||
371 | else if (mcspi_wait_for_reg_bit(chstat_reg, | ||
372 | OMAP2_MCSPI_CHSTAT_EOT) < 0) | ||
373 | dev_err(&spi->dev, "EOT timed out\n"); | ||
374 | } | ||
375 | } | 354 | } |
376 | 355 | ||
377 | static unsigned | 356 | static unsigned |
@@ -492,6 +471,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
492 | struct dma_slave_config cfg; | 471 | struct dma_slave_config cfg; |
493 | enum dma_slave_buswidth width; | 472 | enum dma_slave_buswidth width; |
494 | unsigned es; | 473 | unsigned es; |
474 | void __iomem *chstat_reg; | ||
495 | 475 | ||
496 | mcspi = spi_master_get_devdata(spi->master); | 476 | mcspi = spi_master_get_devdata(spi->master); |
497 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; | 477 | mcspi_dma = &mcspi->dma_channels[spi->chip_select]; |
@@ -526,8 +506,24 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) | |||
526 | omap2_mcspi_tx_dma(spi, xfer, cfg); | 506 | omap2_mcspi_tx_dma(spi, xfer, cfg); |
527 | 507 | ||
528 | if (rx != NULL) | 508 | if (rx != NULL) |
529 | return omap2_mcspi_rx_dma(spi, xfer, cfg, es); | 509 | count = omap2_mcspi_rx_dma(spi, xfer, cfg, es); |
530 | 510 | ||
511 | if (tx != NULL) { | ||
512 | chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0; | ||
513 | wait_for_completion(&mcspi_dma->dma_tx_completion); | ||
514 | dma_unmap_single(mcspi->dev, xfer->tx_dma, xfer->len, | ||
515 | DMA_TO_DEVICE); | ||
516 | |||
517 | /* for TX_ONLY mode, be sure all words have shifted out */ | ||
518 | if (rx == NULL) { | ||
519 | if (mcspi_wait_for_reg_bit(chstat_reg, | ||
520 | OMAP2_MCSPI_CHSTAT_TXS) < 0) | ||
521 | dev_err(&spi->dev, "TXS timed out\n"); | ||
522 | else if (mcspi_wait_for_reg_bit(chstat_reg, | ||
523 | OMAP2_MCSPI_CHSTAT_EOT) < 0) | ||
524 | dev_err(&spi->dev, "EOT timed out\n"); | ||
525 | } | ||
526 | } | ||
531 | return count; | 527 | return count; |
532 | } | 528 | } |
533 | 529 | ||
@@ -765,8 +761,15 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi, | |||
765 | /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS | 761 | /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS |
766 | * REVISIT: this controller could support SPI_3WIRE mode. | 762 | * REVISIT: this controller could support SPI_3WIRE mode. |
767 | */ | 763 | */ |
768 | l &= ~(OMAP2_MCSPI_CHCONF_IS|OMAP2_MCSPI_CHCONF_DPE1); | 764 | if (mcspi->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) { |
769 | l |= OMAP2_MCSPI_CHCONF_DPE0; | 765 | l &= ~OMAP2_MCSPI_CHCONF_IS; |
766 | l &= ~OMAP2_MCSPI_CHCONF_DPE1; | ||
767 | l |= OMAP2_MCSPI_CHCONF_DPE0; | ||
768 | } else { | ||
769 | l |= OMAP2_MCSPI_CHCONF_IS; | ||
770 | l |= OMAP2_MCSPI_CHCONF_DPE1; | ||
771 | l &= ~OMAP2_MCSPI_CHCONF_DPE0; | ||
772 | } | ||
770 | 773 | ||
771 | /* wordlength */ | 774 | /* wordlength */ |
772 | l &= ~OMAP2_MCSPI_CHCONF_WL_MASK; | 775 | l &= ~OMAP2_MCSPI_CHCONF_WL_MASK; |
@@ -1085,7 +1088,7 @@ static int omap2_mcspi_transfer_one_message(struct spi_master *master, | |||
1085 | return 0; | 1088 | return 0; |
1086 | } | 1089 | } |
1087 | 1090 | ||
1088 | static int __devinit omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) | 1091 | static int omap2_mcspi_master_setup(struct omap2_mcspi *mcspi) |
1089 | { | 1092 | { |
1090 | struct spi_master *master = mcspi->master; | 1093 | struct spi_master *master = mcspi->master; |
1091 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; | 1094 | struct omap2_mcspi_regs *ctx = &mcspi->ctx; |
@@ -1138,7 +1141,7 @@ static const struct of_device_id omap_mcspi_of_match[] = { | |||
1138 | }; | 1141 | }; |
1139 | MODULE_DEVICE_TABLE(of, omap_mcspi_of_match); | 1142 | MODULE_DEVICE_TABLE(of, omap_mcspi_of_match); |
1140 | 1143 | ||
1141 | static int __devinit omap2_mcspi_probe(struct platform_device *pdev) | 1144 | static int omap2_mcspi_probe(struct platform_device *pdev) |
1142 | { | 1145 | { |
1143 | struct spi_master *master; | 1146 | struct spi_master *master; |
1144 | const struct omap2_mcspi_platform_config *pdata; | 1147 | const struct omap2_mcspi_platform_config *pdata; |
@@ -1167,6 +1170,11 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) | |||
1167 | master->cleanup = omap2_mcspi_cleanup; | 1170 | master->cleanup = omap2_mcspi_cleanup; |
1168 | master->dev.of_node = node; | 1171 | master->dev.of_node = node; |
1169 | 1172 | ||
1173 | dev_set_drvdata(&pdev->dev, master); | ||
1174 | |||
1175 | mcspi = spi_master_get_devdata(master); | ||
1176 | mcspi->master = master; | ||
1177 | |||
1170 | match = of_match_device(omap_mcspi_of_match, &pdev->dev); | 1178 | match = of_match_device(omap_mcspi_of_match, &pdev->dev); |
1171 | if (match) { | 1179 | if (match) { |
1172 | u32 num_cs = 1; /* default number of chipselect */ | 1180 | u32 num_cs = 1; /* default number of chipselect */ |
@@ -1175,19 +1183,17 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) | |||
1175 | of_property_read_u32(node, "ti,spi-num-cs", &num_cs); | 1183 | of_property_read_u32(node, "ti,spi-num-cs", &num_cs); |
1176 | master->num_chipselect = num_cs; | 1184 | master->num_chipselect = num_cs; |
1177 | master->bus_num = bus_num++; | 1185 | master->bus_num = bus_num++; |
1186 | if (of_get_property(node, "ti,pindir-d0-out-d1-in", NULL)) | ||
1187 | mcspi->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN; | ||
1178 | } else { | 1188 | } else { |
1179 | pdata = pdev->dev.platform_data; | 1189 | pdata = pdev->dev.platform_data; |
1180 | master->num_chipselect = pdata->num_cs; | 1190 | master->num_chipselect = pdata->num_cs; |
1181 | if (pdev->id != -1) | 1191 | if (pdev->id != -1) |
1182 | master->bus_num = pdev->id; | 1192 | master->bus_num = pdev->id; |
1193 | mcspi->pin_dir = pdata->pin_dir; | ||
1183 | } | 1194 | } |
1184 | regs_offset = pdata->regs_offset; | 1195 | regs_offset = pdata->regs_offset; |
1185 | 1196 | ||
1186 | dev_set_drvdata(&pdev->dev, master); | ||
1187 | |||
1188 | mcspi = spi_master_get_devdata(master); | ||
1189 | mcspi->master = master; | ||
1190 | |||
1191 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1197 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1192 | if (r == NULL) { | 1198 | if (r == NULL) { |
1193 | status = -ENODEV; | 1199 | status = -ENODEV; |
@@ -1272,7 +1278,7 @@ free_master: | |||
1272 | return status; | 1278 | return status; |
1273 | } | 1279 | } |
1274 | 1280 | ||
1275 | static int __devexit omap2_mcspi_remove(struct platform_device *pdev) | 1281 | static int omap2_mcspi_remove(struct platform_device *pdev) |
1276 | { | 1282 | { |
1277 | struct spi_master *master; | 1283 | struct spi_master *master; |
1278 | struct omap2_mcspi *mcspi; | 1284 | struct omap2_mcspi *mcspi; |
@@ -1341,7 +1347,7 @@ static struct platform_driver omap2_mcspi_driver = { | |||
1341 | .of_match_table = omap_mcspi_of_match, | 1347 | .of_match_table = omap_mcspi_of_match, |
1342 | }, | 1348 | }, |
1343 | .probe = omap2_mcspi_probe, | 1349 | .probe = omap2_mcspi_probe, |
1344 | .remove = __devexit_p(omap2_mcspi_remove), | 1350 | .remove = omap2_mcspi_remove, |
1345 | }; | 1351 | }; |
1346 | 1352 | ||
1347 | module_platform_driver(omap2_mcspi_driver); | 1353 | module_platform_driver(omap2_mcspi_driver); |