diff options
author | Chao Fu <B44548@freescale.com> | 2015-01-27 05:57:22 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-01-28 14:25:17 -0500 |
commit | 9298bc727385cd625cdda5e877bd3cba8acff668 (patch) | |
tree | 1c0a2f51260c16a0a65867db30845c3aae5461c6 /drivers/spi/spi-fsl-dspi.c | |
parent | 973fbce69ed8e79b5fe3ad19cfecb581a7ef8048 (diff) |
spi: spi-fsl-dspi: Remove spi-bitbang
DSPI module need cs change information in
a spi transfer. According to cs change, DSPI
will give last data the right flag. Bitbang
provide cs change behind the last data in
a transfer. So DSPI can not deal the last
data in every transfer properly, so remove
the bitbang in the driver.
Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi-fsl-dspi.c')
-rw-r--r-- | drivers/spi/spi-fsl-dspi.c | 144 |
1 files changed, 71 insertions, 73 deletions
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 9b80d54d4ddb..2c52c2e185c7 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c | |||
@@ -106,7 +106,7 @@ struct chip_data { | |||
106 | }; | 106 | }; |
107 | 107 | ||
108 | struct fsl_dspi { | 108 | struct fsl_dspi { |
109 | struct spi_bitbang bitbang; | 109 | struct spi_master *master; |
110 | struct platform_device *pdev; | 110 | struct platform_device *pdev; |
111 | 111 | ||
112 | struct regmap *regmap; | 112 | struct regmap *regmap; |
@@ -114,6 +114,7 @@ struct fsl_dspi { | |||
114 | struct clk *clk; | 114 | struct clk *clk; |
115 | 115 | ||
116 | struct spi_transfer *cur_transfer; | 116 | struct spi_transfer *cur_transfer; |
117 | struct spi_message *cur_msg; | ||
117 | struct chip_data *cur_chip; | 118 | struct chip_data *cur_chip; |
118 | size_t len; | 119 | size_t len; |
119 | void *tx; | 120 | void *tx; |
@@ -123,6 +124,7 @@ struct fsl_dspi { | |||
123 | char dataflags; | 124 | char dataflags; |
124 | u8 cs; | 125 | u8 cs; |
125 | u16 void_write_data; | 126 | u16 void_write_data; |
127 | u32 cs_change; | ||
126 | 128 | ||
127 | wait_queue_head_t waitq; | 129 | wait_queue_head_t waitq; |
128 | u32 waitflags; | 130 | u32 waitflags; |
@@ -225,6 +227,8 @@ static int dspi_transfer_write(struct fsl_dspi *dspi) | |||
225 | if (dspi->len == 0 || tx_count == DSPI_FIFO_SIZE - 1) { | 227 | if (dspi->len == 0 || tx_count == DSPI_FIFO_SIZE - 1) { |
226 | /* last transfer in the transfer */ | 228 | /* last transfer in the transfer */ |
227 | dspi_pushr |= SPI_PUSHR_EOQ; | 229 | dspi_pushr |= SPI_PUSHR_EOQ; |
230 | if ((dspi->cs_change) && (!dspi->len)) | ||
231 | dspi_pushr &= ~SPI_PUSHR_CONT; | ||
228 | } else if (tx_word && (dspi->len == 1)) | 232 | } else if (tx_word && (dspi->len == 1)) |
229 | dspi_pushr |= SPI_PUSHR_EOQ; | 233 | dspi_pushr |= SPI_PUSHR_EOQ; |
230 | 234 | ||
@@ -246,6 +250,7 @@ static int dspi_transfer_read(struct fsl_dspi *dspi) | |||
246 | int rx_count = 0; | 250 | int rx_count = 0; |
247 | int rx_word = is_double_byte_mode(dspi); | 251 | int rx_word = is_double_byte_mode(dspi); |
248 | u16 d; | 252 | u16 d; |
253 | |||
249 | while ((dspi->rx < dspi->rx_end) | 254 | while ((dspi->rx < dspi->rx_end) |
250 | && (rx_count < DSPI_FIFO_SIZE)) { | 255 | && (rx_count < DSPI_FIFO_SIZE)) { |
251 | if (rx_word) { | 256 | if (rx_word) { |
@@ -276,64 +281,67 @@ static int dspi_transfer_read(struct fsl_dspi *dspi) | |||
276 | return rx_count; | 281 | return rx_count; |
277 | } | 282 | } |
278 | 283 | ||
279 | static int dspi_txrx_transfer(struct spi_device *spi, struct spi_transfer *t) | 284 | static int dspi_transfer_one_message(struct spi_master *master, |
285 | struct spi_message *message) | ||
280 | { | 286 | { |
281 | struct fsl_dspi *dspi = spi_master_get_devdata(spi->master); | 287 | struct fsl_dspi *dspi = spi_master_get_devdata(master); |
282 | dspi->cur_transfer = t; | 288 | struct spi_device *spi = message->spi; |
283 | dspi->cur_chip = spi_get_ctldata(spi); | 289 | struct spi_transfer *transfer; |
284 | dspi->cs = spi->chip_select; | 290 | int status = 0; |
285 | dspi->void_write_data = dspi->cur_chip->void_write_data; | 291 | message->actual_length = 0; |
286 | 292 | ||
287 | dspi->dataflags = 0; | 293 | list_for_each_entry(transfer, &message->transfers, transfer_list) { |
288 | dspi->tx = (void *)t->tx_buf; | 294 | dspi->cur_transfer = transfer; |
289 | dspi->tx_end = dspi->tx + t->len; | 295 | dspi->cur_msg = message; |
290 | dspi->rx = t->rx_buf; | 296 | dspi->cur_chip = spi_get_ctldata(spi); |
291 | dspi->rx_end = dspi->rx + t->len; | 297 | dspi->cs = spi->chip_select; |
292 | dspi->len = t->len; | 298 | if (dspi->cur_transfer->transfer_list.next |
293 | 299 | == &dspi->cur_msg->transfers) | |
294 | if (!dspi->rx) | 300 | transfer->cs_change = 1; |
295 | dspi->dataflags |= TRAN_STATE_RX_VOID; | 301 | dspi->cs_change = transfer->cs_change; |
296 | 302 | dspi->void_write_data = dspi->cur_chip->void_write_data; | |
297 | if (!dspi->tx) | 303 | |
298 | dspi->dataflags |= TRAN_STATE_TX_VOID; | 304 | dspi->dataflags = 0; |
299 | 305 | dspi->tx = (void *)transfer->tx_buf; | |
300 | regmap_write(dspi->regmap, SPI_MCR, dspi->cur_chip->mcr_val); | 306 | dspi->tx_end = dspi->tx + transfer->len; |
301 | regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), dspi->cur_chip->ctar_val); | 307 | dspi->rx = transfer->rx_buf; |
302 | regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE); | 308 | dspi->rx_end = dspi->rx + transfer->len; |
303 | 309 | dspi->len = transfer->len; | |
304 | if (t->speed_hz) | 310 | |
311 | if (!dspi->rx) | ||
312 | dspi->dataflags |= TRAN_STATE_RX_VOID; | ||
313 | |||
314 | if (!dspi->tx) | ||
315 | dspi->dataflags |= TRAN_STATE_TX_VOID; | ||
316 | |||
317 | regmap_write(dspi->regmap, SPI_MCR, dspi->cur_chip->mcr_val); | ||
318 | regmap_update_bits(dspi->regmap, SPI_MCR, | ||
319 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, | ||
320 | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); | ||
305 | regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), | 321 | regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), |
306 | dspi->cur_chip->ctar_val); | 322 | dspi->cur_chip->ctar_val); |
323 | if (transfer->speed_hz) | ||
324 | regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), | ||
325 | dspi->cur_chip->ctar_val); | ||
307 | 326 | ||
308 | dspi_transfer_write(dspi); | 327 | regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE); |
309 | 328 | message->actual_length += dspi_transfer_write(dspi); | |
310 | if (wait_event_interruptible(dspi->waitq, dspi->waitflags)) | ||
311 | dev_err(&dspi->pdev->dev, "wait transfer complete fail!\n"); | ||
312 | dspi->waitflags = 0; | ||
313 | |||
314 | return t->len - dspi->len; | ||
315 | } | ||
316 | |||
317 | static void dspi_chipselect(struct spi_device *spi, int value) | ||
318 | { | ||
319 | struct fsl_dspi *dspi = spi_master_get_devdata(spi->master); | ||
320 | unsigned int pushr; | ||
321 | 329 | ||
322 | regmap_read(dspi->regmap, SPI_PUSHR, &pushr); | 330 | if (wait_event_interruptible(dspi->waitq, dspi->waitflags)) |
331 | dev_err(&dspi->pdev->dev, "wait transfer complete fail!\n"); | ||
332 | dspi->waitflags = 0; | ||
323 | 333 | ||
324 | switch (value) { | 334 | if (transfer->delay_usecs) |
325 | case BITBANG_CS_ACTIVE: | 335 | udelay(transfer->delay_usecs); |
326 | pushr |= SPI_PUSHR_CONT; | ||
327 | break; | ||
328 | case BITBANG_CS_INACTIVE: | ||
329 | pushr &= ~SPI_PUSHR_CONT; | ||
330 | break; | ||
331 | } | 336 | } |
332 | 337 | ||
333 | regmap_write(dspi->regmap, SPI_PUSHR, pushr); | 338 | message->status = status; |
339 | spi_finalize_current_message(master); | ||
340 | |||
341 | return status; | ||
334 | } | 342 | } |
335 | 343 | ||
336 | static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) | 344 | static int dspi_setup(struct spi_device *spi) |
337 | { | 345 | { |
338 | struct chip_data *chip; | 346 | struct chip_data *chip; |
339 | struct fsl_dspi *dspi = spi_master_get_devdata(spi->master); | 347 | struct fsl_dspi *dspi = spi_master_get_devdata(spi->master); |
@@ -373,14 +381,6 @@ static int dspi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) | |||
373 | return 0; | 381 | return 0; |
374 | } | 382 | } |
375 | 383 | ||
376 | static int dspi_setup(struct spi_device *spi) | ||
377 | { | ||
378 | if (!spi->max_speed_hz) | ||
379 | return -EINVAL; | ||
380 | |||
381 | return dspi_setup_transfer(spi, NULL); | ||
382 | } | ||
383 | |||
384 | static void dspi_cleanup(struct spi_device *spi) | 384 | static void dspi_cleanup(struct spi_device *spi) |
385 | { | 385 | { |
386 | struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi); | 386 | struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi); |
@@ -395,22 +395,20 @@ static irqreturn_t dspi_interrupt(int irq, void *dev_id) | |||
395 | { | 395 | { |
396 | struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id; | 396 | struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id; |
397 | 397 | ||
398 | regmap_write(dspi->regmap, SPI_SR, SPI_SR_EOQF); | 398 | struct spi_message *msg = dspi->cur_msg; |
399 | 399 | ||
400 | regmap_write(dspi->regmap, SPI_SR, SPI_SR_EOQF); | ||
400 | dspi_transfer_read(dspi); | 401 | dspi_transfer_read(dspi); |
401 | 402 | ||
402 | if (!dspi->len) { | 403 | if (!dspi->len) { |
403 | if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) | 404 | if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) |
404 | regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), | 405 | regmap_update_bits(dspi->regmap, SPI_CTAR(dspi->cs), |
405 | SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(16)); | 406 | SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(16)); |
406 | 407 | ||
407 | dspi->waitflags = 1; | 408 | dspi->waitflags = 1; |
408 | wake_up_interruptible(&dspi->waitq); | 409 | wake_up_interruptible(&dspi->waitq); |
409 | } else { | 410 | } else |
410 | dspi_transfer_write(dspi); | 411 | msg->actual_length += dspi_transfer_write(dspi); |
411 | |||
412 | return IRQ_HANDLED; | ||
413 | } | ||
414 | 412 | ||
415 | return IRQ_HANDLED; | 413 | return IRQ_HANDLED; |
416 | } | 414 | } |
@@ -469,12 +467,12 @@ static int dspi_probe(struct platform_device *pdev) | |||
469 | 467 | ||
470 | dspi = spi_master_get_devdata(master); | 468 | dspi = spi_master_get_devdata(master); |
471 | dspi->pdev = pdev; | 469 | dspi->pdev = pdev; |
472 | dspi->bitbang.master = master; | 470 | dspi->master = master; |
473 | dspi->bitbang.chipselect = dspi_chipselect; | 471 | |
474 | dspi->bitbang.setup_transfer = dspi_setup_transfer; | 472 | master->transfer = NULL; |
475 | dspi->bitbang.txrx_bufs = dspi_txrx_transfer; | 473 | master->setup = dspi_setup; |
476 | dspi->bitbang.master->setup = dspi_setup; | 474 | master->transfer_one_message = dspi_transfer_one_message; |
477 | dspi->bitbang.master->dev.of_node = pdev->dev.of_node; | 475 | master->dev.of_node = pdev->dev.of_node; |
478 | 476 | ||
479 | master->cleanup = dspi_cleanup; | 477 | master->cleanup = dspi_cleanup; |
480 | master->mode_bits = SPI_CPOL | SPI_CPHA; | 478 | master->mode_bits = SPI_CPOL | SPI_CPHA; |
@@ -535,7 +533,7 @@ static int dspi_probe(struct platform_device *pdev) | |||
535 | init_waitqueue_head(&dspi->waitq); | 533 | init_waitqueue_head(&dspi->waitq); |
536 | platform_set_drvdata(pdev, master); | 534 | platform_set_drvdata(pdev, master); |
537 | 535 | ||
538 | ret = spi_bitbang_start(&dspi->bitbang); | 536 | ret = spi_register_master(master); |
539 | if (ret != 0) { | 537 | if (ret != 0) { |
540 | dev_err(&pdev->dev, "Problem registering DSPI master\n"); | 538 | dev_err(&pdev->dev, "Problem registering DSPI master\n"); |
541 | goto out_clk_put; | 539 | goto out_clk_put; |
@@ -557,9 +555,9 @@ static int dspi_remove(struct platform_device *pdev) | |||
557 | struct fsl_dspi *dspi = spi_master_get_devdata(master); | 555 | struct fsl_dspi *dspi = spi_master_get_devdata(master); |
558 | 556 | ||
559 | /* Disconnect from the SPI framework */ | 557 | /* Disconnect from the SPI framework */ |
560 | spi_bitbang_stop(&dspi->bitbang); | ||
561 | clk_disable_unprepare(dspi->clk); | 558 | clk_disable_unprepare(dspi->clk); |
562 | spi_master_put(dspi->bitbang.master); | 559 | spi_unregister_master(dspi->master); |
560 | spi_master_put(dspi->master); | ||
563 | 561 | ||
564 | return 0; | 562 | return 0; |
565 | } | 563 | } |