forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/usb/typec/tcpm/tcpm.c
....@@ -8,7 +8,6 @@
88 #include <linux/completion.h>
99 #include <linux/debugfs.h>
1010 #include <linux/device.h>
11
-#include <linux/extcon-provider.h>
1211 #include <linux/hrtimer.h>
1312 #include <linux/jiffies.h>
1413 #include <linux/kernel.h>
....@@ -18,11 +17,11 @@
1817 #include <linux/power_supply.h>
1918 #include <linux/proc_fs.h>
2019 #include <linux/property.h>
21
-#include <linux/regulator/consumer.h>
2220 #include <linux/sched/clock.h>
2321 #include <linux/seq_file.h>
2422 #include <linux/slab.h>
2523 #include <linux/spinlock.h>
24
+#include <linux/usb.h>
2625 #include <linux/usb/pd.h>
2726 #include <linux/usb/pd_ado.h>
2827 #include <linux/usb/pd_bdo.h>
....@@ -31,8 +30,8 @@
3130 #include <linux/usb/role.h>
3231 #include <linux/usb/tcpm.h>
3332 #include <linux/usb/typec_altmode.h>
34
-#include <linux/usb/typec_dp.h>
3533
34
+#include <trace/hooks/typec.h>
3635 #include <uapi/linux/sched/types.h>
3736
3837 #define FOREACH_STATE(S) \
....@@ -145,7 +144,8 @@
145144 S(PORT_RESET), \
146145 S(PORT_RESET_WAIT_OFF), \
147146 \
148
- S(AMS_START)
147
+ S(AMS_START), \
148
+ S(CHUNK_NOT_SUPP)
149149
150150 #define FOREACH_AMS(S) \
151151 S(NONE_AMS), \
....@@ -223,6 +223,14 @@
223223 PD_MSG_DATA_SOURCE_CAP,
224224 };
225225
226
+enum adev_actions {
227
+ ADEV_NONE = 0,
228
+ ADEV_NOTIFY_USB_AND_QUEUE_VDM,
229
+ ADEV_QUEUE_VDM,
230
+ ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL,
231
+ ADEV_ATTENTION,
232
+};
233
+
226234 /*
227235 * Initial current capability of the new source when vSafe5V is applied during PD3.0 Fast Role Swap.
228236 * Based on "Table 6-14 Fixed Supply PDO - Sink" of "USB Power Delivery Specification Revision 3.0,
....@@ -234,24 +242,6 @@
234242 FRS_5V_1P5A,
235243 FRS_5V_3A,
236244 };
237
-
238
-static const unsigned int tcpm_cable[] = {
239
- EXTCON_USB,
240
- EXTCON_USB_HOST,
241
- EXTCON_USB_VBUS_EN,
242
- EXTCON_CHG_USB_SDP,
243
- EXTCON_CHG_USB_CDP,
244
- EXTCON_CHG_USB_DCP,
245
- EXTCON_CHG_USB_SLOW,
246
- EXTCON_CHG_USB_FAST,
247
- EXTCON_DISP_DP,
248
- EXTCON_NONE,
249
-};
250
-
251
-/* Pin assignments where one channel is for USB */
252
-#define DP_PIN_ASSIGN_MULTI_FUNCTION_MASK (BIT(DP_PIN_ASSIGN_B) | \
253
- BIT(DP_PIN_ASSIGN_D) | \
254
- BIT(DP_PIN_ASSIGN_F))
255245
256246 /* Events from low level driver */
257247
....@@ -270,7 +260,7 @@
270260 #define ALTMODE_DISCOVERY_MAX (SVID_DISCOVERY_MAX * MODE_DISCOVERY_MAX)
271261
272262 #define GET_SINK_CAP_RETRY_MS 100
273
-#define SEND_NEW_MODE_NOTIFY_MS 20
263
+#define SEND_DISCOVER_RETRY_MS 100
274264
275265 struct pd_mode_data {
276266 int svid_index; /* current SVID index */
....@@ -280,12 +270,27 @@
280270 struct typec_altmode_desc altmode_desc[ALTMODE_DISCOVERY_MAX];
281271 };
282272
273
+/*
274
+ * @min_volt: Actual min voltage at the local port
275
+ * @req_min_volt: Requested min voltage to the port partner
276
+ * @max_volt: Actual max voltage at the local port
277
+ * @req_max_volt: Requested max voltage to the port partner
278
+ * @max_curr: Actual max current at the local port
279
+ * @req_max_curr: Requested max current of the port partner
280
+ * @req_out_volt: Requested output voltage to the port partner
281
+ * @req_op_curr: Requested operating current to the port partner
282
+ * @supported: Parter has atleast one APDO hence supports PPS
283
+ * @active: PPS mode is active
284
+ */
283285 struct pd_pps_data {
284286 u32 min_volt;
287
+ u32 req_min_volt;
285288 u32 max_volt;
289
+ u32 req_max_volt;
286290 u32 max_curr;
287
- u32 out_volt;
288
- u32 op_curr;
291
+ u32 req_max_curr;
292
+ u32 req_out_volt;
293
+ u32 req_op_curr;
289294 bool supported;
290295 bool active;
291296 };
....@@ -311,9 +316,6 @@
311316 struct typec_partner_desc partner_desc;
312317 struct typec_partner *partner;
313318
314
- struct regulator *vbus;
315
- struct extcon_dev *extcon;
316
-
317319 enum typec_cc_status cc_req;
318320
319321 enum typec_cc_status cc1;
....@@ -323,14 +325,26 @@
323325 bool attached;
324326 bool connected;
325327 enum typec_port_type port_type;
328
+
329
+ /*
330
+ * Set to true when vbus is greater than VSAFE5V min.
331
+ * Set to false when vbus falls below vSinkDisconnect max threshold.
332
+ */
326333 bool vbus_present;
334
+
335
+ /*
336
+ * Set to true when vbus is less than VSAFE0V max.
337
+ * Set to false when vbus is greater than VSAFE0V max.
338
+ */
339
+ bool vbus_vsafe0v;
340
+
327341 bool vbus_never_low;
328342 bool vbus_source;
329343 bool vbus_charge;
330344
345
+ /* Set to true when Discover_Identity Command is expected to be sent in Ready states. */
331346 bool send_discover;
332347 bool op_vsafe5v;
333
- bool vbus_on;
334348
335349 int try_role;
336350 int try_snk_count;
....@@ -346,7 +360,9 @@
346360 unsigned long delay_ms;
347361
348362 spinlock_t pd_event_lock;
363
+#ifdef CONFIG_NO_GKI
349364 struct mutex pd_handler_lock;
365
+#endif
350366 u32 pd_events;
351367
352368 struct kthread_work event_work;
....@@ -356,9 +372,10 @@
356372 struct kthread_work vdm_state_machine;
357373 struct hrtimer enable_frs_timer;
358374 struct kthread_work enable_frs;
359
- struct kthread_work data_role_swap;
360
- struct hrtimer data_role_swap_timer;
375
+ struct hrtimer send_discover_timer;
376
+ struct kthread_work send_discover_work;
361377 bool state_machine_running;
378
+ /* Set to true when VDM State Machine has following actions. */
362379 bool vdm_sm_running;
363380
364381 struct completion tx_complete;
....@@ -378,10 +395,6 @@
378395 bool explicit_contract;
379396 unsigned int rx_msgid;
380397
381
- u32 dp_pin_assignment;
382
- u32 dp_status;
383
- bool dp_configured;
384
-
385398 /* Partner capabilities/requests */
386399 u32 sink_request;
387400 u32 source_caps[PDO_MAX_OBJECTS];
....@@ -394,13 +407,18 @@
394407 unsigned int nr_src_pdo;
395408 u32 snk_pdo[PDO_MAX_OBJECTS];
396409 unsigned int nr_snk_pdo;
410
+ u32 snk_vdo_v1[VDO_MAX_OBJECTS];
411
+ unsigned int nr_snk_vdo_v1;
397412 u32 snk_vdo[VDO_MAX_OBJECTS];
398413 unsigned int nr_snk_vdo;
399414
400415 unsigned int operating_snk_mw;
401416 bool update_sink_caps;
402417
403
- /* Requested current / voltage */
418
+ /* Requested current / voltage to the port partner */
419
+ u32 req_current_limit;
420
+ u32 req_supply_voltage;
421
+ /* Actual current / voltage limit of the local port */
404422 u32 current_limit;
405423 u32 supply_voltage;
406424
....@@ -437,17 +455,30 @@
437455 /* port belongs to a self powered device */
438456 bool self_powered;
439457
440
- /* FRS */
441
- enum frs_typec_current frs_current;
458
+ /* Sink FRS */
459
+ enum frs_typec_current new_source_frs_current;
442460
443461 /* Sink caps have been queried */
444462 bool sink_cap_done;
445463
464
+ /* Port is still in tCCDebounce */
465
+ bool debouncing;
466
+
446467 /* Collision Avoidance and Atomic Message Sequence */
447468 enum tcpm_state upcoming_state;
448469 enum tcpm_ams ams;
470
+ enum tcpm_ams next_ams;
449471 bool in_ams;
450472
473
+ /* Auto vbus discharge status */
474
+ bool auto_vbus_discharge_enabled;
475
+
476
+ /*
477
+ * When set, port requests PD_P_SNK_STDBY_MW upon entering SNK_DISCOVERY and
478
+ * the actual currrent limit after RX of PD_CTRL_PSRDY for PD link,
479
+ * SNK_READY for non-pd link.
480
+ */
481
+ bool slow_charger_loop;
451482 #ifdef CONFIG_DEBUG_FS
452483 struct dentry *dentry;
453484 struct mutex logbuffer_lock; /* log buffer access lock */
....@@ -505,9 +536,20 @@
505536 ((port)->try_src_count == 0 && (port)->try_role == TYPEC_SOURCE && \
506537 (port)->port_type == TYPEC_PORT_DRP)
507538
539
+#define tcpm_data_role_for_source(port) \
540
+ ((port)->typec_caps.data == TYPEC_PORT_UFP ? \
541
+ TYPEC_DEVICE : TYPEC_HOST)
542
+
543
+#define tcpm_data_role_for_sink(port) \
544
+ ((port)->typec_caps.data == TYPEC_PORT_DFP ? \
545
+ TYPEC_HOST : TYPEC_DEVICE)
546
+
508547 #define tcpm_sink_tx_ok(port) \
509548 (tcpm_port_is_sink(port) && \
510549 ((port)->cc1 == TYPEC_CC_RP_3_0 || (port)->cc2 == TYPEC_CC_RP_3_0))
550
+
551
+#define tcpm_wait_for_discharge(port) \
552
+ (((port)->auto_vbus_discharge_enabled && !(port)->vbus_vsafe0v) ? PD_T_SAFE_0V : 0)
511553
512554 static enum tcpm_state tcpm_default_state(struct tcpm_port *port)
513555 {
....@@ -521,12 +563,6 @@
521563 return SNK_UNATTACHED;
522564 }
523565 return SRC_UNATTACHED;
524
-}
525
-
526
-static inline
527
-struct tcpm_port *typec_cap_to_tcpm(const struct typec_capability *cap)
528
-{
529
- return container_of(cap, struct tcpm_port, typec_caps);
530566 }
531567
532568 static bool tcpm_port_is_disconnected(struct tcpm_port *port)
....@@ -557,6 +593,7 @@
557593 char tmpbuffer[LOG_BUFFER_ENTRY_SIZE];
558594 u64 ts_nsec = local_clock();
559595 unsigned long rem_nsec;
596
+ bool bypass_log = false;
560597
561598 mutex_lock(&port->logbuffer_lock);
562599 if (!port->logbuffer[port->logbuffer_head]) {
....@@ -569,6 +606,9 @@
569606 }
570607
571608 vsnprintf(tmpbuffer, sizeof(tmpbuffer), fmt, args);
609
+ trace_android_vh_typec_tcpm_log(tmpbuffer, &bypass_log);
610
+ if (bypass_log)
611
+ goto abort;
572612
573613 if (tcpm_log_full(port)) {
574614 port->logbuffer_head = max(port->logbuffer_head - 1, 0);
....@@ -705,17 +745,13 @@
705745 }
706746 DEFINE_SHOW_ATTRIBUTE(tcpm_debug);
707747
708
-static struct dentry *rootdir;
709
-
710748 static void tcpm_debugfs_init(struct tcpm_port *port)
711749 {
712
- mutex_init(&port->logbuffer_lock);
713
- /* /sys/kernel/debug/tcpm/usbcX */
714
- if (!rootdir)
715
- rootdir = debugfs_create_dir("tcpm", NULL);
750
+ char name[NAME_MAX];
716751
717
- port->dentry = debugfs_create_file(dev_name(port->dev),
718
- S_IFREG | 0444, rootdir,
752
+ mutex_init(&port->logbuffer_lock);
753
+ snprintf(name, NAME_MAX, "tcpm-%s", dev_name(port->dev));
754
+ port->dentry = debugfs_create_file(name, S_IFREG | 0444, usb_debug_root,
719755 port, &tcpm_debug_fops);
720756 }
721757
....@@ -731,10 +767,6 @@
731767 mutex_unlock(&port->logbuffer_lock);
732768
733769 debugfs_remove(port->dentry);
734
- if (list_empty(&rootdir->d_subdirs)) {
735
- debugfs_remove(rootdir);
736
- rootdir = NULL;
737
- }
738770 }
739771
740772 #else
....@@ -749,110 +781,39 @@
749781
750782 #endif
751783
752
-static int tcpm_send_vbus_notify(struct tcpm_port *port, bool enable)
753
-{
754
- int ret = 0;
755
-
756
- if (port->vbus_on == enable) {
757
- tcpm_log(port, "vbus is already %s", enable ? "on" : "Off");
758
- goto done;
759
- }
760
-
761
- if (port->vbus) {
762
- if (enable)
763
- ret = regulator_enable(port->vbus);
764
- else
765
- ret = regulator_disable(port->vbus);
766
- if (ret < 0) {
767
- dev_err(port->dev, "failed to %s vbus supply(%d)\n",
768
- enable ? "enable" : "disable", ret);
769
- goto done;
770
- }
771
-
772
- /* Only set state here, don't sync notifier to PMIC */
773
- extcon_set_state(port->extcon, EXTCON_USB_VBUS_EN, enable);
774
- } else {
775
- extcon_set_state(port->extcon, EXTCON_USB_VBUS_EN, enable);
776
- extcon_sync(port->extcon, EXTCON_USB_VBUS_EN);
777
- tcpm_log(port, "tcpm driver send extcon to %s vbus 5v\n",
778
- enable ? "enable" : "disable");
779
- }
780
-
781
- port->vbus_on = enable;
782
-
783
-done:
784
- return ret;
785
-}
786
-
787
-static void tcpm_send_orientation_notify(struct tcpm_port *port)
788
-{
789
- union extcon_property_value property;
790
-
791
- property.intval = port->polarity;
792
- extcon_set_property(port->extcon, EXTCON_USB,
793
- EXTCON_PROP_USB_TYPEC_POLARITY, property);
794
- extcon_set_property(port->extcon, EXTCON_USB_HOST,
795
- EXTCON_PROP_USB_TYPEC_POLARITY, property);
796
- extcon_set_property(port->extcon, EXTCON_DISP_DP,
797
- EXTCON_PROP_USB_TYPEC_POLARITY, property);
798
-}
799
-
800
-static void tcpm_send_data_role_notify(struct tcpm_port *port, bool attached,
801
- enum typec_data_role data)
802
-{
803
- bool dfp = false;
804
- bool ufp = false;
805
-
806
- if (attached) {
807
- if (data == TYPEC_HOST)
808
- dfp = true;
809
- else
810
- ufp = true;
811
- }
812
- extcon_set_state(port->extcon, EXTCON_USB, ufp);
813
- extcon_set_state(port->extcon, EXTCON_USB_HOST, dfp);
814
- extcon_sync(port->extcon, EXTCON_USB);
815
- extcon_sync(port->extcon, EXTCON_USB_HOST);
816
-}
817
-
818
-static void tcpm_send_dp_notify(struct tcpm_port *port)
819
-{
820
- union extcon_property_value property;
821
- bool usb_ss = false;
822
- bool hpd = false;
823
-
824
- if (port->dp_configured) {
825
- usb_ss = (port->dp_pin_assignment &
826
- DP_PIN_ASSIGN_MULTI_FUNCTION_MASK) ? true : false;
827
- hpd = !!(port->dp_status & DP_STATUS_HPD_STATE);
828
- }
829
- property.intval = usb_ss;
830
- extcon_set_property(port->extcon, EXTCON_USB,
831
- EXTCON_PROP_USB_SS, property);
832
- extcon_set_property(port->extcon, EXTCON_USB_HOST,
833
- EXTCON_PROP_USB_SS, property);
834
- extcon_set_property(port->extcon, EXTCON_DISP_DP,
835
- EXTCON_PROP_USB_SS, property);
836
- extcon_set_state(port->extcon, EXTCON_DISP_DP, port->dp_configured && hpd);
837
- extcon_sync(port->extcon, EXTCON_DISP_DP);
838
-}
839
-
840
-static void tcpm_send_power_change_notify(struct tcpm_port *port)
841
-{
842
- union extcon_property_value property;
843
-
844
- property.intval = (port->current_limit << 15 | port->supply_voltage);
845
- extcon_set_property(port->extcon, EXTCON_CHG_USB_FAST,
846
- EXTCON_PROP_USB_TYPEC_POLARITY, property);
847
- extcon_set_state(port->extcon, EXTCON_CHG_USB_FAST, true);
848
- extcon_sync(port->extcon, EXTCON_CHG_USB_FAST);
849
-}
850
-
851784 static void tcpm_set_cc(struct tcpm_port *port, enum typec_cc_status cc)
852785 {
853786 tcpm_log(port, "cc:=%d", cc);
854787 port->cc_req = cc;
855788 port->tcpc->set_cc(port->tcpc, cc);
789
+}
790
+
791
+static int tcpm_enable_auto_vbus_discharge(struct tcpm_port *port, bool enable)
792
+{
793
+ int ret = 0;
794
+
795
+ if (port->tcpc->enable_auto_vbus_discharge) {
796
+ ret = port->tcpc->enable_auto_vbus_discharge(port->tcpc, enable);
797
+ tcpm_log_force(port, "%s vbus discharge ret:%d", enable ? "enable" : "disable",
798
+ ret);
799
+ if (!ret)
800
+ port->auto_vbus_discharge_enabled = enable;
801
+ }
802
+
803
+ return ret;
804
+}
805
+
806
+static void tcpm_apply_rc(struct tcpm_port *port)
807
+{
808
+ /*
809
+ * TCPCI: Move to APPLY_RC state to prevent disconnect during PR_SWAP
810
+ * when Vbus auto discharge on disconnect is enabled.
811
+ */
812
+ if (port->tcpc->enable_auto_vbus_discharge && port->tcpc->apply_rc) {
813
+ tcpm_log(port, "Apply_RC");
814
+ port->tcpc->apply_rc(port->tcpc, port->cc_req, port->polarity);
815
+ tcpm_enable_auto_vbus_discharge(port, false);
816
+ }
856817 }
857818
858819 /*
....@@ -888,10 +849,8 @@
888849 return TYPEC_CC_RP_DEF;
889850 }
890851
891
-static int tcpm_ams_finish(struct tcpm_port *port)
852
+static void tcpm_ams_finish(struct tcpm_port *port)
892853 {
893
- int ret = 0;
894
-
895854 tcpm_log(port, "AMS %s finished", tcpm_ams_str[port->ams]);
896855
897856 if (port->pd_capable && port->pwr_role == TYPEC_SOURCE) {
....@@ -905,8 +864,6 @@
905864
906865 port->in_ams = false;
907866 port->ams = NONE_AMS;
908
-
909
- return ret;
910867 }
911868
912869 static int tcpm_pd_transmit(struct tcpm_port *port,
....@@ -922,7 +879,7 @@
922879 tcpm_log(port, "PD TX, type: %#x", type);
923880
924881 reinit_completion(&port->tx_complete);
925
- ret = port->tcpc->pd_transmit(port->tcpc, type, msg);
882
+ ret = port->tcpc->pd_transmit(port->tcpc, type, msg, port->negotiated_rev);
926883 if (ret < 0)
927884 return ret;
928885
....@@ -1024,6 +981,21 @@
1024981 return ret;
1025982 }
1026983
984
+bool tcpm_is_debouncing(struct tcpm_port *port)
985
+{
986
+ bool debounce;
987
+
988
+ if (!port)
989
+ return false;
990
+
991
+ mutex_lock(&port->lock);
992
+ debounce = port->debouncing;
993
+ mutex_unlock(&port->lock);
994
+
995
+ return debounce;
996
+}
997
+EXPORT_SYMBOL_GPL(tcpm_is_debouncing);
998
+
1027999 static u32 tcpm_get_current_limit(struct tcpm_port *port)
10281000 {
10291001 enum typec_cc_status cc;
....@@ -1057,6 +1029,7 @@
10571029
10581030 port->supply_voltage = mv;
10591031 port->current_limit = max_ma;
1032
+ power_supply_changed(port->psy);
10601033
10611034 if (port->tcpc->set_current_limit)
10621035 ret = port->tcpc->set_current_limit(port->tcpc, max_ma, mv);
....@@ -1082,10 +1055,30 @@
10821055 else
10831056 orientation = TYPEC_ORIENTATION_REVERSE;
10841057
1085
- if (data == TYPEC_HOST)
1086
- usb_role = USB_ROLE_HOST;
1087
- else
1088
- usb_role = USB_ROLE_DEVICE;
1058
+ if (port->typec_caps.data == TYPEC_PORT_DRD) {
1059
+ if (data == TYPEC_HOST)
1060
+ usb_role = USB_ROLE_HOST;
1061
+ else
1062
+ usb_role = USB_ROLE_DEVICE;
1063
+ } else if (port->typec_caps.data == TYPEC_PORT_DFP) {
1064
+ if (data == TYPEC_HOST) {
1065
+ if (role == TYPEC_SOURCE)
1066
+ usb_role = USB_ROLE_HOST;
1067
+ else
1068
+ usb_role = USB_ROLE_NONE;
1069
+ } else {
1070
+ return -ENOTSUPP;
1071
+ }
1072
+ } else {
1073
+ if (data == TYPEC_DEVICE) {
1074
+ if (role == TYPEC_SINK)
1075
+ usb_role = USB_ROLE_DEVICE;
1076
+ else
1077
+ usb_role = USB_ROLE_NONE;
1078
+ } else {
1079
+ return -ENOTSUPP;
1080
+ }
1081
+ }
10891082
10901083 ret = tcpm_mux_set(port, TYPEC_STATE_USB, usb_role, orientation);
10911084 if (ret < 0)
....@@ -1118,13 +1111,47 @@
11181111 return 0;
11191112 }
11201113
1114
+/*
1115
+ * Transform the PDO to be compliant to PD rev2.0.
1116
+ * Return 0 if the PDO type is not defined in PD rev2.0.
1117
+ * Otherwise, return the converted PDO.
1118
+ */
1119
+static u32 tcpm_forge_legacy_pdo(struct tcpm_port *port, u32 pdo, enum typec_role role)
1120
+{
1121
+ switch (pdo_type(pdo)) {
1122
+ case PDO_TYPE_FIXED:
1123
+ if (role == TYPEC_SINK)
1124
+ return pdo & ~PDO_FIXED_FRS_CURR_MASK;
1125
+ else
1126
+ return pdo & ~PDO_FIXED_UNCHUNK_EXT;
1127
+ case PDO_TYPE_VAR:
1128
+ case PDO_TYPE_BATT:
1129
+ return pdo;
1130
+ case PDO_TYPE_APDO:
1131
+ default:
1132
+ return 0;
1133
+ }
1134
+}
1135
+
11211136 static int tcpm_pd_send_source_caps(struct tcpm_port *port)
11221137 {
11231138 struct pd_message msg;
1124
- int i;
1139
+ u32 pdo;
1140
+ unsigned int i, nr_pdo = 0;
11251141
11261142 memset(&msg, 0, sizeof(msg));
1127
- if (!port->nr_src_pdo) {
1143
+
1144
+ for (i = 0; i < port->nr_src_pdo; i++) {
1145
+ if (port->negotiated_rev >= PD_REV30) {
1146
+ msg.payload[nr_pdo++] = cpu_to_le32(port->src_pdo[i]);
1147
+ } else {
1148
+ pdo = tcpm_forge_legacy_pdo(port, port->src_pdo[i], TYPEC_SOURCE);
1149
+ if (pdo)
1150
+ msg.payload[nr_pdo++] = cpu_to_le32(pdo);
1151
+ }
1152
+ }
1153
+
1154
+ if (!nr_pdo) {
11281155 /* No source capabilities defined, sink only */
11291156 msg.header = PD_HEADER_LE(PD_CTRL_REJECT,
11301157 port->pwr_role,
....@@ -1137,10 +1164,8 @@
11371164 port->data_role,
11381165 port->negotiated_rev,
11391166 port->message_id,
1140
- port->nr_src_pdo);
1167
+ nr_pdo);
11411168 }
1142
- for (i = 0; i < port->nr_src_pdo; i++)
1143
- msg.payload[i] = cpu_to_le32(port->src_pdo[i]);
11441169
11451170 return tcpm_pd_transmit(port, TCPC_TX_SOP, &msg);
11461171 }
....@@ -1148,10 +1173,22 @@
11481173 static int tcpm_pd_send_sink_caps(struct tcpm_port *port)
11491174 {
11501175 struct pd_message msg;
1151
- int i;
1176
+ u32 pdo;
1177
+ unsigned int i, nr_pdo = 0;
11521178
11531179 memset(&msg, 0, sizeof(msg));
1154
- if (!port->nr_snk_pdo) {
1180
+
1181
+ for (i = 0; i < port->nr_snk_pdo; i++) {
1182
+ if (port->negotiated_rev >= PD_REV30) {
1183
+ msg.payload[nr_pdo++] = cpu_to_le32(port->snk_pdo[i]);
1184
+ } else {
1185
+ pdo = tcpm_forge_legacy_pdo(port, port->snk_pdo[i], TYPEC_SINK);
1186
+ if (pdo)
1187
+ msg.payload[nr_pdo++] = cpu_to_le32(pdo);
1188
+ }
1189
+ }
1190
+
1191
+ if (!nr_pdo) {
11551192 /* No sink capabilities defined, source only */
11561193 msg.header = PD_HEADER_LE(PD_CTRL_REJECT,
11571194 port->pwr_role,
....@@ -1164,10 +1201,8 @@
11641201 port->data_role,
11651202 port->negotiated_rev,
11661203 port->message_id,
1167
- port->nr_snk_pdo);
1204
+ nr_pdo);
11681205 }
1169
- for (i = 0; i < port->nr_snk_pdo; i++)
1170
- msg.payload[i] = cpu_to_le32(port->snk_pdo[i]);
11711206
11721207 return tcpm_pd_transmit(port, TCPC_TX_SOP, &msg);
11731208 }
....@@ -1203,14 +1238,13 @@
12031238 }
12041239 }
12051240
1206
-static void mod_data_role_swap_work(struct tcpm_port *port, unsigned int delay_ms)
1241
+static void mod_send_discover_delayed_work(struct tcpm_port *port, unsigned int delay_ms)
12071242 {
12081243 if (delay_ms) {
1209
- hrtimer_start(&port->data_role_swap_timer,
1210
- ms_to_ktime(delay_ms), HRTIMER_MODE_REL);
1244
+ hrtimer_start(&port->send_discover_timer, ms_to_ktime(delay_ms), HRTIMER_MODE_REL);
12111245 } else {
1212
- hrtimer_cancel(&port->data_role_swap_timer);
1213
- kthread_queue_work(port->wq, &port->data_role_swap);
1246
+ hrtimer_cancel(&port->send_discover_timer);
1247
+ kthread_queue_work(port->wq, &port->send_discover_work);
12141248 }
12151249 }
12161250
....@@ -1322,7 +1356,8 @@
13221356
13231357 tcpm_log(port, "AMS %s start", tcpm_ams_str[ams]);
13241358
1325
- if (!tcpm_ams_interruptible(port) && ams != HARD_RESET) {
1359
+ if (!tcpm_ams_interruptible(port) &&
1360
+ !(ams == HARD_RESET || ams == SOFT_RESET_AMS)) {
13261361 port->upcoming_state = INVALID_STATE;
13271362 tcpm_log(port, "AMS %s not interruptible, aborting",
13281363 tcpm_ams_str[port->ams]);
....@@ -1340,11 +1375,10 @@
13401375 tcpm_set_state(port, HARD_RESET_START, 0);
13411376 return ret;
13421377 } else if (ams == SOFT_RESET_AMS) {
1343
- if (!port->explicit_contract) {
1344
- port->upcoming_state = INVALID_STATE;
1378
+ if (!port->explicit_contract)
13451379 tcpm_set_cc(port, tcpm_rp_cc(port));
1346
- return ret;
1347
- }
1380
+ tcpm_set_state(port, SOFT_RESET_SEND, 0);
1381
+ return ret;
13481382 } else if (tcpm_vdm_ams(port)) {
13491383 /* tSinkTx is enforced in vdm_run_state_machine */
13501384 if (port->negotiated_rev >= PD_REV30)
....@@ -1413,24 +1447,48 @@
14131447 static void tcpm_queue_vdm(struct tcpm_port *port, const u32 header,
14141448 const u32 *data, int cnt)
14151449 {
1450
+ WARN_ON(!mutex_is_locked(&port->lock));
1451
+
1452
+ /* Make sure we are not still processing a previous VDM packet */
1453
+ WARN_ON(port->vdm_state > VDM_STATE_DONE);
1454
+
14161455 port->vdo_count = cnt + 1;
14171456 port->vdo_data[0] = header;
14181457 memcpy(&port->vdo_data[1], data, sizeof(u32) * cnt);
14191458 /* Set ready, vdm state machine will actually send */
14201459 port->vdm_retries = 0;
14211460 port->vdm_state = VDM_STATE_READY;
1461
+ port->vdm_sm_running = true;
1462
+
1463
+ mod_vdm_delayed_work(port, 0);
14221464 }
14231465
1424
-static void svdm_consume_identity(struct tcpm_port *port, const __le32 *payload,
1425
- int cnt)
1466
+static void tcpm_queue_vdm_unlocked(struct tcpm_port *port, const u32 header,
1467
+ const u32 *data, int cnt)
14261468 {
1427
- u32 vdo = le32_to_cpu(payload[VDO_INDEX_IDH]);
1428
- u32 product = le32_to_cpu(payload[VDO_INDEX_PRODUCT]);
1469
+#ifdef CONFIG_NO_GKI
1470
+ mutex_lock(&port->pd_handler_lock);
1471
+ if (tcpm_port_is_disconnected(port))
1472
+ goto unlock;
1473
+#endif
1474
+ mutex_lock(&port->lock);
1475
+ tcpm_queue_vdm(port, header, data, cnt);
1476
+ mutex_unlock(&port->lock);
1477
+#ifdef CONFIG_NO_GKI
1478
+unlock:
1479
+ mutex_unlock(&port->pd_handler_lock);
1480
+#endif
1481
+}
1482
+
1483
+static void svdm_consume_identity(struct tcpm_port *port, const u32 *p, int cnt)
1484
+{
1485
+ u32 vdo = p[VDO_INDEX_IDH];
1486
+ u32 product = p[VDO_INDEX_PRODUCT];
14291487
14301488 memset(&port->mode_data, 0, sizeof(port->mode_data));
14311489
14321490 port->partner_ident.id_header = vdo;
1433
- port->partner_ident.cert_stat = le32_to_cpu(payload[VDO_INDEX_CSTAT]);
1491
+ port->partner_ident.cert_stat = p[VDO_INDEX_CSTAT];
14341492 port->partner_ident.product = product;
14351493
14361494 typec_partner_set_identity(port->partner);
....@@ -1440,17 +1498,15 @@
14401498 PD_PRODUCT_PID(product), product & 0xffff);
14411499 }
14421500
1443
-static bool svdm_consume_svids(struct tcpm_port *port, const __le32 *payload,
1444
- int cnt)
1501
+static bool svdm_consume_svids(struct tcpm_port *port, const u32 *p, int cnt)
14451502 {
14461503 struct pd_mode_data *pmdata = &port->mode_data;
14471504 int i;
14481505
14491506 for (i = 1; i < cnt; i++) {
1450
- u32 p = le32_to_cpu(payload[i]);
14511507 u16 svid;
14521508
1453
- svid = (p >> 16) & 0xffff;
1509
+ svid = (p[i] >> 16) & 0xffff;
14541510 if (!svid)
14551511 return false;
14561512
....@@ -1460,7 +1516,7 @@
14601516 pmdata->svids[pmdata->nsvids++] = svid;
14611517 tcpm_log(port, "SVID %d: 0x%x", pmdata->nsvids, svid);
14621518
1463
- svid = p & 0xffff;
1519
+ svid = p[i] & 0xffff;
14641520 if (!svid)
14651521 return false;
14661522
....@@ -1470,14 +1526,27 @@
14701526 pmdata->svids[pmdata->nsvids++] = svid;
14711527 tcpm_log(port, "SVID %d: 0x%x", pmdata->nsvids, svid);
14721528 }
1473
- return true;
1529
+
1530
+ /*
1531
+ * PD3.0 Spec 6.4.4.3.2: The SVIDs are returned 2 per VDO (see Table
1532
+ * 6-43), and can be returned maximum 6 VDOs per response (see Figure
1533
+ * 6-19). If the Respondersupports 12 or more SVID then the Discover
1534
+ * SVIDs Command Shall be executed multiple times until a Discover
1535
+ * SVIDs VDO is returned ending either with a SVID value of 0x0000 in
1536
+ * the last part of the last VDO or with a VDO containing two SVIDs
1537
+ * with values of 0x0000.
1538
+ *
1539
+ * However, some odd dockers support SVIDs less than 12 but without
1540
+ * 0x0000 in the last VDO, so we need to break the Discover SVIDs
1541
+ * request and return false here.
1542
+ */
1543
+ return cnt == 7 ? true : false;
14741544 abort:
14751545 tcpm_log(port, "SVID_DISCOVERY_MAX(%d) too low!", SVID_DISCOVERY_MAX);
14761546 return false;
14771547 }
14781548
1479
-static void svdm_consume_modes(struct tcpm_port *port, const __le32 *payload,
1480
- int cnt)
1549
+static void svdm_consume_modes(struct tcpm_port *port, const u32 *p, int cnt)
14811550 {
14821551 struct pd_mode_data *pmdata = &port->mode_data;
14831552 struct typec_altmode_desc *paltmode;
....@@ -1494,7 +1563,7 @@
14941563
14951564 paltmode->svid = pmdata->svids[pmdata->svid_index];
14961565 paltmode->mode = i;
1497
- paltmode->vdo = le32_to_cpu(payload[i]);
1566
+ paltmode->vdo = p[i];
14981567
14991568 tcpm_log(port, " Alternate mode %d: SVID 0x%04x, VDO %d: 0x%08x",
15001569 pmdata->altmodes, paltmode->svid,
....@@ -1513,29 +1582,29 @@
15131582 for (i = 0; i < modep->altmodes; i++) {
15141583 altmode = typec_partner_register_altmode(port->partner,
15151584 &modep->altmode_desc[i]);
1516
- if (!altmode)
1585
+ if (IS_ERR(altmode)) {
15171586 tcpm_log(port, "Failed to register partner SVID 0x%04x",
15181587 modep->altmode_desc[i].svid);
1588
+ altmode = NULL;
1589
+ }
15191590 port->partner_altmode[i] = altmode;
15201591 }
15211592 }
15221593
15231594 #define supports_modal(port) PD_IDH_MODAL_SUPP((port)->partner_ident.id_header)
15241595
1525
-static int tcpm_pd_svdm(struct tcpm_port *port, const __le32 *payload, int cnt,
1526
- u32 *response)
1596
+static int tcpm_pd_svdm(struct tcpm_port *port, struct typec_altmode *adev,
1597
+ const u32 *p, int cnt, u32 *response,
1598
+ enum adev_actions *adev_action)
15271599 {
1528
- struct typec_altmode *adev;
1600
+ struct typec_port *typec = port->typec_port;
15291601 struct typec_altmode *pdev;
15301602 struct pd_mode_data *modep;
1531
- u32 p[PD_MAX_PAYLOAD];
1603
+ int svdm_version;
15321604 int rlen = 0;
15331605 int cmd_type;
15341606 int cmd;
15351607 int i;
1536
-
1537
- for (i = 0; i < cnt; i++)
1538
- p[i] = le32_to_cpu(payload[i]);
15391608
15401609 cmd_type = PD_VDO_CMDT(p[0]);
15411610 cmd = PD_VDO_CMD(p[0]);
....@@ -1545,36 +1614,61 @@
15451614
15461615 modep = &port->mode_data;
15471616
1548
- adev = typec_match_altmode(port->port_altmode, ALTMODE_DISCOVERY_MAX,
1549
- PD_VDO_VID(p[0]), PD_VDO_OPOS(p[0]));
1550
-
15511617 pdev = typec_match_altmode(port->partner_altmode, ALTMODE_DISCOVERY_MAX,
15521618 PD_VDO_VID(p[0]), PD_VDO_OPOS(p[0]));
1619
+
1620
+ svdm_version = typec_get_negotiated_svdm_version(typec);
1621
+ if (svdm_version < 0)
1622
+ return 0;
15531623
15541624 switch (cmd_type) {
15551625 case CMDT_INIT:
15561626 switch (cmd) {
15571627 case CMD_DISCOVER_IDENT:
1558
- /* 6.4.4.3.1: Only respond as UFP (device) */
1559
- if (port->data_role == TYPEC_DEVICE &&
1628
+ if (PD_VDO_VID(p[0]) != USB_SID_PD)
1629
+ break;
1630
+
1631
+ if (PD_VDO_SVDM_VER(p[0]) < svdm_version) {
1632
+ typec_partner_set_svdm_version(port->partner,
1633
+ PD_VDO_SVDM_VER(p[0]));
1634
+ svdm_version = PD_VDO_SVDM_VER(p[0]);
1635
+ }
1636
+
1637
+ port->ams = DISCOVER_IDENTITY;
1638
+ /*
1639
+ * PD2.0 Spec 6.10.3: respond with NAK as DFP (data host)
1640
+ * PD3.1 Spec 6.4.4.2.5.1: respond with NAK if "invalid field" or
1641
+ * "wrong configuation" or "Unrecognized"
1642
+ */
1643
+ if ((port->data_role == TYPEC_DEVICE || svdm_version >= SVDM_VER_2_0) &&
15601644 port->nr_snk_vdo) {
1561
- for (i = 0; i < port->nr_snk_vdo; i++)
1562
- response[i + 1] = port->snk_vdo[i];
1563
- rlen = port->nr_snk_vdo + 1;
1645
+ if (svdm_version < SVDM_VER_2_0) {
1646
+ for (i = 0; i < port->nr_snk_vdo_v1; i++)
1647
+ response[i + 1] = port->snk_vdo_v1[i];
1648
+ rlen = port->nr_snk_vdo_v1 + 1;
1649
+
1650
+ } else {
1651
+ for (i = 0; i < port->nr_snk_vdo; i++)
1652
+ response[i + 1] = port->snk_vdo[i];
1653
+ rlen = port->nr_snk_vdo + 1;
1654
+ }
15641655 }
15651656 break;
15661657 case CMD_DISCOVER_SVID:
1658
+ port->ams = DISCOVER_SVIDS;
15671659 break;
15681660 case CMD_DISCOVER_MODES:
1661
+ port->ams = DISCOVER_MODES;
15691662 break;
15701663 case CMD_ENTER_MODE:
1664
+ port->ams = DFP_TO_UFP_ENTER_MODE;
15711665 break;
15721666 case CMD_EXIT_MODE:
1667
+ port->ams = DFP_TO_UFP_EXIT_MODE;
15731668 break;
15741669 case CMD_ATTENTION:
15751670 /* Attention command does not have response */
1576
- if (adev)
1577
- typec_altmode_attention(adev, p[1]);
1671
+ *adev_action = ADEV_ATTENTION;
15781672 return 0;
15791673 default:
15801674 break;
....@@ -1588,6 +1682,8 @@
15881682 response[0] = p[0] | VDO_CMDT(CMDT_RSP_BUSY);
15891683 rlen = 1;
15901684 }
1685
+ response[0] = (response[0] & ~VDO_SVDM_VERS_MASK) |
1686
+ (VDO_SVDM_VERS(typec_get_negotiated_svdm_version(typec)));
15911687 break;
15921688 case CMDT_RSP_ACK:
15931689 /* silently drop message if we are not connected */
....@@ -1598,101 +1694,121 @@
15981694
15991695 switch (cmd) {
16001696 case CMD_DISCOVER_IDENT:
1697
+ if (PD_VDO_SVDM_VER(p[0]) < svdm_version)
1698
+ typec_partner_set_svdm_version(port->partner,
1699
+ PD_VDO_SVDM_VER(p[0]));
16011700 /* 6.4.4.3.1 */
1602
- svdm_consume_identity(port, payload, cnt);
1603
- response[0] = VDO(USB_SID_PD, 1, CMD_DISCOVER_SVID);
1701
+ svdm_consume_identity(port, p, cnt);
1702
+ response[0] = VDO(USB_SID_PD, 1, typec_get_negotiated_svdm_version(typec),
1703
+ CMD_DISCOVER_SVID);
16041704 rlen = 1;
16051705 break;
16061706 case CMD_DISCOVER_SVID:
16071707 /* 6.4.4.3.2 */
1608
- if (svdm_consume_svids(port, payload, cnt)) {
1609
- response[0] = VDO(USB_SID_PD, 1,
1610
- CMD_DISCOVER_SVID);
1708
+ if (svdm_consume_svids(port, p, cnt)) {
1709
+ response[0] = VDO(USB_SID_PD, 1, svdm_version, CMD_DISCOVER_SVID);
16111710 rlen = 1;
16121711 } else if (modep->nsvids && supports_modal(port)) {
1613
- response[0] = VDO(modep->svids[0], 1,
1712
+ response[0] = VDO(modep->svids[0], 1, svdm_version,
16141713 CMD_DISCOVER_MODES);
16151714 rlen = 1;
16161715 }
16171716 break;
16181717 case CMD_DISCOVER_MODES:
16191718 /* 6.4.4.3.3 */
1620
- svdm_consume_modes(port, payload, cnt);
1719
+ svdm_consume_modes(port, p, cnt);
16211720 modep->svid_index++;
16221721 if (modep->svid_index < modep->nsvids) {
16231722 u16 svid = modep->svids[modep->svid_index];
1624
- response[0] = VDO(svid, 1, CMD_DISCOVER_MODES);
1723
+ response[0] = VDO(svid, 1, svdm_version, CMD_DISCOVER_MODES);
16251724 rlen = 1;
1626
- } else {
1725
+ } else if (port->data_role == TYPEC_HOST) {
16271726 tcpm_register_partner_altmodes(port);
1628
- port->vdm_sm_running = false;
16291727 }
16301728 break;
16311729 case CMD_ENTER_MODE:
16321730 if (adev && pdev) {
16331731 typec_altmode_update_active(pdev, true);
1634
-
1635
- if (typec_altmode_vdm(adev, p[0], &p[1], cnt)) {
1636
- response[0] = VDO(adev->svid, 1,
1637
- CMD_EXIT_MODE);
1638
- response[0] |= VDO_OPOS(adev->mode);
1639
- return 1;
1640
- }
1732
+ *adev_action = ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL;
16411733 }
16421734 return 0;
16431735 case CMD_EXIT_MODE:
16441736 if (adev && pdev) {
16451737 typec_altmode_update_active(pdev, false);
1646
-
16471738 /* Back to USB Operation */
1648
- WARN_ON(typec_altmode_notify(adev,
1649
- TYPEC_STATE_USB,
1650
- NULL));
1739
+ *adev_action = ADEV_NOTIFY_USB_AND_QUEUE_VDM;
1740
+ return 0;
16511741 }
16521742 break;
1743
+ case VDO_CMD_VENDOR(0) ... VDO_CMD_VENDOR(15):
1744
+ break;
16531745 default:
1746
+ /* Unrecognized SVDM */
1747
+ response[0] = p[0] | VDO_CMDT(CMDT_RSP_NAK);
1748
+ rlen = 1;
1749
+ response[0] = (response[0] & ~VDO_SVDM_VERS_MASK) |
1750
+ (VDO_SVDM_VERS(svdm_version));
16541751 break;
16551752 }
16561753 break;
16571754 case CMDT_RSP_NAK:
16581755 tcpm_ams_finish(port);
16591756 switch (cmd) {
1757
+ case CMD_DISCOVER_IDENT:
1758
+ case CMD_DISCOVER_SVID:
1759
+ case CMD_DISCOVER_MODES:
1760
+ case VDO_CMD_VENDOR(0) ... VDO_CMD_VENDOR(15):
1761
+ break;
16601762 case CMD_ENTER_MODE:
16611763 /* Back to USB Operation */
1662
- if (adev)
1663
- WARN_ON(typec_altmode_notify(adev,
1664
- TYPEC_STATE_USB,
1665
- NULL));
1666
- break;
1764
+ *adev_action = ADEV_NOTIFY_USB_AND_QUEUE_VDM;
1765
+ return 0;
16671766 default:
1767
+ /* Unrecognized SVDM */
1768
+ response[0] = p[0] | VDO_CMDT(CMDT_RSP_NAK);
1769
+ rlen = 1;
1770
+ response[0] = (response[0] & ~VDO_SVDM_VERS_MASK) |
1771
+ (VDO_SVDM_VERS(svdm_version));
16681772 break;
16691773 }
1670
- port->vdm_sm_running = false;
16711774 break;
16721775 default:
1673
- port->vdm_sm_running = false;
1776
+ response[0] = p[0] | VDO_CMDT(CMDT_RSP_NAK);
1777
+ rlen = 1;
1778
+ response[0] = (response[0] & ~VDO_SVDM_VERS_MASK) |
1779
+ (VDO_SVDM_VERS(svdm_version));
16741780 break;
16751781 }
16761782
16771783 /* Informing the alternate mode drivers about everything */
1678
- if (adev)
1679
- typec_altmode_vdm(adev, p[0], &p[1], cnt);
1680
-
1784
+ *adev_action = ADEV_QUEUE_VDM;
16811785 return rlen;
16821786 }
1787
+
1788
+static void tcpm_pd_handle_msg(struct tcpm_port *port,
1789
+ enum pd_msg_request message,
1790
+ enum tcpm_ams ams);
16831791
16841792 static void tcpm_handle_vdm_request(struct tcpm_port *port,
16851793 const __le32 *payload, int cnt)
16861794 {
1687
- int rlen = 0;
1795
+ enum adev_actions adev_action = ADEV_NONE;
1796
+ struct typec_altmode *adev;
1797
+ u32 p[PD_MAX_PAYLOAD];
16881798 u32 response[8] = { };
1689
- u32 p0 = le32_to_cpu(payload[0]);
1799
+ int i, rlen = 0;
1800
+
1801
+ for (i = 0; i < cnt; i++)
1802
+ p[i] = le32_to_cpu(payload[i]);
1803
+
1804
+ adev = typec_match_altmode(port->port_altmode, ALTMODE_DISCOVERY_MAX,
1805
+ PD_VDO_VID(p[0]), PD_VDO_OPOS(p[0]));
16901806
16911807 if (port->vdm_state == VDM_STATE_BUSY) {
16921808 /* If UFP responded busy retry after timeout */
1693
- if (PD_VDO_CMDT(p0) == CMDT_RSP_BUSY) {
1809
+ if (PD_VDO_CMDT(p[0]) == CMDT_RSP_BUSY) {
16941810 port->vdm_state = VDM_STATE_WAIT_RSP_BUSY;
1695
- port->vdo_retry = (p0 & ~VDO_CMDT_MASK) |
1811
+ port->vdo_retry = (p[0] & ~VDO_CMDT_MASK) |
16961812 CMDT_INIT;
16971813 mod_vdm_delayed_work(port, PD_T_VDM_BUSY);
16981814 return;
....@@ -1700,29 +1816,110 @@
17001816 port->vdm_state = VDM_STATE_DONE;
17011817 }
17021818
1703
- if (PD_VDO_SVDM(p0))
1704
- rlen = tcpm_pd_svdm(port, payload, cnt, response);
1705
-
1706
- if (rlen > 0) {
1707
- tcpm_queue_vdm(port, response[0], &response[1], rlen - 1);
1708
- mod_vdm_delayed_work(port, 0);
1819
+ if (PD_VDO_SVDM(p[0]) && (adev || tcpm_vdm_ams(port) || port->nr_snk_vdo)) {
1820
+ /*
1821
+ * Here a SVDM is received (INIT or RSP or unknown). Set the vdm_sm_running in
1822
+ * advance because we are dropping the lock but may send VDMs soon.
1823
+ * For the cases of INIT received:
1824
+ * - If no response to send, it will be cleared later in this function.
1825
+ * - If there are responses to send, it will be cleared in the state machine.
1826
+ * For the cases of RSP received:
1827
+ * - If no further INIT to send, it will be cleared later in this function.
1828
+ * - Otherwise, it will be cleared in the state machine if timeout or it will go
1829
+ * back here until no further INIT to send.
1830
+ * For the cases of unknown type received:
1831
+ * - We will send NAK and the flag will be cleared in the state machine.
1832
+ */
1833
+ port->vdm_sm_running = true;
1834
+ rlen = tcpm_pd_svdm(port, adev, p, cnt, response, &adev_action);
1835
+ } else {
1836
+ if (port->negotiated_rev >= PD_REV30)
1837
+ tcpm_pd_handle_msg(port, PD_MSG_CTRL_NOT_SUPP, NONE_AMS);
17091838 }
1839
+
1840
+ /*
1841
+ * We are done with any state stored in the port struct now, except
1842
+ * for any port struct changes done by the tcpm_queue_vdm() call
1843
+ * below, which is a separate operation.
1844
+ *
1845
+ * So we can safely release the lock here; and we MUST release the
1846
+ * lock here to avoid an AB BA lock inversion:
1847
+ *
1848
+ * If we keep the lock here then the lock ordering in this path is:
1849
+ * 1. tcpm_pd_rx_handler take the tcpm port lock
1850
+ * 2. One of the typec_altmode_* calls below takes the alt-mode's lock
1851
+ *
1852
+ * And we also have this ordering:
1853
+ * 1. alt-mode driver takes the alt-mode's lock
1854
+ * 2. alt-mode driver calls tcpm_altmode_enter which takes the
1855
+ * tcpm port lock
1856
+ *
1857
+ * Dropping our lock here avoids this.
1858
+ */
1859
+ mutex_unlock(&port->lock);
1860
+
1861
+ if (adev) {
1862
+ switch (adev_action) {
1863
+ case ADEV_NONE:
1864
+ break;
1865
+ case ADEV_NOTIFY_USB_AND_QUEUE_VDM:
1866
+ WARN_ON(typec_altmode_notify(adev, TYPEC_STATE_USB, NULL));
1867
+ typec_altmode_vdm(adev, p[0], &p[1], cnt);
1868
+ break;
1869
+ case ADEV_QUEUE_VDM:
1870
+ typec_altmode_vdm(adev, p[0], &p[1], cnt);
1871
+ break;
1872
+ case ADEV_QUEUE_VDM_SEND_EXIT_MODE_ON_FAIL:
1873
+ if (typec_altmode_vdm(adev, p[0], &p[1], cnt)) {
1874
+ int svdm_version = typec_get_negotiated_svdm_version(
1875
+ port->typec_port);
1876
+ if (svdm_version < 0)
1877
+ break;
1878
+
1879
+ response[0] = VDO(adev->svid, 1, svdm_version,
1880
+ CMD_EXIT_MODE);
1881
+ response[0] |= VDO_OPOS(adev->mode);
1882
+ rlen = 1;
1883
+ }
1884
+ break;
1885
+ case ADEV_ATTENTION:
1886
+ typec_altmode_attention(adev, p[1]);
1887
+ break;
1888
+ }
1889
+ }
1890
+
1891
+ /*
1892
+ * We must re-take the lock here to balance the unlock in
1893
+ * tcpm_pd_rx_handler, note that no changes, other then the
1894
+ * tcpm_queue_vdm call, are made while the lock is held again.
1895
+ * All that is done after the call is unwinding the call stack until
1896
+ * we return to tcpm_pd_rx_handler and do the unlock there.
1897
+ */
1898
+ mutex_lock(&port->lock);
1899
+
1900
+ if (rlen > 0)
1901
+ tcpm_queue_vdm(port, response[0], &response[1], rlen - 1);
1902
+ else
1903
+ port->vdm_sm_running = false;
17101904 }
17111905
17121906 static void tcpm_send_vdm(struct tcpm_port *port, u32 vid, int cmd,
17131907 const u32 *data, int count)
17141908 {
1909
+ int svdm_version = typec_get_negotiated_svdm_version(port->typec_port);
17151910 u32 header;
1911
+
1912
+ if (svdm_version < 0)
1913
+ return;
17161914
17171915 if (WARN_ON(count > VDO_MAX_SIZE - 1))
17181916 count = VDO_MAX_SIZE - 1;
17191917
17201918 /* set VDM header with VID & CMD */
17211919 header = VDO(vid, ((vid & USB_SID_PD) == USB_SID_PD) ?
1722
- 1 : (PD_VDO_CMD(cmd) <= CMD_ATTENTION), cmd);
1920
+ 1 : (PD_VDO_CMD(cmd) <= CMD_ATTENTION),
1921
+ svdm_version, cmd);
17231922 tcpm_queue_vdm(port, header, data, count);
1724
-
1725
- mod_vdm_delayed_work(port, 0);
17261923 }
17271924
17281925 static unsigned int vdm_ready_timeout(u32 vdm_hdr)
....@@ -1769,8 +1966,10 @@
17691966 * if there's traffic or we're not in PDO ready state don't send
17701967 * a VDM.
17711968 */
1772
- if (port->state != SRC_READY && port->state != SNK_READY)
1969
+ if (port->state != SRC_READY && port->state != SNK_READY) {
1970
+ port->vdm_sm_running = false;
17731971 break;
1972
+ }
17741973
17751974 /* TODO: AMS operation for Unstructured VDM */
17761975 if (PD_VDO_SVDM(vdo_hdr) && PD_VDO_CMDT(vdo_hdr) == CMDT_INIT) {
....@@ -1779,6 +1978,9 @@
17791978 res = tcpm_ams_start(port, DISCOVER_IDENTITY);
17801979 if (res == 0)
17811980 port->send_discover = false;
1981
+ else if (res == -EAGAIN)
1982
+ mod_send_discover_delayed_work(port,
1983
+ SEND_DISCOVER_RETRY_MS);
17821984 break;
17831985 case CMD_DISCOVER_SVID:
17841986 res = tcpm_ams_start(port, DISCOVER_SVIDS);
....@@ -1804,7 +2006,7 @@
18042006 }
18052007
18062008 if (res < 0) {
1807
- port->vdm_sm_running = false;
2009
+ port->vdm_state = VDM_STATE_ERR_BUSY;
18082010 return;
18092011 }
18102012 }
....@@ -1820,6 +2022,7 @@
18202022 port->vdo_data[0] = port->vdo_retry;
18212023 port->vdo_count = 1;
18222024 port->vdm_state = VDM_STATE_READY;
2025
+ tcpm_ams_finish(port);
18232026 break;
18242027 case VDM_STATE_BUSY:
18252028 port->vdm_state = VDM_STATE_ERR_TMOUT;
....@@ -1888,7 +2091,7 @@
18882091 port->vdm_state != VDM_STATE_BUSY &&
18892092 port->vdm_state != VDM_STATE_SEND_MESSAGE);
18902093
1891
- if (port->vdm_state == VDM_STATE_ERR_TMOUT)
2094
+ if (port->vdm_state < VDM_STATE_READY)
18922095 port->vdm_sm_running = false;
18932096
18942097 mutex_unlock(&port->lock);
....@@ -2014,101 +2217,46 @@
20142217 return 0;
20152218 }
20162219
2017
-static int tcpm_altmode_enter(struct typec_altmode *altmode)
2220
+static int tcpm_altmode_enter(struct typec_altmode *altmode, u32 *vdo)
20182221 {
20192222 struct tcpm_port *port = typec_altmode_get_drvdata(altmode);
2223
+ int svdm_version;
20202224 u32 header;
2021
- int ret = 0;
20222225
2023
- mutex_lock(&port->pd_handler_lock);
2024
- if (tcpm_port_is_disconnected(port)) {
2025
- ret = -ENODEV;
2026
- goto unlock;
2027
- }
2226
+ svdm_version = typec_get_negotiated_svdm_version(port->typec_port);
2227
+ if (svdm_version < 0)
2228
+ return svdm_version;
20282229
2029
- mutex_lock(&port->lock);
2030
- header = VDO(altmode->svid, 1, CMD_ENTER_MODE);
2230
+ header = VDO(altmode->svid, vdo ? 2 : 1, svdm_version, CMD_ENTER_MODE);
20312231 header |= VDO_OPOS(altmode->mode);
20322232
2033
- tcpm_queue_vdm(port, header, NULL, 0);
2034
- mod_vdm_delayed_work(port, 0);
2035
- mutex_unlock(&port->lock);
2036
-unlock:
2037
- mutex_unlock(&port->pd_handler_lock);
2038
- return ret;
2233
+ tcpm_queue_vdm_unlocked(port, header, vdo, vdo ? 1 : 0);
2234
+ return 0;
20392235 }
20402236
20412237 static int tcpm_altmode_exit(struct typec_altmode *altmode)
20422238 {
20432239 struct tcpm_port *port = typec_altmode_get_drvdata(altmode);
2240
+ int svdm_version;
20442241 u32 header;
2045
- int ret = 0;
20462242
2047
- mutex_lock(&port->pd_handler_lock);
2048
- if (tcpm_port_is_disconnected(port)) {
2049
- ret = -ENODEV;
2050
- goto unlock;
2051
- }
2243
+ svdm_version = typec_get_negotiated_svdm_version(port->typec_port);
2244
+ if (svdm_version < 0)
2245
+ return svdm_version;
20522246
2053
- mutex_lock(&port->lock);
2054
- header = VDO(altmode->svid, 1, CMD_EXIT_MODE);
2247
+ header = VDO(altmode->svid, 1, svdm_version, CMD_EXIT_MODE);
20552248 header |= VDO_OPOS(altmode->mode);
20562249
2057
- tcpm_queue_vdm(port, header, NULL, 0);
2058
- mod_vdm_delayed_work(port, 0);
2059
- mutex_unlock(&port->lock);
2060
-
2061
-unlock:
2062
- mutex_unlock(&port->pd_handler_lock);
2063
- return ret;
2250
+ tcpm_queue_vdm_unlocked(port, header, NULL, 0);
2251
+ return 0;
20642252 }
20652253
20662254 static int tcpm_altmode_vdm(struct typec_altmode *altmode,
20672255 u32 header, const u32 *data, int count)
20682256 {
20692257 struct tcpm_port *port = typec_altmode_get_drvdata(altmode);
2070
- int ret = 0;
20712258
2072
- mutex_lock(&port->pd_handler_lock);
2073
- if (tcpm_port_is_disconnected(port)) {
2074
- ret = -ENODEV;
2075
- goto unlock;
2076
- }
2077
-
2078
- mutex_lock(&port->lock);
2079
- tcpm_queue_vdm(port, header, data, count - 1);
2080
- mod_vdm_delayed_work(port, 0);
2081
- mutex_unlock(&port->lock);
2082
-
2083
-unlock:
2084
- mutex_unlock(&port->pd_handler_lock);
2085
- return ret;
2086
-}
2087
-
2088
-static int tcpm_altmode_notify(struct typec_altmode *altmode,
2089
- unsigned long conf, void *data)
2090
-{
2091
- struct tcpm_port *port = typec_altmode_get_drvdata(altmode);
2092
- struct typec_displayport_data *dp_data = data;
2093
-
2094
- if ((conf >= TYPEC_DP_STATE_A) && (conf <= TYPEC_DP_STATE_F)) {
2095
- if (port->dp_configured) {
2096
- port->dp_status = dp_data->status;
2097
- tcpm_send_dp_notify(port);
2098
- dev_info(port->dev, "dp_status %x\n", dp_data->status);
2099
- } else {
2100
- port->dp_pin_assignment = dp_data->conf;
2101
- port->dp_configured = true;
2102
- dev_info(port->dev, "DP pin assignment 0x%x\n",
2103
- port->dp_pin_assignment);
2104
- }
2105
- } else if ((conf == TYPEC_STATE_USB) && (port->dp_configured)) {
2106
- /* may receive ufp device response Exit Mode Command Ack */
2107
- port->dp_status = 0;
2108
- port->dp_pin_assignment = 0;
2109
- port->dp_configured = false;
2110
- tcpm_send_dp_notify(port);
2111
- }
2259
+ tcpm_queue_vdm_unlocked(port, header, data, count - 1);
21122260
21132261 return 0;
21142262 }
....@@ -2117,7 +2265,6 @@
21172265 .enter = tcpm_altmode_enter,
21182266 .exit = tcpm_altmode_exit,
21192267 .vdm = tcpm_altmode_vdm,
2120
- .notify = tcpm_altmode_notify,
21212268 };
21222269
21232270 /*
....@@ -2142,20 +2289,108 @@
21422289
21432290 if (!type) {
21442291 tcpm_log(port, "Alert message received with no type");
2292
+ tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP);
21452293 return;
21462294 }
21472295
21482296 /* Just handling non-battery alerts for now */
21492297 if (!(type & USB_PD_ADO_TYPE_BATT_STATUS_CHANGE)) {
2150
- switch (port->state) {
2151
- case SRC_READY:
2152
- case SNK_READY:
2298
+ if (port->pwr_role == TYPEC_SOURCE) {
2299
+ port->upcoming_state = GET_STATUS_SEND;
2300
+ tcpm_ams_start(port, GETTING_SOURCE_SINK_STATUS);
2301
+ } else {
2302
+ /*
2303
+ * Do not check SinkTxOk here in case the Source doesn't set its Rp to
2304
+ * SinkTxOk in time.
2305
+ */
2306
+ port->ams = GETTING_SOURCE_SINK_STATUS;
21532307 tcpm_set_state(port, GET_STATUS_SEND, 0);
2154
- break;
2155
- default:
2156
- tcpm_queue_message(port, PD_MSG_CTRL_WAIT);
2157
- break;
21582308 }
2309
+ } else {
2310
+ tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP);
2311
+ }
2312
+}
2313
+
2314
+static int tcpm_set_auto_vbus_discharge_threshold(struct tcpm_port *port,
2315
+ enum typec_pwr_opmode mode, bool pps_active,
2316
+ u32 requested_vbus_voltage)
2317
+{
2318
+ int ret;
2319
+
2320
+ if (!port->tcpc->set_auto_vbus_discharge_threshold)
2321
+ return 0;
2322
+
2323
+ ret = port->tcpc->set_auto_vbus_discharge_threshold(port->tcpc, mode, pps_active,
2324
+ requested_vbus_voltage);
2325
+ tcpm_log_force(port,
2326
+ "set_auto_vbus_discharge_threshold mode:%d pps_active:%c vbus:%u ret:%d",
2327
+ mode, pps_active ? 'y' : 'n', requested_vbus_voltage, ret);
2328
+
2329
+ return ret;
2330
+}
2331
+
2332
+static void tcpm_pd_handle_state(struct tcpm_port *port,
2333
+ enum tcpm_state state,
2334
+ enum tcpm_ams ams,
2335
+ unsigned int delay_ms)
2336
+{
2337
+ switch (port->state) {
2338
+ case SRC_READY:
2339
+ case SNK_READY:
2340
+ port->ams = ams;
2341
+ tcpm_set_state(port, state, delay_ms);
2342
+ break;
2343
+ /* 8.3.3.4.1.1 and 6.8.1 power transitioning */
2344
+ case SNK_TRANSITION_SINK:
2345
+ case SNK_TRANSITION_SINK_VBUS:
2346
+ case SRC_TRANSITION_SUPPLY:
2347
+ tcpm_set_state(port, HARD_RESET_SEND, 0);
2348
+ break;
2349
+ default:
2350
+ if (!tcpm_ams_interruptible(port)) {
2351
+ tcpm_set_state(port, port->pwr_role == TYPEC_SOURCE ?
2352
+ SRC_SOFT_RESET_WAIT_SNK_TX :
2353
+ SNK_SOFT_RESET,
2354
+ 0);
2355
+ } else {
2356
+ /* process the Message 6.8.1 */
2357
+ port->upcoming_state = state;
2358
+ port->next_ams = ams;
2359
+ tcpm_set_state(port, ready_state(port), delay_ms);
2360
+ }
2361
+ break;
2362
+ }
2363
+}
2364
+
2365
+static void tcpm_pd_handle_msg(struct tcpm_port *port,
2366
+ enum pd_msg_request message,
2367
+ enum tcpm_ams ams)
2368
+{
2369
+ switch (port->state) {
2370
+ case SRC_READY:
2371
+ case SNK_READY:
2372
+ port->ams = ams;
2373
+ tcpm_queue_message(port, message);
2374
+ break;
2375
+ /* PD 3.0 Spec 8.3.3.4.1.1 and 6.8.1 */
2376
+ case SNK_TRANSITION_SINK:
2377
+ case SNK_TRANSITION_SINK_VBUS:
2378
+ case SRC_TRANSITION_SUPPLY:
2379
+ tcpm_set_state(port, HARD_RESET_SEND, 0);
2380
+ break;
2381
+ default:
2382
+ if (!tcpm_ams_interruptible(port)) {
2383
+ tcpm_set_state(port, port->pwr_role == TYPEC_SOURCE ?
2384
+ SRC_SOFT_RESET_WAIT_SNK_TX :
2385
+ SNK_SOFT_RESET,
2386
+ 0);
2387
+ } else {
2388
+ port->next_ams = ams;
2389
+ tcpm_set_state(port, ready_state(port), 0);
2390
+ /* 6.8.1 process the Message */
2391
+ tcpm_queue_message(port, message);
2392
+ }
2393
+ break;
21592394 }
21602395 }
21612396
....@@ -2166,15 +2401,18 @@
21662401 unsigned int cnt = pd_header_cnt_le(msg->header);
21672402 unsigned int rev = pd_header_rev_le(msg->header);
21682403 unsigned int i;
2169
- enum frs_typec_current frs_current;
2404
+ enum frs_typec_current partner_frs_current;
21702405 bool frs_enable;
21712406 int ret;
21722407
2408
+ if (tcpm_vdm_ams(port) && type != PD_DATA_VENDOR_DEF) {
2409
+ port->vdm_state = VDM_STATE_ERR_BUSY;
2410
+ tcpm_ams_finish(port);
2411
+ mod_vdm_delayed_work(port, 0);
2412
+ }
2413
+
21732414 switch (type) {
21742415 case PD_DATA_SOURCE_CAP:
2175
- if (port->pwr_role != TYPEC_SINK)
2176
- break;
2177
-
21782416 for (i = 0; i < cnt; i++)
21792417 port->source_caps[i] = le32_to_cpu(msg->payload[i]);
21802418
....@@ -2185,17 +2423,34 @@
21852423 tcpm_validate_caps(port, port->source_caps,
21862424 port->nr_source_caps);
21872425
2426
+ trace_android_vh_typec_store_partner_src_caps(port, &port->nr_source_caps,
2427
+ &port->source_caps);
2428
+
21882429 /*
21892430 * Adjust revision in subsequent message headers, as required,
21902431 * to comply with 6.2.1.1.5 of the USB PD 3.0 spec. We don't
21912432 * support Rev 1.0 so just do nothing in that scenario.
21922433 */
2193
- if (rev == PD_REV10)
2434
+ if (rev == PD_REV10) {
2435
+ if (port->ams == GET_SOURCE_CAPABILITIES)
2436
+ tcpm_ams_finish(port);
21942437 break;
2438
+ }
21952439
21962440 if (rev < PD_MAX_REV)
2197
- port->negotiated_rev = rev;
2441
+ port->negotiated_rev = min_t(u16, rev, port->negotiated_rev);
21982442
2443
+ if (port->pwr_role == TYPEC_SOURCE) {
2444
+ if (port->ams == GET_SOURCE_CAPABILITIES)
2445
+ tcpm_pd_handle_state(port, SRC_READY, NONE_AMS, 0);
2446
+ /* Unexpected Source Capabilities */
2447
+ else
2448
+ tcpm_pd_handle_msg(port,
2449
+ port->negotiated_rev < PD_REV30 ?
2450
+ PD_MSG_CTRL_REJECT :
2451
+ PD_MSG_CTRL_NOT_SUPP,
2452
+ NONE_AMS);
2453
+ } else if (port->state == SNK_WAIT_CAPABILITIES) {
21992454 /*
22002455 * This message may be received even if VBUS is not
22012456 * present. This is quite unexpected; see USB PD
....@@ -2209,48 +2464,68 @@
22092464 * but be prepared to keep waiting for VBUS after it was
22102465 * handled.
22112466 */
2212
- tcpm_set_state(port, SNK_NEGOTIATE_CAPABILITIES, 0);
2467
+ port->ams = POWER_NEGOTIATION;
2468
+ port->in_ams = true;
2469
+ tcpm_set_state(port, SNK_NEGOTIATE_CAPABILITIES, 0);
2470
+ } else {
2471
+ if (port->ams == GET_SOURCE_CAPABILITIES)
2472
+ tcpm_ams_finish(port);
2473
+ tcpm_pd_handle_state(port, SNK_NEGOTIATE_CAPABILITIES,
2474
+ POWER_NEGOTIATION, 0);
2475
+ }
22132476 break;
22142477 case PD_DATA_REQUEST:
2215
- if (port->pwr_role != TYPEC_SOURCE ||
2216
- cnt != 1) {
2217
- tcpm_queue_message(port, PD_MSG_CTRL_REJECT);
2218
- break;
2219
- }
2220
-
22212478 /*
22222479 * Adjust revision in subsequent message headers, as required,
22232480 * to comply with 6.2.1.1.5 of the USB PD 3.0 spec. We don't
22242481 * support Rev 1.0 so just reject in that scenario.
22252482 */
22262483 if (rev == PD_REV10) {
2227
- tcpm_queue_message(port, PD_MSG_CTRL_REJECT);
2484
+ tcpm_pd_handle_msg(port,
2485
+ port->negotiated_rev < PD_REV30 ?
2486
+ PD_MSG_CTRL_REJECT :
2487
+ PD_MSG_CTRL_NOT_SUPP,
2488
+ NONE_AMS);
22282489 break;
22292490 }
22302491
22312492 if (rev < PD_MAX_REV)
2232
- port->negotiated_rev = rev;
2493
+ port->negotiated_rev = min_t(u16, rev, port->negotiated_rev);
2494
+
2495
+ if (port->pwr_role != TYPEC_SOURCE || cnt != 1) {
2496
+ tcpm_pd_handle_msg(port,
2497
+ port->negotiated_rev < PD_REV30 ?
2498
+ PD_MSG_CTRL_REJECT :
2499
+ PD_MSG_CTRL_NOT_SUPP,
2500
+ NONE_AMS);
2501
+ break;
2502
+ }
22332503
22342504 port->sink_request = le32_to_cpu(msg->payload[0]);
22352505
22362506 if (port->vdm_sm_running && port->explicit_contract) {
2237
- tcpm_queue_message(port, PD_MSG_CTRL_WAIT);
2507
+ tcpm_pd_handle_msg(port, PD_MSG_CTRL_WAIT, port->ams);
22382508 break;
22392509 }
22402510
2241
- tcpm_set_state(port, SRC_NEGOTIATE_CAPABILITIES, 0);
2511
+ if (port->state == SRC_SEND_CAPABILITIES)
2512
+ tcpm_set_state(port, SRC_NEGOTIATE_CAPABILITIES, 0);
2513
+ else
2514
+ tcpm_pd_handle_state(port, SRC_NEGOTIATE_CAPABILITIES,
2515
+ POWER_NEGOTIATION, 0);
22422516 break;
22432517 case PD_DATA_SINK_CAP:
22442518 /* We don't do anything with this at the moment... */
22452519 for (i = 0; i < cnt; i++)
22462520 port->sink_caps[i] = le32_to_cpu(msg->payload[i]);
22472521
2248
- frs_current = (port->sink_caps[0] & PDO_FIXED_FRS_CURR_MASK) >>
2522
+ partner_frs_current = (port->sink_caps[0] & PDO_FIXED_FRS_CURR_MASK) >>
22492523 PDO_FIXED_FRS_CURR_SHIFT;
2250
- frs_enable = frs_current && (frs_current <= port->frs_current);
2524
+ frs_enable = partner_frs_current && (partner_frs_current <=
2525
+ port->new_source_frs_current);
22512526 tcpm_log(port,
22522527 "Port partner FRS capable partner_frs_current:%u port_frs_current:%u enable:%c",
2253
- frs_current, port->frs_current, frs_enable ? 'y' : 'n');
2528
+ partner_frs_current, port->new_source_frs_current, frs_enable ? 'y' : 'n');
22542529 if (frs_enable) {
22552530 ret = port->tcpc->enable_frs(port->tcpc, true);
22562531 tcpm_log(port, "Enable FRS %s, ret:%d\n", ret ? "fail" : "success", ret);
....@@ -2258,27 +2533,45 @@
22582533
22592534 port->nr_sink_caps = cnt;
22602535 port->sink_cap_done = true;
2261
- tcpm_set_state(port, SNK_READY, 0);
2536
+ if (port->ams == GET_SINK_CAPABILITIES)
2537
+ tcpm_set_state(port, ready_state(port), 0);
2538
+ /* Unexpected Sink Capabilities */
2539
+ else
2540
+ tcpm_pd_handle_msg(port,
2541
+ port->negotiated_rev < PD_REV30 ?
2542
+ PD_MSG_CTRL_REJECT :
2543
+ PD_MSG_CTRL_NOT_SUPP,
2544
+ NONE_AMS);
22622545 break;
22632546 case PD_DATA_VENDOR_DEF:
22642547 tcpm_handle_vdm_request(port, msg->payload, cnt);
22652548 break;
22662549 case PD_DATA_BIST:
2267
- if (port->state == SRC_READY || port->state == SNK_READY) {
2268
- port->bist_request = le32_to_cpu(msg->payload[0]);
2269
- tcpm_set_state(port, BIST_RX, 0);
2270
- }
2550
+ port->bist_request = le32_to_cpu(msg->payload[0]);
2551
+ tcpm_pd_handle_state(port, BIST_RX, BIST, 0);
22712552 break;
22722553 case PD_DATA_ALERT:
2273
- tcpm_handle_alert(port, msg->payload, cnt);
2554
+ if (port->state != SRC_READY && port->state != SNK_READY)
2555
+ tcpm_pd_handle_state(port, port->pwr_role == TYPEC_SOURCE ?
2556
+ SRC_SOFT_RESET_WAIT_SNK_TX : SNK_SOFT_RESET,
2557
+ NONE_AMS, 0);
2558
+ else
2559
+ tcpm_handle_alert(port, msg->payload, cnt);
22742560 break;
22752561 case PD_DATA_BATT_STATUS:
22762562 case PD_DATA_GET_COUNTRY_INFO:
22772563 /* Currently unsupported */
2278
- tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP);
2564
+ tcpm_pd_handle_msg(port, port->negotiated_rev < PD_REV30 ?
2565
+ PD_MSG_CTRL_REJECT :
2566
+ PD_MSG_CTRL_NOT_SUPP,
2567
+ NONE_AMS);
22792568 break;
22802569 default:
2281
- tcpm_log(port, "Unhandled data message type %#x", type);
2570
+ tcpm_pd_handle_msg(port, port->negotiated_rev < PD_REV30 ?
2571
+ PD_MSG_CTRL_REJECT :
2572
+ PD_MSG_CTRL_NOT_SUPP,
2573
+ NONE_AMS);
2574
+ tcpm_log(port, "Unrecognized data message type %#x", type);
22822575 break;
22832576 }
22842577 }
....@@ -2298,31 +2591,25 @@
22982591 enum pd_ctrl_msg_type type = pd_header_type_le(msg->header);
22992592 enum tcpm_state next_state;
23002593
2594
+ /*
2595
+ * Stop VDM state machine if interrupted by other Messages while NOT_SUPP is allowed in
2596
+ * VDM AMS if waiting for VDM responses and will be handled later.
2597
+ */
2598
+ if (tcpm_vdm_ams(port) && type != PD_CTRL_NOT_SUPP && type != PD_CTRL_GOOD_CRC) {
2599
+ port->vdm_state = VDM_STATE_ERR_BUSY;
2600
+ tcpm_ams_finish(port);
2601
+ mod_vdm_delayed_work(port, 0);
2602
+ }
2603
+
23012604 switch (type) {
23022605 case PD_CTRL_GOOD_CRC:
23032606 case PD_CTRL_PING:
23042607 break;
23052608 case PD_CTRL_GET_SOURCE_CAP:
2306
- switch (port->state) {
2307
- case SRC_READY:
2308
- case SNK_READY:
2309
- tcpm_queue_message(port, PD_MSG_DATA_SOURCE_CAP);
2310
- break;
2311
- default:
2312
- tcpm_queue_message(port, PD_MSG_CTRL_REJECT);
2313
- break;
2314
- }
2609
+ tcpm_pd_handle_msg(port, PD_MSG_DATA_SOURCE_CAP, GET_SOURCE_CAPABILITIES);
23152610 break;
23162611 case PD_CTRL_GET_SINK_CAP:
2317
- switch (port->state) {
2318
- case SRC_READY:
2319
- case SNK_READY:
2320
- tcpm_queue_message(port, PD_MSG_DATA_SINK_CAP);
2321
- break;
2322
- default:
2323
- tcpm_queue_message(port, PD_MSG_CTRL_REJECT);
2324
- break;
2325
- }
2612
+ tcpm_pd_handle_msg(port, PD_MSG_DATA_SINK_CAP, GET_SINK_CAPABILITIES);
23262613 break;
23272614 case PD_CTRL_GOTO_MIN:
23282615 break;
....@@ -2331,13 +2618,13 @@
23312618 case SNK_TRANSITION_SINK:
23322619 if (port->vbus_present) {
23332620 tcpm_set_current_limit(port,
2334
- port->current_limit,
2335
- port->supply_voltage);
2621
+ port->req_current_limit,
2622
+ port->req_supply_voltage);
23362623 port->explicit_contract = true;
2337
- /* Set VDM running flag ASAP */
2338
- if (port->data_role == TYPEC_HOST &&
2339
- port->send_discover)
2340
- port->vdm_sm_running = true;
2624
+ tcpm_set_auto_vbus_discharge_threshold(port,
2625
+ TYPEC_PWR_MODE_PD,
2626
+ port->pps_data.active,
2627
+ port->supply_voltage);
23412628 tcpm_set_state(port, SNK_READY, 0);
23422629 } else {
23432630 /*
....@@ -2361,6 +2648,11 @@
23612648 tcpm_set_state(port, FR_SWAP_SNK_SRC_NEW_SINK_READY, 0);
23622649 break;
23632650 default:
2651
+ tcpm_pd_handle_state(port,
2652
+ port->pwr_role == TYPEC_SOURCE ?
2653
+ SRC_SOFT_RESET_WAIT_SNK_TX :
2654
+ SNK_SOFT_RESET,
2655
+ NONE_AMS, 0);
23642656 break;
23652657 }
23662658 break;
....@@ -2370,26 +2662,28 @@
23702662 switch (port->state) {
23712663 case SNK_NEGOTIATE_CAPABILITIES:
23722664 /* USB PD specification, Figure 8-43 */
2373
- if (port->explicit_contract) {
2665
+ if (port->explicit_contract)
23742666 next_state = SNK_READY;
2375
- if (port->data_role == TYPEC_HOST &&
2376
- port->send_discover)
2377
- port->vdm_sm_running = true;
2378
- } else {
2667
+ else
23792668 next_state = SNK_WAIT_CAPABILITIES;
2380
- }
2669
+
2670
+ /* Threshold was relaxed before sending Request. Restore it back. */
2671
+ tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD,
2672
+ port->pps_data.active,
2673
+ port->supply_voltage);
23812674 tcpm_set_state(port, next_state, 0);
23822675 break;
23832676 case SNK_NEGOTIATE_PPS_CAPABILITIES:
23842677 /* Revert data back from any requested PPS updates */
2385
- port->pps_data.out_volt = port->supply_voltage;
2386
- port->pps_data.op_curr = port->current_limit;
2678
+ port->pps_data.req_out_volt = port->supply_voltage;
2679
+ port->pps_data.req_op_curr = port->current_limit;
23872680 port->pps_status = (type == PD_CTRL_WAIT ?
23882681 -EAGAIN : -EOPNOTSUPP);
23892682
2390
- if (port->data_role == TYPEC_HOST &&
2391
- port->send_discover)
2392
- port->vdm_sm_running = true;
2683
+ /* Threshold was relaxed before sending Request. Restore it back. */
2684
+ tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD,
2685
+ port->pps_data.active,
2686
+ port->supply_voltage);
23932687
23942688 tcpm_set_state(port, SNK_READY, 0);
23952689 break;
....@@ -2415,7 +2709,22 @@
24152709 port->sink_cap_done = true;
24162710 tcpm_set_state(port, ready_state(port), 0);
24172711 break;
2712
+ case SRC_READY:
2713
+ case SNK_READY:
2714
+ if (port->vdm_state > VDM_STATE_READY) {
2715
+ port->vdm_state = VDM_STATE_DONE;
2716
+ if (tcpm_vdm_ams(port))
2717
+ tcpm_ams_finish(port);
2718
+ mod_vdm_delayed_work(port, 0);
2719
+ break;
2720
+ }
2721
+ fallthrough;
24182722 default:
2723
+ tcpm_pd_handle_state(port,
2724
+ port->pwr_role == TYPEC_SOURCE ?
2725
+ SRC_SOFT_RESET_WAIT_SNK_TX :
2726
+ SNK_SOFT_RESET,
2727
+ NONE_AMS, 0);
24192728 break;
24202729 }
24212730 break;
....@@ -2427,13 +2736,15 @@
24272736 break;
24282737 case SNK_NEGOTIATE_PPS_CAPABILITIES:
24292738 port->pps_data.active = true;
2430
- port->supply_voltage = port->pps_data.out_volt;
2431
- port->current_limit = port->pps_data.op_curr;
2739
+ port->pps_data.min_volt = port->pps_data.req_min_volt;
2740
+ port->pps_data.max_volt = port->pps_data.req_max_volt;
2741
+ port->pps_data.max_curr = port->pps_data.req_max_curr;
2742
+ port->req_supply_voltage = port->pps_data.req_out_volt;
2743
+ port->req_current_limit = port->pps_data.req_op_curr;
2744
+ power_supply_changed(port->psy);
24322745 tcpm_set_state(port, SNK_TRANSITION_SINK, 0);
24332746 break;
24342747 case SOFT_RESET_SEND:
2435
- port->message_id = 0;
2436
- port->rx_msgid = -1;
24372748 if (port->ams == SOFT_RESET_AMS)
24382749 tcpm_ams_finish(port);
24392750 if (port->pwr_role == TYPEC_SOURCE) {
....@@ -2444,10 +2755,6 @@
24442755 }
24452756 break;
24462757 case DR_SWAP_SEND:
2447
- if (port->data_role == TYPEC_DEVICE &&
2448
- port->send_discover)
2449
- port->vdm_sm_running = true;
2450
-
24512758 tcpm_set_state(port, DR_SWAP_CHANGE_DR, 0);
24522759 break;
24532760 case PR_SWAP_SEND:
....@@ -2460,69 +2767,62 @@
24602767 tcpm_set_state(port, FR_SWAP_SNK_SRC_TRANSITION_TO_OFF, 0);
24612768 break;
24622769 default:
2770
+ tcpm_pd_handle_state(port,
2771
+ port->pwr_role == TYPEC_SOURCE ?
2772
+ SRC_SOFT_RESET_WAIT_SNK_TX :
2773
+ SNK_SOFT_RESET,
2774
+ NONE_AMS, 0);
24632775 break;
24642776 }
24652777 break;
24662778 case PD_CTRL_SOFT_RESET:
2779
+ port->ams = SOFT_RESET_AMS;
24672780 tcpm_set_state(port, SOFT_RESET, 0);
24682781 break;
24692782 case PD_CTRL_DR_SWAP:
2470
- if (port->port_type != TYPEC_PORT_DRP) {
2471
- tcpm_queue_message(port, PD_MSG_CTRL_REJECT);
2472
- break;
2473
- }
24742783 /*
24752784 * XXX
24762785 * 6.3.9: If an alternate mode is active, a request to swap
24772786 * alternate modes shall trigger a port reset.
24782787 */
2479
- switch (port->state) {
2480
- case SRC_READY:
2481
- case SNK_READY:
2482
- if (port->vdm_sm_running) {
2788
+ if (port->typec_caps.data != TYPEC_PORT_DRD) {
2789
+ tcpm_pd_handle_msg(port,
2790
+ port->negotiated_rev < PD_REV30 ?
2791
+ PD_MSG_CTRL_REJECT :
2792
+ PD_MSG_CTRL_NOT_SUPP,
2793
+ NONE_AMS);
2794
+ } else {
2795
+ if (port->send_discover) {
24832796 tcpm_queue_message(port, PD_MSG_CTRL_WAIT);
24842797 break;
24852798 }
2486
- tcpm_set_state(port, DR_SWAP_ACCEPT, 0);
2487
- break;
2488
- default:
2489
- tcpm_queue_message(port, PD_MSG_CTRL_WAIT);
2490
- break;
2799
+
2800
+ tcpm_pd_handle_state(port, DR_SWAP_ACCEPT, DATA_ROLE_SWAP, 0);
24912801 }
24922802 break;
24932803 case PD_CTRL_PR_SWAP:
24942804 if (port->port_type != TYPEC_PORT_DRP) {
2495
- tcpm_queue_message(port, PD_MSG_CTRL_REJECT);
2496
- break;
2497
- }
2498
- switch (port->state) {
2499
- case SRC_READY:
2500
- case SNK_READY:
2501
- if (port->vdm_sm_running) {
2805
+ tcpm_pd_handle_msg(port,
2806
+ port->negotiated_rev < PD_REV30 ?
2807
+ PD_MSG_CTRL_REJECT :
2808
+ PD_MSG_CTRL_NOT_SUPP,
2809
+ NONE_AMS);
2810
+ } else {
2811
+ if (port->send_discover) {
25022812 tcpm_queue_message(port, PD_MSG_CTRL_WAIT);
25032813 break;
25042814 }
2505
- tcpm_set_state(port, PR_SWAP_ACCEPT, 0);
2506
- break;
2507
- default:
2508
- tcpm_queue_message(port, PD_MSG_CTRL_WAIT);
2509
- break;
2815
+
2816
+ tcpm_pd_handle_state(port, PR_SWAP_ACCEPT, POWER_ROLE_SWAP, 0);
25102817 }
25112818 break;
25122819 case PD_CTRL_VCONN_SWAP:
2513
- switch (port->state) {
2514
- case SRC_READY:
2515
- case SNK_READY:
2516
- if (port->vdm_sm_running) {
2517
- tcpm_queue_message(port, PD_MSG_CTRL_WAIT);
2518
- break;
2519
- }
2520
- tcpm_set_state(port, VCONN_SWAP_ACCEPT, 0);
2521
- break;
2522
- default:
2820
+ if (port->send_discover) {
25232821 tcpm_queue_message(port, PD_MSG_CTRL_WAIT);
25242822 break;
25252823 }
2824
+
2825
+ tcpm_pd_handle_state(port, VCONN_SWAP_ACCEPT, VCONN_SWAP, 0);
25262826 break;
25272827 case PD_CTRL_GET_SOURCE_CAP_EXT:
25282828 case PD_CTRL_GET_STATUS:
....@@ -2530,10 +2830,19 @@
25302830 case PD_CTRL_GET_PPS_STATUS:
25312831 case PD_CTRL_GET_COUNTRY_CODES:
25322832 /* Currently not supported */
2533
- tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP);
2833
+ tcpm_pd_handle_msg(port,
2834
+ port->negotiated_rev < PD_REV30 ?
2835
+ PD_MSG_CTRL_REJECT :
2836
+ PD_MSG_CTRL_NOT_SUPP,
2837
+ NONE_AMS);
25342838 break;
25352839 default:
2536
- tcpm_log(port, "Unhandled ctrl message type %#x", type);
2840
+ tcpm_pd_handle_msg(port,
2841
+ port->negotiated_rev < PD_REV30 ?
2842
+ PD_MSG_CTRL_REJECT :
2843
+ PD_MSG_CTRL_NOT_SUPP,
2844
+ NONE_AMS);
2845
+ tcpm_log(port, "Unrecognized ctrl message type %#x", type);
25372846 break;
25382847 }
25392848 }
....@@ -2544,34 +2853,37 @@
25442853 enum pd_ext_msg_type type = pd_header_type_le(msg->header);
25452854 unsigned int data_size = pd_ext_header_data_size_le(msg->ext_msg.header);
25462855
2547
- if (!(msg->ext_msg.header & PD_EXT_HDR_CHUNKED)) {
2856
+ /* stopping VDM state machine if interrupted by other Messages */
2857
+ if (tcpm_vdm_ams(port)) {
2858
+ port->vdm_state = VDM_STATE_ERR_BUSY;
2859
+ tcpm_ams_finish(port);
2860
+ mod_vdm_delayed_work(port, 0);
2861
+ }
2862
+
2863
+ if (!(le16_to_cpu(msg->ext_msg.header) & PD_EXT_HDR_CHUNKED)) {
2864
+ tcpm_pd_handle_msg(port, PD_MSG_CTRL_NOT_SUPP, NONE_AMS);
25482865 tcpm_log(port, "Unchunked extended messages unsupported");
25492866 return;
25502867 }
25512868
25522869 if (data_size > PD_EXT_MAX_CHUNK_DATA) {
2870
+ tcpm_pd_handle_state(port, CHUNK_NOT_SUPP, NONE_AMS, PD_T_CHUNK_NOT_SUPP);
25532871 tcpm_log(port, "Chunk handling not yet supported");
25542872 return;
25552873 }
25562874
25572875 switch (type) {
25582876 case PD_EXT_STATUS:
2559
- /*
2560
- * If PPS related events raised then get PPS status to clear
2561
- * (see USB PD 3.0 Spec, 6.5.2.4)
2562
- */
2563
- if (msg->ext_msg.data[USB_PD_EXT_SDB_EVENT_FLAGS] &
2564
- USB_PD_EXT_SDB_PPS_EVENTS)
2565
- tcpm_set_state(port, GET_PPS_STATUS_SEND, 0);
2566
- else
2567
- tcpm_set_state(port, ready_state(port), 0);
2568
- break;
25692877 case PD_EXT_PPS_STATUS:
2570
- /*
2571
- * For now the PPS status message is used to clear events
2572
- * and nothing more.
2573
- */
2574
- tcpm_set_state(port, ready_state(port), 0);
2878
+ if (port->ams == GETTING_SOURCE_SINK_STATUS) {
2879
+ tcpm_ams_finish(port);
2880
+ tcpm_set_state(port, ready_state(port), 0);
2881
+ } else {
2882
+ /* unexpected Status or PPS_Status Message */
2883
+ tcpm_pd_handle_state(port, port->pwr_role == TYPEC_SOURCE ?
2884
+ SRC_SOFT_RESET_WAIT_SNK_TX : SNK_SOFT_RESET,
2885
+ NONE_AMS, 0);
2886
+ }
25752887 break;
25762888 case PD_EXT_SOURCE_CAP_EXT:
25772889 case PD_EXT_GET_BATT_CAP:
....@@ -2585,10 +2897,11 @@
25852897 case PD_EXT_FW_UPDATE_RESPONSE:
25862898 case PD_EXT_COUNTRY_INFO:
25872899 case PD_EXT_COUNTRY_CODES:
2588
- tcpm_queue_message(port, PD_MSG_CTRL_NOT_SUPP);
2900
+ tcpm_pd_handle_msg(port, PD_MSG_CTRL_NOT_SUPP, NONE_AMS);
25892901 break;
25902902 default:
2591
- tcpm_log(port, "Unhandled extended message type %#x", type);
2903
+ tcpm_pd_handle_msg(port, PD_MSG_CTRL_NOT_SUPP, NONE_AMS);
2904
+ tcpm_log(port, "Unrecognized extended message type %#x", type);
25922905 break;
25932906 }
25942907 }
....@@ -2633,7 +2946,7 @@
26332946 "Data role mismatch, initiating error recovery");
26342947 tcpm_set_state(port, ERROR_RECOVERY, 0);
26352948 } else {
2636
- if (msg->header & PD_HEADER_EXT_HDR)
2949
+ if (le16_to_cpu(msg->header) & PD_HEADER_EXT_HDR)
26372950 tcpm_pd_ext_msg_request(port, msg);
26382951 else if (cnt)
26392952 tcpm_pd_data_request(port, msg);
....@@ -2684,6 +2997,7 @@
26842997 static bool tcpm_send_queued_message(struct tcpm_port *port)
26852998 {
26862999 enum pd_msg_request queued_message;
3000
+ int ret;
26873001
26883002 do {
26893003 queued_message = port->queued_message;
....@@ -2700,10 +3014,27 @@
27003014 tcpm_pd_send_control(port, PD_CTRL_NOT_SUPP);
27013015 break;
27023016 case PD_MSG_DATA_SINK_CAP:
2703
- tcpm_pd_send_sink_caps(port);
3017
+ ret = tcpm_pd_send_sink_caps(port);
3018
+ if (ret < 0) {
3019
+ tcpm_log(port, "Unable to send snk caps, ret=%d", ret);
3020
+ tcpm_set_state(port, SNK_SOFT_RESET, 0);
3021
+ }
3022
+ tcpm_ams_finish(port);
27043023 break;
27053024 case PD_MSG_DATA_SOURCE_CAP:
2706
- tcpm_pd_send_source_caps(port);
3025
+ ret = tcpm_pd_send_source_caps(port);
3026
+ if (ret < 0) {
3027
+ tcpm_log(port,
3028
+ "Unable to send src caps, ret=%d",
3029
+ ret);
3030
+ tcpm_set_state(port, SOFT_RESET_SEND, 0);
3031
+ } else if (port->pwr_role == TYPEC_SOURCE) {
3032
+ tcpm_ams_finish(port);
3033
+ tcpm_set_state(port, HARD_RESET_SEND,
3034
+ PD_T_SENDER_RESPONSE);
3035
+ } else {
3036
+ tcpm_ams_finish(port);
3037
+ }
27073038 break;
27083039 default:
27093040 break;
....@@ -2791,6 +3122,7 @@
27913122
27923123 port->pps_data.supported = false;
27933124 port->usb_type = POWER_SUPPLY_USB_TYPE_PD;
3125
+ power_supply_changed(port->psy);
27943126
27953127 /*
27963128 * Select the source PDO providing the most power which has a
....@@ -2815,6 +3147,7 @@
28153147 port->pps_data.supported = true;
28163148 port->usb_type =
28173149 POWER_SUPPLY_USB_TYPE_PD_PPS;
3150
+ power_supply_changed(port->psy);
28183151 }
28193152 continue;
28203153 default:
....@@ -2884,7 +3217,8 @@
28843217 unsigned int i, j, max_mw = 0, max_mv = 0;
28853218 unsigned int min_src_mv, max_src_mv, src_ma, src_mw;
28863219 unsigned int min_snk_mv, max_snk_mv;
2887
- u32 pdo;
3220
+ unsigned int max_op_mv;
3221
+ u32 pdo, src, snk;
28883222 unsigned int src_pdo = 0, snk_pdo = 0;
28893223
28903224 /*
....@@ -2934,16 +3268,18 @@
29343268 continue;
29353269 }
29363270
2937
- if (max_src_mv <= max_snk_mv &&
2938
- min_src_mv >= min_snk_mv) {
3271
+ if (min_src_mv <= max_snk_mv &&
3272
+ max_src_mv >= min_snk_mv) {
3273
+ max_op_mv = min(max_src_mv, max_snk_mv);
3274
+ src_mw = (max_op_mv * src_ma) / 1000;
29393275 /* Prefer higher voltages if available */
29403276 if ((src_mw == max_mw &&
2941
- min_src_mv > max_mv) ||
3277
+ max_op_mv > max_mv) ||
29423278 src_mw > max_mw) {
29433279 src_pdo = i;
29443280 snk_pdo = j;
29453281 max_mw = src_mw;
2946
- max_mv = max_src_mv;
3282
+ max_mv = max_op_mv;
29473283 }
29483284 }
29493285 }
....@@ -2956,16 +3292,19 @@
29563292 }
29573293
29583294 if (src_pdo) {
2959
- pdo = port->source_caps[src_pdo];
3295
+ src = port->source_caps[src_pdo];
3296
+ snk = port->snk_pdo[snk_pdo];
29603297
2961
- port->pps_data.min_volt = pdo_pps_apdo_min_voltage(pdo);
2962
- port->pps_data.max_volt = pdo_pps_apdo_max_voltage(pdo);
2963
- port->pps_data.max_curr =
2964
- min_pps_apdo_current(pdo, port->snk_pdo[snk_pdo]);
2965
- port->pps_data.out_volt =
2966
- min(pdo_pps_apdo_max_voltage(pdo), port->pps_data.out_volt);
2967
- port->pps_data.op_curr =
2968
- min(port->pps_data.max_curr, port->pps_data.op_curr);
3298
+ port->pps_data.req_min_volt = max(pdo_pps_apdo_min_voltage(src),
3299
+ pdo_pps_apdo_min_voltage(snk));
3300
+ port->pps_data.req_max_volt = min(pdo_pps_apdo_max_voltage(src),
3301
+ pdo_pps_apdo_max_voltage(snk));
3302
+ port->pps_data.req_max_curr = min_pps_apdo_current(src, snk);
3303
+ port->pps_data.req_out_volt = min(port->pps_data.req_max_volt,
3304
+ max(port->pps_data.req_min_volt,
3305
+ port->pps_data.req_out_volt));
3306
+ port->pps_data.req_op_curr = min(port->pps_data.req_max_curr,
3307
+ port->pps_data.req_op_curr);
29693308 }
29703309
29713310 return src_pdo;
....@@ -3045,8 +3384,8 @@
30453384 flags & RDO_CAP_MISMATCH ? " [mismatch]" : "");
30463385 }
30473386
3048
- port->current_limit = ma;
3049
- port->supply_voltage = mv;
3387
+ port->req_current_limit = ma;
3388
+ port->req_supply_voltage = mv;
30503389
30513390 return 0;
30523391 }
....@@ -3060,6 +3399,12 @@
30603399 ret = tcpm_pd_build_request(port, &rdo);
30613400 if (ret < 0)
30623401 return ret;
3402
+
3403
+ /*
3404
+ * Relax the threshold as voltage will be adjusted after Accept Message plus tSrcTransition.
3405
+ * It is safer to modify the threshold here.
3406
+ */
3407
+ tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, 0);
30633408
30643409 memset(&msg, 0, sizeof(msg));
30653410 msg.header = PD_HEADER_LE(PD_DATA_REQUEST,
....@@ -3092,10 +3437,10 @@
30923437 tcpm_log(port, "Invalid APDO selected!");
30933438 return -EINVAL;
30943439 }
3095
- max_mv = port->pps_data.max_volt;
3096
- max_ma = port->pps_data.max_curr;
3097
- out_mv = port->pps_data.out_volt;
3098
- op_ma = port->pps_data.op_curr;
3440
+ max_mv = port->pps_data.req_max_volt;
3441
+ max_ma = port->pps_data.req_max_curr;
3442
+ out_mv = port->pps_data.req_out_volt;
3443
+ op_ma = port->pps_data.req_op_curr;
30993444 break;
31003445 default:
31013446 tcpm_log(port, "Invalid PDO selected!");
....@@ -3142,8 +3487,8 @@
31423487 tcpm_log(port, "Requesting APDO %d: %u mV, %u mA",
31433488 src_pdo_index, out_mv, op_ma);
31443489
3145
- port->pps_data.op_curr = op_ma;
3146
- port->pps_data.out_volt = out_mv;
3490
+ port->pps_data.req_op_curr = op_ma;
3491
+ port->pps_data.req_out_volt = out_mv;
31473492
31483493 return 0;
31493494 }
....@@ -3157,6 +3502,9 @@
31573502 ret = tcpm_pd_build_pps_request(port, &rdo);
31583503 if (ret < 0)
31593504 return ret;
3505
+
3506
+ /* Relax the threshold as voltage will be adjusted right after Accept Message. */
3507
+ tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, 0);
31603508
31613509 memset(&msg, 0, sizeof(msg));
31623510 msg.header = PD_HEADER_LE(PD_DATA_REQUEST,
....@@ -3178,10 +3526,6 @@
31783526
31793527 tcpm_log(port, "vbus:=%d charge=%d", enable, port->vbus_charge);
31803528
3181
- ret = tcpm_send_vbus_notify(port, enable);
3182
- if (ret)
3183
- return ret;
3184
-
31853529 ret = port->tcpc->set_vbus(port->tcpc, enable, port->vbus_charge);
31863530 if (ret < 0)
31873531 return ret;
....@@ -3199,17 +3543,13 @@
31993543
32003544 if (charge != port->vbus_charge) {
32013545 tcpm_log(port, "vbus=%d charge:=%d", port->vbus_source, charge);
3202
-
3203
- ret = tcpm_send_vbus_notify(port, port->vbus_source);
3204
- if (ret < 0)
3205
- return ret;
3206
-
32073546 ret = port->tcpc->set_vbus(port->tcpc, port->vbus_source,
32083547 charge);
32093548 if (ret < 0)
32103549 return ret;
32113550 }
32123551 port->vbus_charge = charge;
3552
+ power_supply_changed(port->psy);
32133553 return 0;
32143554 }
32153555
....@@ -3228,10 +3568,6 @@
32283568 static int tcpm_init_vbus(struct tcpm_port *port)
32293569 {
32303570 int ret;
3231
-
3232
- ret = tcpm_send_vbus_notify(port, false);
3233
- if (ret)
3234
- return ret;
32353571
32363572 ret = port->tcpc->set_vbus(port->tcpc, false, false);
32373573 port->vbus_source = false;
....@@ -3280,7 +3616,9 @@
32803616 if (ret < 0)
32813617 return ret;
32823618
3283
- ret = tcpm_set_roles(port, true, TYPEC_SOURCE, TYPEC_HOST);
3619
+ tcpm_enable_auto_vbus_discharge(port, true);
3620
+
3621
+ ret = tcpm_set_roles(port, true, TYPEC_SOURCE, tcpm_data_role_for_source(port));
32843622 if (ret < 0)
32853623 return ret;
32863624
....@@ -3309,12 +3647,8 @@
33093647 port->partner = NULL;
33103648
33113649 port->attached = true;
3650
+ port->debouncing = false;
33123651 port->send_discover = true;
3313
-
3314
- dev_info(port->dev, "CC connected in %s as DFP\n",
3315
- polarity ? "CC2" : "CC1");
3316
- tcpm_send_orientation_notify(port);
3317
- tcpm_send_data_role_notify(port, port->attached, port->data_role);
33183652
33193653 return 0;
33203654
....@@ -3350,26 +3684,26 @@
33503684 memset(modep, 0, sizeof(*modep));
33513685 }
33523686
3687
+static void tcpm_set_partner_usb_comm_capable(struct tcpm_port *port, bool capable)
3688
+{
3689
+ tcpm_log(port, "Setting usb_comm capable %s", capable ? "true" : "false");
3690
+
3691
+ if (port->tcpc->set_partner_usb_comm_capable)
3692
+ port->tcpc->set_partner_usb_comm_capable(port->tcpc, capable);
3693
+}
3694
+
33533695 static void tcpm_reset_port(struct tcpm_port *port)
33543696 {
3697
+ tcpm_enable_auto_vbus_discharge(port, false);
33553698 port->in_ams = false;
33563699 port->ams = NONE_AMS;
33573700 port->vdm_sm_running = false;
33583701 tcpm_unregister_altmodes(port);
33593702 tcpm_typec_disconnect(port);
3360
- if (port->attached) {
3361
- port->attached = false;
3362
- if (port->dp_configured) {
3363
- port->dp_configured = false;
3364
- port->dp_pin_assignment = 0;
3365
- port->dp_status = 0;
3366
- tcpm_send_dp_notify(port);
3367
- }
3368
- tcpm_send_data_role_notify(port, port->attached,
3369
- port->data_role);
3370
- }
3703
+ port->attached = false;
33713704 port->pd_capable = false;
33723705 port->pps_data.supported = false;
3706
+ tcpm_set_partner_usb_comm_capable(port, false);
33733707
33743708 /*
33753709 * First Rx ID should be 0; set this to a sentinel of -1 so that
....@@ -3388,12 +3722,11 @@
33883722 port->try_src_count = 0;
33893723 port->try_snk_count = 0;
33903724 port->usb_type = POWER_SUPPLY_USB_TYPE_C;
3725
+ power_supply_changed(port->psy);
33913726 port->nr_sink_caps = 0;
33923727 port->sink_cap_done = false;
33933728 if (port->tcpc->enable_frs)
33943729 port->tcpc->enable_frs(port->tcpc, false);
3395
-
3396
- power_supply_changed(port->psy);
33973730 }
33983731
33993732 static void tcpm_detach(struct tcpm_port *port)
....@@ -3403,6 +3736,11 @@
34033736
34043737 if (!port->attached)
34053738 return;
3739
+
3740
+ if (port->tcpc->set_bist_data) {
3741
+ tcpm_log(port, "disable BIST MODE TESTDATA");
3742
+ port->tcpc->set_bist_data(port->tcpc, false);
3743
+ }
34063744
34073745 tcpm_reset_port(port);
34083746 }
....@@ -3424,7 +3762,9 @@
34243762 if (ret < 0)
34253763 return ret;
34263764
3427
- ret = tcpm_set_roles(port, true, TYPEC_SINK, TYPEC_DEVICE);
3765
+ tcpm_enable_auto_vbus_discharge(port, true);
3766
+
3767
+ ret = tcpm_set_roles(port, true, TYPEC_SINK, tcpm_data_role_for_sink(port));
34283768 if (ret < 0)
34293769 return ret;
34303770
....@@ -3433,12 +3773,8 @@
34333773 port->partner = NULL;
34343774
34353775 port->attached = true;
3776
+ port->debouncing = false;
34363777 port->send_discover = true;
3437
-
3438
- dev_info(port->dev, "CC connected in %s as UFP\n",
3439
- port->cc1 != TYPEC_CC_OPEN ? "CC1" : "CC2");
3440
- tcpm_send_orientation_notify(port);
3441
- tcpm_send_data_role_notify(port, port->attached, port->data_role);
34423778
34433779 return 0;
34443780 }
....@@ -3455,7 +3791,8 @@
34553791 if (port->attached)
34563792 return 0;
34573793
3458
- ret = tcpm_set_roles(port, true, TYPEC_SOURCE, TYPEC_HOST);
3794
+ ret = tcpm_set_roles(port, true, TYPEC_SOURCE,
3795
+ tcpm_data_role_for_source(port));
34593796 if (ret < 0)
34603797 return ret;
34613798
....@@ -3464,10 +3801,7 @@
34643801 tcpm_typec_connect(port);
34653802
34663803 port->attached = true;
3467
-
3468
- dev_info(port->dev, "CC connected as Audio Accessory\n");
3469
- tcpm_send_orientation_notify(port);
3470
- tcpm_send_data_role_notify(port, port->attached, port->data_role);
3804
+ port->debouncing = false;
34713805
34723806 return 0;
34733807 }
....@@ -3504,14 +3838,15 @@
35043838 return SNK_UNATTACHED;
35053839 }
35063840
3507
-static void tcpm_check_send_discover(struct tcpm_port *port)
3841
+bool tcpm_is_toggling(struct tcpm_port *port)
35083842 {
3509
- if (port->data_role == TYPEC_HOST && port->send_discover &&
3510
- port->pd_capable) {
3511
- tcpm_send_vdm(port, USB_SID_PD, CMD_DISCOVER_IDENT, NULL, 0);
3512
- port->send_discover = false;
3513
- }
3843
+ if (port->port_type == TYPEC_PORT_DRP)
3844
+ return port->state == SRC_UNATTACHED || port->state == SNK_UNATTACHED ||
3845
+ port->state == TOGGLING;
3846
+
3847
+ return false;
35143848 }
3849
+EXPORT_SYMBOL_GPL(tcpm_is_toggling);
35153850
35163851 static void tcpm_swap_complete(struct tcpm_port *port, int result)
35173852 {
....@@ -3540,8 +3875,11 @@
35403875 {
35413876 int ret;
35423877 enum typec_pwr_opmode opmode;
3543
- unsigned int msecs;
3878
+ unsigned int msecs, timer_val_msecs;
35443879 enum tcpm_state upcoming_state;
3880
+ const char *state_name;
3881
+ u32 current_limit;
3882
+ bool adjust;
35453883
35463884 port->enter_state = port->state;
35473885 switch (port->state) {
....@@ -3552,6 +3890,15 @@
35523890 if (!port->non_pd_role_swap)
35533891 tcpm_swap_complete(port, -ENOTCONN);
35543892 tcpm_src_detach(port);
3893
+ if (port->debouncing) {
3894
+ port->debouncing = false;
3895
+ if (port->tcpc->check_contaminant &&
3896
+ port->tcpc->check_contaminant(port->tcpc)) {
3897
+ /* Contaminant detection would handle toggling */
3898
+ tcpm_set_state(port, TOGGLING, 0);
3899
+ break;
3900
+ }
3901
+ }
35553902 if (tcpm_start_toggling(port, tcpm_rp_cc(port))) {
35563903 tcpm_set_state(port, TOGGLING, 0);
35573904 break;
....@@ -3561,20 +3908,25 @@
35613908 tcpm_set_state(port, SNK_UNATTACHED, PD_T_DRP_SNK);
35623909 break;
35633910 case SRC_ATTACH_WAIT:
3911
+ port->debouncing = true;
3912
+ timer_val_msecs = PD_T_CC_DEBOUNCE;
3913
+ trace_android_vh_typec_tcpm_get_timer(tcpm_states[SRC_ATTACH_WAIT],
3914
+ CC_DEBOUNCE, &timer_val_msecs);
35643915 if (tcpm_port_is_debug(port))
35653916 tcpm_set_state(port, DEBUG_ACC_ATTACHED,
3566
- PD_T_CC_DEBOUNCE);
3917
+ timer_val_msecs);
35673918 else if (tcpm_port_is_audio(port))
35683919 tcpm_set_state(port, AUDIO_ACC_ATTACHED,
3569
- PD_T_CC_DEBOUNCE);
3570
- else if (tcpm_port_is_source(port))
3920
+ timer_val_msecs);
3921
+ else if (tcpm_port_is_source(port) && port->vbus_vsafe0v)
35713922 tcpm_set_state(port,
35723923 tcpm_try_snk(port) ? SNK_TRY
35733924 : SRC_ATTACHED,
3574
- PD_T_CC_DEBOUNCE);
3925
+ timer_val_msecs);
35753926 break;
35763927
35773928 case SNK_TRY:
3929
+ port->debouncing = false;
35783930 port->try_snk_count++;
35793931 /*
35803932 * Requirements:
....@@ -3597,15 +3949,13 @@
35973949 break;
35983950 case SNK_TRY_WAIT_DEBOUNCE:
35993951 tcpm_set_state(port, SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS,
3600
- PD_T_PD_DEBOUNCE);
3952
+ PD_T_TRY_CC_DEBOUNCE);
36013953 break;
36023954 case SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS:
3603
- if (port->vbus_present && tcpm_port_is_sink(port)) {
3955
+ if (port->vbus_present && tcpm_port_is_sink(port))
36043956 tcpm_set_state(port, SNK_ATTACHED, 0);
3605
- } else {
3606
- tcpm_set_state(port, SRC_TRYWAIT, 0);
3957
+ else
36073958 port->max_wait = 0;
3608
- }
36093959 break;
36103960 case SRC_TRYWAIT:
36113961 tcpm_set_cc(port, tcpm_rp_cc(port));
....@@ -3624,7 +3974,10 @@
36243974 }
36253975 break;
36263976 case SRC_TRYWAIT_DEBOUNCE:
3627
- tcpm_set_state(port, SRC_ATTACHED, PD_T_CC_DEBOUNCE);
3977
+ timer_val_msecs = PD_T_CC_DEBOUNCE;
3978
+ trace_android_vh_typec_tcpm_get_timer(tcpm_states[SRC_TRYWAIT_DEBOUNCE],
3979
+ CC_DEBOUNCE, &timer_val_msecs);
3980
+ tcpm_set_state(port, SRC_ATTACHED, timer_val_msecs);
36283981 break;
36293982 case SRC_TRYWAIT_UNATTACHED:
36303983 tcpm_set_state(port, SNK_UNATTACHED, 0);
....@@ -3640,7 +3993,7 @@
36403993 typec_set_pwr_opmode(port->typec_port, opmode);
36413994 port->pwr_opmode = TYPEC_PWR_MODE_USB;
36423995 port->caps_count = 0;
3643
- port->negotiated_rev = PD_MAX_REV;
3996
+ port->negotiated_rev = (((port->typec_caps.pd_revision >> 8) & 0xff) - 1);
36443997 port->message_id = 0;
36453998 port->rx_msgid = -1;
36463999 port->explicit_contract = false;
....@@ -3710,6 +4063,8 @@
37104063 }
37114064 } else {
37124065 tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
4066
+ tcpm_set_partner_usb_comm_capable(port,
4067
+ !!(port->sink_request & RDO_USB_COMM));
37134068 tcpm_set_state(port, SRC_TRANSITION_SUPPLY,
37144069 PD_T_SRC_TRANSITION);
37154070 }
....@@ -3733,6 +4088,11 @@
37334088
37344089 if (port->ams != NONE_AMS)
37354090 tcpm_ams_finish(port);
4091
+ if (port->next_ams != NONE_AMS) {
4092
+ port->ams = port->next_ams;
4093
+ port->next_ams = NONE_AMS;
4094
+ }
4095
+
37364096 /*
37374097 * If previous AMS is interrupted, switch to the upcoming
37384098 * state.
....@@ -3744,7 +4104,18 @@
37444104 break;
37454105 }
37464106
3747
- tcpm_check_send_discover(port);
4107
+ /*
4108
+ * 6.4.4.3.1 Discover Identity
4109
+ * "The Discover Identity Command Shall only be sent to SOP when there is an
4110
+ * Explicit Contract."
4111
+ * For now, this driver only supports SOP for DISCOVER_IDENTITY, thus using
4112
+ * port->explicit_contract to decide whether to send the command.
4113
+ */
4114
+ if (port->explicit_contract)
4115
+ mod_send_discover_delayed_work(port, 0);
4116
+ else
4117
+ port->send_discover = false;
4118
+
37484119 /*
37494120 * 6.3.5
37504121 * Sending ping messages is not necessary if
....@@ -3769,6 +4140,15 @@
37694140 tcpm_swap_complete(port, -ENOTCONN);
37704141 tcpm_pps_complete(port, -ENOTCONN);
37714142 tcpm_snk_detach(port);
4143
+ if (port->debouncing) {
4144
+ port->debouncing = false;
4145
+ if (port->tcpc->check_contaminant &&
4146
+ port->tcpc->check_contaminant(port->tcpc)) {
4147
+ /* Contaminant detection would handle toggling */
4148
+ tcpm_set_state(port, TOGGLING, 0);
4149
+ break;
4150
+ }
4151
+ }
37724152 if (tcpm_start_toggling(port, TYPEC_CC_RD)) {
37734153 tcpm_set_state(port, TOGGLING, 0);
37744154 break;
....@@ -3778,25 +4158,33 @@
37784158 tcpm_set_state(port, SRC_UNATTACHED, PD_T_DRP_SRC);
37794159 break;
37804160 case SNK_ATTACH_WAIT:
4161
+ port->debouncing = true;
4162
+ timer_val_msecs = PD_T_CC_DEBOUNCE;
4163
+ trace_android_vh_typec_tcpm_get_timer(tcpm_states[SNK_ATTACH_WAIT],
4164
+ CC_DEBOUNCE, &timer_val_msecs);
37814165 if ((port->cc1 == TYPEC_CC_OPEN &&
37824166 port->cc2 != TYPEC_CC_OPEN) ||
37834167 (port->cc1 != TYPEC_CC_OPEN &&
37844168 port->cc2 == TYPEC_CC_OPEN))
37854169 tcpm_set_state(port, SNK_DEBOUNCED,
3786
- PD_T_CC_DEBOUNCE);
4170
+ timer_val_msecs);
37874171 else if (tcpm_port_is_disconnected(port))
37884172 tcpm_set_state(port, SNK_UNATTACHED,
3789
- PD_T_PD_DEBOUNCE);
4173
+ timer_val_msecs);
37904174 break;
37914175 case SNK_DEBOUNCED:
3792
- if (tcpm_port_is_disconnected(port))
4176
+ if (tcpm_port_is_disconnected(port)) {
37934177 tcpm_set_state(port, SNK_UNATTACHED,
37944178 PD_T_PD_DEBOUNCE);
3795
- else if (port->vbus_present)
4179
+ } else if (port->vbus_present) {
37964180 tcpm_set_state(port,
37974181 tcpm_try_src(port) ? SRC_TRY
37984182 : SNK_ATTACHED,
37994183 0);
4184
+ port->debouncing = false;
4185
+ } else {
4186
+ port->debouncing = false;
4187
+ }
38004188 break;
38014189 case SRC_TRY:
38024190 port->try_src_count++;
....@@ -3822,8 +4210,11 @@
38224210 tcpm_set_state(port, SRC_ATTACHED, PD_T_PD_DEBOUNCE);
38234211 break;
38244212 case SNK_TRYWAIT:
4213
+ timer_val_msecs = PD_T_CC_DEBOUNCE;
4214
+ trace_android_vh_typec_tcpm_get_timer(tcpm_states[SNK_TRYWAIT],
4215
+ CC_DEBOUNCE, &timer_val_msecs);
38254216 tcpm_set_cc(port, TYPEC_CC_RD);
3826
- tcpm_set_state(port, SNK_TRYWAIT_VBUS, PD_T_CC_DEBOUNCE);
4217
+ tcpm_set_state(port, SNK_TRYWAIT_VBUS, timer_val_msecs);
38274218 break;
38284219 case SNK_TRYWAIT_VBUS:
38294220 /*
....@@ -3853,7 +4244,7 @@
38534244 port->cc2 : port->cc1);
38544245 typec_set_pwr_opmode(port->typec_port, opmode);
38554246 port->pwr_opmode = TYPEC_PWR_MODE_USB;
3856
- port->negotiated_rev = PD_MAX_REV;
4247
+ port->negotiated_rev = (((port->typec_caps.pd_revision >> 8) & 0xff) - 1);
38574248 port->message_id = 0;
38584249 port->rx_msgid = -1;
38594250 port->explicit_contract = false;
....@@ -3863,13 +4254,22 @@
38634254 /* SRC -> SNK POWER/FAST_ROLE_SWAP finished */
38644255 tcpm_ams_finish(port);
38654256
3866
- tcpm_set_state(port, SNK_DISCOVERY, 0);
4257
+ timer_val_msecs = 0;
4258
+ trace_android_vh_typec_tcpm_get_timer(tcpm_states[SNK_STARTUP],
4259
+ SINK_DISCOVERY_BC12, &timer_val_msecs);
4260
+ tcpm_set_state(port, SNK_DISCOVERY, timer_val_msecs);
38674261 break;
38684262 case SNK_DISCOVERY:
38694263 if (port->vbus_present) {
3870
- tcpm_set_current_limit(port,
3871
- tcpm_get_current_limit(port),
3872
- 5000);
4264
+ current_limit = tcpm_get_current_limit(port);
4265
+ trace_android_vh_typec_tcpm_adj_current_limit(tcpm_states[SNK_DISCOVERY],
4266
+ port->current_limit,
4267
+ port->supply_voltage,
4268
+ port->pd_capable,
4269
+ &current_limit, &adjust);
4270
+ if (port->slow_charger_loop && (current_limit > PD_P_SNK_STDBY_MW / 5))
4271
+ current_limit = PD_P_SNK_STDBY_MW / 5;
4272
+ tcpm_set_current_limit(port, current_limit, 5000);
38734273 tcpm_set_charge(port, true);
38744274 tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0);
38754275 break;
....@@ -3884,8 +4284,10 @@
38844284 PD_T_DB_DETECT : PD_T_NO_RESPONSE);
38854285 break;
38864286 case SNK_DISCOVERY_DEBOUNCE:
3887
- tcpm_set_state(port, SNK_DISCOVERY_DEBOUNCE_DONE,
3888
- PD_T_CC_DEBOUNCE);
4287
+ timer_val_msecs = PD_T_CC_DEBOUNCE;
4288
+ trace_android_vh_typec_tcpm_get_timer(tcpm_states[SNK_DISCOVERY_DEBOUNCE],
4289
+ CC_DEBOUNCE, &timer_val_msecs);
4290
+ tcpm_set_state(port, SNK_DISCOVERY_DEBOUNCE_DONE, timer_val_msecs);
38894291 break;
38904292 case SNK_DISCOVERY_DEBOUNCE_DONE:
38914293 if (!tcpm_port_is_disconnected(port) &&
....@@ -3898,11 +4300,16 @@
38984300 tcpm_set_state(port, unattached_state(port), 0);
38994301 break;
39004302 case SNK_WAIT_CAPABILITIES:
3901
- ret = port->tcpc->set_pd_rx(port->tcpc, true);
3902
- if (ret < 0) {
3903
- tcpm_set_state(port, SNK_READY, 0);
3904
- break;
4303
+ if (port->prev_state != SOFT_RESET_SEND) {
4304
+ ret = port->tcpc->set_pd_rx(port->tcpc, true);
4305
+ if (ret < 0) {
4306
+ tcpm_set_state(port, SNK_READY, 0);
4307
+ break;
4308
+ }
39054309 }
4310
+ timer_val_msecs = PD_T_SINK_WAIT_CAP;
4311
+ trace_android_vh_typec_tcpm_get_timer(tcpm_states[SNK_WAIT_CAPABILITIES],
4312
+ SINK_WAIT_CAP, &timer_val_msecs);
39064313 /*
39074314 * If VBUS has never been low, and we time out waiting
39084315 * for source cap, try a soft reset first, in case we
....@@ -3912,17 +4319,23 @@
39124319 if (port->vbus_never_low) {
39134320 port->vbus_never_low = false;
39144321 tcpm_set_state(port, SNK_SOFT_RESET,
3915
- PD_T_SINK_WAIT_CAP);
4322
+ timer_val_msecs);
39164323 } else {
39174324 tcpm_set_state(port, hard_reset_state(port),
3918
- PD_T_SINK_WAIT_CAP);
4325
+ timer_val_msecs);
39194326 }
39204327 break;
39214328 case SNK_NEGOTIATE_CAPABILITIES:
39224329 port->pd_capable = true;
4330
+ tcpm_set_partner_usb_comm_capable(port,
4331
+ !!(port->source_caps[0] & PDO_FIXED_USB_COMM));
39234332 port->hard_reset_count = 0;
39244333 ret = tcpm_pd_send_request(port);
39254334 if (ret < 0) {
4335
+ /* Restore back to the original state */
4336
+ tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD,
4337
+ port->pps_data.active,
4338
+ port->supply_voltage);
39264339 /* Let the Source send capabilities again. */
39274340 tcpm_set_state(port, SNK_WAIT_CAPABILITIES, 0);
39284341 } else {
....@@ -3933,6 +4346,10 @@
39334346 case SNK_NEGOTIATE_PPS_CAPABILITIES:
39344347 ret = tcpm_pd_send_pps_request(port);
39354348 if (ret < 0) {
4349
+ /* Restore back to the original state */
4350
+ tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_PD,
4351
+ port->pps_data.active,
4352
+ port->supply_voltage);
39364353 port->pps_status = ret;
39374354 /*
39384355 * If this was called due to updates to sink
....@@ -3949,6 +4366,23 @@
39494366 }
39504367 break;
39514368 case SNK_TRANSITION_SINK:
4369
+ /* From the USB PD spec:
4370
+ * "The Sink Shall transition to Sink Standby before a positive or
4371
+ * negative voltage transition of VBUS. During Sink Standby
4372
+ * the Sink Shall reduce its power draw to pSnkStdby."
4373
+ *
4374
+ * This is not applicable to PPS though as the port can continue
4375
+ * to draw negotiated power without switching to standby.
4376
+ */
4377
+ if (port->supply_voltage != port->req_supply_voltage && !port->pps_data.active &&
4378
+ port->current_limit * port->supply_voltage / 1000 > PD_P_SNK_STDBY_MW) {
4379
+ u32 stdby_ma = PD_P_SNK_STDBY_MW * 1000 / port->supply_voltage;
4380
+
4381
+ tcpm_log(port, "Setting standby current %u mV @ %u mA",
4382
+ port->supply_voltage, stdby_ma);
4383
+ tcpm_set_current_limit(port, stdby_ma, port->supply_voltage);
4384
+ }
4385
+ fallthrough;
39524386 case SNK_TRANSITION_SINK_VBUS:
39534387 tcpm_set_state(port, hard_reset_state(port),
39544388 PD_T_PS_TRANSITION);
....@@ -3962,6 +4396,19 @@
39624396 port->pwr_opmode = TYPEC_PWR_MODE_PD;
39634397 }
39644398
4399
+ current_limit = tcpm_get_current_limit(port);
4400
+ adjust = false;
4401
+ trace_android_vh_typec_tcpm_adj_current_limit(tcpm_states[SNK_READY],
4402
+ port->current_limit,
4403
+ port->supply_voltage,
4404
+ port->pd_capable,
4405
+ &current_limit,
4406
+ &adjust);
4407
+ if (adjust)
4408
+ tcpm_set_current_limit(port, current_limit, 5000);
4409
+
4410
+ if (!port->pd_capable && port->slow_charger_loop)
4411
+ tcpm_set_current_limit(port, tcpm_get_current_limit(port), 5000);
39654412 tcpm_swap_complete(port, 0);
39664413 tcpm_typec_connect(port);
39674414 mod_enable_frs_delayed_work(port, 0);
....@@ -3969,6 +4416,11 @@
39694416
39704417 if (port->ams != NONE_AMS)
39714418 tcpm_ams_finish(port);
4419
+ if (port->next_ams != NONE_AMS) {
4420
+ port->ams = port->next_ams;
4421
+ port->next_ams = NONE_AMS;
4422
+ }
4423
+
39724424 /*
39734425 * If previous AMS is interrupted, switch to the upcoming
39744426 * state.
....@@ -3980,11 +4432,19 @@
39804432 break;
39814433 }
39824434
3983
- tcpm_check_send_discover(port);
4435
+ /*
4436
+ * 6.4.4.3.1 Discover Identity
4437
+ * "The Discover Identity Command Shall only be sent to SOP when there is an
4438
+ * Explicit Contract."
4439
+ * For now, this driver only supports SOP for DISCOVER_IDENTITY, thus using
4440
+ * port->explicit_contract.
4441
+ */
4442
+ if (port->explicit_contract)
4443
+ mod_send_discover_delayed_work(port, 0);
4444
+ else
4445
+ port->send_discover = false;
4446
+
39844447 power_supply_changed(port->psy);
3985
- if (port->usb_type == POWER_SUPPLY_USB_TYPE_PD ||
3986
- port->usb_type == POWER_SUPPLY_USB_TYPE_PD_PPS)
3987
- tcpm_send_power_change_notify(port);
39884448 break;
39894449
39904450 /* Accessory states */
....@@ -3999,7 +4459,10 @@
39994459 tcpm_set_state(port, ACC_UNATTACHED, 0);
40004460 break;
40014461 case AUDIO_ACC_DEBOUNCE:
4002
- tcpm_set_state(port, ACC_UNATTACHED, PD_T_CC_DEBOUNCE);
4462
+ timer_val_msecs = PD_T_CC_DEBOUNCE;
4463
+ trace_android_vh_typec_tcpm_get_timer(tcpm_states[AUDIO_ACC_DEBOUNCE],
4464
+ CC_DEBOUNCE, &timer_val_msecs);
4465
+ tcpm_set_state(port, ACC_UNATTACHED, timer_val_msecs);
40034466 break;
40044467
40054468 /* Hard_Reset states */
....@@ -4029,13 +4492,31 @@
40294492 tcpm_set_state(port, SNK_HARD_RESET_SINK_OFF, 0);
40304493 break;
40314494 case SRC_HARD_RESET_VBUS_OFF:
4032
- tcpm_set_vconn(port, true);
4495
+ /*
4496
+ * 7.1.5 Response to Hard Resets
4497
+ * Hard Reset Signaling indicates a communication failure has occurred and the
4498
+ * Source Shall stop driving VCONN, Shall remove Rp from the VCONN pin and Shall
4499
+ * drive VBUS to vSafe0V as shown in Figure 7-9.
4500
+ */
4501
+ tcpm_set_vconn(port, false);
40334502 tcpm_set_vbus(port, false);
40344503 tcpm_set_roles(port, port->self_powered, TYPEC_SOURCE,
4035
- TYPEC_HOST);
4036
- tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, PD_T_SRC_RECOVER);
4504
+ tcpm_data_role_for_source(port));
4505
+ /*
4506
+ * If tcpc fails to notify vbus off, TCPM will wait for PD_T_SAFE_0V +
4507
+ * PD_T_SRC_RECOVER before turning vbus back on.
4508
+ * From Table 7-12 Sequence Description for a Source Initiated Hard Reset:
4509
+ * 4. Policy Engine waits tPSHardReset after sending Hard Reset Signaling and then
4510
+ * tells the Device Policy Manager to instruct the power supply to perform a
4511
+ * Hard Reset. The transition to vSafe0V Shall occur within tSafe0V (t2).
4512
+ * 5. After tSrcRecover the Source applies power to VBUS in an attempt to
4513
+ * re-establish communication with the Sink and resume USB Default Operation.
4514
+ * The transition to vSafe5V Shall occur within tSrcTurnOn(t4).
4515
+ */
4516
+ tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, PD_T_SAFE_0V + PD_T_SRC_RECOVER);
40374517 break;
40384518 case SRC_HARD_RESET_VBUS_ON:
4519
+ tcpm_set_vconn(port, true);
40394520 tcpm_set_vbus(port, true);
40404521 if (port->ams == HARD_RESET)
40414522 tcpm_ams_finish(port);
....@@ -4044,12 +4525,14 @@
40444525 tcpm_set_state(port, SRC_UNATTACHED, PD_T_PS_SOURCE_ON);
40454526 break;
40464527 case SNK_HARD_RESET_SINK_OFF:
4528
+ /* Do not discharge/disconnect during hard reseet */
4529
+ tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, 0);
40474530 memset(&port->pps_data, 0, sizeof(port->pps_data));
40484531 tcpm_set_vconn(port, false);
40494532 if (port->pd_capable)
40504533 tcpm_set_charge(port, false);
40514534 tcpm_set_roles(port, port->self_powered, TYPEC_SINK,
4052
- TYPEC_DEVICE);
4535
+ tcpm_data_role_for_sink(port));
40534536 /*
40544537 * VBUS may or may not toggle, depending on the adapter.
40554538 * If it doesn't toggle, transition to SNK_HARD_RESET_SINK_ON
....@@ -4090,6 +4573,7 @@
40904573 if (port->ams == HARD_RESET)
40914574 tcpm_ams_finish(port);
40924575 tcpm_set_attached_state(port, true);
4576
+ tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, VSAFE5V);
40934577 tcpm_set_state(port, SNK_STARTUP, 0);
40944578 break;
40954579
....@@ -4098,6 +4582,7 @@
40984582 port->message_id = 0;
40994583 port->rx_msgid = -1;
41004584 tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
4585
+ tcpm_ams_finish(port);
41014586 if (port->pwr_role == TYPEC_SOURCE) {
41024587 port->upcoming_state = SRC_SEND_CAPABILITIES;
41034588 tcpm_ams_start(port, POWER_NEGOTIATION);
....@@ -4115,6 +4600,7 @@
41154600 case SOFT_RESET_SEND:
41164601 port->message_id = 0;
41174602 port->rx_msgid = -1;
4603
+ port->tcpc->set_pd_rx(port->tcpc, true);
41184604 if (tcpm_pd_send_control(port, PD_CTRL_SOFT_RESET))
41194605 tcpm_set_state_cond(port, hard_reset_state(port), 0);
41204606 else
....@@ -4125,52 +4611,33 @@
41254611 /* DR_Swap states */
41264612 case DR_SWAP_SEND:
41274613 tcpm_pd_send_control(port, PD_CTRL_DR_SWAP);
4614
+ if (port->data_role == TYPEC_DEVICE || port->negotiated_rev > PD_REV20)
4615
+ port->send_discover = true;
41284616 tcpm_set_state_cond(port, DR_SWAP_SEND_TIMEOUT,
41294617 PD_T_SENDER_RESPONSE);
41304618 break;
41314619 case DR_SWAP_ACCEPT:
41324620 tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
4133
- /* Set VDM state machine running flag ASAP */
4134
- if (port->data_role == TYPEC_DEVICE && port->send_discover)
4135
- port->vdm_sm_running = true;
4621
+ if (port->data_role == TYPEC_DEVICE || port->negotiated_rev > PD_REV20)
4622
+ port->send_discover = true;
41364623 tcpm_set_state_cond(port, DR_SWAP_CHANGE_DR, 0);
41374624 break;
41384625 case DR_SWAP_SEND_TIMEOUT:
41394626 tcpm_swap_complete(port, -ETIMEDOUT);
4627
+ port->send_discover = false;
4628
+ tcpm_ams_finish(port);
41404629 tcpm_set_state(port, ready_state(port), 0);
41414630 break;
41424631 case DR_SWAP_CHANGE_DR:
4143
- /*
4144
- * After the DR_swap process is executed, for the
4145
- * Rockchip platform, the tcpm framework needs to
4146
- * send two notifications to the dwc3 driver, the
4147
- * two notifications require a time interval.
4148
- *
4149
- * (a) For Type-C devices with DP function,
4150
- * a notification will be sent here, another
4151
- * notification can be sent after receiving
4152
- * Attention cmd.
4153
- * (b) But for Type-C devices without DP function,
4154
- * the tcpm framework will only send a notification once.
4155
- *
4156
- * Based on the above reasons, it is necessary to start
4157
- * the timer here, wait for 20 ms to start work and send
4158
- * the notification again.
4159
- */
4160
-
41614632 if (port->data_role == TYPEC_HOST) {
41624633 tcpm_unregister_altmodes(port);
41634634 tcpm_set_roles(port, true, port->pwr_role,
41644635 TYPEC_DEVICE);
4165
- tcpm_send_data_role_notify(port, false, TYPEC_HOST);
4166
- mod_data_role_swap_work(port, SEND_NEW_MODE_NOTIFY_MS);
41674636 } else {
41684637 tcpm_set_roles(port, true, port->pwr_role,
41694638 TYPEC_HOST);
4170
- port->send_discover = true;
4171
- tcpm_send_data_role_notify(port, false, TYPEC_DEVICE);
4172
- mod_data_role_swap_work(port, SEND_NEW_MODE_NOTIFY_MS);
41734639 }
4640
+ tcpm_ams_finish(port);
41744641 tcpm_set_state(port, ready_state(port), 0);
41754642 break;
41764643
....@@ -4185,7 +4652,10 @@
41854652 tcpm_set_state(port, ERROR_RECOVERY, 0);
41864653 break;
41874654 case FR_SWAP_SNK_SRC_TRANSITION_TO_OFF:
4188
- tcpm_set_state(port, ERROR_RECOVERY, PD_T_PS_SOURCE_OFF);
4655
+ timer_val_msecs = PD_T_PS_SOURCE_OFF;
4656
+ state_name = tcpm_states[FR_SWAP_SNK_SRC_TRANSITION_TO_OFF];
4657
+ trace_android_vh_typec_tcpm_get_timer(state_name, SOURCE_OFF, &timer_val_msecs);
4658
+ tcpm_set_state(port, ERROR_RECOVERY, timer_val_msecs);
41894659 break;
41904660 case FR_SWAP_SNK_SRC_NEW_SINK_READY:
41914661 if (port->vbus_source)
....@@ -4218,6 +4688,7 @@
42184688 tcpm_set_state(port, ready_state(port), 0);
42194689 break;
42204690 case PR_SWAP_START:
4691
+ tcpm_apply_rc(port);
42214692 if (port->pwr_role == TYPEC_SOURCE)
42224693 tcpm_set_state(port, PR_SWAP_SRC_SNK_TRANSITION_OFF,
42234694 PD_T_SRC_TRANSITION);
....@@ -4225,6 +4696,10 @@
42254696 tcpm_set_state(port, PR_SWAP_SNK_SRC_SINK_OFF, 0);
42264697 break;
42274698 case PR_SWAP_SRC_SNK_TRANSITION_OFF:
4699
+ /*
4700
+ * Prevent vbus discharge circuit from turning on during PR_SWAP
4701
+ * as this is not a disconnect.
4702
+ */
42284703 tcpm_set_vbus(port, false);
42294704 port->explicit_contract = false;
42304705 /* allow time for Vbus discharge, must be < tSrcSwapStdby */
....@@ -4232,10 +4707,13 @@
42324707 PD_T_SRCSWAPSTDBY);
42334708 break;
42344709 case PR_SWAP_SRC_SNK_SOURCE_OFF:
4710
+ timer_val_msecs = PD_T_CC_DEBOUNCE;
4711
+ trace_android_vh_typec_tcpm_get_timer(tcpm_states[PR_SWAP_SRC_SNK_SOURCE_OFF],
4712
+ CC_DEBOUNCE, &timer_val_msecs);
42354713 tcpm_set_cc(port, TYPEC_CC_RD);
42364714 /* allow CC debounce */
42374715 tcpm_set_state(port, PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED,
4238
- PD_T_CC_DEBOUNCE);
4716
+ timer_val_msecs);
42394717 break;
42404718 case PR_SWAP_SRC_SNK_SOURCE_OFF_CC_DEBOUNCED:
42414719 /*
....@@ -4250,17 +4728,29 @@
42504728 tcpm_set_state(port, ERROR_RECOVERY, 0);
42514729 break;
42524730 }
4253
- tcpm_set_state_cond(port, SNK_UNATTACHED, PD_T_PS_SOURCE_ON);
4731
+ tcpm_set_state(port, ERROR_RECOVERY, PD_T_PS_SOURCE_ON_PRS);
42544732 break;
42554733 case PR_SWAP_SRC_SNK_SINK_ON:
4734
+ tcpm_enable_auto_vbus_discharge(port, true);
4735
+ /* Set the vbus disconnect threshold for implicit contract */
4736
+ tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB, false, VSAFE5V);
42564737 tcpm_set_state(port, SNK_STARTUP, 0);
42574738 break;
42584739 case PR_SWAP_SNK_SRC_SINK_OFF:
4740
+ timer_val_msecs = PD_T_PS_SOURCE_OFF;
4741
+ trace_android_vh_typec_tcpm_get_timer(tcpm_states[PR_SWAP_SNK_SRC_SINK_OFF],
4742
+ SOURCE_OFF, &timer_val_msecs);
4743
+ /*
4744
+ * Prevent vbus discharge circuit from turning on during PR_SWAP
4745
+ * as this is not a disconnect.
4746
+ */
4747
+ tcpm_set_auto_vbus_discharge_threshold(port, TYPEC_PWR_MODE_USB,
4748
+ port->pps_data.active, 0);
42594749 tcpm_set_charge(port, false);
4260
- tcpm_set_state(port, hard_reset_state(port),
4261
- PD_T_PS_SOURCE_OFF);
4750
+ tcpm_set_state(port, hard_reset_state(port), timer_val_msecs);
42624751 break;
42634752 case PR_SWAP_SNK_SRC_SOURCE_ON:
4753
+ tcpm_enable_auto_vbus_discharge(port, true);
42644754 tcpm_set_cc(port, tcpm_rp_cc(port));
42654755 tcpm_set_vbus(port, true);
42664756 /*
....@@ -4286,6 +4776,7 @@
42864776
42874777 case VCONN_SWAP_ACCEPT:
42884778 tcpm_pd_send_control(port, PD_CTRL_ACCEPT);
4779
+ tcpm_ams_finish(port);
42894780 tcpm_set_state(port, VCONN_SWAP_START, 0);
42904781 break;
42914782 case VCONN_SWAP_SEND:
....@@ -4295,8 +4786,6 @@
42954786 break;
42964787 case VCONN_SWAP_SEND_TIMEOUT:
42974788 tcpm_swap_complete(port, -ETIMEDOUT);
4298
- if (port->data_role == TYPEC_HOST && port->send_discover)
4299
- port->vdm_sm_running = true;
43004789 tcpm_set_state(port, ready_state(port), 0);
43014790 break;
43024791 case VCONN_SWAP_START:
....@@ -4312,14 +4801,10 @@
43124801 case VCONN_SWAP_TURN_ON_VCONN:
43134802 tcpm_set_vconn(port, true);
43144803 tcpm_pd_send_control(port, PD_CTRL_PS_RDY);
4315
- if (port->data_role == TYPEC_HOST && port->send_discover)
4316
- port->vdm_sm_running = true;
43174804 tcpm_set_state(port, ready_state(port), 0);
43184805 break;
43194806 case VCONN_SWAP_TURN_OFF_VCONN:
43204807 tcpm_set_vconn(port, false);
4321
- if (port->data_role == TYPEC_HOST && port->send_discover)
4322
- port->vdm_sm_running = true;
43234808 tcpm_set_state(port, ready_state(port), 0);
43244809 break;
43254810
....@@ -4327,8 +4812,6 @@
43274812 case PR_SWAP_CANCEL:
43284813 case VCONN_SWAP_CANCEL:
43294814 tcpm_swap_complete(port, port->swap_status);
4330
- if (port->data_role == TYPEC_HOST && port->send_discover)
4331
- port->vdm_sm_running = true;
43324815 if (port->pwr_role == TYPEC_SOURCE)
43334816 tcpm_set_state(port, SRC_READY, 0);
43344817 else
....@@ -4345,12 +4828,18 @@
43454828 switch (BDO_MODE_MASK(port->bist_request)) {
43464829 case BDO_MODE_CARRIER2:
43474830 tcpm_pd_transmit(port, TCPC_TX_BIST_MODE_2, NULL);
4831
+ tcpm_set_state(port, unattached_state(port),
4832
+ PD_T_BIST_CONT_MODE);
4833
+ break;
4834
+ case BDO_MODE_TESTDATA:
4835
+ if (port->tcpc->set_bist_data) {
4836
+ tcpm_log(port, "Enable BIST MODE TESTDATA");
4837
+ port->tcpc->set_bist_data(port->tcpc, true);
4838
+ }
43484839 break;
43494840 default:
43504841 break;
43514842 }
4352
- /* Always switch to unattached state */
4353
- tcpm_set_state(port, unattached_state(port), 0);
43544843 break;
43554844 case GET_STATUS_SEND:
43564845 tcpm_pd_send_control(port, PD_CTRL_GET_STATUS);
....@@ -4383,14 +4872,17 @@
43834872 break;
43844873 case PORT_RESET:
43854874 tcpm_reset_port(port);
4386
- tcpm_set_cc(port, TYPEC_CC_OPEN);
4875
+ tcpm_set_cc(port, TYPEC_CC_RD);
43874876 tcpm_set_state(port, PORT_RESET_WAIT_OFF,
43884877 PD_T_ERROR_RECOVERY);
43894878 break;
43904879 case PORT_RESET_WAIT_OFF:
4880
+ timer_val_msecs = PD_T_PS_SOURCE_OFF;
4881
+ trace_android_vh_typec_tcpm_get_timer(tcpm_states[PORT_RESET_WAIT_OFF],
4882
+ SOURCE_OFF, &timer_val_msecs);
43914883 tcpm_set_state(port,
43924884 tcpm_default_state(port),
4393
- port->vbus_present ? PD_T_PS_SOURCE_OFF : 0);
4885
+ port->vbus_present ? timer_val_msecs : 0);
43944886 break;
43954887
43964888 /* AMS intermediate state */
....@@ -4404,6 +4896,12 @@
44044896 upcoming_state = port->upcoming_state;
44054897 port->upcoming_state = INVALID_STATE;
44064898 tcpm_set_state(port, upcoming_state, 0);
4899
+ break;
4900
+
4901
+ /* Chunk state */
4902
+ case CHUNK_NOT_SUPP:
4903
+ tcpm_pd_send_control(port, PD_CTRL_NOT_SUPP);
4904
+ tcpm_set_state(port, port->pwr_role == TYPEC_SOURCE ? SRC_READY : SNK_READY, 0);
44074905 break;
44084906 default:
44094907 WARN(1, "Unexpected port state %d\n", port->state);
....@@ -4488,11 +4986,16 @@
44884986 tcpm_set_state(port, SRC_ATTACH_WAIT, 0);
44894987 break;
44904988 case SRC_ATTACHED:
4989
+ case SRC_STARTUP:
44914990 case SRC_SEND_CAPABILITIES:
44924991 case SRC_READY:
44934992 if (tcpm_port_is_disconnected(port) ||
4494
- !tcpm_port_is_source(port))
4495
- tcpm_set_state(port, SRC_UNATTACHED, 0);
4993
+ !tcpm_port_is_source(port)) {
4994
+ if (port->port_type == TYPEC_PORT_SRC)
4995
+ tcpm_set_state(port, SRC_UNATTACHED, tcpm_wait_for_discharge(port));
4996
+ else
4997
+ tcpm_set_state(port, SNK_UNATTACHED, tcpm_wait_for_discharge(port));
4998
+ }
44964999 break;
44975000 case SNK_UNATTACHED:
44985001 if (tcpm_port_is_sink(port))
....@@ -4522,7 +5025,23 @@
45225025 tcpm_set_state(port, SNK_DEBOUNCED, 0);
45235026 break;
45245027 case SNK_READY:
4525
- if (tcpm_port_is_disconnected(port))
5028
+ /*
5029
+ * EXIT condition is based primarily on vbus disconnect and CC is secondary.
5030
+ * "A port that has entered into USB PD communications with the Source and
5031
+ * has seen the CC voltage exceed vRd-USB may monitor the CC pin to detect
5032
+ * cable disconnect in addition to monitoring VBUS.
5033
+ *
5034
+ * A port that is monitoring the CC voltage for disconnect (but is not in
5035
+ * the process of a USB PD PR_Swap or USB PD FR_Swap) shall transition to
5036
+ * Unattached.SNK within tSinkDisconnect after the CC voltage remains below
5037
+ * vRd-USB for tPDDebounce."
5038
+ *
5039
+ * When set_auto_vbus_discharge_threshold is enabled, CC pins go
5040
+ * away before vbus decays to disconnect threshold. Allow
5041
+ * disconnect to be driven by vbus disconnect when auto vbus
5042
+ * discharge is enabled.
5043
+ */
5044
+ if (!port->auto_vbus_discharge_enabled && tcpm_port_is_disconnected(port))
45265045 tcpm_set_state(port, unattached_state(port), 0);
45275046 else if (!port->pd_capable &&
45285047 (cc1 != old_cc1 || cc2 != old_cc2))
....@@ -4587,6 +5106,12 @@
45875106 if (!tcpm_port_is_sink(port))
45885107 tcpm_set_state(port, SNK_TRYWAIT_DEBOUNCE, 0);
45895108 break;
5109
+ case SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS:
5110
+ if (!tcpm_port_is_sink(port))
5111
+ tcpm_set_state(port, SRC_TRYWAIT, PD_T_TRY_CC_DEBOUNCE);
5112
+ else
5113
+ tcpm_set_state(port, SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS, 0);
5114
+ break;
45905115 case SNK_TRYWAIT:
45915116 /* Do nothing, waiting for tCCDebounce */
45925117 break;
....@@ -4615,9 +5140,13 @@
46155140 * Ignore CC changes here.
46165141 */
46175142 break;
4618
-
46195143 default:
4620
- if (tcpm_port_is_disconnected(port))
5144
+ /*
5145
+ * While acting as sink and auto vbus discharge is enabled, Allow disconnect
5146
+ * to be driven by vbus disconnect.
5147
+ */
5148
+ if (tcpm_port_is_disconnected(port) && !(port->pwr_role == TYPEC_SINK &&
5149
+ port->auto_vbus_discharge_enabled))
46215150 tcpm_set_state(port, unattached_state(port), 0);
46225151 break;
46235152 }
....@@ -4627,12 +5156,15 @@
46275156 {
46285157 tcpm_log_force(port, "VBUS on");
46295158 port->vbus_present = true;
5159
+ /*
5160
+ * When vbus_present is true i.e. Voltage at VBUS is greater than VSAFE5V implicitly
5161
+ * states that vbus is not at VSAFE0V, hence clear the vbus_vsafe0v flag here.
5162
+ */
5163
+ port->vbus_vsafe0v = false;
5164
+
46305165 switch (port->state) {
46315166 case SNK_TRANSITION_SINK_VBUS:
46325167 port->explicit_contract = true;
4633
- /* Set the VDM flag ASAP */
4634
- if (port->data_role == TYPEC_HOST && port->send_discover)
4635
- port->vdm_sm_running = true;
46365168 tcpm_set_state(port, SNK_READY, 0);
46375169 break;
46385170 case SNK_DISCOVERY:
....@@ -4676,11 +5208,24 @@
46765208 case SNK_TRYWAIT_DEBOUNCE:
46775209 /* Do nothing, waiting for Rp */
46785210 break;
5211
+ case SNK_TRY_WAIT_DEBOUNCE_CHECK_VBUS:
5212
+ if (port->vbus_present && tcpm_port_is_sink(port))
5213
+ tcpm_set_state(port, SNK_ATTACHED, 0);
5214
+ break;
46795215 case SRC_TRY_WAIT:
46805216 case SRC_TRY_DEBOUNCE:
46815217 /* Do nothing, waiting for sink detection */
46825218 break;
5219
+ case FR_SWAP_SEND:
5220
+ case FR_SWAP_SEND_TIMEOUT:
5221
+ case FR_SWAP_SNK_SRC_TRANSITION_TO_OFF:
5222
+ case FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED:
5223
+ if (port->tcpc->frs_sourcing_vbus)
5224
+ port->tcpc->frs_sourcing_vbus(port->tcpc);
5225
+ break;
46835226 case FR_SWAP_SNK_SRC_NEW_SINK_READY:
5227
+ if (port->tcpc->frs_sourcing_vbus)
5228
+ port->tcpc->frs_sourcing_vbus(port->tcpc);
46845229 tcpm_set_state(port, FR_SWAP_SNK_SRC_SOURCE_VBUS_APPLIED, 0);
46855230 break;
46865231
....@@ -4706,12 +5251,8 @@
47065251 case SNK_HARD_RESET_SINK_OFF:
47075252 tcpm_set_state(port, SNK_HARD_RESET_WAIT_VBUS, 0);
47085253 break;
4709
- case SRC_HARD_RESET_VBUS_OFF:
4710
- tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, 0);
4711
- break;
47125254 case HARD_RESET_SEND:
47135255 break;
4714
-
47155256 case SNK_TRY:
47165257 /* Do nothing, waiting for timeout */
47175258 break;
....@@ -4729,6 +5270,7 @@
47295270 break;
47305271 case SNK_ATTACH_WAIT:
47315272 case SNK_DEBOUNCED:
5273
+ port->debouncing = false;
47325274 /* Do nothing, as TCPM is still waiting for vbus to reaach VSAFE5V to connect */
47335275 break;
47345276
....@@ -4743,6 +5285,14 @@
47435285 /* Do nothing, expected */
47445286 break;
47455287
5288
+ case PR_SWAP_SNK_SRC_SOURCE_ON:
5289
+ /*
5290
+ * Do nothing when vbus off notification is received.
5291
+ * TCPM can wait for PD_T_NEWSRC in PR_SWAP_SNK_SRC_SOURCE_ON
5292
+ * for the vbus source to ramp up.
5293
+ */
5294
+ break;
5295
+
47465296 case PORT_RESET_WAIT_OFF:
47475297 tcpm_set_state(port, tcpm_default_state(port), 0);
47485298 break;
....@@ -4750,6 +5300,25 @@
47505300 case SRC_TRY_WAIT:
47515301 case SRC_TRY_DEBOUNCE:
47525302 /* Do nothing, waiting for sink detection */
5303
+ break;
5304
+
5305
+ case SRC_STARTUP:
5306
+ case SRC_SEND_CAPABILITIES:
5307
+ case SRC_SEND_CAPABILITIES_TIMEOUT:
5308
+ case SRC_NEGOTIATE_CAPABILITIES:
5309
+ case SRC_TRANSITION_SUPPLY:
5310
+ case SRC_READY:
5311
+ case SRC_WAIT_NEW_CAPABILITIES:
5312
+ /*
5313
+ * Force to unattached state to re-initiate connection.
5314
+ * DRP port should move to Unattached.SNK instead of Unattached.SRC if
5315
+ * sink removed. Although sink removal here is due to source's vbus collapse,
5316
+ * treat it the same way for consistency.
5317
+ */
5318
+ if (port->port_type == TYPEC_PORT_SRC)
5319
+ tcpm_set_state(port, SRC_UNATTACHED, tcpm_wait_for_discharge(port));
5320
+ else
5321
+ tcpm_set_state(port, SNK_UNATTACHED, tcpm_wait_for_discharge(port));
47535322 break;
47545323
47555324 case PORT_RESET:
....@@ -4768,8 +5337,58 @@
47685337 break;
47695338
47705339 default:
4771
- if (port->pwr_role == TYPEC_SINK &&
4772
- port->attached)
5340
+ if (port->pwr_role == TYPEC_SINK && port->attached)
5341
+ tcpm_set_state(port, SNK_UNATTACHED, tcpm_wait_for_discharge(port));
5342
+ break;
5343
+ }
5344
+}
5345
+
5346
+static void _tcpm_pd_vbus_vsafe0v(struct tcpm_port *port)
5347
+{
5348
+ unsigned int timer_val_msecs;
5349
+
5350
+ tcpm_log_force(port, "VBUS VSAFE0V");
5351
+ port->vbus_vsafe0v = true;
5352
+ switch (port->state) {
5353
+ case SRC_HARD_RESET_VBUS_OFF:
5354
+ /*
5355
+ * After establishing the vSafe0V voltage condition on VBUS, the Source Shall wait
5356
+ * tSrcRecover before re-applying VCONN and restoring VBUS to vSafe5V.
5357
+ */
5358
+ tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, PD_T_SRC_RECOVER);
5359
+ break;
5360
+ case SRC_ATTACH_WAIT:
5361
+ timer_val_msecs = PD_T_CC_DEBOUNCE;
5362
+ trace_android_vh_typec_tcpm_get_timer(tcpm_states[SRC_ATTACH_WAIT],
5363
+ CC_DEBOUNCE, &timer_val_msecs);
5364
+ if (tcpm_port_is_source(port))
5365
+ tcpm_set_state(port, tcpm_try_snk(port) ? SNK_TRY : SRC_ATTACHED,
5366
+ timer_val_msecs);
5367
+ break;
5368
+ case SRC_STARTUP:
5369
+ case SRC_SEND_CAPABILITIES:
5370
+ case SRC_SEND_CAPABILITIES_TIMEOUT:
5371
+ case SRC_NEGOTIATE_CAPABILITIES:
5372
+ case SRC_TRANSITION_SUPPLY:
5373
+ case SRC_READY:
5374
+ case SRC_WAIT_NEW_CAPABILITIES:
5375
+ if (port->auto_vbus_discharge_enabled) {
5376
+ if (port->port_type == TYPEC_PORT_SRC)
5377
+ tcpm_set_state(port, SRC_UNATTACHED, 0);
5378
+ else
5379
+ tcpm_set_state(port, SNK_UNATTACHED, 0);
5380
+ }
5381
+ break;
5382
+ case PR_SWAP_SNK_SRC_SINK_OFF:
5383
+ case PR_SWAP_SNK_SRC_SOURCE_ON:
5384
+ /* Do nothing, vsafe0v is expected during transition */
5385
+ break;
5386
+ case SNK_ATTACH_WAIT:
5387
+ case SNK_DEBOUNCED:
5388
+ /*Do nothing, still waiting for VSAFE5V for connect */
5389
+ break;
5390
+ default:
5391
+ if (port->pwr_role == TYPEC_SINK && port->auto_vbus_discharge_enabled)
47735392 tcpm_set_state(port, SNK_UNATTACHED, 0);
47745393 break;
47755394 }
....@@ -4778,9 +5397,13 @@
47785397 static void _tcpm_pd_hard_reset(struct tcpm_port *port)
47795398 {
47805399 tcpm_log_force(port, "Received hard reset");
5400
+ if (port->bist_request == BDO_MODE_TESTDATA && port->tcpc->set_bist_data)
5401
+ port->tcpc->set_bist_data(port->tcpc, false);
47815402
47825403 if (port->ams != NONE_AMS)
47835404 port->ams = NONE_AMS;
5405
+ if (port->hard_reset_count < PD_N_HARD_RESET_COUNT)
5406
+ port->ams = HARD_RESET;
47845407 /*
47855408 * If we keep receiving hard reset requests, executing the hard reset
47865409 * must have failed. Revert to error recovery if that happens.
....@@ -4797,7 +5420,9 @@
47975420 event_work);
47985421 u32 events;
47995422
5423
+#ifdef CONFIG_NO_GKI
48005424 mutex_lock(&port->pd_handler_lock);
5425
+#endif
48015426 mutex_lock(&port->lock);
48025427
48035428 spin_lock(&port->pd_event_lock);
....@@ -4811,10 +5436,19 @@
48115436 bool vbus;
48125437
48135438 vbus = port->tcpc->get_vbus(port->tcpc);
4814
- if (vbus)
5439
+ if (vbus) {
48155440 _tcpm_pd_vbus_on(port);
4816
- else
5441
+ } else {
48175442 _tcpm_pd_vbus_off(port);
5443
+ /*
5444
+ * When TCPC does not support detecting vsafe0v voltage level,
5445
+ * treat vbus absent as vsafe0v. Else invoke is_vbus_vsafe0v
5446
+ * to see if vbus has discharge to VSAFE0V.
5447
+ */
5448
+ if (!port->tcpc->is_vbus_vsafe0v ||
5449
+ port->tcpc->is_vbus_vsafe0v(port->tcpc))
5450
+ _tcpm_pd_vbus_vsafe0v(port);
5451
+ }
48185452 }
48195453 if (events & TCPM_CC_EVENT) {
48205454 enum typec_cc_status cc1, cc2;
....@@ -4851,7 +5485,9 @@
48515485 }
48525486 spin_unlock(&port->pd_event_lock);
48535487 mutex_unlock(&port->lock);
5488
+#ifdef CONFIG_NO_GKI
48545489 mutex_unlock(&port->pd_handler_lock);
5490
+#endif
48555491 }
48565492
48575493 void tcpm_cc_change(struct tcpm_port *port)
....@@ -4931,27 +5567,41 @@
49315567 mutex_unlock(&port->lock);
49325568 }
49335569
4934
-static void tcpm_data_role_swap_work(struct kthread_work *work)
5570
+static void tcpm_send_discover_work(struct kthread_work *work)
49355571 {
4936
- struct tcpm_port *port =
4937
- container_of(work, struct tcpm_port, data_role_swap);
5572
+ struct tcpm_port *port = container_of(work, struct tcpm_port, send_discover_work);
49385573
4939
- if (tcpm_port_is_disconnected(port))
4940
- return;
5574
+ mutex_lock(&port->lock);
5575
+ /* No need to send DISCOVER_IDENTITY anymore */
5576
+ if (!port->send_discover)
5577
+ goto unlock;
49415578
4942
- tcpm_send_data_role_notify(port, true, port->data_role);
5579
+ if (port->data_role == TYPEC_DEVICE && port->negotiated_rev < PD_REV30) {
5580
+ port->send_discover = false;
5581
+ goto unlock;
5582
+ }
5583
+
5584
+ /* Retry if the port is not idle */
5585
+ if ((port->state != SRC_READY && port->state != SNK_READY) || port->vdm_sm_running) {
5586
+ mod_send_discover_delayed_work(port, SEND_DISCOVER_RETRY_MS);
5587
+ goto unlock;
5588
+ }
5589
+
5590
+ tcpm_send_vdm(port, USB_SID_PD, CMD_DISCOVER_IDENT, NULL, 0);
5591
+
5592
+unlock:
5593
+ mutex_unlock(&port->lock);
49435594 }
49445595
4945
-static int tcpm_dr_set(const struct typec_capability *cap,
4946
- enum typec_data_role data)
5596
+static int tcpm_dr_set(struct typec_port *p, enum typec_data_role data)
49475597 {
4948
- struct tcpm_port *port = typec_cap_to_tcpm(cap);
5598
+ struct tcpm_port *port = typec_get_drvdata(p);
49495599 int ret;
49505600
49515601 mutex_lock(&port->swap_lock);
49525602 mutex_lock(&port->lock);
49535603
4954
- if (port->port_type != TYPEC_PORT_DRP) {
5604
+ if (port->typec_caps.data != TYPEC_PORT_DRD) {
49555605 ret = -EINVAL;
49565606 goto port_unlock;
49575607 }
....@@ -5015,10 +5665,9 @@
50155665 return ret;
50165666 }
50175667
5018
-static int tcpm_pr_set(const struct typec_capability *cap,
5019
- enum typec_role role)
5668
+static int tcpm_pr_set(struct typec_port *p, enum typec_role role)
50205669 {
5021
- struct tcpm_port *port = typec_cap_to_tcpm(cap);
5670
+ struct tcpm_port *port = typec_get_drvdata(p);
50225671 int ret;
50235672
50245673 mutex_lock(&port->swap_lock);
....@@ -5065,10 +5714,9 @@
50655714 return ret;
50665715 }
50675716
5068
-static int tcpm_vconn_set(const struct typec_capability *cap,
5069
- enum typec_role role)
5717
+static int tcpm_vconn_set(struct typec_port *p, enum typec_role role)
50705718 {
5071
- struct tcpm_port *port = typec_cap_to_tcpm(cap);
5719
+ struct tcpm_port *port = typec_get_drvdata(p);
50725720 int ret;
50735721
50745722 mutex_lock(&port->swap_lock);
....@@ -5111,9 +5759,9 @@
51115759 return ret;
51125760 }
51135761
5114
-static int tcpm_try_role(const struct typec_capability *cap, int role)
5762
+static int tcpm_try_role(struct typec_port *p, int role)
51155763 {
5116
- struct tcpm_port *port = typec_cap_to_tcpm(cap);
5764
+ struct tcpm_port *port = typec_get_drvdata(p);
51175765 struct tcpc_dev *tcpc = port->tcpc;
51185766 int ret = 0;
51195767
....@@ -5129,7 +5777,7 @@
51295777 return ret;
51305778 }
51315779
5132
-static int tcpm_pps_set_op_curr(struct tcpm_port *port, u16 op_curr)
5780
+static int tcpm_pps_set_op_curr(struct tcpm_port *port, u16 req_op_curr)
51335781 {
51345782 unsigned int target_mw;
51355783 int ret;
....@@ -5147,12 +5795,12 @@
51475795 goto port_unlock;
51485796 }
51495797
5150
- if (op_curr > port->pps_data.max_curr) {
5798
+ if (req_op_curr > port->pps_data.max_curr) {
51515799 ret = -EINVAL;
51525800 goto port_unlock;
51535801 }
51545802
5155
- target_mw = (op_curr * port->pps_data.out_volt) / 1000;
5803
+ target_mw = (req_op_curr * port->supply_voltage) / 1000;
51565804 if (target_mw < port->operating_snk_mw) {
51575805 ret = -EINVAL;
51585806 goto port_unlock;
....@@ -5166,10 +5814,10 @@
51665814 }
51675815
51685816 /* Round down operating current to align with PPS valid steps */
5169
- op_curr = op_curr - (op_curr % RDO_PROG_CURR_MA_STEP);
5817
+ req_op_curr = req_op_curr - (req_op_curr % RDO_PROG_CURR_MA_STEP);
51705818
51715819 reinit_completion(&port->pps_complete);
5172
- port->pps_data.op_curr = op_curr;
5820
+ port->pps_data.req_op_curr = req_op_curr;
51735821 port->pps_status = 0;
51745822 port->pps_pending = true;
51755823 mutex_unlock(&port->lock);
....@@ -5190,7 +5838,7 @@
51905838 return ret;
51915839 }
51925840
5193
-static int tcpm_pps_set_out_volt(struct tcpm_port *port, u16 out_volt)
5841
+static int tcpm_pps_set_out_volt(struct tcpm_port *port, u16 req_out_volt)
51945842 {
51955843 unsigned int target_mw;
51965844 int ret;
....@@ -5208,13 +5856,13 @@
52085856 goto port_unlock;
52095857 }
52105858
5211
- if (out_volt < port->pps_data.min_volt ||
5212
- out_volt > port->pps_data.max_volt) {
5859
+ if (req_out_volt < port->pps_data.min_volt ||
5860
+ req_out_volt > port->pps_data.max_volt) {
52135861 ret = -EINVAL;
52145862 goto port_unlock;
52155863 }
52165864
5217
- target_mw = (port->pps_data.op_curr * out_volt) / 1000;
5865
+ target_mw = (port->current_limit * req_out_volt) / 1000;
52185866 if (target_mw < port->operating_snk_mw) {
52195867 ret = -EINVAL;
52205868 goto port_unlock;
....@@ -5228,10 +5876,10 @@
52285876 }
52295877
52305878 /* Round down output voltage to align with PPS valid steps */
5231
- out_volt = out_volt - (out_volt % RDO_PROG_VOLT_MV_STEP);
5879
+ req_out_volt = req_out_volt - (req_out_volt % RDO_PROG_VOLT_MV_STEP);
52325880
52335881 reinit_completion(&port->pps_complete);
5234
- port->pps_data.out_volt = out_volt;
5882
+ port->pps_data.req_out_volt = req_out_volt;
52355883 port->pps_status = 0;
52365884 port->pps_pending = true;
52375885 mutex_unlock(&port->lock);
....@@ -5289,8 +5937,8 @@
52895937
52905938 /* Trigger PPS request or move back to standard PDO contract */
52915939 if (activate) {
5292
- port->pps_data.out_volt = port->supply_voltage;
5293
- port->pps_data.op_curr = port->current_limit;
5940
+ port->pps_data.req_out_volt = port->supply_voltage;
5941
+ port->pps_data.req_op_curr = port->current_limit;
52945942 }
52955943 mutex_unlock(&port->lock);
52965944
....@@ -5327,6 +5975,24 @@
53275975 if (port->vbus_present)
53285976 port->vbus_never_low = true;
53295977
5978
+ /*
5979
+ * 1. When vbus_present is true, voltage on VBUS is already at VSAFE5V.
5980
+ * So implicitly vbus_vsafe0v = false.
5981
+ *
5982
+ * 2. When vbus_present is false and TCPC does NOT support querying
5983
+ * vsafe0v status, then, it's best to assume vbus is at VSAFE0V i.e.
5984
+ * vbus_vsafe0v is true.
5985
+ *
5986
+ * 3. When vbus_present is false and TCPC does support querying vsafe0v,
5987
+ * then, query tcpc for vsafe0v status.
5988
+ */
5989
+ if (port->vbus_present)
5990
+ port->vbus_vsafe0v = false;
5991
+ else if (!port->tcpc->is_vbus_vsafe0v)
5992
+ port->vbus_vsafe0v = true;
5993
+ else
5994
+ port->vbus_vsafe0v = port->tcpc->is_vbus_vsafe0v(port->tcpc);
5995
+
53305996 tcpm_set_state(port, tcpm_default_state(port), 0);
53315997
53325998 if (port->tcpc->get_cc(port->tcpc, &cc1, &cc2) == 0)
....@@ -5339,10 +6005,9 @@
53396005 tcpm_set_state(port, PORT_RESET, 0);
53406006 }
53416007
5342
-static int tcpm_port_type_set(const struct typec_capability *cap,
5343
- enum typec_port_type type)
6008
+static int tcpm_port_type_set(struct typec_port *p, enum typec_port_type type)
53446009 {
5345
- struct tcpm_port *port = typec_cap_to_tcpm(cap);
6010
+ struct tcpm_port *port = typec_get_drvdata(p);
53466011
53476012 mutex_lock(&port->lock);
53486013 if (type == port->port_type)
....@@ -5367,6 +6032,14 @@
53676032 return 0;
53686033 }
53696034
6035
+static const struct typec_operations tcpm_ops = {
6036
+ .try_role = tcpm_try_role,
6037
+ .dr_set = tcpm_dr_set,
6038
+ .pr_set = tcpm_pr_set,
6039
+ .vconn_set = tcpm_vconn_set,
6040
+ .port_type_set = tcpm_port_type_set
6041
+};
6042
+
53706043 void tcpm_tcpc_reset(struct tcpm_port *port)
53716044 {
53726045 mutex_lock(&port->lock);
....@@ -5376,63 +6049,48 @@
53766049 }
53776050 EXPORT_SYMBOL_GPL(tcpm_tcpc_reset);
53786051
5379
-static int tcpm_copy_pdos(u32 *dest_pdo, const u32 *src_pdo,
5380
- unsigned int nr_pdo)
5381
-{
5382
- unsigned int i;
5383
-
5384
- if (nr_pdo > PDO_MAX_OBJECTS)
5385
- nr_pdo = PDO_MAX_OBJECTS;
5386
-
5387
- for (i = 0; i < nr_pdo; i++)
5388
- dest_pdo[i] = src_pdo[i];
5389
-
5390
- return nr_pdo;
5391
-}
5392
-
53936052 static int tcpm_fw_get_caps(struct tcpm_port *port,
53946053 struct fwnode_handle *fwnode)
53956054 {
53966055 const char *cap_str;
53976056 int ret;
5398
- u32 mw, frs_current;
6057
+ u32 mw, frs_current, pd_revision;
53996058
54006059 if (!fwnode)
54016060 return -EINVAL;
54026061
5403
- /* get vbus regulator */
5404
- port->vbus = devm_regulator_get_optional(port->dev, "vbus");
5405
- if (IS_ERR(port->vbus)) {
5406
- if (PTR_ERR(port->vbus) == -EPROBE_DEFER)
5407
- return PTR_ERR(port->vbus);
5408
-
5409
- dev_info(port->dev, "may no need vbus regulator\n");
5410
- port->vbus = NULL;
5411
- }
6062
+ ret = fwnode_property_read_u32(fwnode, "pd-revision",
6063
+ &pd_revision);
6064
+ if (ret < 0)
6065
+ port->typec_caps.pd_revision = 0x0300;
6066
+ else
6067
+ port->typec_caps.pd_revision = pd_revision & 0xffff;
54126068
54136069 /* USB data support is optional */
54146070 ret = fwnode_property_read_string(fwnode, "data-role", &cap_str);
54156071 if (ret == 0) {
5416
- port->typec_caps.data = typec_find_port_data_role(cap_str);
5417
- if (port->typec_caps.data < 0)
5418
- return -EINVAL;
6072
+ ret = typec_find_port_data_role(cap_str);
6073
+ if (ret < 0)
6074
+ return ret;
6075
+ port->typec_caps.data = ret;
54196076 }
54206077
54216078 ret = fwnode_property_read_string(fwnode, "power-role", &cap_str);
54226079 if (ret < 0)
54236080 return ret;
54246081
5425
- port->typec_caps.type = typec_find_port_power_role(cap_str);
5426
- if (port->typec_caps.type < 0)
5427
- return -EINVAL;
6082
+ ret = typec_find_port_power_role(cap_str);
6083
+ if (ret < 0)
6084
+ return ret;
6085
+ port->typec_caps.type = ret;
54286086 port->port_type = port->typec_caps.type;
54296087
6088
+ port->slow_charger_loop = fwnode_property_read_bool(fwnode, "slow-charger-loop");
54306089 if (port->port_type == TYPEC_PORT_SNK)
54316090 goto sink;
54326091
54336092 /* Get source pdos */
5434
- ret = fwnode_property_read_u32_array(fwnode, "source-pdos",
5435
- NULL, 0);
6093
+ ret = fwnode_property_count_u32(fwnode, "source-pdos");
54366094 if (ret <= 0)
54376095 return -EINVAL;
54386096
....@@ -5456,8 +6114,7 @@
54566114 return -EINVAL;
54576115 sink:
54586116 /* Get sink pdos */
5459
- ret = fwnode_property_read_u32_array(fwnode, "sink-pdos",
5460
- NULL, 0);
6117
+ ret = fwnode_property_count_u32(fwnode, "sink-pdos");
54616118 if (ret <= 0)
54626119 return -EINVAL;
54636120
....@@ -5476,9 +6133,10 @@
54766133
54776134 /* FRS can only be supported byb DRP ports */
54786135 if (port->port_type == TYPEC_PORT_DRP) {
5479
- ret = fwnode_property_read_u32(fwnode, "frs-typec-current", &frs_current);
6136
+ ret = fwnode_property_read_u32(fwnode, "new-source-frs-typec-current",
6137
+ &frs_current);
54806138 if (ret >= 0 && frs_current <= FRS_5V_3A)
5481
- port->frs_current = frs_current;
6139
+ port->new_source_frs_current = frs_current;
54826140 }
54836141
54846142 /* sink-vdos is optional */
....@@ -5495,49 +6153,49 @@
54956153 return ret;
54966154 }
54976155
5498
- return 0;
5499
-}
6156
+ /* If sink-vdos is found, sink-vdos-v1 is expected for backward compatibility. */
6157
+ if (port->nr_snk_vdo) {
6158
+ ret = fwnode_property_count_u32(fwnode, "sink-vdos-v1");
6159
+ if (ret < 0)
6160
+ return ret;
6161
+ else if (ret == 0)
6162
+ return -ENODATA;
55006163
5501
-int tcpm_update_source_capabilities(struct tcpm_port *port, const u32 *pdo,
5502
- unsigned int nr_pdo)
5503
-{
5504
- if (tcpm_validate_caps(port, pdo, nr_pdo))
5505
- return -EINVAL;
5506
-
5507
- mutex_lock(&port->lock);
5508
- port->nr_src_pdo = tcpm_copy_pdos(port->src_pdo, pdo, nr_pdo);
5509
- switch (port->state) {
5510
- case SRC_UNATTACHED:
5511
- case SRC_ATTACH_WAIT:
5512
- case SRC_TRYWAIT:
5513
- tcpm_set_cc(port, tcpm_rp_cc(port));
5514
- break;
5515
- case SRC_SEND_CAPABILITIES:
5516
- case SRC_NEGOTIATE_CAPABILITIES:
5517
- case SRC_READY:
5518
- case SRC_WAIT_NEW_CAPABILITIES:
5519
- tcpm_set_cc(port, tcpm_rp_cc(port));
5520
- tcpm_set_state(port, SRC_SEND_CAPABILITIES, 0);
5521
- break;
5522
- default:
5523
- break;
6164
+ port->nr_snk_vdo_v1 = min(ret, VDO_MAX_OBJECTS);
6165
+ ret = fwnode_property_read_u32_array(fwnode, "sink-vdos-v1",
6166
+ port->snk_vdo_v1,
6167
+ port->nr_snk_vdo_v1);
6168
+ if (ret < 0)
6169
+ return ret;
55246170 }
5525
- mutex_unlock(&port->lock);
6171
+
55266172 return 0;
55276173 }
5528
-EXPORT_SYMBOL_GPL(tcpm_update_source_capabilities);
55296174
5530
-int tcpm_update_sink_capabilities(struct tcpm_port *port, const u32 *pdo,
5531
- unsigned int nr_pdo,
6175
+static int tcpm_copy_pdos(u32 *dest_pdo, const u32 *src_pdo, unsigned int nr_pdo)
6176
+{
6177
+ unsigned int i;
6178
+
6179
+ if (nr_pdo > PDO_MAX_OBJECTS)
6180
+ nr_pdo = PDO_MAX_OBJECTS;
6181
+
6182
+ for (i = 0; i < nr_pdo; i++)
6183
+ dest_pdo[i] = src_pdo[i];
6184
+
6185
+ return nr_pdo;
6186
+}
6187
+
6188
+int tcpm_update_sink_capabilities(struct tcpm_port *port, const u32 *pdo, unsigned int nr_pdo,
55326189 unsigned int operating_snk_mw)
55336190 {
6191
+ int ret = 0;
6192
+
55346193 if (tcpm_validate_caps(port, pdo, nr_pdo))
55356194 return -EINVAL;
55366195
55376196 mutex_lock(&port->lock);
55386197 port->nr_snk_pdo = tcpm_copy_pdos(port->snk_pdo, pdo, nr_pdo);
55396198 port->operating_snk_mw = operating_snk_mw;
5540
- port->update_sink_caps = true;
55416199
55426200 switch (port->state) {
55436201 case SNK_NEGOTIATE_CAPABILITIES:
....@@ -5546,15 +6204,25 @@
55466204 case SNK_TRANSITION_SINK:
55476205 case SNK_TRANSITION_SINK_VBUS:
55486206 if (port->pps_data.active)
5549
- tcpm_set_state(port, SNK_NEGOTIATE_PPS_CAPABILITIES, 0);
6207
+ port->upcoming_state = SNK_NEGOTIATE_PPS_CAPABILITIES;
6208
+ else if (port->pd_capable)
6209
+ port->upcoming_state = SNK_NEGOTIATE_CAPABILITIES;
55506210 else
5551
- tcpm_set_state(port, SNK_NEGOTIATE_CAPABILITIES, 0);
6211
+ break;
6212
+
6213
+ port->update_sink_caps = true;
6214
+
6215
+ ret = tcpm_ams_start(port, POWER_NEGOTIATION);
6216
+ if (ret == -EAGAIN) {
6217
+ port->upcoming_state = INVALID_STATE;
6218
+ break;
6219
+ }
55526220 break;
55536221 default:
55546222 break;
55556223 }
55566224 mutex_unlock(&port->lock);
5557
- return 0;
6225
+ return ret;
55586226 }
55596227 EXPORT_SYMBOL_GPL(tcpm_update_sink_capabilities);
55606228
....@@ -5639,6 +6307,27 @@
56396307 return 0;
56406308 }
56416309
6310
+static int tcpm_psy_get_input_power_limit(struct tcpm_port *port,
6311
+ union power_supply_propval *val)
6312
+{
6313
+ unsigned int src_mv, src_ma, max_src_mw = 0;
6314
+ unsigned int i, tmp;
6315
+
6316
+ for (i = 0; i < port->nr_source_caps; i++) {
6317
+ u32 pdo = port->source_caps[i];
6318
+
6319
+ if (pdo_type(pdo) == PDO_TYPE_FIXED) {
6320
+ src_mv = pdo_fixed_voltage(pdo);
6321
+ src_ma = pdo_max_current(pdo);
6322
+ tmp = src_mv * src_ma / 1000;
6323
+ max_src_mw = tmp > max_src_mw ? tmp : max_src_mw;
6324
+ }
6325
+ }
6326
+
6327
+ val->intval = max_src_mw;
6328
+ return 0;
6329
+}
6330
+
56426331 static int tcpm_psy_get_prop(struct power_supply *psy,
56436332 enum power_supply_property psp,
56446333 union power_supply_propval *val)
....@@ -5668,11 +6357,13 @@
56686357 case POWER_SUPPLY_PROP_CURRENT_NOW:
56696358 ret = tcpm_psy_get_current_now(port, val);
56706359 break;
6360
+ case POWER_SUPPLY_PROP_INPUT_POWER_LIMIT:
6361
+ tcpm_psy_get_input_power_limit(port, val);
6362
+ break;
56716363 default:
56726364 ret = -EINVAL;
56736365 break;
56746366 }
5675
-
56766367 return ret;
56776368 }
56786369
....@@ -5724,7 +6415,7 @@
57246415 ret = -EINVAL;
57256416 break;
57266417 }
5727
-
6418
+ power_supply_changed(port->psy);
57286419 return ret;
57296420 }
57306421
....@@ -5807,92 +6498,18 @@
58076498 return HRTIMER_NORESTART;
58086499 }
58096500
5810
-static enum hrtimer_restart data_role_swap_timer_handler(struct hrtimer *timer)
6501
+static enum hrtimer_restart send_discover_timer_handler(struct hrtimer *timer)
58116502 {
5812
- struct tcpm_port *port =
5813
- container_of(timer, struct tcpm_port, data_role_swap_timer);
6503
+ struct tcpm_port *port = container_of(timer, struct tcpm_port, send_discover_timer);
58146504
5815
- kthread_queue_work(port->wq, &port->data_role_swap);
6505
+ kthread_queue_work(port->wq, &port->send_discover_work);
58166506 return HRTIMER_NORESTART;
5817
-}
5818
-
5819
-static int tcpm_extcon_register(struct tcpm_port *port)
5820
-{
5821
- struct extcon_dev *extcon;
5822
- int ret;
5823
-
5824
- extcon = devm_extcon_dev_allocate(port->dev, tcpm_cable);
5825
- if (IS_ERR(extcon)) {
5826
- dev_err(port->dev, "allocate extcon failed\n");
5827
- return -ENOMEM;
5828
- }
5829
-
5830
- ret = devm_extcon_dev_register(port->dev, extcon);
5831
- if (ret) {
5832
- dev_err(port->dev, "failed to register extcon: %d\n", ret);
5833
- goto init_err;
5834
- }
5835
-
5836
- ret = extcon_set_property_capability(extcon, EXTCON_USB,
5837
- EXTCON_PROP_USB_TYPEC_POLARITY);
5838
- if (ret) {
5839
- dev_err(port->dev, "failed to set USB property capability: %d\n", ret);
5840
- goto init_err;
5841
- }
5842
-
5843
- ret = extcon_set_property_capability(extcon, EXTCON_USB_HOST,
5844
- EXTCON_PROP_USB_TYPEC_POLARITY);
5845
- if (ret) {
5846
- dev_err(port->dev, "failed to set USB_HOST property capability: %d\n", ret);
5847
- goto init_err;
5848
- }
5849
-
5850
- ret = extcon_set_property_capability(extcon, EXTCON_DISP_DP,
5851
- EXTCON_PROP_USB_TYPEC_POLARITY);
5852
- if (ret) {
5853
- dev_err(port->dev, "failed to set DISP_DP property capability: %d\n", ret);
5854
- goto init_err;
5855
- }
5856
-
5857
- ret = extcon_set_property_capability(extcon, EXTCON_USB, EXTCON_PROP_USB_SS);
5858
- if (ret) {
5859
- dev_err(port->dev, "failed to set USB USB_SS property capability: %d\n", ret);
5860
- goto init_err;
5861
- }
5862
-
5863
- ret = extcon_set_property_capability(extcon, EXTCON_USB_HOST, EXTCON_PROP_USB_SS);
5864
- if (ret) {
5865
- dev_err(port->dev, "failed to set USB_HOST USB_SS property capability: %d", ret);
5866
- goto init_err;
5867
- }
5868
-
5869
- ret = extcon_set_property_capability(extcon, EXTCON_DISP_DP, EXTCON_PROP_USB_SS);
5870
- if (ret) {
5871
- dev_err(port->dev, "failed to set DISP_DP USB_SS property capability: %d", ret);
5872
- goto init_err;
5873
- }
5874
-
5875
- ret = extcon_set_property_capability(extcon, EXTCON_CHG_USB_FAST,
5876
- EXTCON_PROP_USB_TYPEC_POLARITY);
5877
- if (ret) {
5878
- dev_err(port->dev, "failed to set USB_PD property capability: %d\n", ret);
5879
- goto init_err;
5880
- }
5881
-
5882
- port->extcon = extcon;
5883
- tcpm_log(port, "init extcon finished\n");
5884
-
5885
- return 0;
5886
-
5887
-init_err:
5888
- return ret;
58896507 }
58906508
58916509 struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc)
58926510 {
58936511 struct tcpm_port *port;
58946512 int err;
5895
- struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
58966513
58976514 if (!dev || !tcpc ||
58986515 !tcpc->get_vbus || !tcpc->set_cc || !tcpc->get_cc ||
....@@ -5909,26 +6526,28 @@
59096526
59106527 mutex_init(&port->lock);
59116528 mutex_init(&port->swap_lock);
6529
+#ifdef CONFIG_NO_GKI
59126530 mutex_init(&port->pd_handler_lock);
6531
+#endif
59136532
59146533 port->wq = kthread_create_worker(0, dev_name(dev));
59156534 if (IS_ERR(port->wq))
59166535 return ERR_CAST(port->wq);
5917
- sched_setscheduler_nocheck(port->wq->task, SCHED_FIFO, &param);
6536
+ sched_set_fifo(port->wq->task);
59186537
59196538 kthread_init_work(&port->state_machine, tcpm_state_machine_work);
59206539 kthread_init_work(&port->vdm_state_machine, vdm_state_machine_work);
59216540 kthread_init_work(&port->event_work, tcpm_pd_event_handler);
59226541 kthread_init_work(&port->enable_frs, tcpm_enable_frs_work);
5923
- kthread_init_work(&port->data_role_swap, tcpm_data_role_swap_work);
6542
+ kthread_init_work(&port->send_discover_work, tcpm_send_discover_work);
59246543 hrtimer_init(&port->state_machine_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
59256544 port->state_machine_timer.function = state_machine_timer_handler;
59266545 hrtimer_init(&port->vdm_state_machine_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
59276546 port->vdm_state_machine_timer.function = vdm_state_machine_timer_handler;
59286547 hrtimer_init(&port->enable_frs_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
59296548 port->enable_frs_timer.function = enable_frs_timer_handler;
5930
- hrtimer_init(&port->data_role_swap_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
5931
- port->data_role_swap_timer.function = data_role_swap_timer_handler;
6549
+ hrtimer_init(&port->send_discover_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
6550
+ port->send_discover_timer.function = send_discover_timer_handler;
59326551
59336552 spin_lock_init(&port->pd_event_lock);
59346553
....@@ -5936,11 +6555,6 @@
59366555 init_completion(&port->swap_complete);
59376556 init_completion(&port->pps_complete);
59386557 tcpm_debugfs_init(port);
5939
-
5940
- /* init extcon */
5941
- err = tcpm_extcon_register(port);
5942
- if (err)
5943
- goto out_destroy_wq;
59446558
59456559 err = tcpm_fw_get_caps(port, tcpc->fwnode);
59466560 if (err < 0)
....@@ -5950,12 +6564,10 @@
59506564
59516565 port->typec_caps.fwnode = tcpc->fwnode;
59526566 port->typec_caps.revision = 0x0120; /* Type-C spec release 1.2 */
5953
- port->typec_caps.pd_revision = 0x0300; /* USB-PD spec release 3.0 */
5954
- port->typec_caps.dr_set = tcpm_dr_set;
5955
- port->typec_caps.pr_set = tcpm_pr_set;
5956
- port->typec_caps.vconn_set = tcpm_vconn_set;
5957
- port->typec_caps.try_role = tcpm_try_role;
5958
- port->typec_caps.port_type_set = tcpm_port_type_set;
6567
+ port->typec_caps.svdm_version = SVDM_VER_2_0;
6568
+ port->typec_caps.driver_data = port;
6569
+ port->typec_caps.ops = &tcpm_ops;
6570
+ port->typec_caps.orientation_aware = 1;
59596571
59606572 port->partner_desc.identity = &port->partner_ident;
59616573 port->port_type = port->typec_caps.type;
....@@ -5968,12 +6580,13 @@
59686580
59696581 err = devm_tcpm_psy_register(port);
59706582 if (err)
5971
- goto out_destroy_wq;
6583
+ goto out_role_sw_put;
6584
+ power_supply_changed(port->psy);
59726585
59736586 port->typec_port = typec_register_port(port->dev, &port->typec_caps);
59746587 if (IS_ERR(port->typec_port)) {
59756588 err = PTR_ERR(port->typec_port);
5976
- goto out_destroy_wq;
6589
+ goto out_role_sw_put;
59776590 }
59786591
59796592 typec_port_register_altmodes(port->typec_port,
....@@ -5987,8 +6600,10 @@
59876600 tcpm_log(port, "%s: registered", dev_name(dev));
59886601 return port;
59896602
5990
-out_destroy_wq:
6603
+out_role_sw_put:
59916604 usb_role_switch_put(port->role_sw);
6605
+out_destroy_wq:
6606
+ tcpm_debugfs_exit(port);
59926607 kthread_destroy_worker(port->wq);
59936608 return ERR_PTR(err);
59946609 }
....@@ -5998,10 +6613,10 @@
59986613 {
59996614 int i;
60006615
6616
+ hrtimer_cancel(&port->send_discover_timer);
60016617 hrtimer_cancel(&port->enable_frs_timer);
60026618 hrtimer_cancel(&port->vdm_state_machine_timer);
60036619 hrtimer_cancel(&port->state_machine_timer);
6004
- hrtimer_cancel(&port->data_role_swap_timer);
60056620
60066621 tcpm_reset_port(port);
60076622 for (i = 0; i < ARRAY_SIZE(port->port_altmode); i++)