Lines Matching full:port
247 * @min_volt: Actual min voltage at the local port
248 * @req_min_volt: Requested min voltage to the port partner
249 * @max_volt: Actual max voltage at the local port
250 * @req_max_volt: Requested max voltage to the port partner
251 * @max_curr: Actual max current at the local port
252 * @req_max_curr: Requested max current of the port partner
253 * @req_out_volt: Requested output voltage to the port partner
254 * @req_op_curr: Requested operating current to the port partner
273 POWER_SUPPLY_USB_TYPE_SDP, /* Standard Downstream Port */
274 POWER_SUPPLY_USB_TYPE_DCP, /* Dedicated Charging Port */
275 POWER_SUPPLY_USB_TYPE_CDP, /* Charging Downstream Port */
277 POWER_SUPPLY_USB_TYPE_C, /* Type C Port */
278 POWER_SUPPLY_USB_TYPE_PD, /* Power Delivery Port */
279 POWER_SUPPLY_USB_TYPE_PD_DRP, /* PD Dual Role Port */
373 * For Type-C device with Dual-Role Power and Dual-Role Data, the port side
392 /* Requested current / voltage to the port partner */
395 /* Actual current / voltage limit of the local port */
420 /* port belongs to a self powered device */
429 /* Port is still in tCCDebounce */
442 * When set, port requests PD_P_SNK_STDBY_MW upon entering SNK_DISCOVERY and
457 struct tcpm_port *port; member
471 #define tcpm_port_is_sink(port) \ argument
472 ((tcpm_cc_is_sink((port)->cc1) && !tcpm_cc_is_sink((port)->cc2)) || \
473 (tcpm_cc_is_sink((port)->cc2) && !tcpm_cc_is_sink((port)->cc1)))
479 #define tcpm_port_is_source(port) \ argument
480 ((tcpm_cc_is_source((port)->cc1) && \
481 !tcpm_cc_is_source((port)->cc2)) || \
482 (tcpm_cc_is_source((port)->cc2) && \
483 !tcpm_cc_is_source((port)->cc1)))
485 #define tcpm_port_is_debug(port) \ argument
486 (tcpm_cc_is_source((port)->cc1) && tcpm_cc_is_source((port)->cc2))
488 #define tcpm_port_is_audio(port) \ argument
489 (tcpm_cc_is_audio((port)->cc1) && tcpm_cc_is_audio((port)->cc2))
491 #define tcpm_port_is_audio_detached(port) \ argument
492 ((tcpm_cc_is_audio((port)->cc1) && tcpm_cc_is_open((port)->cc2)) || \
493 (tcpm_cc_is_audio((port)->cc2) && tcpm_cc_is_open((port)->cc1)))
495 #define tcpm_try_snk(port) \ argument
496 ((port)->try_snk_count == 0 && (port)->try_role == TYPEC_SINK && \
497 (port)->port_type == TYPEC_PORT_DRP)
499 #define tcpm_try_src(port) \ argument
500 ((port)->try_src_count == 0 && (port)->try_role == TYPEC_SOURCE && \
501 (port)->port_type == TYPEC_PORT_DRP)
503 #define tcpm_data_role_for_source(port) \ argument
504 ((port)->typec_caps.data == TYPEC_PORT_UFP ? \
507 #define tcpm_data_role_for_sink(port) \ argument
508 ((port)->typec_caps.data == TYPEC_PORT_DFP ? \
511 static enum tcpm_state tcpm_default_state(struct tcpm_port *port) in tcpm_default_state() argument
513 if (port->port_type == TYPEC_PORT_DRP) { in tcpm_default_state()
514 if (port->try_role == TYPEC_SINK) in tcpm_default_state()
516 else if (port->try_role == TYPEC_SOURCE) in tcpm_default_state()
519 } else if (port->port_type == TYPEC_PORT_SNK) { in tcpm_default_state()
525 static bool tcpm_port_is_disconnected(struct tcpm_port *port) in tcpm_port_is_disconnected() argument
527 return (!port->attached && port->cc1 == TYPEC_CC_OPEN && in tcpm_port_is_disconnected()
528 port->cc2 == TYPEC_CC_OPEN) || in tcpm_port_is_disconnected()
529 (port->attached && ((port->polarity == TYPEC_POLARITY_CC1 && in tcpm_port_is_disconnected()
530 port->cc1 == TYPEC_CC_OPEN) || in tcpm_port_is_disconnected()
531 (port->polarity == TYPEC_POLARITY_CC2 && in tcpm_port_is_disconnected()
532 port->cc2 == TYPEC_CC_OPEN))); in tcpm_port_is_disconnected()
535 static void tcpm_set_cc(struct tcpm_port *port, enum typec_cc_status cc) in tcpm_set_cc() argument
538 port->cc_req = cc; in tcpm_set_cc()
539 port->tcpc->set_cc(port->tcpc, cc); in tcpm_set_cc()
544 * by a port if configured as source.
547 static enum typec_cc_status tcpm_rp_cc(struct tcpm_port *port) in tcpm_rp_cc() argument
549 const u32 *src_pdo = port->src_pdo; in tcpm_rp_cc()
550 int nr_pdo = port->nr_src_pdo; in tcpm_rp_cc()
575 static int tcpm_pd_transmit(struct tcpm_port *port, in tcpm_pd_transmit() argument
587 port->tx_complete = false; in tcpm_pd_transmit()
588 ret = port->tcpc->pd_transmit(port->tcpc, type, msg, port->negotiated_rev); in tcpm_pd_transmit()
592 while ((timeout > 0) && (!port->tx_complete)) { in tcpm_pd_transmit()
593 port->tcpc->poll_event(port->tcpc); in tcpm_pd_transmit()
603 switch (port->tx_status) { in tcpm_pd_transmit()
605 port->message_id = (port->message_id + 1) & PD_HEADER_ID_MASK; in tcpm_pd_transmit()
619 void tcpm_pd_transmit_complete(struct tcpm_port *port, in tcpm_pd_transmit_complete() argument
623 port->poll_event_cnt = 0; in tcpm_pd_transmit_complete()
624 port->tx_status = status; in tcpm_pd_transmit_complete()
625 port->tx_complete = true; in tcpm_pd_transmit_complete()
629 static int tcpm_set_polarity(struct tcpm_port *port, in tcpm_set_polarity() argument
636 ret = port->tcpc->set_polarity(port->tcpc, polarity); in tcpm_set_polarity()
640 port->polarity = polarity; in tcpm_set_polarity()
645 static int tcpm_set_vconn(struct tcpm_port *port, bool enable) in tcpm_set_vconn() argument
651 ret = port->tcpc->set_vconn(port->tcpc, enable); in tcpm_set_vconn()
653 port->vconn_role = enable ? TYPEC_SOURCE : TYPEC_SINK; in tcpm_set_vconn()
658 static u32 tcpm_get_current_limit(struct tcpm_port *port) in tcpm_get_current_limit() argument
663 cc = port->polarity ? port->cc2 : port->cc1; in tcpm_get_current_limit()
673 if (port->tcpc->get_current_limit) in tcpm_get_current_limit()
674 limit = port->tcpc->get_current_limit(port->tcpc); in tcpm_get_current_limit()
683 static int tcpm_set_current_limit(struct tcpm_port *port, u32 max_ma, u32 mv) in tcpm_set_current_limit() argument
689 port->supply_voltage = mv; in tcpm_set_current_limit()
690 port->current_limit = max_ma; in tcpm_set_current_limit()
692 if (port->tcpc->set_current_limit) in tcpm_set_current_limit()
693 ret = port->tcpc->set_current_limit(port->tcpc, max_ma, mv); in tcpm_set_current_limit()
698 static int tcpm_set_attached_state(struct tcpm_port *port, bool attached) in tcpm_set_attached_state() argument
700 return port->tcpc->set_roles(port->tcpc, attached, port->pwr_role, in tcpm_set_attached_state()
701 port->data_role); in tcpm_set_attached_state()
704 static int tcpm_set_roles(struct tcpm_port *port, bool attached, in tcpm_set_roles() argument
714 if (port->polarity == TYPEC_POLARITY_CC1) in tcpm_set_roles()
724 ret = tcpm_mux_set(port, TYPEC_STATE_USB, usb_role, orientation); in tcpm_set_roles()
729 ret = port->tcpc->set_roles(port->tcpc, attached, role, data); in tcpm_set_roles()
733 port->pwr_role = role; in tcpm_set_roles()
734 port->data_role = data; in tcpm_set_roles()
736 typec_set_data_role(port->typec_port, data); in tcpm_set_roles()
737 typec_set_pwr_role(port->typec_port, role); in tcpm_set_roles()
743 static int tcpm_pd_send_source_caps(struct tcpm_port *port) in tcpm_pd_send_source_caps() argument
750 if (!port->nr_src_pdo) { in tcpm_pd_send_source_caps()
753 port->pwr_role, in tcpm_pd_send_source_caps()
754 port->data_role, in tcpm_pd_send_source_caps()
755 port->negotiated_rev, in tcpm_pd_send_source_caps()
756 port->message_id, 0); in tcpm_pd_send_source_caps()
759 port->pwr_role, in tcpm_pd_send_source_caps()
760 port->data_role, in tcpm_pd_send_source_caps()
761 port->negotiated_rev, in tcpm_pd_send_source_caps()
762 port->message_id, in tcpm_pd_send_source_caps()
763 port->nr_src_pdo); in tcpm_pd_send_source_caps()
766 for (i = 0; i < port->nr_src_pdo; i++) in tcpm_pd_send_source_caps()
767 msg.payload[i] = cpu_to_le32(port->src_pdo[i]); in tcpm_pd_send_source_caps()
769 return tcpm_pd_transmit(port, TCPC_TX_SOP, &msg); in tcpm_pd_send_source_caps()
772 static int tcpm_pd_send_sink_caps(struct tcpm_port *port) in tcpm_pd_send_sink_caps() argument
779 if (!port->nr_snk_pdo) { in tcpm_pd_send_sink_caps()
782 port->pwr_role, in tcpm_pd_send_sink_caps()
783 port->data_role, in tcpm_pd_send_sink_caps()
784 port->negotiated_rev, in tcpm_pd_send_sink_caps()
785 port->message_id, 0); in tcpm_pd_send_sink_caps()
788 port->pwr_role, in tcpm_pd_send_sink_caps()
789 port->data_role, in tcpm_pd_send_sink_caps()
790 port->negotiated_rev, in tcpm_pd_send_sink_caps()
791 port->message_id, in tcpm_pd_send_sink_caps()
792 port->nr_snk_pdo); in tcpm_pd_send_sink_caps()
795 for (i = 0; i < port->nr_snk_pdo; i++) in tcpm_pd_send_sink_caps()
796 msg.payload[i] = cpu_to_le32(port->snk_pdo[i]); in tcpm_pd_send_sink_caps()
798 return tcpm_pd_transmit(port, TCPC_TX_SOP, &msg); in tcpm_pd_send_sink_caps()
801 static void tcpm_state_machine(struct tcpm_port *port);
802 static void tcpm_timer_uninit(struct tcpm_port *port);
805 struct tcpm_port *port = data; in tcpm_timer_irq() local
808 tcpm_timer_uninit(port); in tcpm_timer_irq()
809 tcpm_state_machine(port); in tcpm_timer_irq()
812 static void tcpm_timer_init(struct tcpm_port *port, uint32_t ms) in tcpm_timer_init() argument
827 (interrupt_handler_t *)tcpm_timer_irq, port); in tcpm_timer_init()
831 static void tcpm_timer_uninit(struct tcpm_port *port) in tcpm_timer_uninit() argument
839 static void mod_tcpm_delayed_work(struct tcpm_port *port, unsigned int delay_ms) in mod_tcpm_delayed_work() argument
842 tcpm_timer_init(port, delay_ms); in mod_tcpm_delayed_work()
844 tcpm_timer_uninit(port); in mod_tcpm_delayed_work()
845 tcpm_state_machine(port); in mod_tcpm_delayed_work()
849 static void tcpm_set_state(struct tcpm_port *port, enum tcpm_state state, in tcpm_set_state() argument
857 tcpm_states[port->state], tcpm_states[state], delay_ms, in tcpm_set_state()
858 pd_rev[port->negotiated_rev]); in tcpm_set_state()
859 port->delayed_state = state; in tcpm_set_state()
860 mod_tcpm_delayed_work(port, delay_ms); in tcpm_set_state()
861 port->delay_ms = delay_ms; in tcpm_set_state()
864 tcpm_states[port->state], tcpm_states[state]); in tcpm_set_state()
865 port->delayed_state = INVALID_STATE; in tcpm_set_state()
866 port->prev_state = port->state; in tcpm_set_state()
867 port->state = state; in tcpm_set_state()
874 if (!port->state_machine_running) in tcpm_set_state()
875 mod_tcpm_delayed_work(port, 0); in tcpm_set_state()
879 static void tcpm_set_state_cond(struct tcpm_port *port, enum tcpm_state state, in tcpm_set_state_cond() argument
882 if (port->enter_state == port->state) in tcpm_set_state_cond()
883 tcpm_set_state(port, state, delay_ms); in tcpm_set_state_cond()
887 tcpm_states[port->state], tcpm_states[state], in tcpm_set_state_cond()
888 delay_ms, tcpm_states[port->enter_state], in tcpm_set_state_cond()
889 pd_rev[port->negotiated_rev], tcpm_ams_str[port->ams]); in tcpm_set_state_cond()
892 static void tcpm_queue_message(struct tcpm_port *port, in tcpm_queue_message() argument
895 port->queued_message = message; in tcpm_queue_message()
896 mod_tcpm_delayed_work(port, 0); in tcpm_queue_message()
900 static void tcpm_pd_handle_msg(struct tcpm_port *port,
936 static enum pdo_err tcpm_caps_err(struct tcpm_port *port, const u32 *pdo, in tcpm_caps_err() argument
1012 static int tcpm_validate_caps(struct tcpm_port *port, const u32 *pdo, in tcpm_validate_caps() argument
1015 enum pdo_err err_index = tcpm_caps_err(port, pdo, nr_pdo); in tcpm_validate_caps()
1028 static inline enum tcpm_state ready_state(struct tcpm_port *port) in ready_state() argument
1030 if (port->pwr_role == TYPEC_SOURCE) in ready_state()
1036 static int tcpm_pd_send_control(struct tcpm_port *port,
1040 static void tcpm_pd_handle_msg(struct tcpm_port *port,
1044 switch (port->state) {
1047 port->ams = ams;
1048 tcpm_queue_message(port, message);
1054 tcpm_set_state(port, HARD_RESET_SEND, 0);
1057 if (!tcpm_ams_interruptible(port)) {
1058 tcpm_set_state(port, port->pwr_role == TYPEC_SOURCE ?
1063 port->next_ams = ams;
1064 tcpm_set_state(port, ready_state(port), 0);
1066 tcpm_queue_message(port, message);
1073 static void tcpm_pd_data_request(struct tcpm_port *port, in tcpm_pd_data_request() argument
1084 port->source_caps[i] = le32_to_cpu(msg->payload[i]); in tcpm_pd_data_request()
1086 port->nr_source_caps = cnt; in tcpm_pd_data_request()
1088 tcpm_validate_caps(port, port->source_caps, in tcpm_pd_data_request()
1089 port->nr_source_caps); in tcpm_pd_data_request()
1101 port->negotiated_rev = rev; in tcpm_pd_data_request()
1103 if ((pdo_type(port->source_caps[0]) == PDO_TYPE_FIXED) && in tcpm_pd_data_request()
1104 (port->source_caps[0] & PDO_FIXED_DUAL_ROLE) && in tcpm_pd_data_request()
1105 (port->source_caps[0] & PDO_FIXED_DATA_SWAP)) { in tcpm_pd_data_request()
1107 port->wait_dr_swap_Message = true; in tcpm_pd_data_request()
1110 port->wait_dr_swap_Message = false; in tcpm_pd_data_request()
1126 tcpm_set_state(port, SNK_NEGOTIATE_CAPABILITIES, 0); in tcpm_pd_data_request()
1135 tcpm_queue_message(port, PD_MSG_CTRL_REJECT); in tcpm_pd_data_request()
1140 port->negotiated_rev = rev; in tcpm_pd_data_request()
1142 port->sink_request = le32_to_cpu(msg->payload[0]); in tcpm_pd_data_request()
1144 tcpm_set_state(port, SRC_NEGOTIATE_CAPABILITIES, 0); in tcpm_pd_data_request()
1149 port->sink_caps[i] = le32_to_cpu(msg->payload[i]); in tcpm_pd_data_request()
1151 port->nr_sink_caps = cnt; in tcpm_pd_data_request()
1158 static void tcpm_pd_ctrl_request(struct tcpm_port *port, in tcpm_pd_ctrl_request() argument
1169 switch (port->state) { in tcpm_pd_ctrl_request()
1172 tcpm_queue_message(port, PD_MSG_DATA_SOURCE_CAP); in tcpm_pd_ctrl_request()
1175 tcpm_queue_message(port, PD_MSG_CTRL_REJECT); in tcpm_pd_ctrl_request()
1180 switch (port->state) { in tcpm_pd_ctrl_request()
1183 tcpm_queue_message(port, PD_MSG_DATA_SINK_CAP); in tcpm_pd_ctrl_request()
1186 tcpm_queue_message(port, PD_MSG_CTRL_REJECT); in tcpm_pd_ctrl_request()
1193 switch (port->state) { in tcpm_pd_ctrl_request()
1195 if (port->vbus_present) { in tcpm_pd_ctrl_request()
1196 tcpm_set_current_limit(port, in tcpm_pd_ctrl_request()
1197 port->req_current_limit, in tcpm_pd_ctrl_request()
1198 port->req_supply_voltage); in tcpm_pd_ctrl_request()
1199 port->explicit_contract = true; in tcpm_pd_ctrl_request()
1200 tcpm_set_state(port, SNK_READY, 0); in tcpm_pd_ctrl_request()
1206 tcpm_set_state(port, in tcpm_pd_ctrl_request()
1217 switch (port->state) { in tcpm_pd_ctrl_request()
1220 if (port->explicit_contract) in tcpm_pd_ctrl_request()
1225 tcpm_set_state(port, next_state, 0); in tcpm_pd_ctrl_request()
1229 port->pps_data.req_out_volt = port->supply_voltage; in tcpm_pd_ctrl_request()
1230 port->pps_data.req_op_curr = port->current_limit; in tcpm_pd_ctrl_request()
1231 port->pps_status = (type == PD_CTRL_WAIT ? in tcpm_pd_ctrl_request()
1233 tcpm_set_state(port, SNK_READY, 0); in tcpm_pd_ctrl_request()
1240 switch (port->state) { in tcpm_pd_ctrl_request()
1242 port->pps_data.active = false; in tcpm_pd_ctrl_request()
1243 tcpm_set_state(port, SNK_TRANSITION_SINK, 0); in tcpm_pd_ctrl_request()
1246 port->pps_data.active = true; in tcpm_pd_ctrl_request()
1248 port->pps_data.min_volt = port->pps_data.req_min_volt; in tcpm_pd_ctrl_request()
1249 port->pps_data.max_volt = port->pps_data.req_max_volt; in tcpm_pd_ctrl_request()
1250 port->pps_data.max_curr = port->pps_data.req_max_curr; in tcpm_pd_ctrl_request()
1251 port->req_supply_voltage = port->pps_data.req_out_volt; in tcpm_pd_ctrl_request()
1252 port->req_current_limit = port->pps_data.req_op_curr; in tcpm_pd_ctrl_request()
1253 tcpm_set_state(port, SNK_TRANSITION_SINK, 0); in tcpm_pd_ctrl_request()
1256 port->message_id = 0; in tcpm_pd_ctrl_request()
1257 port->rx_msgid = -1; in tcpm_pd_ctrl_request()
1258 if (port->pwr_role == TYPEC_SOURCE) in tcpm_pd_ctrl_request()
1262 tcpm_set_state(port, next_state, 0); in tcpm_pd_ctrl_request()
1269 tcpm_set_state(port, SOFT_RESET, 0); in tcpm_pd_ctrl_request()
1272 if (port->port_type != TYPEC_PORT_DRP) { in tcpm_pd_ctrl_request()
1273 tcpm_queue_message(port, PD_MSG_CTRL_REJECT); in tcpm_pd_ctrl_request()
1279 * alternate modes shall trigger a port reset. in tcpm_pd_ctrl_request()
1281 switch (port->state) { in tcpm_pd_ctrl_request()
1285 if (port->vdm_sm_running) { in tcpm_pd_ctrl_request()
1286 tcpm_queue_message(port, PD_MSG_CTRL_WAIT); in tcpm_pd_ctrl_request()
1290 tcpm_set_state(port, DR_SWAP_ACCEPT, 0); in tcpm_pd_ctrl_request()
1293 tcpm_queue_message(port, PD_MSG_CTRL_WAIT); in tcpm_pd_ctrl_request()
1306 tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP); in tcpm_pd_ctrl_request()
1315 static void tcpm_pd_ext_msg_request(struct tcpm_port *port,
1322 tcpm_pd_handle_msg(port, PD_MSG_CTRL_NOT_SUPP, NONE_AMS);
1328 tcpm_pd_handle_state(port, CHUNK_NOT_SUPP, NONE_AMS, PD_T_CHUNK_NOT_SUPP);
1336 tcpm_set_state(port, ready_state(port), 0);
1351 tcpm_pd_handle_msg(port, PD_MSG_CTRL_NOT_SUPP, NONE_AMS);
1354 tcpm_pd_handle_msg(port, PD_MSG_CTRL_NOT_SUPP, NONE_AMS);
1361 static void tcpm_pd_rx_handler(struct tcpm_port *port, in tcpm_pd_rx_handler() argument
1368 port->attached); in tcpm_pd_rx_handler()
1370 if (port->attached) { in tcpm_pd_rx_handler()
1383 if (msgid == port->rx_msgid && type != PD_CTRL_SOFT_RESET) in tcpm_pd_rx_handler()
1385 port->rx_msgid = msgid; in tcpm_pd_rx_handler()
1392 (port->data_role == TYPEC_HOST)) { in tcpm_pd_rx_handler()
1394 tcpm_set_state(port, ERROR_RECOVERY, 0); in tcpm_pd_rx_handler()
1397 tcpm_pd_data_request(port, msg); in tcpm_pd_rx_handler()
1399 tcpm_pd_ctrl_request(port, msg); in tcpm_pd_rx_handler()
1407 void tcpm_pd_receive(struct tcpm_port *port, const struct pd_message *msg) in tcpm_pd_receive() argument
1411 port->poll_event_cnt = 0; in tcpm_pd_receive()
1416 event->port = port; in tcpm_pd_receive()
1418 tcpm_pd_rx_handler(port, event); in tcpm_pd_receive()
1422 static int tcpm_pd_send_control(struct tcpm_port *port, in tcpm_pd_send_control() argument
1428 msg.header = PD_HEADER_LE(type, port->pwr_role, in tcpm_pd_send_control()
1429 port->data_role, in tcpm_pd_send_control()
1430 port->negotiated_rev, in tcpm_pd_send_control()
1431 port->message_id, 0); in tcpm_pd_send_control()
1433 return tcpm_pd_transmit(port, TCPC_TX_SOP, &msg); in tcpm_pd_send_control()
1441 static bool tcpm_send_queued_message(struct tcpm_port *port) in tcpm_send_queued_message() argument
1446 queued_message = port->queued_message; in tcpm_send_queued_message()
1447 port->queued_message = PD_MSG_NONE; in tcpm_send_queued_message()
1451 tcpm_pd_send_control(port, PD_CTRL_WAIT); in tcpm_send_queued_message()
1454 tcpm_pd_send_control(port, PD_CTRL_REJECT); in tcpm_send_queued_message()
1457 tcpm_pd_send_control(port, PD_CTRL_NOT_SUPP); in tcpm_send_queued_message()
1460 tcpm_pd_send_sink_caps(port); in tcpm_send_queued_message()
1463 tcpm_pd_send_source_caps(port); in tcpm_send_queued_message()
1468 } while (port->queued_message != PD_MSG_NONE); in tcpm_send_queued_message()
1472 if (port->delayed_state != INVALID_STATE) { in tcpm_send_queued_message()
1473 if (ktime_after(port->delayed_runtime, ktime_get())) { in tcpm_send_queued_message()
1474 mod_tcpm_delayed_work(port, ktime_to_ms(ktime_sub(port->delayed_runtime, in tcpm_send_queued_message()
1478 port->delayed_state = INVALID_STATE; in tcpm_send_queued_message()
1484 static int tcpm_pd_check_request(struct tcpm_port *port) in tcpm_pd_check_request() argument
1486 u32 pdo, rdo = port->sink_request; in tcpm_pd_check_request()
1491 if (!index || index > port->nr_src_pdo) in tcpm_pd_check_request()
1494 pdo = port->src_pdo[index - 1]; in tcpm_pd_check_request()
1533 port->op_vsafe5v = index == 1; in tcpm_pd_check_request()
1541 static int tcpm_pd_select_pdo(struct tcpm_port *port, int *sink_pdo, in tcpm_pd_select_pdo() argument
1549 port->pps_data.supported = false; in tcpm_pd_select_pdo()
1550 port->usb_type = POWER_SUPPLY_USB_TYPE_PD; in tcpm_pd_select_pdo()
1556 for (i = 0; i < port->nr_source_caps; i++) { in tcpm_pd_select_pdo()
1557 u32 pdo = port->source_caps[i]; in tcpm_pd_select_pdo()
1572 port->pps_data.supported = true; in tcpm_pd_select_pdo()
1573 port->usb_type = in tcpm_pd_select_pdo()
1598 for (j = 0; j < port->nr_snk_pdo; j++) { in tcpm_pd_select_pdo()
1599 pdo = port->snk_pdo[j]; in tcpm_pd_select_pdo()
1639 static unsigned int tcpm_pd_select_pps_apdo(struct tcpm_port *port) in tcpm_pd_select_pps_apdo() argument
1653 for (i = 1; i < port->nr_source_caps; ++i) { in tcpm_pd_select_pps_apdo()
1654 pdo = port->source_caps[i]; in tcpm_pd_select_pps_apdo()
1673 for (j = 1; j < port->nr_snk_pdo; j++) { in tcpm_pd_select_pps_apdo()
1674 pdo = port->snk_pdo[j]; in tcpm_pd_select_pps_apdo()
1717 src = port->source_caps[src_pdo]; in tcpm_pd_select_pps_apdo()
1718 snk = port->snk_pdo[snk_pdo]; in tcpm_pd_select_pps_apdo()
1720 port->pps_data.req_min_volt = max(pdo_pps_apdo_min_voltage(src), in tcpm_pd_select_pps_apdo()
1722 port->pps_data.req_max_volt = min(pdo_pps_apdo_max_voltage(src), in tcpm_pd_select_pps_apdo()
1724 port->pps_data.req_max_curr = min_pps_apdo_current(src, snk); in tcpm_pd_select_pps_apdo()
1725 port->pps_data.req_out_volt = min(port->pps_data.req_max_volt, in tcpm_pd_select_pps_apdo()
1726 max(port->pps_data.req_min_volt, in tcpm_pd_select_pps_apdo()
1727 port->pps_data.req_out_volt)); in tcpm_pd_select_pps_apdo()
1728 port->pps_data.req_op_curr = min(port->pps_data.req_max_curr, in tcpm_pd_select_pps_apdo()
1729 port->pps_data.req_op_curr); in tcpm_pd_select_pps_apdo()
1735 static int tcpm_pd_build_request(struct tcpm_port *port, u32 *rdo) in tcpm_pd_build_request() argument
1745 ret = tcpm_pd_select_pdo(port, &snk_pdo_index, &src_pdo_index); in tcpm_pd_build_request()
1749 pdo = port->source_caps[src_pdo_index]; in tcpm_pd_build_request()
1750 matching_snk_pdo = port->snk_pdo[snk_pdo_index]; in tcpm_pd_build_request()
1780 if (mw < port->operating_snk_mw) { in tcpm_pd_build_request()
1791 port->cc_req, port->cc1, port->cc2, port->vbus_source, in tcpm_pd_build_request()
1792 port->vconn_role == TYPEC_SOURCE ? "source" : "sink", in tcpm_pd_build_request()
1793 port->polarity); in tcpm_pd_build_request()
1809 port->req_current_limit = ma; in tcpm_pd_build_request()
1810 port->req_supply_voltage = mv; in tcpm_pd_build_request()
1815 static int tcpm_pd_send_request(struct tcpm_port *port) in tcpm_pd_send_request() argument
1821 ret = tcpm_pd_build_request(port, &rdo); in tcpm_pd_send_request()
1827 port->pwr_role, in tcpm_pd_send_request()
1828 port->data_role, in tcpm_pd_send_request()
1829 port->negotiated_rev, in tcpm_pd_send_request()
1830 port->message_id, 1); in tcpm_pd_send_request()
1833 return tcpm_pd_transmit(port, TCPC_TX_SOP, &msg); in tcpm_pd_send_request()
1836 static int tcpm_pd_build_pps_request(struct tcpm_port *port, u32 *rdo) in tcpm_pd_build_pps_request() argument
1843 src_pdo_index = tcpm_pd_select_pps_apdo(port); in tcpm_pd_build_pps_request()
1847 pdo = port->source_caps[src_pdo_index]; in tcpm_pd_build_pps_request()
1856 max_mv = port->pps_data.req_max_volt; in tcpm_pd_build_pps_request()
1857 max_ma = port->pps_data.req_max_curr; in tcpm_pd_build_pps_request()
1858 out_mv = port->pps_data.req_out_volt; in tcpm_pd_build_pps_request()
1859 op_ma = port->pps_data.req_op_curr; in tcpm_pd_build_pps_request()
1869 if (op_mw < port->operating_snk_mw) { in tcpm_pd_build_pps_request()
1876 op_ma = (port->operating_snk_mw * 1000) / out_mv; in tcpm_pd_build_pps_request()
1877 if ((port->operating_snk_mw * 1000) % out_mv) in tcpm_pd_build_pps_request()
1883 out_mv = (port->operating_snk_mw * 1000) / op_ma; in tcpm_pd_build_pps_request()
1884 if ((port->operating_snk_mw * 1000) % op_ma) in tcpm_pd_build_pps_request()
1897 port->cc_req, port->cc1, port->cc2, port->vbus_source, in tcpm_pd_build_pps_request()
1898 port->vconn_role == TYPEC_SOURCE ? "source" : "sink", in tcpm_pd_build_pps_request()
1899 port->polarity); in tcpm_pd_build_pps_request()
1906 port->pps_data.req_op_curr = op_ma; in tcpm_pd_build_pps_request()
1907 port->pps_data.req_out_volt = out_mv; in tcpm_pd_build_pps_request()
1912 static int tcpm_pd_send_pps_request(struct tcpm_port *port) in tcpm_pd_send_pps_request() argument
1918 ret = tcpm_pd_build_pps_request(port, &rdo); in tcpm_pd_send_pps_request()
1924 port->pwr_role, in tcpm_pd_send_pps_request()
1925 port->data_role, in tcpm_pd_send_pps_request()
1926 port->negotiated_rev, in tcpm_pd_send_pps_request()
1927 port->message_id, 1); in tcpm_pd_send_pps_request()
1930 return tcpm_pd_transmit(port, TCPC_TX_SOP, &msg); in tcpm_pd_send_pps_request()
1933 static int tcpm_set_vbus(struct tcpm_port *port, bool enable) in tcpm_set_vbus() argument
1937 if (enable && port->vbus_charge) in tcpm_set_vbus()
1940 debug("vbus = %d charge = %d\n", enable, port->vbus_charge); in tcpm_set_vbus()
1942 ret = port->tcpc->set_vbus(port->tcpc, enable, port->vbus_charge); in tcpm_set_vbus()
1946 port->vbus_source = enable; in tcpm_set_vbus()
1950 static int tcpm_set_charge(struct tcpm_port *port, bool charge) in tcpm_set_charge() argument
1954 if (charge && port->vbus_source) in tcpm_set_charge()
1957 if (charge != port->vbus_charge) { in tcpm_set_charge()
1958 debug("vbus = %d charge = %d\n", port->vbus_source, charge); in tcpm_set_charge()
1959 ret = port->tcpc->set_vbus(port->tcpc, port->vbus_source, in tcpm_set_charge()
1964 port->vbus_charge = charge; in tcpm_set_charge()
1968 static bool tcpm_start_toggling(struct tcpm_port *port, enum typec_cc_status cc) in tcpm_start_toggling() argument
1972 if (!port->tcpc->start_toggling) in tcpm_start_toggling()
1976 ret = port->tcpc->start_toggling(port->tcpc, port->port_type, cc); in tcpm_start_toggling()
1980 static int tcpm_init_vbus(struct tcpm_port *port) in tcpm_init_vbus() argument
1984 ret = port->tcpc->set_vbus(port->tcpc, false, false); in tcpm_init_vbus()
1985 port->vbus_source = false; in tcpm_init_vbus()
1986 port->vbus_charge = false; in tcpm_init_vbus()
1990 static int tcpm_init_vconn(struct tcpm_port *port) in tcpm_init_vconn() argument
1994 ret = port->tcpc->set_vconn(port->tcpc, false); in tcpm_init_vconn()
1995 port->vconn_role = TYPEC_SINK; in tcpm_init_vconn()
1999 static void tcpm_typec_connect(struct tcpm_port *port) in tcpm_typec_connect() argument
2001 if (!port->connected) { in tcpm_typec_connect()
2002 port->connected = true; in tcpm_typec_connect()
2006 static int tcpm_src_attach(struct tcpm_port *port) in tcpm_src_attach() argument
2009 port->cc2 == TYPEC_CC_RD ? TYPEC_POLARITY_CC2 in tcpm_src_attach()
2013 if (port->attached) in tcpm_src_attach()
2016 ret = tcpm_set_polarity(port, polarity); in tcpm_src_attach()
2020 ret = tcpm_set_roles(port, true, TYPEC_SOURCE, TYPEC_HOST); in tcpm_src_attach()
2024 ret = port->tcpc->set_pd_rx(port->tcpc, true); in tcpm_src_attach()
2031 * Enable VCONN only if the non-RD port is set to RA. in tcpm_src_attach()
2033 if ((polarity == TYPEC_POLARITY_CC1 && port->cc2 == TYPEC_CC_RA) || in tcpm_src_attach()
2034 (polarity == TYPEC_POLARITY_CC2 && port->cc1 == TYPEC_CC_RA)) { in tcpm_src_attach()
2035 ret = tcpm_set_vconn(port, true); in tcpm_src_attach()
2040 ret = tcpm_set_vbus(port, true); in tcpm_src_attach()
2044 port->pd_capable = false; in tcpm_src_attach()
2046 port->partner = NULL; in tcpm_src_attach()
2048 port->attached = true; in tcpm_src_attach()
2049 port->debouncing = false; in tcpm_src_attach()
2050 //port->send_discover = true; in tcpm_src_attach()
2055 tcpm_set_vconn(port, false); in tcpm_src_attach()
2057 port->tcpc->set_pd_rx(port->tcpc, false); in tcpm_src_attach()
2064 static void tcpm_typec_disconnect(struct tcpm_port *port) in tcpm_typec_disconnect() argument
2066 if (port->connected) { in tcpm_typec_disconnect()
2067 port->partner = NULL; in tcpm_typec_disconnect()
2068 port->connected = false; in tcpm_typec_disconnect()
2072 static void tcpm_reset_port(struct tcpm_port *port) in tcpm_reset_port() argument
2074 tcpm_timer_uninit(port); in tcpm_reset_port()
2075 tcpm_typec_disconnect(port); in tcpm_reset_port()
2076 port->poll_event_cnt = 0; in tcpm_reset_port()
2077 port->wait_dr_swap_Message = false; in tcpm_reset_port()
2078 port->attached = false; in tcpm_reset_port()
2079 port->pd_capable = false; in tcpm_reset_port()
2080 port->pps_data.supported = false; in tcpm_reset_port()
2086 port->rx_msgid = -1; in tcpm_reset_port()
2088 port->tcpc->set_pd_rx(port->tcpc, false); in tcpm_reset_port()
2089 tcpm_init_vbus(port); /* also disables charging */ in tcpm_reset_port()
2090 tcpm_init_vconn(port); in tcpm_reset_port()
2091 tcpm_set_current_limit(port, 0, 0); in tcpm_reset_port()
2092 tcpm_set_polarity(port, TYPEC_POLARITY_CC1); in tcpm_reset_port()
2093 tcpm_set_attached_state(port, false); in tcpm_reset_port()
2094 port->usb_type = POWER_SUPPLY_USB_TYPE_C; in tcpm_reset_port()
2095 port->nr_sink_caps = 0; in tcpm_reset_port()
2096 port->sink_cap_done = false; in tcpm_reset_port()
2099 static void tcpm_detach(struct tcpm_port *port) in tcpm_detach() argument
2101 if (tcpm_port_is_disconnected(port)) in tcpm_detach()
2102 port->hard_reset_count = 0; in tcpm_detach()
2104 if (!port->attached) in tcpm_detach()
2107 tcpm_reset_port(port); in tcpm_detach()
2110 static void tcpm_src_detach(struct tcpm_port *port) in tcpm_src_detach() argument
2112 tcpm_detach(port); in tcpm_src_detach()
2115 static int tcpm_snk_attach(struct tcpm_port *port) in tcpm_snk_attach() argument
2119 if (port->attached) in tcpm_snk_attach()
2122 ret = tcpm_set_polarity(port, port->cc2 != TYPEC_CC_OPEN ? in tcpm_snk_attach()
2127 ret = tcpm_set_roles(port, true, TYPEC_SINK, TYPEC_DEVICE); in tcpm_snk_attach()
2131 port->pd_capable = false; in tcpm_snk_attach()
2133 port->partner = NULL; in tcpm_snk_attach()
2135 port->attached = true; in tcpm_snk_attach()
2136 port->debouncing = false; in tcpm_snk_attach()
2138 port->cc1 != TYPEC_CC_OPEN ? "CC1" : "CC2"); in tcpm_snk_attach()
2143 static void tcpm_snk_detach(struct tcpm_port *port) in tcpm_snk_detach() argument
2145 tcpm_detach(port); in tcpm_snk_detach()
2148 static int tcpm_acc_attach(struct tcpm_port *port) in tcpm_acc_attach() argument
2152 if (port->attached) in tcpm_acc_attach()
2155 ret = tcpm_set_roles(port, true, TYPEC_SOURCE, TYPEC_HOST); in tcpm_acc_attach()
2159 port->partner = NULL; in tcpm_acc_attach()
2161 tcpm_typec_connect(port); in tcpm_acc_attach()
2163 port->attached = true; in tcpm_acc_attach()
2165 dev_info(port->dev, "CC connected as Audio Accessory\n"); in tcpm_acc_attach()
2170 static void tcpm_acc_detach(struct tcpm_port *port) in tcpm_acc_detach() argument
2172 tcpm_detach(port); in tcpm_acc_detach()
2175 static inline enum tcpm_state hard_reset_state(struct tcpm_port *port) in hard_reset_state() argument
2177 if (port->hard_reset_count < PD_N_HARD_RESET_COUNT) in hard_reset_state()
2179 if (port->pd_capable) in hard_reset_state()
2181 if (port->pwr_role == TYPEC_SOURCE) in hard_reset_state()
2183 if (port->state == SNK_WAIT_CAPABILITIES) in hard_reset_state()
2188 static inline enum tcpm_state unattached_state(struct tcpm_port *port) in unattached_state() argument
2190 if (port->port_type == TYPEC_PORT_DRP) { in unattached_state()
2191 if (port->pwr_role == TYPEC_SOURCE) in unattached_state()
2195 } else if (port->port_type == TYPEC_PORT_SRC) { in unattached_state()
2202 bool tcpm_is_toggling(struct tcpm_port *port) in tcpm_is_toggling() argument
2204 if (port->port_type == TYPEC_PORT_DRP) in tcpm_is_toggling()
2205 return port->state == SRC_UNATTACHED || port->state == SNK_UNATTACHED || in tcpm_is_toggling()
2206 port->state == TOGGLING; in tcpm_is_toggling()
2212 static void run_state_machine(struct tcpm_port *port) in run_state_machine() argument
2216 port->enter_state = port->state; in run_state_machine()
2217 switch (port->state) { in run_state_machine()
2222 tcpm_src_detach(port); in run_state_machine()
2223 if (tcpm_start_toggling(port, tcpm_rp_cc(port))) { in run_state_machine()
2224 tcpm_set_state(port, TOGGLING, 0); in run_state_machine()
2227 tcpm_set_cc(port, tcpm_rp_cc(port)); in run_state_machine()
2228 if (port->port_type == TYPEC_PORT_DRP) in run_state_machine()
2229 tcpm_set_state(port, SNK_UNATTACHED, PD_T_DRP_SNK); in run_state_machine()
2232 if (tcpm_port_is_debug(port)) in run_state_machine()
2233 tcpm_set_state(port, DEBUG_ACC_ATTACHED, in run_state_machine()
2235 else if (tcpm_port_is_audio(port)) in run_state_machine()
2236 tcpm_set_state(port, AUDIO_ACC_ATTACHED, in run_state_machine()
2238 else if (tcpm_port_is_source(port)) in run_state_machine()
2239 tcpm_set_state(port, SRC_ATTACHED, PD_T_CC_DEBOUNCE); in run_state_machine()
2243 ret = tcpm_src_attach(port); in run_state_machine()
2248 tcpm_set_state(port, SRC_READY, 0); in run_state_machine()
2250 tcpm_set_state(port, SRC_UNATTACHED, in run_state_machine()
2255 port->caps_count = 0; in run_state_machine()
2256 port->negotiated_rev = PD_MAX_REV; in run_state_machine()
2257 port->message_id = 0; in run_state_machine()
2258 port->rx_msgid = -1; in run_state_machine()
2259 port->explicit_contract = false; in run_state_machine()
2260 tcpm_set_state(port, SRC_SEND_CAPABILITIES, 0); in run_state_machine()
2263 port->caps_count++; in run_state_machine()
2264 if (port->caps_count > PD_N_CAPS_COUNT) { in run_state_machine()
2265 tcpm_set_state(port, SRC_READY, 0); in run_state_machine()
2268 ret = tcpm_pd_send_source_caps(port); in run_state_machine()
2270 tcpm_set_state(port, SRC_SEND_CAPABILITIES, in run_state_machine()
2278 /* port->hard_reset_count = 0; */ in run_state_machine()
2279 port->caps_count = 0; in run_state_machine()
2280 port->pd_capable = true; in run_state_machine()
2281 tcpm_set_state_cond(port, SRC_SEND_CAPABILITIES_TIMEOUT, in run_state_machine()
2299 if (port->hard_reset_count < PD_N_HARD_RESET_COUNT) { in run_state_machine()
2300 tcpm_set_state(port, HARD_RESET_SEND, 0); in run_state_machine()
2301 } else if (port->negotiated_rev > PD_REV20) { in run_state_machine()
2302 port->negotiated_rev--; in run_state_machine()
2303 port->hard_reset_count = 0; in run_state_machine()
2304 tcpm_set_state(port, SRC_SEND_CAPABILITIES, 0); in run_state_machine()
2306 tcpm_set_state(port, hard_reset_state(port), 0); in run_state_machine()
2310 ret = tcpm_pd_check_request(port); in run_state_machine()
2312 tcpm_pd_send_control(port, PD_CTRL_REJECT); in run_state_machine()
2313 if (!port->explicit_contract) { in run_state_machine()
2314 tcpm_set_state(port, in run_state_machine()
2317 tcpm_set_state(port, SRC_READY, 0); in run_state_machine()
2320 tcpm_pd_send_control(port, PD_CTRL_ACCEPT); in run_state_machine()
2321 tcpm_set_state(port, SRC_TRANSITION_SUPPLY, in run_state_machine()
2327 tcpm_pd_send_control(port, PD_CTRL_PS_RDY); in run_state_machine()
2328 port->explicit_contract = true; in run_state_machine()
2329 tcpm_set_state_cond(port, SRC_READY, 0); in run_state_machine()
2333 port->hard_reset_count = 0; in run_state_machine()
2335 port->try_src_count = 0; in run_state_machine()
2337 tcpm_typec_connect(port); in run_state_machine()
2345 tcpm_snk_detach(port); in run_state_machine()
2346 if (tcpm_start_toggling(port, TYPEC_CC_RD)) { in run_state_machine()
2347 tcpm_set_state(port, TOGGLING, 0); in run_state_machine()
2350 tcpm_set_cc(port, TYPEC_CC_RD); in run_state_machine()
2351 if (port->port_type == TYPEC_PORT_DRP) in run_state_machine()
2352 tcpm_set_state(port, SRC_UNATTACHED, PD_T_DRP_SRC); in run_state_machine()
2355 if ((port->cc1 == TYPEC_CC_OPEN && in run_state_machine()
2356 port->cc2 != TYPEC_CC_OPEN) || in run_state_machine()
2357 (port->cc1 != TYPEC_CC_OPEN && in run_state_machine()
2358 port->cc2 == TYPEC_CC_OPEN)) in run_state_machine()
2359 tcpm_set_state(port, SNK_DEBOUNCED, in run_state_machine()
2361 else if (tcpm_port_is_disconnected(port)) in run_state_machine()
2362 tcpm_set_state(port, SNK_UNATTACHED, in run_state_machine()
2366 if (tcpm_port_is_disconnected(port)) { in run_state_machine()
2367 tcpm_set_state(port, SNK_UNATTACHED, in run_state_machine()
2369 } else if (port->vbus_present) in run_state_machine()
2370 tcpm_set_state(port, SNK_ATTACHED, 0); in run_state_machine()
2373 tcpm_set_state(port, PORT_RESET, PD_T_PS_SOURCE_ON); in run_state_machine()
2377 ret = tcpm_snk_attach(port); in run_state_machine()
2379 tcpm_set_state(port, SNK_UNATTACHED, 0); in run_state_machine()
2381 tcpm_set_state(port, SNK_STARTUP, 0); in run_state_machine()
2384 port->negotiated_rev = PD_MAX_REV; in run_state_machine()
2385 port->message_id = 0; in run_state_machine()
2386 port->rx_msgid = -1; in run_state_machine()
2387 port->explicit_contract = false; in run_state_machine()
2388 tcpm_set_state(port, SNK_DISCOVERY, 0); in run_state_machine()
2391 if (port->vbus_present) { in run_state_machine()
2392 tcpm_set_current_limit(port, in run_state_machine()
2393 tcpm_get_current_limit(port), in run_state_machine()
2395 tcpm_set_charge(port, true); in run_state_machine()
2396 tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0); in run_state_machine()
2404 tcpm_set_state(port, hard_reset_state(port), in run_state_machine()
2405 port->port_type == TYPEC_PORT_DRP ? in run_state_machine()
2409 tcpm_set_state(port, SNK_DISCOVERY_DEBOUNCE_DONE, in run_state_machine()
2414 if (!tcpm_port_is_disconnected(port) && in run_state_machine()
2415 tcpm_port_is_sink(port) && in run_state_machine()
2416 ktime_after(port->delayed_runtime, ktime_get())) { in run_state_machine()
2417 tcpm_set_state(port, SNK_DISCOVERY, in run_state_machine()
2418 ktime_to_ms(ktime_sub(port->delayed_runtime, ktime_get()))); in run_state_machine()
2422 tcpm_set_state(port, unattached_state(port), 0); in run_state_machine()
2425 ret = port->tcpc->set_pd_rx(port->tcpc, true); in run_state_machine()
2427 tcpm_set_state(port, SNK_READY, 0); in run_state_machine()
2436 if (port->vbus_never_low) { in run_state_machine()
2437 port->vbus_never_low = false; in run_state_machine()
2438 tcpm_set_state(port, SOFT_RESET_SEND, in run_state_machine()
2441 tcpm_set_state(port, hard_reset_state(port), in run_state_machine()
2446 port->pd_capable = true; in run_state_machine()
2447 port->hard_reset_count = 0; in run_state_machine()
2448 ret = tcpm_pd_send_request(port); in run_state_machine()
2451 tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0); in run_state_machine()
2453 tcpm_set_state_cond(port, hard_reset_state(port), in run_state_machine()
2458 ret = tcpm_pd_send_pps_request(port); in run_state_machine()
2460 port->pps_status = ret; in run_state_machine()
2466 if (port->update_sink_caps) in run_state_machine()
2467 tcpm_set_state(port, SNK_NEGOTIATE_CAPABILITIES, 0); in run_state_machine()
2469 tcpm_set_state(port, SNK_READY, 0); in run_state_machine()
2471 tcpm_set_state_cond(port, hard_reset_state(port), in run_state_machine()
2477 tcpm_set_state(port, hard_reset_state(port), in run_state_machine()
2481 port->try_snk_count = 0; in run_state_machine()
2482 port->update_sink_caps = false; in run_state_machine()
2483 tcpm_typec_connect(port); in run_state_machine()
2488 if (port->wait_dr_swap_Message) in run_state_machine()
2489 port->poll_event_cnt = 0; in run_state_machine()
2495 tcpm_acc_detach(port); in run_state_machine()
2496 tcpm_set_state(port, SRC_UNATTACHED, 0); in run_state_machine()
2500 ret = tcpm_acc_attach(port); in run_state_machine()
2502 tcpm_set_state(port, ACC_UNATTACHED, 0); in run_state_machine()
2505 tcpm_set_state(port, ACC_UNATTACHED, PD_T_CC_DEBOUNCE); in run_state_machine()
2510 tcpm_pd_transmit(port, TCPC_TX_HARD_RESET, NULL); in run_state_machine()
2511 tcpm_set_state(port, HARD_RESET_START, 0); in run_state_machine()
2512 port->wait_dr_swap_Message = false; in run_state_machine()
2515 port->hard_reset_count++; in run_state_machine()
2516 port->tcpc->set_pd_rx(port->tcpc, false); in run_state_machine()
2517 port->nr_sink_caps = 0; in run_state_machine()
2518 port->send_discover = true; in run_state_machine()
2519 if (port->pwr_role == TYPEC_SOURCE) in run_state_machine()
2520 tcpm_set_state(port, SRC_HARD_RESET_VBUS_OFF, in run_state_machine()
2523 tcpm_set_state(port, SNK_HARD_RESET_SINK_OFF, 0); in run_state_machine()
2526 tcpm_set_vconn(port, true); in run_state_machine()
2527 tcpm_set_vbus(port, false); in run_state_machine()
2528 tcpm_set_roles(port, port->self_powered, TYPEC_SOURCE, in run_state_machine()
2530 tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, PD_T_SRC_RECOVER); in run_state_machine()
2533 tcpm_set_vconn(port, true); in run_state_machine()
2534 tcpm_set_vbus(port, true); in run_state_machine()
2535 port->tcpc->set_pd_rx(port->tcpc, true); in run_state_machine()
2536 tcpm_set_attached_state(port, true); in run_state_machine()
2537 tcpm_set_state(port, SRC_UNATTACHED, PD_T_PS_SOURCE_ON); in run_state_machine()
2540 memset(&port->pps_data, 0, sizeof(port->pps_data)); in run_state_machine()
2541 tcpm_set_vconn(port, false); in run_state_machine()
2542 if (port->pd_capable) in run_state_machine()
2543 tcpm_set_charge(port, false); in run_state_machine()
2544 tcpm_set_roles(port, port->self_powered, TYPEC_SINK, in run_state_machine()
2551 tcpm_set_state(port, SNK_HARD_RESET_SINK_ON, PD_T_SAFE_0V); in run_state_machine()
2555 tcpm_set_state(port, SNK_UNATTACHED, in run_state_machine()
2575 if (port->pd_capable) { in run_state_machine()
2576 tcpm_set_current_limit(port, in run_state_machine()
2577 tcpm_get_current_limit(port), in run_state_machine()
2579 tcpm_set_charge(port, true); in run_state_machine()
2581 tcpm_set_attached_state(port, true); in run_state_machine()
2582 tcpm_set_state(port, SNK_STARTUP, 0); in run_state_machine()
2587 port->message_id = 0; in run_state_machine()
2588 port->rx_msgid = -1; in run_state_machine()
2589 tcpm_pd_send_control(port, PD_CTRL_ACCEPT); in run_state_machine()
2590 if (port->pwr_role == TYPEC_SOURCE) { in run_state_machine()
2591 tcpm_set_state(port, SRC_SEND_CAPABILITIES, 0); in run_state_machine()
2593 tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0); in run_state_machine()
2597 port->message_id = 0; in run_state_machine()
2598 port->rx_msgid = -1; in run_state_machine()
2599 if (tcpm_pd_send_control(port, PD_CTRL_SOFT_RESET)) in run_state_machine()
2600 tcpm_set_state_cond(port, hard_reset_state(port), 0); in run_state_machine()
2602 tcpm_set_state_cond(port, hard_reset_state(port), in run_state_machine()
2608 tcpm_pd_send_control(port, PD_CTRL_DR_SWAP); in run_state_machine()
2609 tcpm_set_state_cond(port, DR_SWAP_SEND_TIMEOUT, in run_state_machine()
2613 tcpm_pd_send_control(port, PD_CTRL_ACCEPT); in run_state_machine()
2616 if (port->data_role == TYPEC_DEVICE && port->send_discover) in run_state_machine()
2617 port->vdm_sm_running = true; in run_state_machine()
2619 tcpm_set_state_cond(port, DR_SWAP_CHANGE_DR, 0); in run_state_machine()
2622 //tcpm_swap_complete(port, -ETIMEDOUT); in run_state_machine()
2623 tcpm_set_state(port, ready_state(port), 0); in run_state_machine()
2626 if (port->data_role == TYPEC_HOST) { in run_state_machine()
2627 //tcpm_unregister_altmodes(port); in run_state_machine()
2628 tcpm_set_roles(port, true, port->pwr_role, in run_state_machine()
2631 tcpm_set_roles(port, true, port->pwr_role, in run_state_machine()
2633 //port->send_discover = true; in run_state_machine()
2636 port->wait_dr_swap_Message = false; in run_state_machine()
2637 tcpm_set_state(port, ready_state(port), 0); in run_state_machine()
2644 tcpm_pd_send_control(port, PD_CTRL_ACCEPT); in run_state_machine()
2645 tcpm_set_state(port, PR_SWAP_START, 0); in run_state_machine()
2648 tcpm_pd_send_control(port, PD_CTRL_PR_SWAP); in run_state_machine()
2649 tcpm_set_state_cond(port, PR_SWAP_SEND_TIMEOUT, in run_state_machine()
2653 tcpm_set_state(port, ready_state(port), 0); in run_state_machine()
2656 tcpm_apply_rc(port); in run_state_machine()
2657 if (port->pwr_role == TYPEC_SOURCE) in run_state_machine()
2658 tcpm_set_state(port, PR_SWAP_SRC_SNK_TRANSITION_OFF, in run_state_machine()
2661 tcpm_set_state(port, PR_SWAP_SNK_SRC_SINK_OFF, 0); in run_state_machine()
2668 tcpm_set_vbus(port, false); in run_state_machine()
2669 port->explicit_contract = false; in run_state_machine()
2671 tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF, in run_state_machine()
2678 tcpm_set_cc(port, TYPEC_CC_RD); in run_state_machine()
2680 tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED, in run_state_machine()
2685 * USB-PD standard, 6.2.1.4, Port Power Role: in run_state_machine()
2687 * Port, the Port Power Role field shall be set to Sink in the in run_state_machine()
2691 tcpm_set_pwr_role(port, TYPEC_SINK); in run_state_machine()
2692 if (tcpm_pd_send_control(port, PD_CTRL_PS_RDY)) { in run_state_machine()
2693 tcpm_set_state(port, ERROR_RECOVERY, 0); in run_state_machine()
2696 tcpm_set_state(port, ERROR_RECOVERY, PD_T_PS_SOURCE_ON_PRS); in run_state_machine()
2699 tcpm_enable_auto_vbus_discharge(port, true); in run_state_machine()
2701 tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, VSAFE5V); in run_state_machine()
2702 tcpm_set_state(port, SNK_STARTUP, 0); in run_state_machine()
2712 tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, in run_state_machine()
2713 port->pps_data.active, 0); in run_state_machine()
2714 tcpm_set_charge(port, false); in run_state_machine()
2715 tcpm_set_state(port, hard_reset_state(port), timer_val_msecs); in run_state_machine()
2718 tcpm_enable_auto_vbus_discharge(port, true); in run_state_machine()
2719 tcpm_set_cc(port, tcpm_rp_cc(port)); in run_state_machine()
2720 tcpm_set_vbus(port, true); in run_state_machine()
2726 tcpm_set_state(port, PR_SWAP_SNK_SRC_SOURCE_ON_VBUS_RAMPED_UP, in run_state_machine()
2734 * is ready, will have the Port Power Role field set to in run_state_machine()
2737 tcpm_set_pwr_role(port, TYPEC_SOURCE); in run_state_machine()
2738 tcpm_pd_send_control(port, PD_CTRL_PS_RDY); in run_state_machine()
2739 tcpm_set_state(port, SRC_STARTUP, PD_T_SWAP_SRC_START); in run_state_machine()
2743 tcpm_pd_send_control(port, PD_CTRL_GET_STATUS); in run_state_machine()
2744 tcpm_set_state(port, GET_STATUS_SEND_TIMEOUT, in run_state_machine()
2748 tcpm_set_state(port, ready_state(port), 0); in run_state_machine()
2751 tcpm_pd_send_control(port, PD_CTRL_GET_PPS_STATUS); in run_state_machine()
2752 tcpm_set_state(port, GET_PPS_STATUS_SEND_TIMEOUT, in run_state_machine()
2756 tcpm_set_state(port, ready_state(port), 0); in run_state_machine()
2759 tcpm_pd_send_control(port, PD_CTRL_GET_SINK_CAP); in run_state_machine()
2760 tcpm_set_state(port, GET_SINK_CAP_TIMEOUT, PD_T_SENDER_RESPONSE); in run_state_machine()
2763 tcpm_set_state(port, ready_state(port), 0); in run_state_machine()
2766 tcpm_set_state(port, PORT_RESET, 0); in run_state_machine()
2769 tcpm_reset_port(port); in run_state_machine()
2770 tcpm_set_cc(port, TYPEC_CC_OPEN); in run_state_machine()
2771 tcpm_set_state(port, PORT_RESET_WAIT_OFF, in run_state_machine()
2775 tcpm_set_state(port, in run_state_machine()
2776 tcpm_default_state(port), in run_state_machine()
2777 port->vbus_present ? PD_T_PS_SOURCE_OFF : 0); in run_state_machine()
2780 printf("Unexpected port state %d\n", port->state); in run_state_machine()
2785 static void tcpm_state_machine(struct tcpm_port *port) in tcpm_state_machine() argument
2789 mutex_lock(&port->lock); in tcpm_state_machine()
2790 port->state_machine_running = true; in tcpm_state_machine()
2792 if (port->queued_message && tcpm_send_queued_message(port)) in tcpm_state_machine()
2796 if (port->delayed_state) { in tcpm_state_machine()
2798 tcpm_states[port->state], in tcpm_state_machine()
2799 tcpm_states[port->delayed_state], port->delay_ms); in tcpm_state_machine()
2800 port->prev_state = port->state; in tcpm_state_machine()
2801 port->state = port->delayed_state; in tcpm_state_machine()
2802 port->delayed_state = INVALID_STATE; in tcpm_state_machine()
2810 prev_state = port->state; in tcpm_state_machine()
2811 run_state_machine(port); in tcpm_state_machine()
2812 if (port->queued_message) in tcpm_state_machine()
2813 tcpm_send_queued_message(port); in tcpm_state_machine()
2814 } while (port->state != prev_state && !port->delayed_state); in tcpm_state_machine()
2817 port->state_machine_running = false; in tcpm_state_machine()
2818 mutex_unlock(&port->lock); in tcpm_state_machine()
2821 static void _tcpm_cc_change(struct tcpm_port *port, enum typec_cc_status cc1, in _tcpm_cc_change() argument
2827 old_cc1 = port->cc1; in _tcpm_cc_change()
2828 old_cc2 = port->cc2; in _tcpm_cc_change()
2829 port->cc1 = cc1; in _tcpm_cc_change()
2830 port->cc2 = cc2; in _tcpm_cc_change()
2833 old_cc1, cc1, old_cc2, cc2, tcpm_states[port->state], in _tcpm_cc_change()
2834 port->polarity, in _tcpm_cc_change()
2835 tcpm_port_is_disconnected(port) ? "disconnected" : "connected"); in _tcpm_cc_change()
2837 switch (port->state) { in _tcpm_cc_change()
2839 if (tcpm_port_is_debug(port) || tcpm_port_is_audio(port) || in _tcpm_cc_change()
2840 tcpm_port_is_source(port)) in _tcpm_cc_change()
2841 tcpm_set_state(port, SRC_ATTACH_WAIT, 0); in _tcpm_cc_change()
2842 else if (tcpm_port_is_sink(port)) in _tcpm_cc_change()
2843 tcpm_set_state(port, SNK_ATTACH_WAIT, 0); in _tcpm_cc_change()
2847 if (tcpm_port_is_debug(port) || tcpm_port_is_audio(port) || in _tcpm_cc_change()
2848 tcpm_port_is_source(port)) in _tcpm_cc_change()
2849 tcpm_set_state(port, SRC_ATTACH_WAIT, 0); in _tcpm_cc_change()
2852 if (tcpm_port_is_disconnected(port) || in _tcpm_cc_change()
2853 tcpm_port_is_audio_detached(port)) in _tcpm_cc_change()
2854 tcpm_set_state(port, SRC_UNATTACHED, 0); in _tcpm_cc_change()
2856 tcpm_set_state(port, SRC_ATTACH_WAIT, 0); in _tcpm_cc_change()
2861 if (tcpm_port_is_disconnected(port) || in _tcpm_cc_change()
2862 !tcpm_port_is_source(port)) in _tcpm_cc_change()
2863 tcpm_set_state(port, SRC_UNATTACHED, 0); in _tcpm_cc_change()
2866 if (tcpm_port_is_sink(port)) in _tcpm_cc_change()
2867 tcpm_set_state(port, SNK_ATTACH_WAIT, 0); in _tcpm_cc_change()
2870 if ((port->cc1 == TYPEC_CC_OPEN && in _tcpm_cc_change()
2871 port->cc2 != TYPEC_CC_OPEN) || in _tcpm_cc_change()
2872 (port->cc1 != TYPEC_CC_OPEN && in _tcpm_cc_change()
2873 port->cc2 == TYPEC_CC_OPEN)) in _tcpm_cc_change()
2875 else if (tcpm_port_is_disconnected(port)) in _tcpm_cc_change()
2879 if (new_state != port->delayed_state) in _tcpm_cc_change()
2880 tcpm_set_state(port, SNK_ATTACH_WAIT, 0); in _tcpm_cc_change()
2883 if (tcpm_port_is_disconnected(port)) in _tcpm_cc_change()
2885 else if (port->vbus_present) in _tcpm_cc_change()
2886 new_state = tcpm_try_src(port) ? SRC_TRY : SNK_ATTACHED; in _tcpm_cc_change()
2889 if (new_state != port->delayed_state) in _tcpm_cc_change()
2890 tcpm_set_state(port, SNK_DEBOUNCED, 0); in _tcpm_cc_change()
2893 if (tcpm_port_is_disconnected(port)) in _tcpm_cc_change()
2894 tcpm_set_state(port, unattached_state(port), 0); in _tcpm_cc_change()
2895 else if (!port->pd_capable && in _tcpm_cc_change()
2897 tcpm_set_current_limit(port, in _tcpm_cc_change()
2898 tcpm_get_current_limit(port), in _tcpm_cc_change()
2904 tcpm_set_state(port, AUDIO_ACC_DEBOUNCE, 0); in _tcpm_cc_change()
2907 if (tcpm_port_is_audio(port)) in _tcpm_cc_change()
2908 tcpm_set_state(port, AUDIO_ACC_ATTACHED, 0); in _tcpm_cc_change()
2913 tcpm_set_state(port, ACC_UNATTACHED, 0); in _tcpm_cc_change()
2922 if (tcpm_port_is_disconnected(port)) in _tcpm_cc_change()
2923 tcpm_set_state(port, SNK_DISCOVERY_DEBOUNCE, 0); in _tcpm_cc_change()
2930 if (!port->vbus_present && tcpm_port_is_source(port)) in _tcpm_cc_change()
2931 tcpm_set_state(port, SRC_TRYWAIT_DEBOUNCE, 0); in _tcpm_cc_change()
2934 if (port->vbus_present || !tcpm_port_is_source(port)) in _tcpm_cc_change()
2935 tcpm_set_state(port, SRC_TRYWAIT, 0); in _tcpm_cc_change()
2938 if (!tcpm_port_is_sink(port)) { in _tcpm_cc_change()
2939 port->max_wait = 0; in _tcpm_cc_change()
2940 tcpm_set_state(port, SRC_TRYWAIT, 0); in _tcpm_cc_change()
2944 if (tcpm_port_is_source(port)) in _tcpm_cc_change()
2945 tcpm_set_state(port, SRC_TRY_DEBOUNCE, 0); in _tcpm_cc_change()
2948 tcpm_set_state(port, SRC_TRY_WAIT, 0); in _tcpm_cc_change()
2951 if (tcpm_port_is_sink(port)) in _tcpm_cc_change()
2952 tcpm_set_state(port, SNK_TRYWAIT_VBUS, 0); in _tcpm_cc_change()
2955 if (!tcpm_port_is_sink(port)) in _tcpm_cc_change()
2956 tcpm_set_state(port, SNK_TRYWAIT_DEBOUNCE, 0); in _tcpm_cc_change()
2984 if (tcpm_port_is_disconnected(port)) in _tcpm_cc_change()
2985 tcpm_set_state(port, unattached_state(port), 0); in _tcpm_cc_change()
2990 static void _tcpm_pd_vbus_on(struct tcpm_port *port) in _tcpm_pd_vbus_on() argument
2993 port->vbus_present = true; in _tcpm_pd_vbus_on()
2998 port->vbus_vsafe0v = false; in _tcpm_pd_vbus_on()
3000 switch (port->state) { in _tcpm_pd_vbus_on()
3002 port->explicit_contract = true; in _tcpm_pd_vbus_on()
3003 tcpm_set_state(port, SNK_READY, 0); in _tcpm_pd_vbus_on()
3006 tcpm_set_state(port, SNK_DISCOVERY, 0); in _tcpm_pd_vbus_on()
3009 tcpm_set_state(port, SNK_ATTACHED, 0); in _tcpm_pd_vbus_on()
3012 tcpm_set_state(port, SNK_HARD_RESET_SINK_ON, 0); in _tcpm_pd_vbus_on()
3015 tcpm_set_state(port, SRC_STARTUP, 0); in _tcpm_pd_vbus_on()
3018 tcpm_set_state(port, SRC_STARTUP, 0); in _tcpm_pd_vbus_on()
3028 tcpm_set_state(port, SRC_TRYWAIT, 0); in _tcpm_pd_vbus_on()
3037 if (tcpm_port_is_sink(port)) in _tcpm_pd_vbus_on()
3038 tcpm_set_state(port, SNK_ATTACHED, 0); in _tcpm_pd_vbus_on()
3061 static void _tcpm_pd_vbus_off(struct tcpm_port *port) in _tcpm_pd_vbus_off() argument
3064 port->vbus_present = false; in _tcpm_pd_vbus_off()
3065 port->vbus_never_low = false; in _tcpm_pd_vbus_off()
3066 switch (port->state) { in _tcpm_pd_vbus_off()
3068 tcpm_set_state(port, SNK_HARD_RESET_WAIT_VBUS, 0); in _tcpm_pd_vbus_off()
3077 if (tcpm_port_is_source(port)) in _tcpm_pd_vbus_off()
3078 tcpm_set_state(port, SRC_TRYWAIT_DEBOUNCE, 0); in _tcpm_pd_vbus_off()
3088 port->debouncing = false; in _tcpm_pd_vbus_off()
3089 tcpm_set_state(port, SNK_UNATTACHED, 0); in _tcpm_pd_vbus_off()
3096 tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF, 0); in _tcpm_pd_vbus_off()
3112 tcpm_set_state(port, tcpm_default_state(port), 0); in _tcpm_pd_vbus_off()
3128 if (port->pwr_role == TYPEC_SINK && port->attached) in _tcpm_pd_vbus_off()
3129 tcpm_set_state(port, SNK_UNATTACHED, 0); in _tcpm_pd_vbus_off()
3134 static void _tcpm_pd_hard_reset(struct tcpm_port *port) in _tcpm_pd_hard_reset() argument
3137 port->poll_event_cnt = 0; in _tcpm_pd_hard_reset()
3139 /* If a hard reset message is received during the port reset process, in _tcpm_pd_hard_reset()
3140 * we should ignore it, that is, do not set port->state to HARD_RESET_START. in _tcpm_pd_hard_reset()
3142 if (port->state == PORT_RESET || port->state == PORT_RESET_WAIT_OFF) in _tcpm_pd_hard_reset()
3149 tcpm_set_state(port, in _tcpm_pd_hard_reset()
3150 port->hard_reset_count < PD_N_HARD_RESET_COUNT ? in _tcpm_pd_hard_reset()
3156 static void tcpm_pd_event_handler(struct tcpm_port *port)
3160 while (port->pd_events) {
3161 events = port->pd_events;
3162 port->pd_events = 0;
3164 _tcpm_pd_hard_reset(port);
3168 vbus = port->tcpc->get_vbus(port->tcpc);
3170 _tcpm_pd_vbus_on(port);
3172 _tcpm_pd_vbus_off(port);
3178 if (!port->tcpc->is_vbus_vsafe0v ||
3179 port->tcpc->is_vbus_vsafe0v(port->tcpc))
3180 _tcpm_pd_vbus_vsafe0v(port);
3186 if (port->tcpc->get_cc(port->tcpc, &cc1, &cc2) == 0)
3187 _tcpm_cc_change(port, cc1, cc2);
3190 if (port->state == SNK_READY) {
3193 port->upcoming_state = FR_SWAP_SEND;
3194 ret = tcpm_ams_start(port, FAST_ROLE_SWAP);
3196 port->upcoming_state = INVALID_STATE;
3198 tcpm_log(port, "Discarding FRS_SIGNAL! Not in sink ready");
3202 tcpm_log(port, "sourcing vbus");
3210 port->vbus_source = true;
3211 _tcpm_pd_vbus_on(port);
3217 void tcpm_cc_change(struct tcpm_port *port) in tcpm_cc_change() argument
3221 port->poll_event_cnt = 0; in tcpm_cc_change()
3222 if (port->tcpc->get_cc(port->tcpc, &cc1, &cc2) == 0) in tcpm_cc_change()
3223 _tcpm_cc_change(port, cc1, cc2); in tcpm_cc_change()
3227 void tcpm_vbus_change(struct tcpm_port *port) in tcpm_vbus_change() argument
3231 port->poll_event_cnt = 0; in tcpm_vbus_change()
3232 vbus = port->tcpc->get_vbus(port->tcpc); in tcpm_vbus_change()
3234 _tcpm_pd_vbus_on(port); in tcpm_vbus_change()
3236 _tcpm_pd_vbus_off(port); in tcpm_vbus_change()
3240 void tcpm_pd_hard_reset(struct tcpm_port *port) in tcpm_pd_hard_reset() argument
3242 port->poll_event_cnt = 0; in tcpm_pd_hard_reset()
3243 _tcpm_pd_hard_reset(port); in tcpm_pd_hard_reset()
3247 static void tcpm_init(struct tcpm_port *port) in tcpm_init() argument
3251 port->tcpc->init(port->tcpc); in tcpm_init()
3253 tcpm_reset_port(port); in tcpm_init()
3260 port->vbus_present = port->tcpc->get_vbus(port->tcpc); in tcpm_init()
3261 if (port->vbus_present) in tcpm_init()
3262 port->vbus_never_low = true; in tcpm_init()
3275 if (port->vbus_present) in tcpm_init()
3276 port->vbus_vsafe0v = false; in tcpm_init()
3277 else if (!port->tcpc->is_vbus_vsafe0v) in tcpm_init()
3278 port->vbus_vsafe0v = true; in tcpm_init()
3280 port->vbus_vsafe0v = port->tcpc->is_vbus_vsafe0v(port->tcpc); in tcpm_init()
3282 tcpm_set_state(port, tcpm_default_state(port), 0); in tcpm_init()
3284 if (port->tcpc->get_cc(port->tcpc, &cc1, &cc2) == 0) in tcpm_init()
3285 _tcpm_cc_change(port, cc1, cc2); in tcpm_init()
3288 void tcpm_tcpc_reset(struct tcpm_port *port) in tcpm_tcpc_reset() argument
3290 mutex_lock(&port->lock); in tcpm_tcpc_reset()
3292 tcpm_init(port); in tcpm_tcpc_reset()
3293 mutex_unlock(&port->lock); in tcpm_tcpc_reset()
3297 static int tcpm_fw_get_caps(struct tcpm_port *port) in tcpm_fw_get_caps() argument
3300 ofnode node = port->tcpc->connector_node; in tcpm_fw_get_caps()
3311 port->typec_caps.data = ret; in tcpm_fw_get_caps()
3320 port->typec_caps.type = TYPEC_PORT_DRP; in tcpm_fw_get_caps()
3322 port->typec_caps.type = TYPEC_PORT_SRC; in tcpm_fw_get_caps()
3324 port->typec_caps.type = TYPEC_PORT_SNK; in tcpm_fw_get_caps()
3329 port->port_type = port->typec_caps.type; in tcpm_fw_get_caps()
3331 port->slow_charger_loop = ofnode_read_bool(node, "slow-charger-loop"); in tcpm_fw_get_caps()
3332 if (port->port_type == TYPEC_PORT_SNK) in tcpm_fw_get_caps()
3340 port->nr_src_pdo = min(ret, PDO_MAX_OBJECTS); in tcpm_fw_get_caps()
3342 port->src_pdo, port->nr_src_pdo); in tcpm_fw_get_caps()
3343 if (ret || tcpm_validate_caps(port, port->src_pdo, in tcpm_fw_get_caps()
3344 port->nr_src_pdo)) in tcpm_fw_get_caps()
3347 if (port->port_type == TYPEC_PORT_SRC) in tcpm_fw_get_caps()
3356 port->typec_caps.prefer_role = TYPEC_SINK; in tcpm_fw_get_caps()
3358 port->typec_caps.prefer_role = TYPEC_SOURCE; in tcpm_fw_get_caps()
3362 if (port->typec_caps.prefer_role < 0) in tcpm_fw_get_caps()
3370 port->nr_snk_pdo = min(ret, PDO_MAX_OBJECTS); in tcpm_fw_get_caps()
3372 port->snk_pdo, port->nr_snk_pdo); in tcpm_fw_get_caps()
3373 if (ret || tcpm_validate_caps(port, port->snk_pdo, in tcpm_fw_get_caps()
3374 port->nr_snk_pdo)) in tcpm_fw_get_caps()
3379 port->operating_snk_mw = mw / 1000; in tcpm_fw_get_caps()
3381 port->self_powered = ofnode_read_bool(node, "self-powered"); in tcpm_fw_get_caps()
3384 if (port->port_type == TYPEC_PORT_DRP) { in tcpm_fw_get_caps()
3388 port->new_source_frs_current = frs_current; in tcpm_fw_get_caps()
3396 port->nr_snk_vdo = min(ret, VDO_MAX_OBJECTS); in tcpm_fw_get_caps()
3397 if (port->nr_snk_vdo) { in tcpm_fw_get_caps()
3399 port->snk_vdo, port->nr_snk_vdo); in tcpm_fw_get_caps()
3405 if (port->nr_snk_vdo) { in tcpm_fw_get_caps()
3412 port->nr_snk_vdo_v1 = min(ret, VDO_MAX_OBJECTS); in tcpm_fw_get_caps()
3414 port->snk_vdo_v1, in tcpm_fw_get_caps()
3415 port->nr_snk_vdo_v1); in tcpm_fw_get_caps()
3425 struct tcpm_port *port; in tcpm_port_init() local
3434 port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL); in tcpm_port_init()
3435 if (!port) in tcpm_port_init()
3438 port->dev = dev; in tcpm_port_init()
3439 port->tcpc = tcpc; in tcpm_port_init()
3441 err = tcpm_fw_get_caps(port); in tcpm_port_init()
3448 port->try_role = port->typec_caps.prefer_role; in tcpm_port_init()
3450 port->typec_caps.revision = 0x0120; /* Type-C spec release 1.2 */ in tcpm_port_init()
3451 port->typec_caps.pd_revision = 0x0300; /* USB-PD spec release 3.0 */ in tcpm_port_init()
3452 port->typec_caps.svdm_version = SVDM_VER_2_0; in tcpm_port_init()
3453 port->typec_caps.driver_data = port; in tcpm_port_init()
3454 port->typec_caps.orientation_aware = 1; in tcpm_port_init()
3456 port->port_type = port->typec_caps.type; in tcpm_port_init()
3458 tcpm_init(port); in tcpm_port_init()
3462 return port; in tcpm_port_init()
3466 void tcpm_poll_event(struct tcpm_port *port) in tcpm_poll_event() argument
3468 if (!port->tcpc->get_vbus(port->tcpc)) in tcpm_poll_event()
3471 while (port->poll_event_cnt < TCPM_POLL_EVENT_TIME_OUT) { in tcpm_poll_event()
3472 if (!port->wait_dr_swap_Message && in tcpm_poll_event()
3473 ((port->state == SNK_READY) || in tcpm_poll_event()
3474 (port->state == SRC_READY) || in tcpm_poll_event()
3475 (port->state == DEBUG_ACC_ATTACHED) || in tcpm_poll_event()
3476 (port->state == AUDIO_ACC_ATTACHED))) in tcpm_poll_event()
3479 port->tcpc->poll_event(port->tcpc); in tcpm_poll_event()
3480 port->poll_event_cnt++; in tcpm_poll_event()
3496 if (port->tcpc->enter_low_power_mode) { in tcpm_poll_event()
3497 if (port->tcpc->enter_low_power_mode(port->tcpc, in tcpm_poll_event()
3498 port->attached, in tcpm_poll_event()
3499 port->pd_capable)) in tcpm_poll_event()
3507 int tcpm_get_voltage(struct tcpm_port *port) in tcpm_get_voltage() argument
3509 return port->supply_voltage * 1000; in tcpm_get_voltage()
3513 int tcpm_get_current(struct tcpm_port *port) in tcpm_get_current() argument
3515 return port->current_limit * 1000; in tcpm_get_current()
3519 int tcpm_get_online(struct tcpm_port *port) in tcpm_get_online() argument
3521 if (port->state == SNK_READY) in tcpm_get_online()
3528 void tcpm_uninit_port(struct tcpm_port *port) in tcpm_uninit_port() argument
3530 tcpm_reset_port(port); in tcpm_uninit_port()