summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorJun Lin <CHLin56@nuvoton.com>2023-03-03 11:23:01 +0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-05-03 21:37:28 +0000
commit310b3033ac604b87256b2bb2a99eabc5993d70fd (patch)
tree854c8685a922326c600da0e3f1055d70159dc3bf /chip
parentae77e271cec97465733805c55551c3e9fe56e63f (diff)
downloadchrome-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.c70
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.
*