summaryrefslogtreecommitdiff
path: root/chip/g/sps.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/g/sps.c')
-rw-r--r--chip/g/sps.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/chip/g/sps.c b/chip/g/sps.c
index b64e1d1a7b..3a44a4fa0e 100644
--- a/chip/g/sps.c
+++ b/chip/g/sps.c
@@ -310,9 +310,15 @@ static void sps_advance_rx(int port, int data_size)
* passed to the callback, the callback is called one last time with zero data
* size and the CS indication, this allows the client to delineate received
* packets.
+ *
+ * Returns a Boolean indicating if data was seen during the most recent CS
+ * assertion. When 1, it indicates to the caller that the confirmation
+ * pulse to the AP needs to be generated.
*/
-static void sps_rx_interrupt(uint32_t port, int cs_deasserted)
+static uint32_t sps_rx_interrupt(uint32_t port, int cs_deasserted)
{
+ uint32_t pulse_needed = 0;
+
for (;;) {
uint8_t *received_data = NULL;
size_t data_size;
@@ -336,30 +342,18 @@ static void sps_rx_interrupt(uint32_t port, int cs_deasserted)
if (cs_deasserted) {
if (seen_data) {
sps_rx_handler(NULL, 0, 1);
-
- /*
- * Signal the AP that this SPI frame processing is
- * completed.
- */
- gpio_set_level(GPIO_INT_AP_L, 0);
-
- /*
- * This is to meet the AP requirement of minimum 4 usec
- * duration of INT_AP_L assertion.
- *
- * TODO(b/130515803): Ideally, this should be improved
- * to support any duration requirement in future.
- */
- tick_delay(2);
-
- gpio_set_level(GPIO_INT_AP_L, 1);
seen_data = 0;
+ pulse_needed = 1;
}
}
+
+ return pulse_needed;
}
static void sps_cs_deassert_interrupt(uint32_t port)
{
+ uint32_t pulse_needed;
+
if (sps_cs_asserted()) {
/*
* we must have been slow, this is the next CS assertion after
@@ -387,7 +381,7 @@ static void sps_cs_deassert_interrupt(uint32_t port)
}
/* Make sure the receive FIFO is drained. */
- sps_rx_interrupt(port, 1);
+ pulse_needed = sps_rx_interrupt(port, 1);
GWRITE_FIELD(SPS, ISTATE_CLR, CS_DEASSERT, 1);
GWRITE_FIELD(SPS, FIFO_CTRL, TXFIFO_EN, 0);
@@ -396,6 +390,25 @@ static void sps_cs_deassert_interrupt(uint32_t port)
* by clocking out any bytes left over from this one.
*/
GREG32(SPS, TXFIFO_WPTR) = GREG32(SPS, TXFIFO_RPTR);
+
+ if (pulse_needed) {
+ /*
+ * Signal the AP that this SPI frame processing is
+ * completed.
+ */
+ gpio_set_level(GPIO_INT_AP_L, 0);
+
+ /*
+ * This is to meet the AP requirement of minimum 4 usec
+ * duration of INT_AP_L assertion.
+ *
+ * TODO(b/130515803): Ideally, this should be improved
+ * to support any duration requirement in future.
+ */
+ tick_delay(2);
+
+ gpio_set_level(GPIO_INT_AP_L, 1);
+ }
}
void _sps0_interrupt(void)