Re: [PATCH v7 6/6] typec: tcpm: Add support for sink PPS related messages
On 03/23/2018 03:12 AM, Adam Thomson wrote: This commit adds sink side support for Get_Status, Status, Get_PPS_Status and PPS_Status handling. As there's the potential for a partner to respond with Not_Supported, handling of this message is also added. Sending of Not_Supported is added to handle messagescreceived but not yet handled. Signed-off-by: Adam ThomsonAcked-by: Heikki Krogerus Reviewed-by: Guenter Roeck --- drivers/usb/typec/tcpm.c | 143 --- 1 file changed, 134 insertions(+), 9 deletions(-) diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c index 57a7d1a..7025a16 100644 --- a/drivers/usb/typec/tcpm.c +++ b/drivers/usb/typec/tcpm.c @@ -19,7 +19,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -113,6 +115,11 @@ S(SNK_TRYWAIT_VBUS),\ S(BIST_RX), \ \ + S(GET_STATUS_SEND), \ + S(GET_STATUS_SEND_TIMEOUT), \ + S(GET_PPS_STATUS_SEND), \ + S(GET_PPS_STATUS_SEND_TIMEOUT), \ + \ S(ERROR_RECOVERY), \ S(PORT_RESET), \ S(PORT_RESET_WAIT_OFF) @@ -143,6 +150,7 @@ enum pd_msg_request { PD_MSG_NONE = 0, PD_MSG_CTRL_REJECT, PD_MSG_CTRL_WAIT, + PD_MSG_CTRL_NOT_SUPP, PD_MSG_DATA_SINK_CAP, PD_MSG_DATA_SOURCE_CAP, }; @@ -1398,10 +1406,42 @@ static int tcpm_validate_caps(struct tcpm_port *port, const u32 *pdo, /* * PD (data, control) command handling functions */ +static inline enum tcpm_state ready_state(struct tcpm_port *port) +{ + if (port->pwr_role == TYPEC_SOURCE) + return SRC_READY; + else + return SNK_READY; +} static int tcpm_pd_send_control(struct tcpm_port *port, enum pd_ctrl_msg_type type); +static void tcpm_handle_alert(struct tcpm_port *port, const __le32 *payload, + int cnt) +{ + u32 p0 = le32_to_cpu(payload[0]); + unsigned int type = usb_pd_ado_type(p0); + + if (!type) { + tcpm_log(port, "Alert message received with no type"); + return; + } + + /* Just handling non-battery alerts for now */ + if (!(type & USB_PD_ADO_TYPE_BATT_STATUS_CHANGE)) { + switch (port->state) { + case SRC_READY: + case SNK_READY: + tcpm_set_state(port, GET_STATUS_SEND, 0); + break; + default: + tcpm_queue_message(port, PD_MSG_CTRL_WAIT); + break; + } + } +} + static void tcpm_pd_data_request(struct tcpm_port *port, const struct pd_message *msg) { @@ -1489,6 +1529,14 @@ static void tcpm_pd_data_request(struct tcpm_port *port, tcpm_set_state(port, BIST_RX, 0); } break; + case PD_DATA_ALERT: + tcpm_handle_alert(port, msg->payload, cnt); + break; + case PD_DATA_BATT_STATUS: + case PD_DATA_GET_COUNTRY_INFO: + /* Currently unsupported */ + tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP); + break; default: tcpm_log(port, "Unhandled data message type %#x", type); break; @@ -1571,6 +1619,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, break; case PD_CTRL_REJECT: case PD_CTRL_WAIT: + case PD_CTRL_NOT_SUPP: switch (port->state) { case SNK_NEGOTIATE_CAPABILITIES: /* USB PD specification, Figure 8-43 */ @@ -1690,12 +1739,75 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, break; } break; + case PD_CTRL_GET_SOURCE_CAP_EXT: + case PD_CTRL_GET_STATUS: + case PD_CTRL_FR_SWAP: + case PD_CTRL_GET_PPS_STATUS: + case PD_CTRL_GET_COUNTRY_CODES: + /* Currently not supported */ + tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP); + break; default: tcpm_log(port, "Unhandled ctrl message type %#x", type); break; } } +static void tcpm_pd_ext_msg_request(struct tcpm_port *port, + const struct pd_message *msg) +{ + enum pd_ext_msg_type type = pd_header_type_le(msg->header); + unsigned int data_size = pd_ext_header_data_size_le(msg->ext_msg.header); + + if (!(msg->ext_msg.header &&
Re: [PATCH v7 6/6] typec: tcpm: Add support for sink PPS related messages
On 03/23/2018 03:12 AM, Adam Thomson wrote: This commit adds sink side support for Get_Status, Status, Get_PPS_Status and PPS_Status handling. As there's the potential for a partner to respond with Not_Supported, handling of this message is also added. Sending of Not_Supported is added to handle messagescreceived but not yet handled. Signed-off-by: Adam Thomson Acked-by: Heikki Krogerus Reviewed-by: Guenter Roeck --- drivers/usb/typec/tcpm.c | 143 --- 1 file changed, 134 insertions(+), 9 deletions(-) diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c index 57a7d1a..7025a16 100644 --- a/drivers/usb/typec/tcpm.c +++ b/drivers/usb/typec/tcpm.c @@ -19,7 +19,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -113,6 +115,11 @@ S(SNK_TRYWAIT_VBUS),\ S(BIST_RX), \ \ + S(GET_STATUS_SEND), \ + S(GET_STATUS_SEND_TIMEOUT), \ + S(GET_PPS_STATUS_SEND), \ + S(GET_PPS_STATUS_SEND_TIMEOUT), \ + \ S(ERROR_RECOVERY), \ S(PORT_RESET), \ S(PORT_RESET_WAIT_OFF) @@ -143,6 +150,7 @@ enum pd_msg_request { PD_MSG_NONE = 0, PD_MSG_CTRL_REJECT, PD_MSG_CTRL_WAIT, + PD_MSG_CTRL_NOT_SUPP, PD_MSG_DATA_SINK_CAP, PD_MSG_DATA_SOURCE_CAP, }; @@ -1398,10 +1406,42 @@ static int tcpm_validate_caps(struct tcpm_port *port, const u32 *pdo, /* * PD (data, control) command handling functions */ +static inline enum tcpm_state ready_state(struct tcpm_port *port) +{ + if (port->pwr_role == TYPEC_SOURCE) + return SRC_READY; + else + return SNK_READY; +} static int tcpm_pd_send_control(struct tcpm_port *port, enum pd_ctrl_msg_type type); +static void tcpm_handle_alert(struct tcpm_port *port, const __le32 *payload, + int cnt) +{ + u32 p0 = le32_to_cpu(payload[0]); + unsigned int type = usb_pd_ado_type(p0); + + if (!type) { + tcpm_log(port, "Alert message received with no type"); + return; + } + + /* Just handling non-battery alerts for now */ + if (!(type & USB_PD_ADO_TYPE_BATT_STATUS_CHANGE)) { + switch (port->state) { + case SRC_READY: + case SNK_READY: + tcpm_set_state(port, GET_STATUS_SEND, 0); + break; + default: + tcpm_queue_message(port, PD_MSG_CTRL_WAIT); + break; + } + } +} + static void tcpm_pd_data_request(struct tcpm_port *port, const struct pd_message *msg) { @@ -1489,6 +1529,14 @@ static void tcpm_pd_data_request(struct tcpm_port *port, tcpm_set_state(port, BIST_RX, 0); } break; + case PD_DATA_ALERT: + tcpm_handle_alert(port, msg->payload, cnt); + break; + case PD_DATA_BATT_STATUS: + case PD_DATA_GET_COUNTRY_INFO: + /* Currently unsupported */ + tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP); + break; default: tcpm_log(port, "Unhandled data message type %#x", type); break; @@ -1571,6 +1619,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, break; case PD_CTRL_REJECT: case PD_CTRL_WAIT: + case PD_CTRL_NOT_SUPP: switch (port->state) { case SNK_NEGOTIATE_CAPABILITIES: /* USB PD specification, Figure 8-43 */ @@ -1690,12 +1739,75 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, break; } break; + case PD_CTRL_GET_SOURCE_CAP_EXT: + case PD_CTRL_GET_STATUS: + case PD_CTRL_FR_SWAP: + case PD_CTRL_GET_PPS_STATUS: + case PD_CTRL_GET_COUNTRY_CODES: + /* Currently not supported */ + tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP); + break; default: tcpm_log(port, "Unhandled ctrl message type %#x", type); break; } } +static void tcpm_pd_ext_msg_request(struct tcpm_port *port, + const struct pd_message *msg) +{ + enum pd_ext_msg_type type = pd_header_type_le(msg->header); + unsigned int data_size = pd_ext_header_data_size_le(msg->ext_msg.header); + + if (!(msg->ext_msg.header && PD_EXT_HDR_CHUNKED)) { + tcpm_log(port, "Unchunked extended messages
[PATCH v7 6/6] typec: tcpm: Add support for sink PPS related messages
This commit adds sink side support for Get_Status, Status, Get_PPS_Status and PPS_Status handling. As there's the potential for a partner to respond with Not_Supported, handling of this message is also added. Sending of Not_Supported is added to handle messagescreceived but not yet handled. Signed-off-by: Adam ThomsonAcked-by: Heikki Krogerus --- drivers/usb/typec/tcpm.c | 143 --- 1 file changed, 134 insertions(+), 9 deletions(-) diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c index 57a7d1a..7025a16 100644 --- a/drivers/usb/typec/tcpm.c +++ b/drivers/usb/typec/tcpm.c @@ -19,7 +19,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -113,6 +115,11 @@ S(SNK_TRYWAIT_VBUS),\ S(BIST_RX), \ \ + S(GET_STATUS_SEND), \ + S(GET_STATUS_SEND_TIMEOUT), \ + S(GET_PPS_STATUS_SEND), \ + S(GET_PPS_STATUS_SEND_TIMEOUT), \ + \ S(ERROR_RECOVERY), \ S(PORT_RESET), \ S(PORT_RESET_WAIT_OFF) @@ -143,6 +150,7 @@ enum pd_msg_request { PD_MSG_NONE = 0, PD_MSG_CTRL_REJECT, PD_MSG_CTRL_WAIT, + PD_MSG_CTRL_NOT_SUPP, PD_MSG_DATA_SINK_CAP, PD_MSG_DATA_SOURCE_CAP, }; @@ -1398,10 +1406,42 @@ static int tcpm_validate_caps(struct tcpm_port *port, const u32 *pdo, /* * PD (data, control) command handling functions */ +static inline enum tcpm_state ready_state(struct tcpm_port *port) +{ + if (port->pwr_role == TYPEC_SOURCE) + return SRC_READY; + else + return SNK_READY; +} static int tcpm_pd_send_control(struct tcpm_port *port, enum pd_ctrl_msg_type type); +static void tcpm_handle_alert(struct tcpm_port *port, const __le32 *payload, + int cnt) +{ + u32 p0 = le32_to_cpu(payload[0]); + unsigned int type = usb_pd_ado_type(p0); + + if (!type) { + tcpm_log(port, "Alert message received with no type"); + return; + } + + /* Just handling non-battery alerts for now */ + if (!(type & USB_PD_ADO_TYPE_BATT_STATUS_CHANGE)) { + switch (port->state) { + case SRC_READY: + case SNK_READY: + tcpm_set_state(port, GET_STATUS_SEND, 0); + break; + default: + tcpm_queue_message(port, PD_MSG_CTRL_WAIT); + break; + } + } +} + static void tcpm_pd_data_request(struct tcpm_port *port, const struct pd_message *msg) { @@ -1489,6 +1529,14 @@ static void tcpm_pd_data_request(struct tcpm_port *port, tcpm_set_state(port, BIST_RX, 0); } break; + case PD_DATA_ALERT: + tcpm_handle_alert(port, msg->payload, cnt); + break; + case PD_DATA_BATT_STATUS: + case PD_DATA_GET_COUNTRY_INFO: + /* Currently unsupported */ + tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP); + break; default: tcpm_log(port, "Unhandled data message type %#x", type); break; @@ -1571,6 +1619,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, break; case PD_CTRL_REJECT: case PD_CTRL_WAIT: + case PD_CTRL_NOT_SUPP: switch (port->state) { case SNK_NEGOTIATE_CAPABILITIES: /* USB PD specification, Figure 8-43 */ @@ -1690,12 +1739,75 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, break; } break; + case PD_CTRL_GET_SOURCE_CAP_EXT: + case PD_CTRL_GET_STATUS: + case PD_CTRL_FR_SWAP: + case PD_CTRL_GET_PPS_STATUS: + case PD_CTRL_GET_COUNTRY_CODES: + /* Currently not supported */ + tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP); + break; default: tcpm_log(port, "Unhandled ctrl message type %#x", type); break; } } +static void tcpm_pd_ext_msg_request(struct tcpm_port *port, + const struct pd_message *msg) +{ + enum pd_ext_msg_type type = pd_header_type_le(msg->header); + unsigned int data_size = pd_ext_header_data_size_le(msg->ext_msg.header); + + if (!(msg->ext_msg.header && PD_EXT_HDR_CHUNKED)) { + tcpm_log(port, "Unchunked extended messages unsupported"); + return; +
[PATCH v7 6/6] typec: tcpm: Add support for sink PPS related messages
This commit adds sink side support for Get_Status, Status, Get_PPS_Status and PPS_Status handling. As there's the potential for a partner to respond with Not_Supported, handling of this message is also added. Sending of Not_Supported is added to handle messagescreceived but not yet handled. Signed-off-by: Adam Thomson Acked-by: Heikki Krogerus --- drivers/usb/typec/tcpm.c | 143 --- 1 file changed, 134 insertions(+), 9 deletions(-) diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c index 57a7d1a..7025a16 100644 --- a/drivers/usb/typec/tcpm.c +++ b/drivers/usb/typec/tcpm.c @@ -19,7 +19,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -113,6 +115,11 @@ S(SNK_TRYWAIT_VBUS),\ S(BIST_RX), \ \ + S(GET_STATUS_SEND), \ + S(GET_STATUS_SEND_TIMEOUT), \ + S(GET_PPS_STATUS_SEND), \ + S(GET_PPS_STATUS_SEND_TIMEOUT), \ + \ S(ERROR_RECOVERY), \ S(PORT_RESET), \ S(PORT_RESET_WAIT_OFF) @@ -143,6 +150,7 @@ enum pd_msg_request { PD_MSG_NONE = 0, PD_MSG_CTRL_REJECT, PD_MSG_CTRL_WAIT, + PD_MSG_CTRL_NOT_SUPP, PD_MSG_DATA_SINK_CAP, PD_MSG_DATA_SOURCE_CAP, }; @@ -1398,10 +1406,42 @@ static int tcpm_validate_caps(struct tcpm_port *port, const u32 *pdo, /* * PD (data, control) command handling functions */ +static inline enum tcpm_state ready_state(struct tcpm_port *port) +{ + if (port->pwr_role == TYPEC_SOURCE) + return SRC_READY; + else + return SNK_READY; +} static int tcpm_pd_send_control(struct tcpm_port *port, enum pd_ctrl_msg_type type); +static void tcpm_handle_alert(struct tcpm_port *port, const __le32 *payload, + int cnt) +{ + u32 p0 = le32_to_cpu(payload[0]); + unsigned int type = usb_pd_ado_type(p0); + + if (!type) { + tcpm_log(port, "Alert message received with no type"); + return; + } + + /* Just handling non-battery alerts for now */ + if (!(type & USB_PD_ADO_TYPE_BATT_STATUS_CHANGE)) { + switch (port->state) { + case SRC_READY: + case SNK_READY: + tcpm_set_state(port, GET_STATUS_SEND, 0); + break; + default: + tcpm_queue_message(port, PD_MSG_CTRL_WAIT); + break; + } + } +} + static void tcpm_pd_data_request(struct tcpm_port *port, const struct pd_message *msg) { @@ -1489,6 +1529,14 @@ static void tcpm_pd_data_request(struct tcpm_port *port, tcpm_set_state(port, BIST_RX, 0); } break; + case PD_DATA_ALERT: + tcpm_handle_alert(port, msg->payload, cnt); + break; + case PD_DATA_BATT_STATUS: + case PD_DATA_GET_COUNTRY_INFO: + /* Currently unsupported */ + tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP); + break; default: tcpm_log(port, "Unhandled data message type %#x", type); break; @@ -1571,6 +1619,7 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, break; case PD_CTRL_REJECT: case PD_CTRL_WAIT: + case PD_CTRL_NOT_SUPP: switch (port->state) { case SNK_NEGOTIATE_CAPABILITIES: /* USB PD specification, Figure 8-43 */ @@ -1690,12 +1739,75 @@ static void tcpm_pd_ctrl_request(struct tcpm_port *port, break; } break; + case PD_CTRL_GET_SOURCE_CAP_EXT: + case PD_CTRL_GET_STATUS: + case PD_CTRL_FR_SWAP: + case PD_CTRL_GET_PPS_STATUS: + case PD_CTRL_GET_COUNTRY_CODES: + /* Currently not supported */ + tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP); + break; default: tcpm_log(port, "Unhandled ctrl message type %#x", type); break; } } +static void tcpm_pd_ext_msg_request(struct tcpm_port *port, + const struct pd_message *msg) +{ + enum pd_ext_msg_type type = pd_header_type_le(msg->header); + unsigned int data_size = pd_ext_header_data_size_le(msg->ext_msg.header); + + if (!(msg->ext_msg.header && PD_EXT_HDR_CHUNKED)) { + tcpm_log(port, "Unchunked extended messages unsupported"); + return; + } + + if (data_size > PD_EXT_MAX_CHUNK_DATA) { +