diff options
| -rw-r--r-- | drivers/spi/spi-rspi.c | 95 |
1 files changed, 93 insertions, 2 deletions
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 4c8dbac11b42..58449ad4ad0d 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c | |||
| @@ -198,6 +198,11 @@ static u16 rspi_read16(struct rspi_data *rspi, u16 offset) | |||
| 198 | /* optional functions */ | 198 | /* optional functions */ |
| 199 | struct spi_ops { | 199 | struct spi_ops { |
| 200 | int (*set_config_register)(struct rspi_data *rspi, int access_size); | 200 | int (*set_config_register)(struct rspi_data *rspi, int access_size); |
| 201 | int (*send_pio)(struct rspi_data *rspi, struct spi_message *mesg, | ||
| 202 | struct spi_transfer *t); | ||
| 203 | int (*receive_pio)(struct rspi_data *rspi, struct spi_message *mesg, | ||
| 204 | struct spi_transfer *t); | ||
| 205 | |||
| 201 | }; | 206 | }; |
| 202 | 207 | ||
| 203 | /* | 208 | /* |
| @@ -349,6 +354,43 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, | |||
| 349 | return 0; | 354 | return 0; |
| 350 | } | 355 | } |
| 351 | 356 | ||
| 357 | static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, | ||
| 358 | struct spi_transfer *t) | ||
| 359 | { | ||
| 360 | int remain = t->len; | ||
| 361 | u8 *data; | ||
| 362 | |||
| 363 | rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR); | ||
| 364 | rspi_write8(rspi, 0x00, QSPI_SPBFCR); | ||
| 365 | |||
| 366 | data = (u8 *)t->tx_buf; | ||
| 367 | while (remain > 0) { | ||
| 368 | |||
| 369 | if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { | ||
| 370 | dev_err(&rspi->master->dev, | ||
| 371 | "%s: tx empty timeout\n", __func__); | ||
| 372 | return -ETIMEDOUT; | ||
| 373 | } | ||
| 374 | rspi_write8(rspi, *data++, RSPI_SPDR); | ||
| 375 | |||
| 376 | if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { | ||
| 377 | dev_err(&rspi->master->dev, | ||
| 378 | "%s: receive timeout\n", __func__); | ||
| 379 | return -ETIMEDOUT; | ||
| 380 | } | ||
| 381 | rspi_read8(rspi, RSPI_SPDR); | ||
| 382 | |||
| 383 | remain--; | ||
| 384 | } | ||
| 385 | |||
| 386 | /* Waiting for the last transmition */ | ||
| 387 | rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE); | ||
| 388 | |||
| 389 | return 0; | ||
| 390 | } | ||
| 391 | |||
| 392 | #define send_pio(spi, mesg, t) spi->ops->send_pio(spi, mesg, t) | ||
| 393 | |||
| 352 | static void rspi_dma_complete(void *arg) | 394 | static void rspi_dma_complete(void *arg) |
| 353 | { | 395 | { |
| 354 | struct rspi_data *rspi = arg; | 396 | struct rspi_data *rspi = arg; |
| @@ -514,6 +556,51 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, | |||
| 514 | return 0; | 556 | return 0; |
| 515 | } | 557 | } |
| 516 | 558 | ||
| 559 | static void qspi_receive_init(struct rspi_data *rspi) | ||
| 560 | { | ||
| 561 | unsigned char spsr; | ||
| 562 | |||
| 563 | spsr = rspi_read8(rspi, RSPI_SPSR); | ||
| 564 | if (spsr & SPSR_SPRF) | ||
| 565 | rspi_read8(rspi, RSPI_SPDR); /* dummy read */ | ||
| 566 | rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR); | ||
| 567 | rspi_write8(rspi, 0x00, QSPI_SPBFCR); | ||
| 568 | } | ||
| 569 | |||
| 570 | static int qspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, | ||
| 571 | struct spi_transfer *t) | ||
| 572 | { | ||
| 573 | int remain = t->len; | ||
| 574 | u8 *data; | ||
| 575 | |||
| 576 | qspi_receive_init(rspi); | ||
| 577 | |||
| 578 | data = (u8 *)t->rx_buf; | ||
| 579 | while (remain > 0) { | ||
| 580 | |||
| 581 | if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { | ||
| 582 | dev_err(&rspi->master->dev, | ||
| 583 | "%s: tx empty timeout\n", __func__); | ||
| 584 | return -ETIMEDOUT; | ||
| 585 | } | ||
| 586 | /* dummy write for generate clock */ | ||
| 587 | rspi_write8(rspi, 0x00, RSPI_SPDR); | ||
| 588 | |||
| 589 | if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { | ||
| 590 | dev_err(&rspi->master->dev, | ||
| 591 | "%s: receive timeout\n", __func__); | ||
| 592 | return -ETIMEDOUT; | ||
| 593 | } | ||
| 594 | /* SPDR allows 8, 16 or 32-bit access */ | ||
| 595 | *data++ = rspi_read8(rspi, RSPI_SPDR); | ||
| 596 | remain--; | ||
| 597 | } | ||
| 598 | |||
| 599 | return 0; | ||
| 600 | } | ||
| 601 | |||
| 602 | #define receive_pio(spi, mesg, t) spi->ops->receive_pio(spi, mesg, t) | ||
| 603 | |||
| 517 | static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) | 604 | static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) |
| 518 | { | 605 | { |
| 519 | struct scatterlist sg, sg_dummy; | 606 | struct scatterlist sg, sg_dummy; |
| @@ -653,7 +740,7 @@ static void rspi_work(struct work_struct *work) | |||
| 653 | if (rspi_is_dma(rspi, t)) | 740 | if (rspi_is_dma(rspi, t)) |
| 654 | ret = rspi_send_dma(rspi, t); | 741 | ret = rspi_send_dma(rspi, t); |
| 655 | else | 742 | else |
| 656 | ret = rspi_send_pio(rspi, mesg, t); | 743 | ret = send_pio(rspi, mesg, t); |
| 657 | if (ret < 0) | 744 | if (ret < 0) |
| 658 | goto error; | 745 | goto error; |
| 659 | } | 746 | } |
| @@ -661,7 +748,7 @@ static void rspi_work(struct work_struct *work) | |||
| 661 | if (rspi_is_dma(rspi, t)) | 748 | if (rspi_is_dma(rspi, t)) |
| 662 | ret = rspi_receive_dma(rspi, t); | 749 | ret = rspi_receive_dma(rspi, t); |
| 663 | else | 750 | else |
| 664 | ret = rspi_receive_pio(rspi, mesg, t); | 751 | ret = receive_pio(rspi, mesg, t); |
| 665 | if (ret < 0) | 752 | if (ret < 0) |
| 666 | goto error; | 753 | goto error; |
| 667 | } | 754 | } |
| @@ -918,10 +1005,14 @@ error1: | |||
| 918 | 1005 | ||
| 919 | static struct spi_ops rspi_ops = { | 1006 | static struct spi_ops rspi_ops = { |
| 920 | .set_config_register = rspi_set_config_register, | 1007 | .set_config_register = rspi_set_config_register, |
| 1008 | .send_pio = rspi_send_pio, | ||
| 1009 | .receive_pio = rspi_receive_pio, | ||
| 921 | }; | 1010 | }; |
| 922 | 1011 | ||
| 923 | static struct spi_ops qspi_ops = { | 1012 | static struct spi_ops qspi_ops = { |
| 924 | .set_config_register = qspi_set_config_register, | 1013 | .set_config_register = qspi_set_config_register, |
| 1014 | .send_pio = qspi_send_pio, | ||
| 1015 | .receive_pio = qspi_receive_pio, | ||
| 925 | }; | 1016 | }; |
| 926 | 1017 | ||
| 927 | static struct platform_device_id spi_driver_ids[] = { | 1018 | static struct platform_device_id spi_driver_ids[] = { |
