diff options
author | Geert Uytterhoeven <geert+renesas@linux-m68k.org> | 2014-01-24 03:43:54 -0500 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-01-27 15:02:09 -0500 |
commit | 35301c996046243ca6e41d490dea2823f045614c (patch) | |
tree | 047c5fb2bbe0ed3259a488a18da18d4fe7dc5b07 /drivers/spi/spi-rspi.c | |
parent | 74da76865d57161cadf8f324281f23ed3eb5db9c (diff) |
spi: rspi: Add rspi_data_{out,in,out_in}() helpers
Add helpers rspi_data_{out,in,out_in}() to write, read, or write and
read data to/from the Data Register, taking care of waiting until data
or space is available in the buffers.
Signed-off-by: Geert Uytterhoeven <geert+renesas@linux-m68k.org>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'drivers/spi/spi-rspi.c')
-rw-r--r-- | drivers/spi/spi-rspi.c | 117 |
1 files changed, 56 insertions, 61 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index a0bb3c28ae91..4b27513e7204 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
@@ -356,22 +356,51 @@ static int rspi_wait_for_interrupt(struct rspi_data *rspi, u8 wait_mask, | |||
356 | return 0; | 356 | return 0; |
357 | } | 357 | } |
358 | 358 | ||
359 | static int rspi_data_out(struct rspi_data *rspi, u8 data) | ||
360 | { | ||
361 | if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { | ||
362 | dev_err(&rspi->master->dev, "transmit timeout\n"); | ||
363 | return -ETIMEDOUT; | ||
364 | } | ||
365 | rspi_write_data(rspi, data); | ||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | static int rspi_data_in(struct rspi_data *rspi) | ||
370 | { | ||
371 | u8 data; | ||
372 | |||
373 | if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { | ||
374 | dev_err(&rspi->master->dev, "receive timeout\n"); | ||
375 | return -ETIMEDOUT; | ||
376 | } | ||
377 | data = rspi_read_data(rspi); | ||
378 | return data; | ||
379 | } | ||
380 | |||
381 | static int rspi_data_out_in(struct rspi_data *rspi, u8 data) | ||
382 | { | ||
383 | int ret; | ||
384 | |||
385 | ret = rspi_data_out(rspi, data); | ||
386 | if (ret < 0) | ||
387 | return ret; | ||
388 | |||
389 | return rspi_data_in(rspi); | ||
390 | } | ||
391 | |||
359 | static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t) | 392 | static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t) |
360 | { | 393 | { |
361 | int remain = t->len; | 394 | int remain = t->len, ret; |
362 | const u8 *data = t->tx_buf; | 395 | const u8 *data = t->tx_buf; |
396 | |||
363 | while (remain > 0) { | 397 | while (remain > 0) { |
364 | rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, | 398 | rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | SPCR_TXMD, |
365 | RSPI_SPCR); | 399 | RSPI_SPCR); |
366 | 400 | ||
367 | if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { | 401 | ret = rspi_data_out(rspi, *data++); |
368 | dev_err(&rspi->master->dev, | 402 | if (ret < 0) |
369 | "%s: tx empty timeout\n", __func__); | 403 | return ret; |
370 | return -ETIMEDOUT; | ||
371 | } | ||
372 | |||
373 | rspi_write_data(rspi, *data); | ||
374 | data++; | ||
375 | remain--; | 404 | remain--; |
376 | } | 405 | } |
377 | 406 | ||
@@ -383,28 +412,17 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t) | |||
383 | 412 | ||
384 | static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t) | 413 | static int qspi_send_pio(struct rspi_data *rspi, struct spi_transfer *t) |
385 | { | 414 | { |
386 | int remain = t->len; | 415 | int remain = t->len, ret; |
387 | const u8 *data = t->tx_buf; | 416 | const u8 *data = t->tx_buf; |
388 | 417 | ||
389 | rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR); | 418 | rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR); |
390 | rspi_write8(rspi, 0x00, QSPI_SPBFCR); | 419 | rspi_write8(rspi, 0x00, QSPI_SPBFCR); |
391 | 420 | ||
392 | while (remain > 0) { | 421 | while (remain > 0) { |
393 | 422 | /* dummy read */ | |
394 | if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { | 423 | ret = rspi_data_out_in(rspi, *data++); |
395 | dev_err(&rspi->master->dev, | 424 | if (ret < 0) |
396 | "%s: tx empty timeout\n", __func__); | 425 | return ret; |
397 | return -ETIMEDOUT; | ||
398 | } | ||
399 | rspi_write_data(rspi, *data++); | ||
400 | |||
401 | if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { | ||
402 | dev_err(&rspi->master->dev, | ||
403 | "%s: receive timeout\n", __func__); | ||
404 | return -ETIMEDOUT; | ||
405 | } | ||
406 | rspi_read_data(rspi); | ||
407 | |||
408 | remain--; | 426 | remain--; |
409 | } | 427 | } |
410 | 428 | ||
@@ -549,32 +567,20 @@ static void rspi_receive_init(const struct rspi_data *rspi) | |||
549 | 567 | ||
550 | static int rspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t) | 568 | static int rspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t) |
551 | { | 569 | { |
552 | int remain = t->len; | 570 | int remain = t->len, ret; |
553 | u8 *data; | 571 | u8 *data = t->rx_buf; |
554 | 572 | ||
555 | rspi_receive_init(rspi); | 573 | rspi_receive_init(rspi); |
556 | 574 | ||
557 | data = t->rx_buf; | ||
558 | while (remain > 0) { | 575 | while (remain > 0) { |
559 | rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, | 576 | rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_TXMD, |
560 | RSPI_SPCR); | 577 | RSPI_SPCR); |
561 | 578 | ||
562 | if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { | 579 | /* dummy write data for generate clock */ |
563 | dev_err(&rspi->master->dev, | 580 | ret = rspi_data_out_in(rspi, DUMMY_DATA); |
564 | "%s: tx empty timeout\n", __func__); | 581 | if (ret < 0) |
565 | return -ETIMEDOUT; | 582 | return ret; |
566 | } | 583 | *data++ = ret; |
567 | /* dummy write for generate clock */ | ||
568 | rspi_write_data(rspi, DUMMY_DATA); | ||
569 | |||
570 | if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { | ||
571 | dev_err(&rspi->master->dev, | ||
572 | "%s: receive timeout\n", __func__); | ||
573 | return -ETIMEDOUT; | ||
574 | } | ||
575 | *data = rspi_read_data(rspi); | ||
576 | |||
577 | data++; | ||
578 | remain--; | 584 | remain--; |
579 | } | 585 | } |
580 | 586 | ||
@@ -594,28 +600,17 @@ static void qspi_receive_init(const struct rspi_data *rspi) | |||
594 | 600 | ||
595 | static int qspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t) | 601 | static int qspi_receive_pio(struct rspi_data *rspi, struct spi_transfer *t) |
596 | { | 602 | { |
597 | int remain = t->len; | 603 | int remain = t->len, ret; |
598 | u8 *data; | 604 | u8 *data = t->rx_buf; |
599 | 605 | ||
600 | qspi_receive_init(rspi); | 606 | qspi_receive_init(rspi); |
601 | 607 | ||
602 | data = t->rx_buf; | ||
603 | while (remain > 0) { | 608 | while (remain > 0) { |
604 | |||
605 | if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { | ||
606 | dev_err(&rspi->master->dev, | ||
607 | "%s: tx empty timeout\n", __func__); | ||
608 | return -ETIMEDOUT; | ||
609 | } | ||
610 | /* dummy write for generate clock */ | 609 | /* dummy write for generate clock */ |
611 | rspi_write_data(rspi, DUMMY_DATA); | 610 | ret = rspi_data_out_in(rspi, DUMMY_DATA); |
612 | 611 | if (ret < 0) | |
613 | if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { | 612 | return ret; |
614 | dev_err(&rspi->master->dev, | 613 | *data++ = ret; |
615 | "%s: receive timeout\n", __func__); | ||
616 | return -ETIMEDOUT; | ||
617 | } | ||
618 | *data++ = rspi_read_data(rspi); | ||
619 | remain--; | 614 | remain--; |
620 | } | 615 | } |
621 | 616 | ||