diff options
author | Jun Lin <CHLin56@nuvoton.com> | 2023-03-03 11:23:01 +0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2023-05-03 21:37:28 +0000 |
commit | 310b3033ac604b87256b2bb2a99eabc5993d70fd (patch) | |
tree | 854c8685a922326c600da0e3f1055d70159dc3bf /chip | |
parent | ae77e271cec97465733805c55551c3e9fe56e63f (diff) | |
download | chrome-ec-310b3033ac604b87256b2bb2a99eabc5993d70fd.tar.gz |
npcx: SPI: add asynchronious transaction APIs
As the finger printer sensor needs multiple SPI transactions in the same
command state without de-asserting the CS pin, this commit implements:
- spi_transaction_async() - does the same thing as the original
spi_transaction does but keeps asserting the CS pin.
- spi_transaction_flush() - de-assert the CS pin.
- spi_transaction_wait() - a noop function as we don't support SPI DMA.
The original spi_transaction() is hence changed to call
spi_transaction_async() and spi_transaction_flush() to
prevent code duplication.
BRANCH=none
BUG=b:266703380, b:269695617
TEST=Test console commands
spi_flashinfo/spi_flashread/spi_flashwrite/spi_flasherase.
TEST=write a test console command to read the unique ID from flash with
multiple spi_transaction_async() calls + 1 spi_transaction_flush() call.
Change-Id: I3aacef0063a7cf2c1f70dfe2683b67110cdd9f5f
Signed-off-by: Jun Lin <CHLin56@nuvoton.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4305803
Reviewed-by: Bobby Casey <bobbycasey@google.com>
Tested-by: CH Lin <chlin56@nuvoton.com>
Reviewed-by: David Cross <davidmcross@google.com>
Commit-Queue: David Cross <davidmcross@google.com>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/npcx/spi.c | 70 |
1 files changed, 47 insertions, 23 deletions
diff --git a/chip/npcx/spi.c b/chip/npcx/spi.c index f152869bc5..f33dfae028 100644 --- a/chip/npcx/spi.c +++ b/chip/npcx/spi.c @@ -27,6 +27,9 @@ /* SPI IP as SPI controller */ #define SPI_CLK 8000000 + +static struct mutex spi_lock; + /** * Clear SPI data buffer. * @@ -106,30 +109,13 @@ int spi_enable(const struct spi_device_t *spi_device, int enable) return EC_SUCCESS; } -/** - * Flush an SPI transaction and receive data from peripheral. - * - * @param spi_device device to talk to - * @param txdata transfer data - * @param txlen transfer length - * @param rxdata receive data - * @param rxlen receive length - * @return success - * @notes set controller transaction mode in npcx chip - */ -int spi_transaction(const struct spi_device_t *spi_device, - const uint8_t *txdata, int txlen, uint8_t *rxdata, - int rxlen) +int spi_transaction_async(const struct spi_device_t *spi_device, + const uint8_t *txdata, int txlen, uint8_t *rxdata, + int rxlen) { int i = 0; enum gpio_signal gpio = spi_device->gpio_cs; - static struct mutex spi_lock; - mutex_lock(&spi_lock); - /* Make sure CS# is a GPIO output mode. */ - gpio_set_flags(gpio, GPIO_OUTPUT); - /* Make sure CS# is deselected */ - gpio_set_level(gpio, 1); /* Cleaning junk data in the buffer */ clear_databuf(); /* Assert CS# to start transaction */ @@ -159,7 +145,7 @@ int spi_transaction(const struct spi_device_t *spi_device, } if (rxlen == SPI_READBACK_ALL) - goto terminate; + return EC_SUCCESS; CPRINTS("write end"); /* Reading the data */ @@ -177,14 +163,52 @@ int spi_transaction(const struct spi_device_t *spi_device, CPRINTS("rxdata[i]=%x", rxdata[i]); } -terminate: + return EC_SUCCESS; +} + +int spi_transaction_flush(const struct spi_device_t *spi_device) +{ + enum gpio_signal gpio = spi_device->gpio_cs; + + /* Making sure if the SPI transaction already finishes */ + while (IS_BIT_SET(NPCX_SPI_STAT, NPCX_SPI_STAT_BSY)) + ; /* Deassert CS# (high) to end transaction */ gpio_set_level(gpio, 1); - mutex_unlock(&spi_lock); return EC_SUCCESS; } +int spi_transaction_wait(const struct spi_device_t *spi_device) +{ + return EC_SUCCESS; +} + +/** + * Flush an SPI transaction and receive data from peripheral. + * + * @param spi_device device to talk to + * @param txdata transfer data + * @param txlen transfer length + * @param rxdata receive data + * @param rxlen receive length + * @return success + * @notes set controller transaction mode in npcx chip + */ +int spi_transaction(const struct spi_device_t *spi_device, + const uint8_t *txdata, int txlen, uint8_t *rxdata, + int rxlen) +{ + int rv; + + mutex_lock(&spi_lock); + rv = spi_transaction_async(spi_device, txdata, txlen, rxdata, rxlen); + rv |= spi_transaction_flush(spi_device); + mutex_unlock(&spi_lock); + + return rv; +} + /** * SPI initial. * |