Commit 3bbb9ba4 authored by RD Babiera's avatar RD Babiera Committed by Greg Kroah-Hartman
Browse files

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: default avatarRD Babiera <rdbabiera@google.com>
Reviewed-by: default avatarHeikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20240108191620.987785-18-rdbabiera@google.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 59cd27a0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
}
+1 −1
Original line number Diff line number Diff line
@@ -299,7 +299,7 @@ static void qcom_pmic_typec_pdphy_pd_receive(struct pmic_typec_pdphy *pmic_typec

	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);
	}
}

+5 −2
Original line number Diff line number Diff line
@@ -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)) {
+17 −3
Original line number Diff line number Diff line
@@ -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)
+9 −1
Original line number Diff line number Diff line
@@ -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 @@ static void tcpm_pd_rx_handler(struct kthread_work *work)
	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);
}
Loading