usb: typec: tcpci: add tcpm_transmit_type to tcpm_pd_receive
tcpm_pd_receive adds the SOP type as a parameter, and passes it within the pd_rx_event struct for tcpm_pd_rx_handler to use. For now, the handler drops all SOP' messages. Maxim based tcpci drivers are capable of SOP' communication, so process_rx now takes the SOP type into account and passes the value to tcpm_pd_receive. tcpci_set_pd_rx now utilizes the cable_comm_capable flag to determine if TCPC_RX_DETECT_SOP1 should be added to the bitfield when enabling PD message reception. For all other consumers of tcpm_pd_receive, default the new field to TCPC_TX_SOP. Signed-off-by: RD Babiera <rdbabiera@google.com> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Link: https://lore.kernel.org/r/20240108191620.987785-18-rdbabiera@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
59cd27a0ca
commit
3bbb9ba4f6
@ -1467,7 +1467,7 @@ static int fusb302_pd_read_message(struct fusb302_chip *chip,
|
||||
if ((!len) && (pd_header_type_le(msg->header) == PD_CTRL_GOOD_CRC))
|
||||
tcpm_pd_transmit_complete(chip->tcpm_port, TCPC_TX_SUCCESS);
|
||||
else
|
||||
tcpm_pd_receive(chip->tcpm_port, msg);
|
||||
tcpm_pd_receive(chip->tcpm_port, msg, TCPC_TX_SOP);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ done:
|
||||
|
||||
if (!ret) {
|
||||
dev_vdbg(dev, "pd_receive: handing %d bytes to tcpm\n", size);
|
||||
tcpm_pd_receive(pmic_typec_pdphy->tcpm_port, &msg);
|
||||
tcpm_pd_receive(pmic_typec_pdphy->tcpm_port, &msg, TCPC_TX_SOP);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,8 +445,11 @@ static int tcpci_set_pd_rx(struct tcpc_dev *tcpc, bool enable)
|
||||
unsigned int reg = 0;
|
||||
int ret;
|
||||
|
||||
if (enable)
|
||||
if (enable) {
|
||||
reg = TCPC_RX_DETECT_SOP | TCPC_RX_DETECT_HARD_RESET;
|
||||
if (tcpci->data->cable_comm_capable)
|
||||
reg |= TCPC_RX_DETECT_SOP1;
|
||||
}
|
||||
ret = regmap_write(tcpci->regmap, TCPC_RX_DETECT, reg);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -719,7 +722,7 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci)
|
||||
/* Read complete, clear RX status alert bit */
|
||||
tcpci_write16(tcpci, TCPC_ALERT, TCPC_ALERT_RX_STATUS);
|
||||
|
||||
tcpm_pd_receive(tcpci->port, &msg);
|
||||
tcpm_pd_receive(tcpci->port, &msg, TCPC_TX_SOP);
|
||||
}
|
||||
|
||||
if (tcpci->data->vbus_vsafe0v && (status & TCPC_ALERT_EXTENDED_STATUS)) {
|
||||
|
@ -128,6 +128,7 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status)
|
||||
u8 count, frame_type, rx_buf[TCPC_RECEIVE_BUFFER_LEN];
|
||||
int ret, payload_index;
|
||||
u8 *rx_buf_ptr;
|
||||
enum tcpm_transmit_type rx_type;
|
||||
|
||||
/*
|
||||
* READABLE_BYTE_COUNT: Indicates the number of bytes in the RX_BUF_BYTE_x registers
|
||||
@ -143,10 +144,23 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status)
|
||||
count = rx_buf[TCPC_RECEIVE_BUFFER_COUNT_OFFSET];
|
||||
frame_type = rx_buf[TCPC_RECEIVE_BUFFER_FRAME_TYPE_OFFSET];
|
||||
|
||||
if (count == 0 || frame_type != TCPC_RX_BUF_FRAME_TYPE_SOP) {
|
||||
switch (frame_type) {
|
||||
case TCPC_RX_BUF_FRAME_TYPE_SOP1:
|
||||
rx_type = TCPC_TX_SOP_PRIME;
|
||||
break;
|
||||
case TCPC_RX_BUF_FRAME_TYPE_SOP:
|
||||
rx_type = TCPC_TX_SOP;
|
||||
break;
|
||||
default:
|
||||
rx_type = TCPC_TX_SOP;
|
||||
break;
|
||||
}
|
||||
|
||||
if (count == 0 || (frame_type != TCPC_RX_BUF_FRAME_TYPE_SOP &&
|
||||
frame_type != TCPC_RX_BUF_FRAME_TYPE_SOP1)) {
|
||||
max_tcpci_write16(chip, TCPC_ALERT, TCPC_ALERT_RX_STATUS);
|
||||
dev_err(chip->dev, "%s\n", count == 0 ? "error: count is 0" :
|
||||
"error frame_type is not SOP");
|
||||
"error frame_type is not SOP/SOP'");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -183,7 +197,7 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status)
|
||||
if (ret < 0)
|
||||
return;
|
||||
|
||||
tcpm_pd_receive(chip->port, &msg);
|
||||
tcpm_pd_receive(chip->port, &msg, rx_type);
|
||||
}
|
||||
|
||||
static int max_tcpci_set_vbus(struct tcpci *tcpci, struct tcpci_data *tdata, bool source, bool sink)
|
||||
|
@ -518,6 +518,7 @@ struct pd_rx_event {
|
||||
struct kthread_work work;
|
||||
struct tcpm_port *port;
|
||||
struct pd_message msg;
|
||||
enum tcpm_transmit_type rx_sop_type;
|
||||
};
|
||||
|
||||
static const char * const pd_rev[] = {
|
||||
@ -2981,12 +2982,17 @@ static void tcpm_pd_rx_handler(struct kthread_work *work)
|
||||
const struct pd_message *msg = &event->msg;
|
||||
unsigned int cnt = pd_header_cnt_le(msg->header);
|
||||
struct tcpm_port *port = event->port;
|
||||
enum tcpm_transmit_type rx_sop_type = event->rx_sop_type;
|
||||
|
||||
mutex_lock(&port->lock);
|
||||
|
||||
tcpm_log(port, "PD RX, header: %#x [%d]", le16_to_cpu(msg->header),
|
||||
port->attached);
|
||||
|
||||
/* Ignore SOP' for now */
|
||||
if (rx_sop_type == TCPC_TX_SOP_PRIME)
|
||||
goto done;
|
||||
|
||||
if (port->attached) {
|
||||
enum pd_ctrl_msg_type type = pd_header_type_le(msg->header);
|
||||
unsigned int msgid = pd_header_msgid_le(msg->header);
|
||||
@ -3028,7 +3034,8 @@ done:
|
||||
kfree(event);
|
||||
}
|
||||
|
||||
void tcpm_pd_receive(struct tcpm_port *port, const struct pd_message *msg)
|
||||
void tcpm_pd_receive(struct tcpm_port *port, const struct pd_message *msg,
|
||||
enum tcpm_transmit_type rx_sop_type)
|
||||
{
|
||||
struct pd_rx_event *event;
|
||||
|
||||
@ -3038,6 +3045,7 @@ void tcpm_pd_receive(struct tcpm_port *port, const struct pd_message *msg)
|
||||
|
||||
kthread_init_work(&event->work, tcpm_pd_rx_handler);
|
||||
event->port = port;
|
||||
event->rx_sop_type = rx_sop_type;
|
||||
memcpy(&event->msg, msg, sizeof(*msg));
|
||||
kthread_queue_work(port->wq, &event->work);
|
||||
}
|
||||
|
@ -535,7 +535,7 @@ static irqreturn_t wcove_typec_irq(int irq, void *data)
|
||||
goto err;
|
||||
}
|
||||
|
||||
tcpm_pd_receive(wcove->tcpm, &msg);
|
||||
tcpm_pd_receive(wcove->tcpm, &msg, TCPC_TX_SOP);
|
||||
|
||||
ret = regmap_read(wcove->regmap, USBC_RXSTATUS,
|
||||
&status);
|
||||
|
@ -145,6 +145,7 @@
|
||||
#define TCPC_RX_BYTE_CNT 0x30
|
||||
#define TCPC_RX_BUF_FRAME_TYPE 0x31
|
||||
#define TCPC_RX_BUF_FRAME_TYPE_SOP 0
|
||||
#define TCPC_RX_BUF_FRAME_TYPE_SOP1 1
|
||||
#define TCPC_RX_HDR 0x32
|
||||
#define TCPC_RX_DATA 0x34 /* through 0x4f */
|
||||
|
||||
|
@ -170,7 +170,8 @@ void tcpm_cc_change(struct tcpm_port *port);
|
||||
void tcpm_sink_frs(struct tcpm_port *port);
|
||||
void tcpm_sourcing_vbus(struct tcpm_port *port);
|
||||
void tcpm_pd_receive(struct tcpm_port *port,
|
||||
const struct pd_message *msg);
|
||||
const struct pd_message *msg,
|
||||
enum tcpm_transmit_type rx_sop_type);
|
||||
void tcpm_pd_transmit_complete(struct tcpm_port *port,
|
||||
enum tcpm_transmit_status status);
|
||||
void tcpm_pd_hard_reset(struct tcpm_port *port);
|
||||
|
Loading…
x
Reference in New Issue
Block a user