mfd: fusb302: Don't mistake meaningful packets for Good_CRC

If a partner port sends a packet at approximately the same time as we
send a packet, we may end up with the initial packet followed by the
GOOD_CRC reply in our HW FIFO. Don't automatically discard the first
packet in the FIFO. Instead, discard the packet only if it's a GOOD_CRC
packet. And, modify our get_message function to automatically discard
GOOD_CRC in search of a meaningful packet.

In addition, due to interrupt latency, we can't rely on receiving one
interrupt per incoming packet. If our Rx FIFO is non-empty, assume that
it contains at least one packet.

Change-Id: Iaad80a4c55eea3e9e2791d81d7c5d28ce97bd2f5
Signed-off-by: zain wang <wzz@rock-chips.com>
This commit is contained in:
zain wang
2017-05-11 15:46:25 +08:00
committed by Huang, Tao
parent cc7d3ea78f
commit 7cf052ec4d

View File

@@ -50,6 +50,10 @@
#define PIN_MAP_E BIT(4)
#define PIN_MAP_F BIT(5)
#define PACKET_IS_GOOD_CRC(header) \
(PD_HEADER_TYPE(header) == CMT_GOODCRC && \
PD_HEADER_CNT(header) == 0)
static u8 fusb30x_port_used;
static struct fusb30x_chip *fusb30x_port_info[256];
@@ -339,11 +343,14 @@ static int tcpm_get_message(struct fusb30x_chip *chip)
u8 buf[32];
int len;
regmap_raw_read(chip->regmap, FUSB_REG_FIFO, buf, 3);
chip->rec_head = (buf[1] & 0xff) | ((buf[2] << 8) & 0xff00);
do {
regmap_raw_read(chip->regmap, FUSB_REG_FIFO, buf, 3);
chip->rec_head = (buf[1] & 0xff) | ((buf[2] << 8) & 0xff00);
len = PD_HEADER_CNT(chip->rec_head) << 2;
regmap_raw_read(chip->regmap, FUSB_REG_FIFO, buf, len + 4);
len = PD_HEADER_CNT(chip->rec_head) << 2;
regmap_raw_read(chip->regmap, FUSB_REG_FIFO, buf, len + 4);
/* ignore good_crc message */
} while (PACKET_IS_GOOD_CRC(chip->rec_head));
memcpy(chip->rec_load, buf, len);
@@ -352,7 +359,7 @@ static int tcpm_get_message(struct fusb30x_chip *chip)
static void fusb302_flush_rx_fifo(struct fusb30x_chip *chip)
{
tcpm_get_message(chip);
regmap_write(chip->regmap, FUSB_REG_CONTROL1, CONTROL1_RX_FLUSH);
}
static int tcpm_get_cc(struct fusb30x_chip *chip, int *CC1, int *CC2)
@@ -741,7 +748,6 @@ static void tcpc_alert(struct fusb30x_chip *chip, int *evt)
if (interrupta & INTERRUPTA_TXSENT) {
*evt |= EVENT_TX;
fusb302_flush_rx_fifo(chip);
chip->tx_state = tx_success;
}