blob: a6a738003d00ab5eb4e41db47b286814063cb017 [file] [log] [blame]
rbandi20d026b2020-03-18 10:15:47 -07001/* Copyright (c) 2016-2020, Linux Foundation. All rights reserved.
Jack Phamf4baeb12017-02-03 19:01:48 -08002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/completion.h>
14#include <linux/delay.h>
15#include <linux/hrtimer.h>
16#include <linux/ipc_logging.h>
17#include <linux/kernel.h>
18#include <linux/list.h>
19#include <linux/module.h>
20#include <linux/of.h>
21#include <linux/of_platform.h>
22#include <linux/power_supply.h>
23#include <linux/regulator/consumer.h>
24#include <linux/slab.h>
25#include <linux/spinlock.h>
26#include <linux/workqueue.h>
27#include <linux/extcon.h>
28#include <linux/usb/class-dual-role.h>
29#include <linux/usb/usbpd.h>
30#include "usbpd.h"
31
Vijayavardhan Vennapusa34a1f1d2017-05-31 12:00:37 +053032/* To start USB stack for USB3.1 complaince testing */
33static bool usb_compliance_mode;
34module_param(usb_compliance_mode, bool, 0644);
35MODULE_PARM_DESC(usb_compliance_mode, "Start USB stack for USB3.1 compliance testing");
36
Vijayavardhan Vennapusa49f21ce2017-06-05 14:47:56 +053037static bool disable_usb_pd;
38module_param(disable_usb_pd, bool, 0644);
39MODULE_PARM_DESC(disable_usb_pd, "Disable USB PD for USB3.1 compliance testing");
40
Hemant Kumarbe746222017-07-20 13:51:49 -070041static bool rev3_sink_only;
42module_param(rev3_sink_only, bool, 0644);
43MODULE_PARM_DESC(rev3_sink_only, "Enable power delivery rev3.0 sink only mode");
44
rbandi20d026b2020-03-18 10:15:47 -070045#define XR1_DISCOVER_VDO 0x1085
46#define XR1_DEFAULT_VDO 0x0
47#define XR1_PIN_E_VDO 0x0082
48#define DP_USBPD_EVT_STATUS_XR1 0x10
49#define DP_USBPD_EVT_CONFIGURE_XR1 0x11
50static bool sxr_dp_mode;
51
Jack Phamf4baeb12017-02-03 19:01:48 -080052enum usbpd_state {
53 PE_UNKNOWN,
54 PE_ERROR_RECOVERY,
55 PE_SRC_DISABLED,
56 PE_SRC_STARTUP,
57 PE_SRC_SEND_CAPABILITIES,
58 PE_SRC_SEND_CAPABILITIES_WAIT, /* substate to wait for Request */
59 PE_SRC_NEGOTIATE_CAPABILITY,
60 PE_SRC_TRANSITION_SUPPLY,
61 PE_SRC_READY,
62 PE_SRC_HARD_RESET,
63 PE_SRC_SOFT_RESET,
64 PE_SRC_SEND_SOFT_RESET,
65 PE_SRC_DISCOVERY,
66 PE_SRC_TRANSITION_TO_DEFAULT,
67 PE_SNK_STARTUP,
68 PE_SNK_DISCOVERY,
69 PE_SNK_WAIT_FOR_CAPABILITIES,
70 PE_SNK_EVALUATE_CAPABILITY,
71 PE_SNK_SELECT_CAPABILITY,
72 PE_SNK_TRANSITION_SINK,
73 PE_SNK_READY,
74 PE_SNK_HARD_RESET,
75 PE_SNK_SOFT_RESET,
76 PE_SNK_SEND_SOFT_RESET,
77 PE_SNK_TRANSITION_TO_DEFAULT,
78 PE_DRS_SEND_DR_SWAP,
79 PE_PRS_SNK_SRC_SEND_SWAP,
80 PE_PRS_SNK_SRC_TRANSITION_TO_OFF,
81 PE_PRS_SNK_SRC_SOURCE_ON,
82 PE_PRS_SRC_SNK_SEND_SWAP,
83 PE_PRS_SRC_SNK_TRANSITION_TO_OFF,
84 PE_PRS_SRC_SNK_WAIT_SOURCE_ON,
85 PE_VCS_WAIT_FOR_VCONN,
86};
87
88static const char * const usbpd_state_strings[] = {
89 "UNKNOWN",
90 "ERROR_RECOVERY",
91 "SRC_Disabled",
92 "SRC_Startup",
93 "SRC_Send_Capabilities",
94 "SRC_Send_Capabilities (Wait for Request)",
95 "SRC_Negotiate_Capability",
96 "SRC_Transition_Supply",
97 "SRC_Ready",
98 "SRC_Hard_Reset",
99 "SRC_Soft_Reset",
100 "SRC_Send_Soft_Reset",
101 "SRC_Discovery",
102 "SRC_Transition_to_default",
103 "SNK_Startup",
104 "SNK_Discovery",
105 "SNK_Wait_for_Capabilities",
106 "SNK_Evaluate_Capability",
107 "SNK_Select_Capability",
108 "SNK_Transition_Sink",
109 "SNK_Ready",
110 "SNK_Hard_Reset",
111 "SNK_Soft_Reset",
112 "SNK_Send_Soft_Reset",
113 "SNK_Transition_to_default",
114 "DRS_Send_DR_Swap",
115 "PRS_SNK_SRC_Send_Swap",
116 "PRS_SNK_SRC_Transition_to_off",
117 "PRS_SNK_SRC_Source_on",
118 "PRS_SRC_SNK_Send_Swap",
119 "PRS_SRC_SNK_Transition_to_off",
120 "PRS_SRC_SNK_Wait_Source_on",
121 "VCS_Wait_for_VCONN",
122};
123
124enum usbpd_control_msg_type {
125 MSG_RESERVED = 0,
126 MSG_GOODCRC,
127 MSG_GOTOMIN,
128 MSG_ACCEPT,
129 MSG_REJECT,
130 MSG_PING,
131 MSG_PS_RDY,
132 MSG_GET_SOURCE_CAP,
133 MSG_GET_SINK_CAP,
134 MSG_DR_SWAP,
135 MSG_PR_SWAP,
136 MSG_VCONN_SWAP,
137 MSG_WAIT,
138 MSG_SOFT_RESET,
Jack Phamf3c1bd32017-08-02 18:32:23 -0700139 MSG_NOT_SUPPORTED = 0x10,
140 MSG_GET_SOURCE_CAP_EXTENDED,
141 MSG_GET_STATUS,
142 MSG_FR_SWAP,
143 MSG_GET_PPS_STATUS,
144 MSG_GET_COUNTRY_CODES,
Jack Phamf4baeb12017-02-03 19:01:48 -0800145};
146
Jack Pham722527a2018-06-28 23:17:17 -0700147static const char * const usbpd_control_msg_strings[] = {
148 "", "GoodCRC", "GotoMin", "Accept", "Reject", "Ping", "PS_RDY",
149 "Get_Source_Cap", "Get_Sink_Cap", "DR_Swap", "PR_Swap", "VCONN_Swap",
150 "Wait", "Soft_Reset", "", "", "Not_Supported",
151 "Get_Source_Cap_Extended", "Get_Status", "FR_Swap", "Get_PPS_Status",
152 "Get_Country_Codes",
153};
154
Jack Phamf4baeb12017-02-03 19:01:48 -0800155enum usbpd_data_msg_type {
156 MSG_SOURCE_CAPABILITIES = 1,
157 MSG_REQUEST,
158 MSG_BIST,
159 MSG_SINK_CAPABILITIES,
Jack Phamf3c1bd32017-08-02 18:32:23 -0700160 MSG_BATTERY_STATUS,
161 MSG_ALERT,
162 MSG_GET_COUNTRY_INFO,
Jack Phamf4baeb12017-02-03 19:01:48 -0800163 MSG_VDM = 0xF,
164};
165
Jack Pham722527a2018-06-28 23:17:17 -0700166static const char * const usbpd_data_msg_strings[] = {
167 "", "Source_Capabilities", "Request", "BIST", "Sink_Capabilities",
168 "Battery_Status", "Alert", "Get_Country_Info", "", "", "", "", "", "",
169 "", "Vendor_Defined",
170};
171
Jack Phamf3c1bd32017-08-02 18:32:23 -0700172enum usbpd_ext_msg_type {
173 MSG_SOURCE_CAPABILITIES_EXTENDED = 1,
174 MSG_STATUS,
175 MSG_GET_BATTERY_CAP,
176 MSG_GET_BATTERY_STATUS,
177 MSG_BATTERY_CAPABILITIES,
178 MSG_GET_MANUFACTURER_INFO,
179 MSG_MANUFACTURER_INFO,
180 MSG_SECURITY_REQUEST,
181 MSG_SECURITY_RESPONSE,
182 MSG_FIRMWARE_UPDATE_REQUEST,
183 MSG_FIRMWARE_UPDATE_RESPONSE,
184 MSG_PPS_STATUS,
185 MSG_COUNTRY_INFO,
186 MSG_COUNTRY_CODES,
187};
188
Jack Pham722527a2018-06-28 23:17:17 -0700189static const char * const usbpd_ext_msg_strings[] = {
190 "", "Source_Capabilities_Extended", "Status", "Get_Battery_Cap",
191 "Get_Battery_Status", "Get_Manufacturer_Info", "Manufacturer_Info",
192 "Security_Request", "Security_Response", "Firmware_Update_Request",
193 "Firmware_Update_Response", "PPS_Status", "Country_Info",
194 "Country_Codes",
195};
196
197static inline const char *msg_to_string(u8 id, bool is_data, bool is_ext)
198{
199 if (is_ext) {
200 if (id < ARRAY_SIZE(usbpd_ext_msg_strings))
201 return usbpd_ext_msg_strings[id];
202 } else if (is_data) {
203 if (id < ARRAY_SIZE(usbpd_data_msg_strings))
204 return usbpd_data_msg_strings[id];
205 } else if (id < ARRAY_SIZE(usbpd_control_msg_strings)) {
206 return usbpd_control_msg_strings[id];
207 }
208
209 return "Invalid";
210}
211
Jack Phamf4baeb12017-02-03 19:01:48 -0800212enum vdm_state {
213 VDM_NONE,
214 DISCOVERED_ID,
215 DISCOVERED_SVIDS,
216 DISCOVERED_MODES,
217 MODE_ENTERED,
218 MODE_EXITED,
219};
220
221static void *usbpd_ipc_log;
222#define usbpd_dbg(dev, fmt, ...) do { \
223 ipc_log_string(usbpd_ipc_log, "%s: %s: " fmt, dev_name(dev), __func__, \
224 ##__VA_ARGS__); \
225 dev_dbg(dev, fmt, ##__VA_ARGS__); \
226 } while (0)
227
228#define usbpd_info(dev, fmt, ...) do { \
229 ipc_log_string(usbpd_ipc_log, "%s: %s: " fmt, dev_name(dev), __func__, \
230 ##__VA_ARGS__); \
231 dev_info(dev, fmt, ##__VA_ARGS__); \
232 } while (0)
233
234#define usbpd_warn(dev, fmt, ...) do { \
235 ipc_log_string(usbpd_ipc_log, "%s: %s: " fmt, dev_name(dev), __func__, \
236 ##__VA_ARGS__); \
237 dev_warn(dev, fmt, ##__VA_ARGS__); \
238 } while (0)
239
240#define usbpd_err(dev, fmt, ...) do { \
241 ipc_log_string(usbpd_ipc_log, "%s: %s: " fmt, dev_name(dev), __func__, \
242 ##__VA_ARGS__); \
243 dev_err(dev, fmt, ##__VA_ARGS__); \
244 } while (0)
245
246#define NUM_LOG_PAGES 10
247
248/* Timeouts (in ms) */
249#define ERROR_RECOVERY_TIME 25
250#define SENDER_RESPONSE_TIME 26
251#define SINK_WAIT_CAP_TIME 500
252#define PS_TRANSITION_TIME 450
253#define SRC_CAP_TIME 120
254#define SRC_TRANSITION_TIME 25
255#define SRC_RECOVER_TIME 750
256#define PS_HARD_RESET_TIME 25
257#define PS_SOURCE_ON 400
258#define PS_SOURCE_OFF 750
Jack Pham92d2d672018-10-17 00:13:44 -0700259#define FIRST_SOURCE_CAP_TIME 100
Jack Phamf4baeb12017-02-03 19:01:48 -0800260#define VDM_BUSY_TIME 50
261#define VCONN_ON_TIME 100
262
263/* tPSHardReset + tSafe0V */
264#define SNK_HARD_RESET_VBUS_OFF_TIME (35 + 650)
265
266/* tSrcRecover + tSrcTurnOn */
267#define SNK_HARD_RESET_VBUS_ON_TIME (1000 + 275)
268
269#define PD_CAPS_COUNT 50
270
271#define PD_MAX_MSG_ID 7
272
Hemant Kumar796534e2017-05-30 15:54:55 -0700273#define PD_MAX_DATA_OBJ 7
274
Hemant Kumar018b5982017-08-09 14:14:37 -0700275#define PD_SRC_CAP_EXT_DB_LEN 24
Hemant Kumara1875942017-08-09 16:50:14 -0700276#define PD_STATUS_DB_LEN 5
Hemant Kumar51ded972017-08-09 17:57:24 -0700277#define PD_BATTERY_CAP_DB_LEN 9
Hemant Kumar018b5982017-08-09 14:14:37 -0700278
Jack Phamf3c1bd32017-08-02 18:32:23 -0700279#define PD_MAX_EXT_MSG_LEN 260
280#define PD_MAX_EXT_MSG_LEGACY_LEN 26
281
Jack Phamf4baeb12017-02-03 19:01:48 -0800282#define PD_MSG_HDR(type, dr, pr, id, cnt, rev) \
Jack Phamf3c1bd32017-08-02 18:32:23 -0700283 (((type) & 0x1F) | ((dr) << 5) | (rev << 6) | \
Jack Phamf4baeb12017-02-03 19:01:48 -0800284 ((pr) << 8) | ((id) << 9) | ((cnt) << 12))
Jack Phamf3c1bd32017-08-02 18:32:23 -0700285#define PD_MSG_HDR_COUNT(hdr) (((hdr) >> 12) & 7)
286#define PD_MSG_HDR_TYPE(hdr) ((hdr) & 0x1F)
287#define PD_MSG_HDR_ID(hdr) (((hdr) >> 9) & 7)
288#define PD_MSG_HDR_REV(hdr) (((hdr) >> 6) & 3)
289#define PD_MSG_HDR_EXTENDED BIT(15)
290#define PD_MSG_HDR_IS_EXTENDED(hdr) ((hdr) & PD_MSG_HDR_EXTENDED)
291
292#define PD_MSG_EXT_HDR(chunked, num, req, size) \
293 (((chunked) << 15) | (((num) & 0xF) << 11) | \
294 ((req) << 10) | ((size) & 0x1FF))
295#define PD_MSG_EXT_HDR_IS_CHUNKED(ehdr) ((ehdr) & 0x8000)
296#define PD_MSG_EXT_HDR_CHUNK_NUM(ehdr) (((ehdr) >> 11) & 0xF)
297#define PD_MSG_EXT_HDR_REQ_CHUNK(ehdr) ((ehdr) & 0x400)
298#define PD_MSG_EXT_HDR_DATA_SIZE(ehdr) ((ehdr) & 0x1FF)
Jack Phamf4baeb12017-02-03 19:01:48 -0800299
300#define PD_RDO_FIXED(obj, gb, mismatch, usb_comm, no_usb_susp, curr1, curr2) \
301 (((obj) << 28) | ((gb) << 27) | ((mismatch) << 26) | \
302 ((usb_comm) << 25) | ((no_usb_susp) << 24) | \
303 ((curr1) << 10) | (curr2))
304
305#define PD_RDO_AUGMENTED(obj, mismatch, usb_comm, no_usb_susp, volt, curr) \
306 (((obj) << 28) | ((mismatch) << 26) | ((usb_comm) << 25) | \
307 ((no_usb_susp) << 24) | ((volt) << 9) | (curr))
308
309#define PD_RDO_OBJ_POS(rdo) ((rdo) >> 28 & 7)
310#define PD_RDO_GIVEBACK(rdo) ((rdo) >> 27 & 1)
311#define PD_RDO_MISMATCH(rdo) ((rdo) >> 26 & 1)
312#define PD_RDO_USB_COMM(rdo) ((rdo) >> 25 & 1)
313#define PD_RDO_NO_USB_SUSP(rdo) ((rdo) >> 24 & 1)
314#define PD_RDO_FIXED_CURR(rdo) ((rdo) >> 10 & 0x3FF)
315#define PD_RDO_FIXED_CURR_MINMAX(rdo) ((rdo) & 0x3FF)
316#define PD_RDO_PROG_VOLTAGE(rdo) ((rdo) >> 9 & 0x7FF)
317#define PD_RDO_PROG_CURR(rdo) ((rdo) & 0x7F)
318
319#define PD_SRC_PDO_TYPE(pdo) (((pdo) >> 30) & 3)
320#define PD_SRC_PDO_TYPE_FIXED 0
321#define PD_SRC_PDO_TYPE_BATTERY 1
322#define PD_SRC_PDO_TYPE_VARIABLE 2
323#define PD_SRC_PDO_TYPE_AUGMENTED 3
324
325#define PD_SRC_PDO_FIXED_PR_SWAP(pdo) (((pdo) >> 29) & 1)
326#define PD_SRC_PDO_FIXED_USB_SUSP(pdo) (((pdo) >> 28) & 1)
327#define PD_SRC_PDO_FIXED_EXT_POWERED(pdo) (((pdo) >> 27) & 1)
328#define PD_SRC_PDO_FIXED_USB_COMM(pdo) (((pdo) >> 26) & 1)
329#define PD_SRC_PDO_FIXED_DR_SWAP(pdo) (((pdo) >> 25) & 1)
330#define PD_SRC_PDO_FIXED_PEAK_CURR(pdo) (((pdo) >> 20) & 3)
331#define PD_SRC_PDO_FIXED_VOLTAGE(pdo) (((pdo) >> 10) & 0x3FF)
332#define PD_SRC_PDO_FIXED_MAX_CURR(pdo) ((pdo) & 0x3FF)
333
334#define PD_SRC_PDO_VAR_BATT_MAX_VOLT(pdo) (((pdo) >> 20) & 0x3FF)
335#define PD_SRC_PDO_VAR_BATT_MIN_VOLT(pdo) (((pdo) >> 10) & 0x3FF)
336#define PD_SRC_PDO_VAR_BATT_MAX(pdo) ((pdo) & 0x3FF)
337
338#define PD_APDO_PPS(pdo) (((pdo) >> 28) & 3)
339#define PD_APDO_MAX_VOLT(pdo) (((pdo) >> 17) & 0xFF)
340#define PD_APDO_MIN_VOLT(pdo) (((pdo) >> 8) & 0xFF)
341#define PD_APDO_MAX_CURR(pdo) ((pdo) & 0x7F)
342
343/* Vendor Defined Messages */
344#define MAX_CRC_RECEIVE_TIME 9 /* ~(2 * tReceive_max(1.1ms) * # retry 4) */
345#define MAX_VDM_RESPONSE_TIME 60 /* 2 * tVDMSenderResponse_max(30ms) */
346#define MAX_VDM_BUSY_TIME 100 /* 2 * tVDMBusy (50ms) */
347
Jack Phamee1f9052017-01-26 12:27:07 -0800348#define PD_SNK_PDO_FIXED(prs, hc, uc, usb_comm, drs, volt, curr) \
349 (((prs) << 29) | ((hc) << 28) | ((uc) << 27) | ((usb_comm) << 26) | \
350 ((drs) << 25) | ((volt) << 10) | (curr))
351
Jack Phamf4baeb12017-02-03 19:01:48 -0800352/* VDM header is the first 32-bit object following the 16-bit PD header */
353#define VDM_HDR_SVID(hdr) ((hdr) >> 16)
354#define VDM_IS_SVDM(hdr) ((hdr) & 0x8000)
355#define SVDM_HDR_OBJ_POS(hdr) (((hdr) >> 8) & 0x7)
356#define SVDM_HDR_CMD_TYPE(hdr) (((hdr) >> 6) & 0x3)
357#define SVDM_HDR_CMD(hdr) ((hdr) & 0x1f)
358
359#define SVDM_HDR(svid, ver, obj, cmd_type, cmd) \
360 (((svid) << 16) | (1 << 15) | ((ver) << 13) \
361 | ((obj) << 8) | ((cmd_type) << 6) | (cmd))
362
363/* discover id response vdo bit fields */
364#define ID_HDR_USB_HOST BIT(31)
365#define ID_HDR_USB_DEVICE BIT(30)
366#define ID_HDR_MODAL_OPR BIT(26)
367#define ID_HDR_PRODUCT_TYPE(n) ((n) >> 27)
368#define ID_HDR_PRODUCT_PER_MASK (2 << 27)
369#define ID_HDR_PRODUCT_HUB 1
370#define ID_HDR_PRODUCT_PER 2
371#define ID_HDR_PRODUCT_AMA 5
372#define ID_HDR_VID 0x05c6 /* qcom */
373#define PROD_VDO_PID 0x0a00 /* TBD */
374
375static bool check_vsafe0v = true;
376module_param(check_vsafe0v, bool, 0600);
377
378static int min_sink_current = 900;
379module_param(min_sink_current, int, 0600);
380
381static const u32 default_src_caps[] = { 0x36019096 }; /* VSafe5V @ 1.5A */
Jack Phamee1f9052017-01-26 12:27:07 -0800382static const u32 default_snk_caps[] = { 0x2601912C }; /* VSafe5V @ 3A */
Jack Phamf4baeb12017-02-03 19:01:48 -0800383
384struct vdm_tx {
Jack Phamf3c1bd32017-08-02 18:32:23 -0700385 u32 data[PD_MAX_DATA_OBJ];
Jack Phamf4baeb12017-02-03 19:01:48 -0800386 int size;
387};
388
389struct rx_msg {
Jack Phamf3c1bd32017-08-02 18:32:23 -0700390 u16 hdr;
391 u16 data_len; /* size of payload in bytes */
Jack Phamf4baeb12017-02-03 19:01:48 -0800392 struct list_head entry;
Jack Phamf3c1bd32017-08-02 18:32:23 -0700393 u8 payload[];
Jack Phamf4baeb12017-02-03 19:01:48 -0800394};
395
Jack Phamf3c1bd32017-08-02 18:32:23 -0700396#define IS_DATA(m, t) ((m) && !PD_MSG_HDR_IS_EXTENDED((m)->hdr) && \
397 PD_MSG_HDR_COUNT((m)->hdr) && \
398 (PD_MSG_HDR_TYPE((m)->hdr) == (t)))
399#define IS_CTRL(m, t) ((m) && !PD_MSG_HDR_COUNT((m)->hdr) && \
400 (PD_MSG_HDR_TYPE((m)->hdr) == (t)))
401#define IS_EXT(m, t) ((m) && PD_MSG_HDR_IS_EXTENDED((m)->hdr) && \
402 (PD_MSG_HDR_TYPE((m)->hdr) == (t)))
Jack Phamf4baeb12017-02-03 19:01:48 -0800403
rbandi20d026b2020-03-18 10:15:47 -0700404#define SXR_SEND_SVDM(pd, cmd, num, tx_vdos, pos) usbpd_send_svdm(pd, 0xFF01, \
405 cmd, SVDM_CMD_TYPE_RESP_ACK, \
406 num, tx_vdos, pos)
Jack Phamf4baeb12017-02-03 19:01:48 -0800407struct usbpd {
408 struct device dev;
409 struct workqueue_struct *wq;
410 struct work_struct sm_work;
411 struct hrtimer timer;
412 bool sm_queued;
413
414 struct extcon_dev *extcon;
415
416 enum usbpd_state current_state;
417 bool hard_reset_recvd;
Jack Pham4b323282017-11-03 12:24:59 -0700418 ktime_t hard_reset_recvd_time;
Jack Phamf4baeb12017-02-03 19:01:48 -0800419 struct list_head rx_q;
420 spinlock_t rx_lock;
Jack Phamf3c1bd32017-08-02 18:32:23 -0700421 struct rx_msg *rx_ext_msg;
Jack Phamf4baeb12017-02-03 19:01:48 -0800422
Hemant Kumar796534e2017-05-30 15:54:55 -0700423 u32 received_pdos[PD_MAX_DATA_OBJ];
Jack Phamf6c02da2017-01-31 15:23:56 -0800424 u16 src_cap_id;
Jack Phamf4baeb12017-02-03 19:01:48 -0800425 u8 selected_pdo;
426 u8 requested_pdo;
427 u32 rdo; /* can be either source or sink */
428 int current_voltage; /* uV */
429 int requested_voltage; /* uV */
430 int requested_current; /* mA */
431 bool pd_connected;
432 bool in_explicit_contract;
433 bool peer_usb_comm;
434 bool peer_pr_swap;
435 bool peer_dr_swap;
436
Jack Phamee1f9052017-01-26 12:27:07 -0800437 u32 sink_caps[7];
438 int num_sink_caps;
439
Jack Phamf4baeb12017-02-03 19:01:48 -0800440 struct power_supply *usb_psy;
441 struct notifier_block psy_nb;
442
443 enum power_supply_typec_mode typec_mode;
444 enum power_supply_type psy_type;
445 enum power_supply_typec_power_role forced_pr;
446 bool vbus_present;
447
448 enum pd_spec_rev spec_rev;
449 enum data_role current_dr;
450 enum power_role current_pr;
451 bool in_pr_swap;
452 bool pd_phy_opened;
Jack Phamaf7d3842017-01-26 13:28:19 -0800453 bool send_request;
454 struct completion is_ready;
Jack Phamf3c1bd32017-08-02 18:32:23 -0700455 struct completion tx_chunk_request;
456 u8 next_tx_chunk;
Jack Phamf4baeb12017-02-03 19:01:48 -0800457
Jack Phamaf7d3842017-01-26 13:28:19 -0800458 struct mutex swap_lock;
Jack Phamf4baeb12017-02-03 19:01:48 -0800459 struct dual_role_phy_instance *dual_role;
460 struct dual_role_phy_desc dr_desc;
461 bool send_pr_swap;
462 bool send_dr_swap;
463
464 struct regulator *vbus;
465 struct regulator *vconn;
466 bool vbus_enabled;
467 bool vconn_enabled;
468 bool vconn_is_external;
469
470 u8 tx_msgid;
471 u8 rx_msgid;
472 int caps_count;
473 int hard_reset_count;
474
475 enum vdm_state vdm_state;
476 u16 *discovered_svids;
477 int num_svids;
478 struct vdm_tx *vdm_tx;
479 struct vdm_tx *vdm_tx_retry;
Mayank Rana83443202017-08-31 15:38:03 -0700480 struct mutex svid_handler_lock;
Jack Phamf4baeb12017-02-03 19:01:48 -0800481 struct list_head svid_handlers;
482
483 struct list_head instance;
Mayank Rana6af43422017-07-18 12:09:02 -0700484
Liangliang Lu7e9fffa2018-06-26 12:45:14 +0800485 bool has_dp;
Mayank Rana6af43422017-07-18 12:09:02 -0700486 u16 ss_lane_svid;
Hemant Kumar018b5982017-08-09 14:14:37 -0700487
488 /* ext msg support */
489 bool send_get_src_cap_ext;
490 u8 src_cap_ext_db[PD_SRC_CAP_EXT_DB_LEN];
491 bool send_get_pps_status;
492 u32 pps_status_db;
Jack Phamda401d72018-06-07 19:29:52 -0700493 bool send_get_status;
Hemant Kumara1875942017-08-09 16:50:14 -0700494 u8 status_db[PD_STATUS_DB_LEN];
Hemant Kumar51ded972017-08-09 17:57:24 -0700495 bool send_get_battery_cap;
496 u8 get_battery_cap_db;
497 u8 battery_cap_db[PD_BATTERY_CAP_DB_LEN];
498 u8 get_battery_status_db;
499 bool send_get_battery_status;
500 u32 battery_sts_dobj;
rbandi20d026b2020-03-18 10:15:47 -0700501 bool is_sxr_dp_sink;
Jack Phamf4baeb12017-02-03 19:01:48 -0800502};
503
504static LIST_HEAD(_usbpd); /* useful for debugging */
505
506static const unsigned int usbpd_extcon_cable[] = {
507 EXTCON_USB,
508 EXTCON_USB_HOST,
Liangliang Lu7e9fffa2018-06-26 12:45:14 +0800509 EXTCON_DISP_DP,
Jack Phamf4baeb12017-02-03 19:01:48 -0800510 EXTCON_NONE,
511};
512
513/* EXTCON_USB and EXTCON_USB_HOST are mutually exclusive */
514static const u32 usbpd_extcon_exclusive[] = {0x3, 0};
515
516enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd)
517{
518 int ret;
519 union power_supply_propval val;
520
521 ret = power_supply_get_property(pd->usb_psy,
522 POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION, &val);
523 if (ret)
524 return ORIENTATION_NONE;
525
526 return val.intval;
527}
528EXPORT_SYMBOL(usbpd_get_plug_orientation);
529
Pratham Pratap033a2d92017-11-14 20:57:05 +0530530static unsigned int get_connector_type(struct usbpd *pd)
531{
532 int ret;
533 union power_supply_propval val;
534
535 ret = power_supply_get_property(pd->usb_psy,
536 POWER_SUPPLY_PROP_CONNECTOR_TYPE, &val);
537
538 if (ret) {
539 dev_err(&pd->dev, "Unable to read CONNECTOR TYPE: %d\n", ret);
540 return ret;
541 }
542 return val.intval;
543}
544
Jack Phamf4baeb12017-02-03 19:01:48 -0800545static inline void stop_usb_host(struct usbpd *pd)
546{
Jack Pham4e9dff72017-04-04 18:05:53 -0700547 extcon_set_state_sync(pd->extcon, EXTCON_USB_HOST, 0);
Jack Phamf4baeb12017-02-03 19:01:48 -0800548}
549
550static inline void start_usb_host(struct usbpd *pd, bool ss)
551{
552 enum plug_orientation cc = usbpd_get_plug_orientation(pd);
Jack Pham4e9dff72017-04-04 18:05:53 -0700553 union extcon_property_value val;
Jack Phamf4baeb12017-02-03 19:01:48 -0800554
Jack Pham4e9dff72017-04-04 18:05:53 -0700555 val.intval = (cc == ORIENTATION_CC2);
556 extcon_set_property(pd->extcon, EXTCON_USB_HOST,
557 EXTCON_PROP_USB_TYPEC_POLARITY, val);
558
559 val.intval = ss;
560 extcon_set_property(pd->extcon, EXTCON_USB_HOST,
561 EXTCON_PROP_USB_SS, val);
562
563 extcon_set_state_sync(pd->extcon, EXTCON_USB_HOST, 1);
Jack Phamf4baeb12017-02-03 19:01:48 -0800564}
565
566static inline void stop_usb_peripheral(struct usbpd *pd)
567{
Jack Pham4e9dff72017-04-04 18:05:53 -0700568 extcon_set_state_sync(pd->extcon, EXTCON_USB, 0);
Jack Phamf4baeb12017-02-03 19:01:48 -0800569}
570
571static inline void start_usb_peripheral(struct usbpd *pd)
572{
573 enum plug_orientation cc = usbpd_get_plug_orientation(pd);
Jack Pham4e9dff72017-04-04 18:05:53 -0700574 union extcon_property_value val;
Jack Phamf4baeb12017-02-03 19:01:48 -0800575
Jack Pham4e9dff72017-04-04 18:05:53 -0700576 val.intval = (cc == ORIENTATION_CC2);
577 extcon_set_property(pd->extcon, EXTCON_USB,
578 EXTCON_PROP_USB_TYPEC_POLARITY, val);
579
580 val.intval = 1;
581 extcon_set_property(pd->extcon, EXTCON_USB, EXTCON_PROP_USB_SS, val);
582
Vijayavardhan Vennapusa79cdf0a2018-08-17 15:37:13 +0530583 val.intval =
584 pd->typec_mode > POWER_SUPPLY_TYPEC_SOURCE_DEFAULT ? 1 : 0;
Vijayavardhan Vennapusadaeb5ac2018-07-13 13:04:17 +0530585 extcon_set_property(pd->extcon, EXTCON_USB,
586 EXTCON_PROP_USB_PD_CONTRACT, val);
Vijayavardhan Vennapusa79cdf0a2018-08-17 15:37:13 +0530587 extcon_set_state_sync(pd->extcon, EXTCON_USB, 1);
Vijayavardhan Vennapusadaeb5ac2018-07-13 13:04:17 +0530588}
589
Mayank Rana6af43422017-07-18 12:09:02 -0700590/**
591 * This API allows client driver to request for releasing SS lanes. It should
592 * not be called from atomic context.
593 *
594 * @pd - USBPD handler
595 * @hdlr - client's handler
596 *
597 * @returns int - Success - 0, else negative error code
598 */
599static int usbpd_release_ss_lane(struct usbpd *pd,
600 struct usbpd_svid_handler *hdlr)
601{
602 int ret = 0;
603
604 if (!hdlr || !pd)
605 return -EINVAL;
606
607 usbpd_dbg(&pd->dev, "hdlr:%pK svid:%d", hdlr, hdlr->svid);
608 /*
609 * If USB SS lanes are already used by one client, and other client is
610 * requesting for same or same client requesting again, return -EBUSY.
611 */
612 if (pd->ss_lane_svid) {
613 usbpd_dbg(&pd->dev, "-EBUSY: ss_lanes are already used by(%d)",
614 pd->ss_lane_svid);
615 ret = -EBUSY;
616 goto err_exit;
617 }
618
619 ret = extcon_blocking_sync(pd->extcon, EXTCON_USB_HOST, 0);
620 if (ret) {
621 usbpd_err(&pd->dev, "err(%d) for releasing ss lane", ret);
622 goto err_exit;
623 }
624
625 pd->ss_lane_svid = hdlr->svid;
626
Liangliang Lu7e9fffa2018-06-26 12:45:14 +0800627 /* DP 4 Lane mode */
628 ret = extcon_blocking_sync(pd->extcon, EXTCON_DISP_DP, 4);
629 if (ret) {
630 usbpd_err(&pd->dev, "err(%d) for notify DP 4 Lane", ret);
631 goto err_exit;
632 }
633
Mayank Rana6af43422017-07-18 12:09:02 -0700634err_exit:
635 return ret;
636}
637
Jack Phamf4baeb12017-02-03 19:01:48 -0800638static int set_power_role(struct usbpd *pd, enum power_role pr)
639{
640 union power_supply_propval val = {0};
641
642 switch (pr) {
643 case PR_NONE:
644 val.intval = POWER_SUPPLY_TYPEC_PR_NONE;
645 break;
646 case PR_SINK:
647 val.intval = POWER_SUPPLY_TYPEC_PR_SINK;
648 break;
649 case PR_SRC:
650 val.intval = POWER_SUPPLY_TYPEC_PR_SOURCE;
651 break;
652 }
653
654 return power_supply_set_property(pd->usb_psy,
655 POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &val);
656}
657
658static struct usbpd_svid_handler *find_svid_handler(struct usbpd *pd, u16 svid)
659{
660 struct usbpd_svid_handler *handler;
661
Mayank Rana83443202017-08-31 15:38:03 -0700662 mutex_lock(&pd->svid_handler_lock);
663 list_for_each_entry(handler, &pd->svid_handlers, entry) {
664 if (svid == handler->svid) {
665 mutex_unlock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -0800666 return handler;
Mayank Rana83443202017-08-31 15:38:03 -0700667 }
668 }
Jack Phamf4baeb12017-02-03 19:01:48 -0800669
Mayank Rana83443202017-08-31 15:38:03 -0700670 mutex_unlock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -0800671 return NULL;
672}
673
674/* Reset protocol layer */
675static inline void pd_reset_protocol(struct usbpd *pd)
676{
677 /*
678 * first Rx ID should be 0; set this to a sentinel of -1 so that in
679 * phy_msg_received() we can check if we had seen it before.
680 */
681 pd->rx_msgid = -1;
682 pd->tx_msgid = 0;
Jack Phamaf7d3842017-01-26 13:28:19 -0800683 pd->send_request = false;
684 pd->send_pr_swap = false;
685 pd->send_dr_swap = false;
Jack Phamf4baeb12017-02-03 19:01:48 -0800686}
687
Jack Phame95cfc72017-08-01 17:36:50 -0700688static int pd_send_msg(struct usbpd *pd, u8 msg_type, const u32 *data,
689 size_t num_data, enum pd_sop_type sop)
Jack Phamf4baeb12017-02-03 19:01:48 -0800690{
691 int ret;
692 u16 hdr;
693
Jack Pham4b323282017-11-03 12:24:59 -0700694 if (pd->hard_reset_recvd)
695 return -EBUSY;
696
Jack Phame95cfc72017-08-01 17:36:50 -0700697 hdr = PD_MSG_HDR(msg_type, pd->current_dr, pd->current_pr,
Jack Phamf4baeb12017-02-03 19:01:48 -0800698 pd->tx_msgid, num_data, pd->spec_rev);
Jack Phamf4baeb12017-02-03 19:01:48 -0800699
Jack Pham7dfd7612017-08-01 18:04:13 -0700700 ret = pd_phy_write(hdr, (u8 *)data, num_data * sizeof(u32), sop);
Jack Pham722527a2018-06-28 23:17:17 -0700701 if (ret) {
702 usbpd_err(&pd->dev, "Error sending %s: %d\n",
703 msg_to_string(msg_type, num_data, false),
704 ret);
Jack Phamf4baeb12017-02-03 19:01:48 -0800705 return ret;
Jack Pham722527a2018-06-28 23:17:17 -0700706 }
Jack Phamcc119752017-06-07 15:35:57 -0700707
708 pd->tx_msgid = (pd->tx_msgid + 1) & PD_MAX_MSG_ID;
Jack Phamf4baeb12017-02-03 19:01:48 -0800709 return 0;
710}
711
Hemant Kumar51ded972017-08-09 17:57:24 -0700712static int pd_send_ext_msg(struct usbpd *pd, u8 msg_type,
713 const u8 *data, size_t data_len, enum pd_sop_type sop)
714{
715 int ret;
716 size_t len_remain, chunk_len;
717 u8 chunked_payload[PD_MAX_DATA_OBJ * sizeof(u32)] = {0};
718 u16 hdr;
719 u16 ext_hdr;
720 u8 num_objs;
721
722 if (data_len > PD_MAX_EXT_MSG_LEN) {
723 usbpd_warn(&pd->dev, "Extended message length exceeds max, truncating...\n");
724 data_len = PD_MAX_EXT_MSG_LEN;
725 }
726
727 pd->next_tx_chunk = 0;
728 len_remain = data_len;
729 do {
730 ext_hdr = PD_MSG_EXT_HDR(1, pd->next_tx_chunk++, 0, data_len);
731 memcpy(chunked_payload, &ext_hdr, sizeof(ext_hdr));
732
733 chunk_len = min_t(size_t, len_remain,
734 PD_MAX_EXT_MSG_LEGACY_LEN);
735 memcpy(chunked_payload + sizeof(ext_hdr), data, chunk_len);
736
737 num_objs = DIV_ROUND_UP(chunk_len + sizeof(u16), sizeof(u32));
738 len_remain -= chunk_len;
739
740 reinit_completion(&pd->tx_chunk_request);
741 hdr = PD_MSG_HDR(msg_type, pd->current_dr, pd->current_pr,
742 pd->tx_msgid, num_objs, pd->spec_rev) |
743 PD_MSG_HDR_EXTENDED;
744 ret = pd_phy_write(hdr, chunked_payload,
745 num_objs * sizeof(u32), sop);
Jack Pham722527a2018-06-28 23:17:17 -0700746 if (ret) {
747 usbpd_err(&pd->dev, "Error sending %s: %d\n",
748 usbpd_ext_msg_strings[msg_type],
749 ret);
Hemant Kumar51ded972017-08-09 17:57:24 -0700750 return ret;
Jack Pham722527a2018-06-28 23:17:17 -0700751 }
Hemant Kumar51ded972017-08-09 17:57:24 -0700752
753 pd->tx_msgid = (pd->tx_msgid + 1) & PD_MAX_MSG_ID;
754
755 /* Wait for request chunk */
756 if (len_remain &&
757 !wait_for_completion_timeout(&pd->tx_chunk_request,
758 msecs_to_jiffies(SENDER_RESPONSE_TIME))) {
759 usbpd_err(&pd->dev, "Timed out waiting for chunk request\n");
760 return -EPROTO;
761 }
762 } while (len_remain);
763
764 return 0;
765}
766
Jack Phamf4baeb12017-02-03 19:01:48 -0800767static int pd_select_pdo(struct usbpd *pd, int pdo_pos, int uv, int ua)
768{
769 int curr;
770 int max_current;
771 bool mismatch = false;
772 u8 type;
773 u32 pdo = pd->received_pdos[pdo_pos - 1];
774
775 type = PD_SRC_PDO_TYPE(pdo);
776 if (type == PD_SRC_PDO_TYPE_FIXED) {
777 curr = max_current = PD_SRC_PDO_FIXED_MAX_CURR(pdo) * 10;
778
779 /*
780 * Check if the PDO has enough current, otherwise set the
781 * Capability Mismatch flag
782 */
783 if (curr < min_sink_current) {
784 mismatch = true;
785 max_current = min_sink_current;
786 }
787
788 pd->requested_voltage =
789 PD_SRC_PDO_FIXED_VOLTAGE(pdo) * 50 * 1000;
790 pd->rdo = PD_RDO_FIXED(pdo_pos, 0, mismatch, 1, 1, curr / 10,
791 max_current / 10);
792 } else if (type == PD_SRC_PDO_TYPE_AUGMENTED) {
793 if ((uv / 100000) > PD_APDO_MAX_VOLT(pdo) ||
794 (uv / 100000) < PD_APDO_MIN_VOLT(pdo) ||
795 (ua / 50000) > PD_APDO_MAX_CURR(pdo) || (ua < 0)) {
796 usbpd_err(&pd->dev, "uv (%d) and ua (%d) out of range of APDO\n",
797 uv, ua);
798 return -EINVAL;
799 }
800
801 curr = ua / 1000;
802 pd->requested_voltage = uv;
803 pd->rdo = PD_RDO_AUGMENTED(pdo_pos, mismatch, 1, 1,
804 uv / 20000, ua / 50000);
805 } else {
806 usbpd_err(&pd->dev, "Only Fixed or Programmable PDOs supported\n");
807 return -ENOTSUPP;
808 }
809
810 /* Can't sink more than 5V if VCONN is sourced from the VBUS input */
811 if (pd->vconn_enabled && !pd->vconn_is_external &&
812 pd->requested_voltage > 5000000)
813 return -ENOTSUPP;
814
815 pd->requested_current = curr;
816 pd->requested_pdo = pdo_pos;
817
818 return 0;
819}
820
821static int pd_eval_src_caps(struct usbpd *pd)
822{
Hemant Kumarbe746222017-07-20 13:51:49 -0700823 int i;
Jack Phamf4baeb12017-02-03 19:01:48 -0800824 union power_supply_propval val;
Jack Pham9660be92018-04-03 16:06:40 -0700825 bool pps_found = false;
Jack Phamf4baeb12017-02-03 19:01:48 -0800826 u32 first_pdo = pd->received_pdos[0];
827
828 if (PD_SRC_PDO_TYPE(first_pdo) != PD_SRC_PDO_TYPE_FIXED) {
829 usbpd_err(&pd->dev, "First src_cap invalid! %08x\n", first_pdo);
830 return -EINVAL;
831 }
832
833 pd->peer_usb_comm = PD_SRC_PDO_FIXED_USB_COMM(first_pdo);
834 pd->peer_pr_swap = PD_SRC_PDO_FIXED_PR_SWAP(first_pdo);
835 pd->peer_dr_swap = PD_SRC_PDO_FIXED_DR_SWAP(first_pdo);
836
837 val.intval = PD_SRC_PDO_FIXED_USB_SUSP(first_pdo);
838 power_supply_set_property(pd->usb_psy,
839 POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED, &val);
840
Jack Pham9660be92018-04-03 16:06:40 -0700841 /* Check for PPS APDOs */
842 if (pd->spec_rev == USBPD_REV_30) {
Hemant Kumarbe746222017-07-20 13:51:49 -0700843 for (i = 1; i < PD_MAX_DATA_OBJ; i++) {
844 if ((PD_SRC_PDO_TYPE(pd->received_pdos[i]) ==
Hemant Kumar796534e2017-05-30 15:54:55 -0700845 PD_SRC_PDO_TYPE_AUGMENTED) &&
Hemant Kumarbe746222017-07-20 13:51:49 -0700846 !PD_APDO_PPS(pd->received_pdos[i])) {
847 pps_found = true;
848 break;
849 }
850 }
Jack Pham9660be92018-04-03 16:06:40 -0700851
852 /* downgrade to 2.0 if no PPS */
853 if (!pps_found && !rev3_sink_only)
Hemant Kumarbe746222017-07-20 13:51:49 -0700854 pd->spec_rev = USBPD_REV_20;
Hemant Kumar796534e2017-05-30 15:54:55 -0700855 }
856
Jack Pham9660be92018-04-03 16:06:40 -0700857 val.intval = pps_found ?
858 POWER_SUPPLY_PD_PPS_ACTIVE :
859 POWER_SUPPLY_PD_ACTIVE;
860 power_supply_set_property(pd->usb_psy,
861 POWER_SUPPLY_PROP_PD_ACTIVE, &val);
862
Jack Phamf4baeb12017-02-03 19:01:48 -0800863 /* Select the first PDO (vSafe5V) immediately. */
864 pd_select_pdo(pd, 1, 0, 0);
865
866 return 0;
867}
868
869static void pd_send_hard_reset(struct usbpd *pd)
870{
Jack Pham857ee682017-05-25 11:53:36 -0700871 union power_supply_propval val = {0};
872
Jack Phamf4baeb12017-02-03 19:01:48 -0800873 usbpd_dbg(&pd->dev, "send hard reset");
874
875 /* Force CC logic to source/sink to keep Rp/Rd unchanged */
876 set_power_role(pd, pd->current_pr);
877 pd->hard_reset_count++;
Jack Pham7dfd7612017-08-01 18:04:13 -0700878 pd_phy_signal(HARD_RESET_SIG);
Jack Phamf4baeb12017-02-03 19:01:48 -0800879 pd->in_pr_swap = false;
Jack Pham857ee682017-05-25 11:53:36 -0700880 power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_PR_SWAP, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -0800881}
882
883static void kick_sm(struct usbpd *pd, int ms)
884{
885 pm_stay_awake(&pd->dev);
886 pd->sm_queued = true;
887
888 if (ms)
889 hrtimer_start(&pd->timer, ms_to_ktime(ms), HRTIMER_MODE_REL);
890 else
891 queue_work(pd->wq, &pd->sm_work);
892}
893
Jack Phame95cfc72017-08-01 17:36:50 -0700894static void phy_sig_received(struct usbpd *pd, enum pd_sig_type sig)
Jack Phamf4baeb12017-02-03 19:01:48 -0800895{
Jack Pham9411cbb2017-06-06 11:10:03 -0700896 union power_supply_propval val = {1};
897
Jack Phame95cfc72017-08-01 17:36:50 -0700898 if (sig != HARD_RESET_SIG) {
899 usbpd_err(&pd->dev, "invalid signal (%d) received\n", sig);
Jack Phamf4baeb12017-02-03 19:01:48 -0800900 return;
901 }
902
Jack Pham4b323282017-11-03 12:24:59 -0700903 pd->hard_reset_recvd = true;
904 pd->hard_reset_recvd_time = ktime_get();
905
906 usbpd_err(&pd->dev, "hard reset received\n");
Jack Phamf4baeb12017-02-03 19:01:48 -0800907
908 /* Force CC logic to source/sink to keep Rp/Rd unchanged */
909 set_power_role(pd, pd->current_pr);
Jack Pham9411cbb2017-06-06 11:10:03 -0700910 power_supply_set_property(pd->usb_psy,
911 POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val);
912
Jack Phamf4baeb12017-02-03 19:01:48 -0800913 kick_sm(pd, 0);
914}
915
Jack Phamf3c1bd32017-08-02 18:32:23 -0700916struct pd_request_chunk {
917 struct work_struct w;
918 struct usbpd *pd;
919 u8 msg_type;
920 u8 chunk_num;
921 enum pd_sop_type sop;
922};
923
924static void pd_request_chunk_work(struct work_struct *w)
925{
926 struct pd_request_chunk *req =
927 container_of(w, struct pd_request_chunk, w);
928 struct usbpd *pd = req->pd;
929 unsigned long flags;
930 int ret;
931 u8 payload[4] = {0}; /* ext_hdr + padding */
932 u16 hdr = PD_MSG_HDR(req->msg_type, pd->current_dr, pd->current_pr,
933 pd->tx_msgid, 1, pd->spec_rev) | PD_MSG_HDR_EXTENDED;
934
935 *(u16 *)payload = PD_MSG_EXT_HDR(1, req->chunk_num, 1, 0);
936
937 ret = pd_phy_write(hdr, payload, sizeof(payload), req->sop);
938 if (!ret) {
939 pd->tx_msgid = (pd->tx_msgid + 1) & PD_MAX_MSG_ID;
940 } else {
941 usbpd_err(&pd->dev, "could not send chunk request\n");
942
943 /* queue what we have anyway */
944 spin_lock_irqsave(&pd->rx_lock, flags);
945 list_add_tail(&pd->rx_ext_msg->entry, &pd->rx_q);
946 spin_unlock_irqrestore(&pd->rx_lock, flags);
947
948 pd->rx_ext_msg = NULL;
949 }
950
951 kfree(req);
952}
953
954static struct rx_msg *pd_ext_msg_received(struct usbpd *pd, u16 header, u8 *buf,
955 size_t len, enum pd_sop_type sop)
956{
957 struct rx_msg *rx_msg;
958 u16 bytes_to_copy;
959 u16 ext_hdr = *(u16 *)buf;
960 u8 chunk_num;
961
962 if (!PD_MSG_EXT_HDR_IS_CHUNKED(ext_hdr)) {
963 usbpd_err(&pd->dev, "unchunked extended messages unsupported\n");
964 return NULL;
965 }
966
967 /* request for next Tx chunk */
968 if (PD_MSG_EXT_HDR_REQ_CHUNK(ext_hdr)) {
969 if (PD_MSG_EXT_HDR_DATA_SIZE(ext_hdr) ||
970 PD_MSG_EXT_HDR_CHUNK_NUM(ext_hdr) !=
971 pd->next_tx_chunk) {
972 usbpd_err(&pd->dev, "invalid request chunk ext header 0x%02x\n",
973 ext_hdr);
974 return NULL;
975 }
976
977 if (!completion_done(&pd->tx_chunk_request))
978 complete(&pd->tx_chunk_request);
979
980 return NULL;
981 }
982
983 chunk_num = PD_MSG_EXT_HDR_CHUNK_NUM(ext_hdr);
984 if (!chunk_num) {
985 /* allocate new message if first chunk */
986 rx_msg = kzalloc(sizeof(*rx_msg) +
987 PD_MSG_EXT_HDR_DATA_SIZE(ext_hdr),
Jack Phama27be8f2017-11-02 10:51:48 -0700988 GFP_ATOMIC);
Jack Phamf3c1bd32017-08-02 18:32:23 -0700989 if (!rx_msg)
990 return NULL;
991
992 rx_msg->hdr = header;
993 rx_msg->data_len = PD_MSG_EXT_HDR_DATA_SIZE(ext_hdr);
994
995 if (rx_msg->data_len > PD_MAX_EXT_MSG_LEN) {
996 usbpd_warn(&pd->dev, "Extended message length exceeds max, truncating...\n");
997 rx_msg->data_len = PD_MAX_EXT_MSG_LEN;
998 }
999 } else {
1000 if (!pd->rx_ext_msg) {
1001 usbpd_err(&pd->dev, "missing first rx_ext_msg chunk\n");
1002 return NULL;
1003 }
1004
1005 rx_msg = pd->rx_ext_msg;
1006 }
1007
1008 /*
1009 * The amount to copy is derived as follows:
1010 *
1011 * - if extended data_len < 26, then copy data_len bytes
1012 * - for chunks 0..N-2, copy 26 bytes
1013 * - for the last chunk (N-1), copy the remainder
1014 */
1015 bytes_to_copy =
1016 min((rx_msg->data_len - chunk_num * PD_MAX_EXT_MSG_LEGACY_LEN),
1017 PD_MAX_EXT_MSG_LEGACY_LEN);
1018
1019 /* check against received length to avoid overrun */
1020 if (bytes_to_copy > len - sizeof(ext_hdr)) {
Vijayavardhan Vennapusab7ce6542018-05-07 16:59:53 +05301021 usbpd_warn(&pd->dev, "not enough bytes in chunk, expected:%u received:%zu\n",
Jack Phamf3c1bd32017-08-02 18:32:23 -07001022 bytes_to_copy, len - sizeof(ext_hdr));
1023 bytes_to_copy = len - sizeof(ext_hdr);
1024 }
1025
1026 memcpy(rx_msg->payload + chunk_num * PD_MAX_EXT_MSG_LEGACY_LEN, buf + 2,
1027 bytes_to_copy);
1028
1029 /* request next chunk? */
1030 if ((rx_msg->data_len - chunk_num * PD_MAX_EXT_MSG_LEGACY_LEN) >
1031 PD_MAX_EXT_MSG_LEGACY_LEN) {
1032 struct pd_request_chunk *req;
1033
1034 if (pd->rx_ext_msg && pd->rx_ext_msg != rx_msg) {
1035 usbpd_dbg(&pd->dev, "stale previous rx_ext_msg?\n");
1036 kfree(pd->rx_ext_msg);
1037 }
1038
1039 pd->rx_ext_msg = rx_msg;
1040
Jack Phama27be8f2017-11-02 10:51:48 -07001041 req = kzalloc(sizeof(*req), GFP_ATOMIC);
Jack Phamf3c1bd32017-08-02 18:32:23 -07001042 if (!req)
1043 goto queue_rx; /* return what we have anyway */
1044
1045 INIT_WORK(&req->w, pd_request_chunk_work);
1046 req->pd = pd;
1047 req->msg_type = PD_MSG_HDR_TYPE(header);
1048 req->chunk_num = chunk_num + 1;
1049 req->sop = sop;
1050 queue_work(pd->wq, &req->w);
1051
1052 return NULL;
1053 }
1054
1055queue_rx:
1056 pd->rx_ext_msg = NULL;
1057 return rx_msg; /* queue it for usbpd_sm */
1058}
1059
Jack Phame95cfc72017-08-01 17:36:50 -07001060static void phy_msg_received(struct usbpd *pd, enum pd_sop_type sop,
Jack Phamf4baeb12017-02-03 19:01:48 -08001061 u8 *buf, size_t len)
1062{
1063 struct rx_msg *rx_msg;
1064 unsigned long flags;
1065 u16 header;
Jack Pham722527a2018-06-28 23:17:17 -07001066 u8 msg_type, num_objs;
Jack Phamf4baeb12017-02-03 19:01:48 -08001067
Jack Phame95cfc72017-08-01 17:36:50 -07001068 if (sop != SOP_MSG) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001069 usbpd_err(&pd->dev, "invalid msg type (%d) received; only SOP supported\n",
Jack Phame95cfc72017-08-01 17:36:50 -07001070 sop);
Jack Phamf4baeb12017-02-03 19:01:48 -08001071 return;
1072 }
1073
1074 if (len < 2) {
1075 usbpd_err(&pd->dev, "invalid message received, len=%zd\n", len);
1076 return;
1077 }
1078
1079 header = *((u16 *)buf);
1080 buf += sizeof(u16);
1081 len -= sizeof(u16);
1082
1083 if (len % 4 != 0) {
1084 usbpd_err(&pd->dev, "len=%zd not multiple of 4\n", len);
1085 return;
1086 }
1087
1088 /* if MSGID already seen, discard */
1089 if (PD_MSG_HDR_ID(header) == pd->rx_msgid &&
1090 PD_MSG_HDR_TYPE(header) != MSG_SOFT_RESET) {
1091 usbpd_dbg(&pd->dev, "MessageID already seen, discarding\n");
1092 return;
1093 }
1094
1095 pd->rx_msgid = PD_MSG_HDR_ID(header);
1096
1097 /* discard Pings */
1098 if (PD_MSG_HDR_TYPE(header) == MSG_PING && !len)
1099 return;
1100
1101 /* check header's count field to see if it matches len */
1102 if (PD_MSG_HDR_COUNT(header) != (len / 4)) {
1103 usbpd_err(&pd->dev, "header count (%d) mismatch, len=%zd\n",
1104 PD_MSG_HDR_COUNT(header), len);
1105 return;
1106 }
1107
Hemant Kumarbe746222017-07-20 13:51:49 -07001108 /* if spec rev differs (i.e. is older), update PHY */
1109 if (PD_MSG_HDR_REV(header) < pd->spec_rev)
1110 pd->spec_rev = PD_MSG_HDR_REV(header);
1111
Jack Pham722527a2018-06-28 23:17:17 -07001112 msg_type = PD_MSG_HDR_TYPE(header);
1113 num_objs = PD_MSG_HDR_COUNT(header);
1114 usbpd_dbg(&pd->dev, "%s type(%d) num_objs(%d)\n",
1115 msg_to_string(msg_type, num_objs,
1116 PD_MSG_HDR_IS_EXTENDED(header)),
1117 msg_type, num_objs);
Jack Phamf4baeb12017-02-03 19:01:48 -08001118
Jack Phamf3c1bd32017-08-02 18:32:23 -07001119 if (!PD_MSG_HDR_IS_EXTENDED(header)) {
Jack Phama27be8f2017-11-02 10:51:48 -07001120 rx_msg = kzalloc(sizeof(*rx_msg) + len, GFP_ATOMIC);
Jack Phamf3c1bd32017-08-02 18:32:23 -07001121 if (!rx_msg)
1122 return;
1123
1124 rx_msg->hdr = header;
1125 rx_msg->data_len = len;
1126 memcpy(rx_msg->payload, buf, len);
1127 } else {
1128 rx_msg = pd_ext_msg_received(pd, header, buf, len, sop);
1129 if (!rx_msg)
1130 return;
1131 }
Jack Phamf4baeb12017-02-03 19:01:48 -08001132
1133 spin_lock_irqsave(&pd->rx_lock, flags);
1134 list_add_tail(&rx_msg->entry, &pd->rx_q);
1135 spin_unlock_irqrestore(&pd->rx_lock, flags);
1136
Jack Phamf4baeb12017-02-03 19:01:48 -08001137 kick_sm(pd, 0);
1138}
1139
1140static void phy_shutdown(struct usbpd *pd)
1141{
1142 usbpd_dbg(&pd->dev, "shutdown");
Jack Pham0ab02962017-10-12 15:33:50 -07001143
1144 if (pd->vconn_enabled) {
1145 regulator_disable(pd->vconn);
1146 pd->vconn_enabled = false;
1147 }
1148
1149 if (pd->vbus_enabled) {
1150 regulator_disable(pd->vbus);
1151 pd->vbus_enabled = false;
1152 }
Jack Phamf4baeb12017-02-03 19:01:48 -08001153}
1154
1155static enum hrtimer_restart pd_timeout(struct hrtimer *timer)
1156{
1157 struct usbpd *pd = container_of(timer, struct usbpd, timer);
1158
1159 usbpd_dbg(&pd->dev, "timeout");
1160 queue_work(pd->wq, &pd->sm_work);
1161
1162 return HRTIMER_NORESTART;
1163}
1164
Jack Pham8cbf8ea2018-06-28 23:15:11 -07001165static void log_decoded_request(struct usbpd *pd, u32 rdo)
1166{
1167 const u32 *pdos;
1168 int pos = PD_RDO_OBJ_POS(rdo);
1169 int type;
1170
1171 usbpd_dbg(&pd->dev, "RDO: 0x%08x\n", pd->rdo);
1172
1173 if (pd->current_pr == PR_SINK)
1174 pdos = pd->received_pdos;
1175 else
1176 pdos = default_src_caps;
1177
1178 type = PD_SRC_PDO_TYPE(pdos[pos - 1]);
1179
1180 switch (type) {
1181 case PD_SRC_PDO_TYPE_FIXED:
1182 case PD_SRC_PDO_TYPE_VARIABLE:
1183 usbpd_dbg(&pd->dev, "Request Fixed/Variable PDO:%d Volt:%dmV OpCurr:%dmA Curr:%dmA\n",
1184 pos,
1185 PD_SRC_PDO_FIXED_VOLTAGE(pdos[pos - 1]) * 50,
1186 PD_RDO_FIXED_CURR(rdo) * 10,
1187 PD_RDO_FIXED_CURR_MINMAX(rdo) * 10);
1188 break;
1189
1190 case PD_SRC_PDO_TYPE_BATTERY:
1191 usbpd_dbg(&pd->dev, "Request Battery PDO:%d OpPow:%dmW Pow:%dmW\n",
1192 pos,
1193 PD_RDO_FIXED_CURR(rdo) * 250,
1194 PD_RDO_FIXED_CURR_MINMAX(rdo) * 250);
1195 break;
1196
1197 case PD_SRC_PDO_TYPE_AUGMENTED:
1198 usbpd_dbg(&pd->dev, "Request PPS PDO:%d Volt:%dmV Curr:%dmA\n",
1199 pos,
1200 PD_RDO_PROG_VOLTAGE(rdo) * 20,
1201 PD_RDO_PROG_CURR(rdo) * 50);
1202 break;
1203 }
1204}
1205
Jack Phamf4baeb12017-02-03 19:01:48 -08001206/* Enters new state and executes actions on entry */
1207static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
1208{
1209 struct pd_phy_params phy_params = {
1210 .signal_cb = phy_sig_received,
1211 .msg_rx_cb = phy_msg_received,
1212 .shutdown_cb = phy_shutdown,
1213 .frame_filter_val = FRAME_FILTER_EN_SOP |
1214 FRAME_FILTER_EN_HARD_RESET,
Jack Phamf4baeb12017-02-03 19:01:48 -08001215 };
1216 union power_supply_propval val = {0};
1217 unsigned long flags;
1218 int ret;
1219
Jack Pham4b323282017-11-03 12:24:59 -07001220 if (pd->hard_reset_recvd) /* let usbpd_sm handle it */
1221 return;
1222
Jack Phamf4baeb12017-02-03 19:01:48 -08001223 usbpd_dbg(&pd->dev, "%s -> %s\n",
1224 usbpd_state_strings[pd->current_state],
1225 usbpd_state_strings[next_state]);
1226
1227 pd->current_state = next_state;
1228
1229 switch (next_state) {
1230 case PE_ERROR_RECOVERY: /* perform hard disconnect/reconnect */
1231 pd->in_pr_swap = false;
1232 pd->current_pr = PR_NONE;
1233 set_power_role(pd, PR_NONE);
1234 pd->typec_mode = POWER_SUPPLY_TYPEC_NONE;
1235 kick_sm(pd, 0);
1236 break;
1237
1238 /* Source states */
Jack Phamb9200bb2017-04-19 00:25:32 -07001239 case PE_SRC_DISABLED:
1240 /* are we still connected? */
1241 if (pd->typec_mode == POWER_SUPPLY_TYPEC_NONE) {
1242 pd->current_pr = PR_NONE;
1243 kick_sm(pd, 0);
1244 }
1245
1246 break;
1247
Jack Phamf4baeb12017-02-03 19:01:48 -08001248 case PE_SRC_STARTUP:
1249 if (pd->current_dr == DR_NONE) {
1250 pd->current_dr = DR_DFP;
Mayank Rana38e9b252017-03-23 12:35:57 -07001251 start_usb_host(pd, true);
Mayank Rana6af43422017-07-18 12:09:02 -07001252 pd->ss_lane_svid = 0x0;
Jack Phamf4baeb12017-02-03 19:01:48 -08001253 }
1254
1255 dual_role_instance_changed(pd->dual_role);
1256
1257 /* Set CC back to DRP toggle for the next disconnect */
1258 val.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
1259 power_supply_set_property(pd->usb_psy,
1260 POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &val);
1261
Hemant Kumarbe746222017-07-20 13:51:49 -07001262 /* support only PD 2.0 as a source */
1263 pd->spec_rev = USBPD_REV_20;
Jack Phamf4baeb12017-02-03 19:01:48 -08001264 pd_reset_protocol(pd);
1265
1266 if (!pd->in_pr_swap) {
1267 if (pd->pd_phy_opened) {
1268 pd_phy_close();
1269 pd->pd_phy_opened = false;
1270 }
1271
1272 phy_params.data_role = pd->current_dr;
1273 phy_params.power_role = pd->current_pr;
Jack Phamf4baeb12017-02-03 19:01:48 -08001274
1275 ret = pd_phy_open(&phy_params);
1276 if (ret) {
1277 WARN_ON_ONCE(1);
1278 usbpd_err(&pd->dev, "error opening PD PHY %d\n",
1279 ret);
1280 pd->current_state = PE_UNKNOWN;
1281 return;
1282 }
1283
1284 pd->pd_phy_opened = true;
Jack Phamf4baeb12017-02-03 19:01:48 -08001285 }
1286
Jack Phamf4baeb12017-02-03 19:01:48 -08001287 if (pd->in_pr_swap) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001288 pd->in_pr_swap = false;
Jack Pham857ee682017-05-25 11:53:36 -07001289 val.intval = 0;
1290 power_supply_set_property(pd->usb_psy,
1291 POWER_SUPPLY_PROP_PR_SWAP, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08001292 }
1293
Jack Pham35121342017-07-06 00:12:15 -07001294 /*
1295 * A sink might remove its terminations (during some Type-C
1296 * compliance tests or a sink attempting to do Try.SRC)
1297 * at this point just after we enabled VBUS. Sending PD
1298 * messages now would delay detecting the detach beyond the
1299 * required timing. Instead, delay sending out the first
1300 * source capabilities to allow for the other side to
1301 * completely settle CC debounce and allow HW to detect detach
1302 * sooner in the meantime. PD spec allows up to
1303 * tFirstSourceCap (250ms).
1304 */
1305 pd->current_state = PE_SRC_SEND_CAPABILITIES;
1306 kick_sm(pd, FIRST_SOURCE_CAP_TIME);
1307 break;
Jack Phamf4baeb12017-02-03 19:01:48 -08001308
1309 case PE_SRC_SEND_CAPABILITIES:
1310 kick_sm(pd, 0);
1311 break;
1312
1313 case PE_SRC_NEGOTIATE_CAPABILITY:
Jack Pham8cbf8ea2018-06-28 23:15:11 -07001314 log_decoded_request(pd, pd->rdo);
1315
Jack Phamf4baeb12017-02-03 19:01:48 -08001316 if (PD_RDO_OBJ_POS(pd->rdo) != 1 ||
1317 PD_RDO_FIXED_CURR(pd->rdo) >
Jack Phamf4baeb12017-02-03 19:01:48 -08001318 PD_SRC_PDO_FIXED_MAX_CURR(*default_src_caps)) {
1319 /* send Reject */
1320 ret = pd_send_msg(pd, MSG_REJECT, NULL, 0, SOP_MSG);
1321 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001322 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
1323 break;
1324 }
1325
1326 usbpd_err(&pd->dev, "Invalid request: %08x\n", pd->rdo);
1327
1328 if (pd->in_explicit_contract)
1329 usbpd_set_state(pd, PE_SRC_READY);
1330 else
1331 /*
1332 * bypass PE_SRC_Capability_Response and
1333 * PE_SRC_Wait_New_Capabilities in this
1334 * implementation for simplicity.
1335 */
1336 usbpd_set_state(pd, PE_SRC_SEND_CAPABILITIES);
1337 break;
1338 }
1339
1340 /* PE_SRC_TRANSITION_SUPPLY pseudo-state */
1341 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
1342 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001343 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
1344 break;
1345 }
1346
1347 /* tSrcTransition required after ACCEPT */
1348 usleep_range(SRC_TRANSITION_TIME * USEC_PER_MSEC,
1349 (SRC_TRANSITION_TIME + 5) * USEC_PER_MSEC);
1350
1351 /*
1352 * Normally a voltage change should occur within tSrcReady
1353 * but since we only support VSafe5V there is nothing more to
1354 * prepare from the power supply so send PS_RDY right away.
1355 */
1356 ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG);
1357 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001358 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
1359 break;
1360 }
1361
1362 usbpd_set_state(pd, PE_SRC_READY);
1363 break;
1364
1365 case PE_SRC_READY:
1366 pd->in_explicit_contract = true;
Jack Phambe0f20c2017-10-05 12:51:26 -07001367
1368 if (pd->vdm_tx)
1369 kick_sm(pd, 0);
1370 else if (pd->current_dr == DR_DFP && pd->vdm_state == VDM_NONE)
1371 usbpd_send_svdm(pd, USBPD_SID,
1372 USBPD_SVDM_DISCOVER_IDENTITY,
1373 SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0);
Jack Phamf4baeb12017-02-03 19:01:48 -08001374
1375 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
Jack Phamaf7d3842017-01-26 13:28:19 -08001376 complete(&pd->is_ready);
Jack Phamf4baeb12017-02-03 19:01:48 -08001377 dual_role_instance_changed(pd->dual_role);
1378 break;
1379
1380 case PE_SRC_HARD_RESET:
1381 case PE_SNK_HARD_RESET:
Jack Phamb9200bb2017-04-19 00:25:32 -07001382 /* are we still connected? */
1383 if (pd->typec_mode == POWER_SUPPLY_TYPEC_NONE)
1384 pd->current_pr = PR_NONE;
1385
Jack Phamf4baeb12017-02-03 19:01:48 -08001386 /* hard reset may sleep; handle it in the workqueue */
1387 kick_sm(pd, 0);
1388 break;
1389
1390 case PE_SRC_SEND_SOFT_RESET:
1391 case PE_SNK_SEND_SOFT_RESET:
1392 pd_reset_protocol(pd);
1393
1394 ret = pd_send_msg(pd, MSG_SOFT_RESET, NULL, 0, SOP_MSG);
1395 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001396 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
1397 PE_SRC_HARD_RESET : PE_SNK_HARD_RESET);
1398 break;
1399 }
1400
1401 /* wait for ACCEPT */
1402 kick_sm(pd, SENDER_RESPONSE_TIME);
1403 break;
1404
1405 /* Sink states */
1406 case PE_SNK_STARTUP:
1407 if (pd->current_dr == DR_NONE || pd->current_dr == DR_UFP) {
1408 pd->current_dr = DR_UFP;
1409
1410 if (pd->psy_type == POWER_SUPPLY_TYPE_USB ||
Vijayavardhan Vennapusa34a1f1d2017-05-31 12:00:37 +05301411 pd->psy_type == POWER_SUPPLY_TYPE_USB_CDP ||
Hemant Kumarbbf7d052017-07-13 12:08:49 -07001412 pd->psy_type == POWER_SUPPLY_TYPE_USB_FLOAT ||
Vijayavardhan Vennapusa34a1f1d2017-05-31 12:00:37 +05301413 usb_compliance_mode)
Jack Phamf4baeb12017-02-03 19:01:48 -08001414 start_usb_peripheral(pd);
1415 }
1416
1417 dual_role_instance_changed(pd->dual_role);
1418
1419 ret = power_supply_get_property(pd->usb_psy,
1420 POWER_SUPPLY_PROP_PD_ALLOWED, &val);
1421 if (ret) {
1422 usbpd_err(&pd->dev, "Unable to read USB PROP_PD_ALLOWED: %d\n",
1423 ret);
1424 break;
1425 }
1426
Vijayavardhan Vennapusa49f21ce2017-06-05 14:47:56 +05301427 if (!val.intval || disable_usb_pd)
Jack Phamf4baeb12017-02-03 19:01:48 -08001428 break;
1429
Hemant Kumarbe746222017-07-20 13:51:49 -07001430 /*
1431 * support up to PD 3.0 as a sink; if source is 2.0
1432 * phy_msg_received() will handle the downgrade.
1433 */
1434 pd->spec_rev = USBPD_REV_30;
Jack Phamf4baeb12017-02-03 19:01:48 -08001435 pd_reset_protocol(pd);
1436
1437 if (!pd->in_pr_swap) {
1438 if (pd->pd_phy_opened) {
1439 pd_phy_close();
1440 pd->pd_phy_opened = false;
1441 }
1442
1443 phy_params.data_role = pd->current_dr;
1444 phy_params.power_role = pd->current_pr;
Jack Phamf4baeb12017-02-03 19:01:48 -08001445
1446 ret = pd_phy_open(&phy_params);
1447 if (ret) {
1448 WARN_ON_ONCE(1);
1449 usbpd_err(&pd->dev, "error opening PD PHY %d\n",
1450 ret);
1451 pd->current_state = PE_UNKNOWN;
1452 return;
1453 }
1454
1455 pd->pd_phy_opened = true;
Jack Phamf4baeb12017-02-03 19:01:48 -08001456 }
1457
1458 pd->current_voltage = pd->requested_voltage = 5000000;
1459 val.intval = pd->requested_voltage; /* set max range to 5V */
1460 power_supply_set_property(pd->usb_psy,
Nicholas Troast7f55c922017-07-25 13:18:03 -07001461 POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08001462
1463 if (!pd->vbus_present) {
1464 pd->current_state = PE_SNK_DISCOVERY;
1465 /* max time for hard reset to turn vbus back on */
1466 kick_sm(pd, SNK_HARD_RESET_VBUS_ON_TIME);
1467 break;
1468 }
1469
1470 pd->current_state = PE_SNK_WAIT_FOR_CAPABILITIES;
1471 /* fall-through */
1472
1473 case PE_SNK_WAIT_FOR_CAPABILITIES:
1474 spin_lock_irqsave(&pd->rx_lock, flags);
1475 if (list_empty(&pd->rx_q))
1476 kick_sm(pd, SINK_WAIT_CAP_TIME);
1477 spin_unlock_irqrestore(&pd->rx_lock, flags);
1478 break;
1479
1480 case PE_SNK_EVALUATE_CAPABILITY:
1481 pd->pd_connected = true; /* we know peer is PD capable */
1482 pd->hard_reset_count = 0;
1483
1484 /* evaluate PDOs and select one */
1485 ret = pd_eval_src_caps(pd);
1486 if (ret < 0) {
1487 usbpd_err(&pd->dev, "Invalid src_caps received. Skipping request\n");
1488 break;
1489 }
1490 pd->current_state = PE_SNK_SELECT_CAPABILITY;
1491 /* fall-through */
1492
1493 case PE_SNK_SELECT_CAPABILITY:
Jack Pham8cbf8ea2018-06-28 23:15:11 -07001494 log_decoded_request(pd, pd->rdo);
1495
Jack Phamf4baeb12017-02-03 19:01:48 -08001496 ret = pd_send_msg(pd, MSG_REQUEST, &pd->rdo, 1, SOP_MSG);
1497 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001498 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
1499 break;
1500 }
1501
1502 /* wait for ACCEPT */
1503 kick_sm(pd, SENDER_RESPONSE_TIME);
1504 break;
1505
1506 case PE_SNK_TRANSITION_SINK:
1507 /* wait for PS_RDY */
1508 kick_sm(pd, PS_TRANSITION_TIME);
1509 break;
1510
1511 case PE_SNK_READY:
1512 pd->in_explicit_contract = true;
Jack Phambe0f20c2017-10-05 12:51:26 -07001513
1514 if (pd->vdm_tx)
1515 kick_sm(pd, 0);
1516 else if (pd->current_dr == DR_DFP && pd->vdm_state == VDM_NONE)
1517 usbpd_send_svdm(pd, USBPD_SID,
1518 USBPD_SVDM_DISCOVER_IDENTITY,
1519 SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0);
1520
Jack Phamf4baeb12017-02-03 19:01:48 -08001521 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
Jack Phamaf7d3842017-01-26 13:28:19 -08001522 complete(&pd->is_ready);
Jack Phamf4baeb12017-02-03 19:01:48 -08001523 dual_role_instance_changed(pd->dual_role);
1524 break;
1525
1526 case PE_SNK_TRANSITION_TO_DEFAULT:
1527 if (pd->current_dr != DR_UFP) {
1528 stop_usb_host(pd);
1529 start_usb_peripheral(pd);
1530 pd->current_dr = DR_UFP;
1531 pd_phy_update_roles(pd->current_dr, pd->current_pr);
1532 }
1533 if (pd->vconn_enabled) {
1534 regulator_disable(pd->vconn);
1535 pd->vconn_enabled = false;
1536 }
1537
1538 /* max time for hard reset to turn vbus off */
1539 kick_sm(pd, SNK_HARD_RESET_VBUS_OFF_TIME);
1540 break;
1541
1542 case PE_PRS_SNK_SRC_TRANSITION_TO_OFF:
1543 val.intval = pd->requested_current = 0; /* suspend charging */
1544 power_supply_set_property(pd->usb_psy,
1545 POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
1546
1547 pd->in_explicit_contract = false;
1548
1549 /*
1550 * need to update PR bit in message header so that
1551 * proper GoodCRC is sent when receiving next PS_RDY
1552 */
1553 pd_phy_update_roles(pd->current_dr, PR_SRC);
1554
1555 /* wait for PS_RDY */
1556 kick_sm(pd, PS_SOURCE_OFF);
1557 break;
1558
1559 default:
1560 usbpd_dbg(&pd->dev, "No action for state %s\n",
1561 usbpd_state_strings[pd->current_state]);
1562 break;
1563 }
1564}
1565
1566int usbpd_register_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr)
1567{
1568 if (find_svid_handler(pd, hdlr->svid)) {
1569 usbpd_err(&pd->dev, "SVID 0x%04x already registered\n",
1570 hdlr->svid);
1571 return -EINVAL;
1572 }
1573
1574 /* require connect/disconnect callbacks be implemented */
1575 if (!hdlr->connect || !hdlr->disconnect) {
1576 usbpd_err(&pd->dev, "SVID 0x%04x connect/disconnect must be non-NULL\n",
1577 hdlr->svid);
1578 return -EINVAL;
1579 }
1580
Mayank Rana83443202017-08-31 15:38:03 -07001581 usbpd_dbg(&pd->dev, "registered handler(%pK) for SVID 0x%04x\n",
1582 hdlr, hdlr->svid);
1583 mutex_lock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08001584 list_add_tail(&hdlr->entry, &pd->svid_handlers);
Mayank Rana83443202017-08-31 15:38:03 -07001585 mutex_unlock(&pd->svid_handler_lock);
Mayank Rana6af43422017-07-18 12:09:02 -07001586 hdlr->request_usb_ss_lane = usbpd_release_ss_lane;
Jack Phamf4baeb12017-02-03 19:01:48 -08001587
1588 /* already connected with this SVID discovered? */
1589 if (pd->vdm_state >= DISCOVERED_SVIDS) {
1590 int i;
1591
1592 for (i = 0; i < pd->num_svids; i++) {
1593 if (pd->discovered_svids[i] == hdlr->svid) {
1594 hdlr->connect(hdlr);
1595 hdlr->discovered = true;
1596 break;
1597 }
1598 }
1599 }
1600
1601 return 0;
1602}
1603EXPORT_SYMBOL(usbpd_register_svid);
1604
1605void usbpd_unregister_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr)
1606{
Mayank Rana83443202017-08-31 15:38:03 -07001607
1608 usbpd_dbg(&pd->dev, "unregistered handler(%pK) for SVID 0x%04x\n",
1609 hdlr, hdlr->svid);
1610 mutex_lock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08001611 list_del_init(&hdlr->entry);
Mayank Rana83443202017-08-31 15:38:03 -07001612 mutex_unlock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08001613}
1614EXPORT_SYMBOL(usbpd_unregister_svid);
1615
1616int usbpd_send_vdm(struct usbpd *pd, u32 vdm_hdr, const u32 *vdos, int num_vdos)
1617{
1618 struct vdm_tx *vdm_tx;
1619
1620 if (!pd->in_explicit_contract || pd->vdm_tx)
1621 return -EBUSY;
1622
1623 vdm_tx = kzalloc(sizeof(*vdm_tx), GFP_KERNEL);
1624 if (!vdm_tx)
1625 return -ENOMEM;
1626
1627 vdm_tx->data[0] = vdm_hdr;
1628 if (vdos && num_vdos)
1629 memcpy(&vdm_tx->data[1], vdos, num_vdos * sizeof(u32));
1630 vdm_tx->size = num_vdos + 1; /* include the header */
1631
1632 /* VDM will get sent in PE_SRC/SNK_READY state handling */
1633 pd->vdm_tx = vdm_tx;
1634
1635 /* slight delay before queuing to prioritize handling of incoming VDM */
1636 kick_sm(pd, 2);
1637
1638 return 0;
1639}
1640EXPORT_SYMBOL(usbpd_send_vdm);
1641
1642int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd,
1643 enum usbpd_svdm_cmd_type cmd_type, int obj_pos,
1644 const u32 *vdos, int num_vdos)
1645{
1646 u32 svdm_hdr = SVDM_HDR(svid, 0, obj_pos, cmd_type, cmd);
1647
1648 usbpd_dbg(&pd->dev, "VDM tx: svid:%x cmd:%x cmd_type:%x svdm_hdr:%x\n",
1649 svid, cmd, cmd_type, svdm_hdr);
1650
1651 return usbpd_send_vdm(pd, svdm_hdr, vdos, num_vdos);
1652}
1653EXPORT_SYMBOL(usbpd_send_svdm);
1654
1655static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg)
1656{
Jack Phamf3c1bd32017-08-02 18:32:23 -07001657 u32 vdm_hdr =
1658 rx_msg->data_len >= sizeof(u32) ? ((u32 *)rx_msg->payload)[0] : 0;
1659
1660 u32 *vdos = (u32 *)&rx_msg->payload[sizeof(u32)];
Jack Phamf4baeb12017-02-03 19:01:48 -08001661 u16 svid = VDM_HDR_SVID(vdm_hdr);
1662 u16 *psvid;
Jack Phamf3c1bd32017-08-02 18:32:23 -07001663 u8 i, num_vdos = PD_MSG_HDR_COUNT(rx_msg->hdr) - 1;
Jack Phamf4baeb12017-02-03 19:01:48 -08001664 u8 cmd = SVDM_HDR_CMD(vdm_hdr);
1665 u8 cmd_type = SVDM_HDR_CMD_TYPE(vdm_hdr);
Jack Phamf4baeb12017-02-03 19:01:48 -08001666 struct usbpd_svid_handler *handler;
1667
Liangliang Lu7e9fffa2018-06-26 12:45:14 +08001668 usbpd_dbg(&pd->dev,
1669 "VDM rx: svid:%x cmd:%x cmd_type:%x vdm_hdr:%x has_dp: %s\n",
1670 svid, cmd, cmd_type, vdm_hdr,
1671 pd->has_dp ? "true" : "false");
1672
1673 if ((svid == 0xFF01) && (pd->has_dp == false)) {
1674 pd->has_dp = true;
1675
1676 /* Set to USB and DP cocurrency mode */
1677 extcon_blocking_sync(pd->extcon, EXTCON_DISP_DP, 2);
1678 }
Jack Phamf4baeb12017-02-03 19:01:48 -08001679
1680 /* if it's a supported SVID, pass the message to the handler */
1681 handler = find_svid_handler(pd, svid);
1682
1683 /* Unstructured VDM */
1684 if (!VDM_IS_SVDM(vdm_hdr)) {
1685 if (handler && handler->vdm_received)
1686 handler->vdm_received(handler, vdm_hdr, vdos, num_vdos);
1687 return;
1688 }
1689
1690 /* if this interrupts a previous exchange, abort queued response */
1691 if (cmd_type == SVDM_CMD_TYPE_INITIATOR && pd->vdm_tx) {
Vijayavardhan Vennapusa2dec2b22018-04-12 17:25:19 +05301692 /*
1693 * Drop ATTENTION command unless atleast one SVID handler is
1694 * discovered/connected.
1695 */
1696 if (cmd == USBPD_SVDM_ATTENTION && handler &&
1697 !handler->discovered) {
1698 usbpd_dbg(&pd->dev, "Send vdm command again queued SVDM tx (SVID:0x%04x)\n",
1699 VDM_HDR_SVID(pd->vdm_tx->data[0]));
1700 kick_sm(pd, 0);
1701 return;
1702 }
1703
Jack Phamf4baeb12017-02-03 19:01:48 -08001704 usbpd_dbg(&pd->dev, "Discarding previously queued SVDM tx (SVID:0x%04x)\n",
1705 VDM_HDR_SVID(pd->vdm_tx->data[0]));
1706
1707 kfree(pd->vdm_tx);
1708 pd->vdm_tx = NULL;
1709 }
1710
1711 if (handler && handler->svdm_received) {
rbandi20d026b2020-03-18 10:15:47 -07001712 if (pd->is_sxr_dp_sink) {
1713 u32 tx_vdos[1];
1714
1715 switch (cmd) {
1716 /*CMD 3, Type 1, PayLoad 43 */
1717 case USBPD_SVDM_DISCOVER_MODES:
1718 usbpd_dbg(&pd->dev,
1719 "USBPD_SVDM_DISCOVER_MODES\n");
1720 tx_vdos[0] = XR1_DISCOVER_VDO;
1721 usbpd_dbg(&pd->dev, "sending RESP_ACK\n");
1722 SXR_SEND_SVDM(pd, cmd, 0x0, tx_vdos, 0x1);
1723 break;
1724 /*CMD 4, Type 1, PayLoad 44 */
1725 case USBPD_SVDM_ENTER_MODE:
1726 usbpd_dbg(&pd->dev, "USBPD_SVDM_ENTER_MODE\n");
1727 tx_vdos[0] = XR1_DEFAULT_VDO;
1728 usbpd_dbg(&pd->dev, "sending RESP_ACK\n");
1729 SXR_SEND_SVDM(pd, cmd, 0x1, tx_vdos, 0x0);
1730 break;
1731 /*CMD 10, Type 1, PayLoad 50 */
1732 case DP_USBPD_EVT_STATUS_XR1:
1733 tx_vdos[0] = XR1_PIN_E_VDO; // Pin assign E
1734 usbpd_dbg(&pd->dev,
1735 "DP_USBPD_EVT_STATUS_XR1\n");
1736 SXR_SEND_SVDM(pd, cmd, 0x1, tx_vdos, 0x1);
1737 break;
1738 /*CMD 11, Type 1, PayLoad 51 */
1739 case DP_USBPD_EVT_CONFIGURE_XR1:
1740 usbpd_dbg(&pd->dev,
1741 "DP_USBPD_EVT_CONFIGURE_XR1\n");
1742 tx_vdos[0] = XR1_DEFAULT_VDO;
1743 usbpd_dbg(&pd->dev,
1744 "DP_USBPD_EVT_STATUS_XR1\n");
1745 SXR_SEND_SVDM(pd, cmd, 0x1, tx_vdos, 0x0);
1746 break;
1747 default:
1748 usbpd_dbg(&pd->dev, "default mode:%d\n", cmd);
1749 }
1750 } else
1751 handler->svdm_received(handler, cmd, cmd_type, vdos,
1752 num_vdos);
Jack Phamf4baeb12017-02-03 19:01:48 -08001753 return;
1754 }
1755
1756 /* Standard Discovery or unhandled messages go here */
1757 switch (cmd_type) {
1758 case SVDM_CMD_TYPE_INITIATOR:
1759 if (svid == USBPD_SID && cmd == USBPD_SVDM_DISCOVER_IDENTITY) {
1760 u32 tx_vdos[3] = {
1761 ID_HDR_USB_HOST | ID_HDR_USB_DEVICE |
1762 ID_HDR_PRODUCT_PER_MASK | ID_HDR_VID,
1763 0x0, /* TBD: Cert Stat VDO */
1764 (PROD_VDO_PID << 16),
1765 /* TBD: Get these from gadget */
1766 };
1767
1768 usbpd_send_svdm(pd, USBPD_SID, cmd,
1769 SVDM_CMD_TYPE_RESP_ACK, 0, tx_vdos, 3);
rbandi20d026b2020-03-18 10:15:47 -07001770 } else if (cmd != USBPD_SVDM_ATTENTION) {
1771 if (pd->is_sxr_dp_sink) {
1772 u32 tx_vdos_pd[3] = {
1773 ID_HDR_VID,
1774 0xFF01,
1775 0x0,
1776 };
1777 usbpd_send_svdm(pd, USBPD_SID, cmd,
1778 SVDM_CMD_TYPE_RESP_ACK, 0,
1779 tx_vdos_pd, 3);
1780 } else {
1781 usbpd_send_svdm(pd, svid, cmd,
1782 SVDM_CMD_TYPE_RESP_NAK,
Jack Phamf4baeb12017-02-03 19:01:48 -08001783 SVDM_HDR_OBJ_POS(vdm_hdr), NULL, 0);
rbandi20d026b2020-03-18 10:15:47 -07001784 }
Jack Phamf4baeb12017-02-03 19:01:48 -08001785 }
1786 break;
1787
1788 case SVDM_CMD_TYPE_RESP_ACK:
1789 if (svid != USBPD_SID) {
1790 usbpd_err(&pd->dev, "unhandled ACK for SVID:0x%x\n",
1791 svid);
1792 break;
1793 }
1794
1795 switch (cmd) {
1796 case USBPD_SVDM_DISCOVER_IDENTITY:
1797 kfree(pd->vdm_tx_retry);
1798 pd->vdm_tx_retry = NULL;
1799
1800 pd->vdm_state = DISCOVERED_ID;
1801 usbpd_send_svdm(pd, USBPD_SID,
1802 USBPD_SVDM_DISCOVER_SVIDS,
1803 SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0);
1804 break;
1805
1806 case USBPD_SVDM_DISCOVER_SVIDS:
1807 pd->vdm_state = DISCOVERED_SVIDS;
1808
1809 kfree(pd->vdm_tx_retry);
1810 pd->vdm_tx_retry = NULL;
1811
1812 if (!pd->discovered_svids) {
1813 pd->num_svids = 2 * num_vdos;
1814 pd->discovered_svids = kcalloc(pd->num_svids,
1815 sizeof(u16),
1816 GFP_KERNEL);
1817 if (!pd->discovered_svids) {
1818 usbpd_err(&pd->dev, "unable to allocate SVIDs\n");
1819 break;
1820 }
1821
1822 psvid = pd->discovered_svids;
1823 } else { /* handle > 12 SVIDs */
1824 void *ptr;
1825 size_t oldsize = pd->num_svids * sizeof(u16);
1826 size_t newsize = oldsize +
1827 (2 * num_vdos * sizeof(u16));
1828
1829 ptr = krealloc(pd->discovered_svids, newsize,
1830 GFP_KERNEL);
1831 if (!ptr) {
1832 usbpd_err(&pd->dev, "unable to realloc SVIDs\n");
1833 break;
1834 }
1835
1836 pd->discovered_svids = ptr;
1837 psvid = pd->discovered_svids + pd->num_svids;
1838 memset(psvid, 0, (2 * num_vdos));
1839 pd->num_svids += 2 * num_vdos;
1840 }
1841
1842 /* convert 32-bit VDOs to list of 16-bit SVIDs */
1843 for (i = 0; i < num_vdos * 2; i++) {
1844 /*
1845 * Within each 32-bit VDO,
1846 * SVID[i]: upper 16-bits
1847 * SVID[i+1]: lower 16-bits
1848 * where i is even.
1849 */
1850 if (!(i & 1))
1851 svid = vdos[i >> 1] >> 16;
1852 else
1853 svid = vdos[i >> 1] & 0xFFFF;
1854
1855 /*
1856 * There are some devices that incorrectly
1857 * swap the order of SVIDs within a VDO. So in
1858 * case of an odd-number of SVIDs it could end
1859 * up with SVID[i] as 0 while SVID[i+1] is
1860 * non-zero. Just skip over the zero ones.
1861 */
1862 if (svid) {
1863 usbpd_dbg(&pd->dev, "Discovered SVID: 0x%04x\n",
1864 svid);
1865 *psvid++ = svid;
1866 }
1867 }
1868
1869 /* if more than 12 SVIDs, resend the request */
1870 if (num_vdos == 6 && vdos[5] != 0) {
1871 usbpd_send_svdm(pd, USBPD_SID,
1872 USBPD_SVDM_DISCOVER_SVIDS,
1873 SVDM_CMD_TYPE_INITIATOR, 0,
1874 NULL, 0);
1875 break;
1876 }
1877
1878 /* now that all SVIDs are discovered, notify handlers */
1879 for (i = 0; i < pd->num_svids; i++) {
1880 svid = pd->discovered_svids[i];
1881 if (svid) {
1882 handler = find_svid_handler(pd, svid);
1883 if (handler) {
1884 handler->connect(handler);
1885 handler->discovered = true;
1886 }
1887 }
Jack Phamf4baeb12017-02-03 19:01:48 -08001888 }
Jack Phamf4baeb12017-02-03 19:01:48 -08001889 break;
1890
1891 default:
1892 usbpd_dbg(&pd->dev, "unhandled ACK for command:0x%x\n",
1893 cmd);
1894 break;
1895 }
1896 break;
1897
1898 case SVDM_CMD_TYPE_RESP_NAK:
1899 usbpd_info(&pd->dev, "VDM NAK received for SVID:0x%04x command:0x%x\n",
1900 svid, cmd);
1901
1902 switch (cmd) {
1903 case USBPD_SVDM_DISCOVER_IDENTITY:
1904 case USBPD_SVDM_DISCOVER_SVIDS:
Jack Phamf4baeb12017-02-03 19:01:48 -08001905 break;
1906 default:
1907 break;
1908 }
1909
1910 break;
1911
1912 case SVDM_CMD_TYPE_RESP_BUSY:
1913 switch (cmd) {
1914 case USBPD_SVDM_DISCOVER_IDENTITY:
1915 case USBPD_SVDM_DISCOVER_SVIDS:
1916 if (!pd->vdm_tx_retry) {
1917 usbpd_err(&pd->dev, "Discover command %d VDM was unexpectedly freed\n",
1918 cmd);
1919 break;
1920 }
1921
1922 /* wait tVDMBusy, then retry */
1923 pd->vdm_tx = pd->vdm_tx_retry;
1924 pd->vdm_tx_retry = NULL;
1925 kick_sm(pd, VDM_BUSY_TIME);
1926 break;
1927 default:
1928 break;
1929 }
1930 break;
1931 }
1932}
1933
1934static void handle_vdm_tx(struct usbpd *pd)
1935{
1936 int ret;
1937 unsigned long flags;
1938
1939 /* only send one VDM at a time */
1940 if (pd->vdm_tx) {
1941 u32 vdm_hdr = pd->vdm_tx->data[0];
1942
1943 /* bail out and try again later if a message just arrived */
1944 spin_lock_irqsave(&pd->rx_lock, flags);
1945 if (!list_empty(&pd->rx_q)) {
1946 spin_unlock_irqrestore(&pd->rx_lock, flags);
1947 return;
1948 }
1949 spin_unlock_irqrestore(&pd->rx_lock, flags);
1950
1951 ret = pd_send_msg(pd, MSG_VDM, pd->vdm_tx->data,
1952 pd->vdm_tx->size, SOP_MSG);
1953 if (ret) {
1954 usbpd_err(&pd->dev, "Error (%d) sending VDM command %d\n",
1955 ret, SVDM_HDR_CMD(pd->vdm_tx->data[0]));
1956
1957 /* retry when hitting PE_SRC/SNK_Ready again */
1958 if (ret != -EBUSY)
1959 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
1960 PE_SRC_SEND_SOFT_RESET :
1961 PE_SNK_SEND_SOFT_RESET);
1962
1963 return;
1964 }
1965
1966 /*
1967 * special case: keep initiated Discover ID/SVIDs
1968 * around in case we need to re-try when receiving BUSY
1969 */
1970 if (VDM_IS_SVDM(vdm_hdr) &&
1971 SVDM_HDR_CMD_TYPE(vdm_hdr) == SVDM_CMD_TYPE_INITIATOR &&
1972 SVDM_HDR_CMD(vdm_hdr) <= USBPD_SVDM_DISCOVER_SVIDS) {
1973 if (pd->vdm_tx_retry) {
1974 usbpd_dbg(&pd->dev, "Previous Discover VDM command %d not ACKed/NAKed\n",
1975 SVDM_HDR_CMD(
1976 pd->vdm_tx_retry->data[0]));
1977 kfree(pd->vdm_tx_retry);
1978 }
1979 pd->vdm_tx_retry = pd->vdm_tx;
1980 } else {
1981 kfree(pd->vdm_tx);
1982 }
1983
1984 pd->vdm_tx = NULL;
1985 }
1986}
1987
1988static void reset_vdm_state(struct usbpd *pd)
1989{
1990 struct usbpd_svid_handler *handler;
1991
Mayank Rana83443202017-08-31 15:38:03 -07001992 mutex_lock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08001993 list_for_each_entry(handler, &pd->svid_handlers, entry) {
1994 if (handler->discovered) {
1995 handler->disconnect(handler);
1996 handler->discovered = false;
1997 }
1998 }
1999
Mayank Rana83443202017-08-31 15:38:03 -07002000 mutex_unlock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08002001 pd->vdm_state = VDM_NONE;
2002 kfree(pd->vdm_tx_retry);
2003 pd->vdm_tx_retry = NULL;
2004 kfree(pd->discovered_svids);
2005 pd->discovered_svids = NULL;
2006 pd->num_svids = 0;
2007 kfree(pd->vdm_tx);
2008 pd->vdm_tx = NULL;
Vijayavardhan Vennapusadea32272018-04-05 14:25:39 +05302009 pd->ss_lane_svid = 0x0;
Jack Phamf4baeb12017-02-03 19:01:48 -08002010}
2011
2012static void dr_swap(struct usbpd *pd)
2013{
2014 reset_vdm_state(pd);
Mayank Rana45b0bc42017-07-25 15:38:05 -07002015 usbpd_dbg(&pd->dev, "dr_swap: current_dr(%d)\n", pd->current_dr);
Jack Phamf4baeb12017-02-03 19:01:48 -08002016
2017 if (pd->current_dr == DR_DFP) {
2018 stop_usb_host(pd);
2019 start_usb_peripheral(pd);
2020 pd->current_dr = DR_UFP;
2021 } else if (pd->current_dr == DR_UFP) {
2022 stop_usb_peripheral(pd);
Mayank Rana45b0bc42017-07-25 15:38:05 -07002023 start_usb_host(pd, true);
Jack Phamf4baeb12017-02-03 19:01:48 -08002024 pd->current_dr = DR_DFP;
2025
Jack Phamf4baeb12017-02-03 19:01:48 -08002026 usbpd_send_svdm(pd, USBPD_SID, USBPD_SVDM_DISCOVER_IDENTITY,
2027 SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0);
2028 }
2029
2030 pd_phy_update_roles(pd->current_dr, pd->current_pr);
Jack Phame232bde2017-03-02 11:37:00 -08002031 dual_role_instance_changed(pd->dual_role);
Jack Phamf4baeb12017-02-03 19:01:48 -08002032}
2033
2034
2035static void vconn_swap(struct usbpd *pd)
2036{
2037 int ret;
2038
2039 if (pd->vconn_enabled) {
2040 pd->current_state = PE_VCS_WAIT_FOR_VCONN;
2041 kick_sm(pd, VCONN_ON_TIME);
2042 } else {
2043 ret = regulator_enable(pd->vconn);
2044 if (ret) {
2045 usbpd_err(&pd->dev, "Unable to enable vconn\n");
2046 return;
2047 }
2048
2049 pd->vconn_enabled = true;
2050
2051 /*
2052 * Small delay to ensure Vconn has ramped up. This is well
2053 * below tVCONNSourceOn (100ms) so we still send PS_RDY within
2054 * the allowed time.
2055 */
2056 usleep_range(5000, 10000);
2057
2058 ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG);
2059 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002060 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
2061 PE_SRC_SEND_SOFT_RESET :
2062 PE_SNK_SEND_SOFT_RESET);
2063 return;
2064 }
2065 }
2066}
2067
2068static int enable_vbus(struct usbpd *pd)
2069{
2070 union power_supply_propval val = {0};
2071 int count = 100;
2072 int ret;
2073
2074 if (!check_vsafe0v)
2075 goto enable_reg;
2076
2077 /*
2078 * Check to make sure there's no lingering charge on
2079 * VBUS before enabling it as a source. If so poll here
2080 * until it goes below VSafe0V (0.8V) before proceeding.
2081 */
2082 while (count--) {
2083 ret = power_supply_get_property(pd->usb_psy,
2084 POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
2085 if (ret || val.intval <= 800000)
2086 break;
2087 usleep_range(20000, 30000);
2088 }
2089
2090 if (count < 99)
2091 msleep(100); /* need to wait an additional tCCDebounce */
2092
2093enable_reg:
2094 ret = regulator_enable(pd->vbus);
2095 if (ret)
2096 usbpd_err(&pd->dev, "Unable to enable vbus (%d)\n", ret);
2097 else
2098 pd->vbus_enabled = true;
2099
Vijayavardhan Vennapusaa9e32702018-07-03 15:47:18 +05302100 count = 10;
2101 /*
2102 * Check to make sure VBUS voltage reaches above Vsafe5Vmin (4.75v)
2103 * before proceeding.
2104 */
2105 while (count--) {
2106 ret = power_supply_get_property(pd->usb_psy,
2107 POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
2108 if (ret || val.intval >= 4750000) /*vsafe5Vmin*/
2109 break;
2110 usleep_range(10000, 12000); /* Delay between two reads */
2111 }
2112
2113 if (ret)
2114 msleep(100); /* Delay to wait for VBUS ramp up if read fails */
2115
Jack Phamf4baeb12017-02-03 19:01:48 -08002116 return ret;
2117}
2118
2119static inline void rx_msg_cleanup(struct usbpd *pd)
2120{
2121 struct rx_msg *msg, *tmp;
2122 unsigned long flags;
2123
2124 spin_lock_irqsave(&pd->rx_lock, flags);
2125 list_for_each_entry_safe(msg, tmp, &pd->rx_q, entry) {
2126 list_del(&msg->entry);
2127 kfree(msg);
2128 }
2129 spin_unlock_irqrestore(&pd->rx_lock, flags);
2130}
2131
2132/* For PD 3.0, check SinkTxOk before allowing initiating AMS */
2133static inline bool is_sink_tx_ok(struct usbpd *pd)
2134{
2135 if (pd->spec_rev == USBPD_REV_30)
2136 return pd->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH;
2137
2138 return true;
2139}
2140
2141/* Handles current state and determines transitions */
2142static void usbpd_sm(struct work_struct *w)
2143{
2144 struct usbpd *pd = container_of(w, struct usbpd, sm_work);
2145 union power_supply_propval val = {0};
2146 int ret;
2147 struct rx_msg *rx_msg = NULL;
2148 unsigned long flags;
2149
2150 usbpd_dbg(&pd->dev, "handle state %s\n",
2151 usbpd_state_strings[pd->current_state]);
2152
2153 hrtimer_cancel(&pd->timer);
2154 pd->sm_queued = false;
2155
2156 spin_lock_irqsave(&pd->rx_lock, flags);
2157 if (!list_empty(&pd->rx_q)) {
2158 rx_msg = list_first_entry(&pd->rx_q, struct rx_msg, entry);
2159 list_del(&rx_msg->entry);
2160 }
2161 spin_unlock_irqrestore(&pd->rx_lock, flags);
2162
2163 /* Disconnect? */
2164 if (pd->current_pr == PR_NONE) {
Sriharsha Allenki8d4687a2018-09-20 17:00:38 +05302165 if (pd->current_state == PE_UNKNOWN &&
2166 pd->current_dr == DR_NONE)
Jack Phamf4baeb12017-02-03 19:01:48 -08002167 goto sm_done;
2168
Hemant Kumar86bd10f2017-05-24 12:25:15 -07002169 if (pd->vconn_enabled) {
2170 regulator_disable(pd->vconn);
2171 pd->vconn_enabled = false;
2172 }
2173
Jack Phamf4baeb12017-02-03 19:01:48 -08002174 usbpd_info(&pd->dev, "USB Type-C disconnect\n");
2175
2176 if (pd->pd_phy_opened) {
2177 pd_phy_close();
2178 pd->pd_phy_opened = false;
2179 }
2180
2181 pd->in_pr_swap = false;
2182 pd->pd_connected = false;
2183 pd->in_explicit_contract = false;
2184 pd->hard_reset_recvd = false;
2185 pd->caps_count = 0;
2186 pd->hard_reset_count = 0;
Jack Phamf4baeb12017-02-03 19:01:48 -08002187 pd->requested_voltage = 0;
2188 pd->requested_current = 0;
Jack Phamf6c02da2017-01-31 15:23:56 -08002189 pd->selected_pdo = pd->requested_pdo = 0;
Jack Phamf4baeb12017-02-03 19:01:48 -08002190 memset(&pd->received_pdos, 0, sizeof(pd->received_pdos));
2191 rx_msg_cleanup(pd);
2192
Jack Phamf4baeb12017-02-03 19:01:48 -08002193 power_supply_set_property(pd->usb_psy,
2194 POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val);
2195
2196 power_supply_set_property(pd->usb_psy,
2197 POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED,
2198 &val);
2199
2200 power_supply_set_property(pd->usb_psy,
2201 POWER_SUPPLY_PROP_PD_ACTIVE, &val);
2202
2203 if (pd->vbus_enabled) {
2204 regulator_disable(pd->vbus);
2205 pd->vbus_enabled = false;
2206 }
2207
Mayank Rana86cb20292017-06-01 11:36:07 -07002208 reset_vdm_state(pd);
Jack Phamf4baeb12017-02-03 19:01:48 -08002209 if (pd->current_dr == DR_UFP)
2210 stop_usb_peripheral(pd);
2211 else if (pd->current_dr == DR_DFP)
2212 stop_usb_host(pd);
2213
Jack Phamf4baeb12017-02-03 19:01:48 -08002214 pd->current_dr = DR_NONE;
2215
Jack Phamf4baeb12017-02-03 19:01:48 -08002216 if (pd->current_state == PE_ERROR_RECOVERY)
2217 /* forced disconnect, wait before resetting to DRP */
2218 usleep_range(ERROR_RECOVERY_TIME * USEC_PER_MSEC,
2219 (ERROR_RECOVERY_TIME + 5) * USEC_PER_MSEC);
2220
Jack Pham01c5cfd2017-06-06 22:22:18 -07002221 val.intval = 0;
2222 power_supply_set_property(pd->usb_psy,
2223 POWER_SUPPLY_PROP_PR_SWAP, &val);
2224
Jack Phamf4baeb12017-02-03 19:01:48 -08002225 /* set due to dual_role class "mode" change */
2226 if (pd->forced_pr != POWER_SUPPLY_TYPEC_PR_NONE)
2227 val.intval = pd->forced_pr;
Hemant Kumarbe746222017-07-20 13:51:49 -07002228 else if (rev3_sink_only)
2229 val.intval = POWER_SUPPLY_TYPEC_PR_SINK;
Jack Phamf4baeb12017-02-03 19:01:48 -08002230 else
2231 /* Set CC back to DRP toggle */
2232 val.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
2233
2234 power_supply_set_property(pd->usb_psy,
2235 POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &val);
2236 pd->forced_pr = POWER_SUPPLY_TYPEC_PR_NONE;
2237
2238 pd->current_state = PE_UNKNOWN;
2239
2240 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
2241 dual_role_instance_changed(pd->dual_role);
2242
Liangliang Lu7e9fffa2018-06-26 12:45:14 +08002243 if (pd->has_dp) {
2244 pd->has_dp = false;
2245
2246 /* Set to USB only mode when cable disconnected */
2247 extcon_blocking_sync(pd->extcon, EXTCON_DISP_DP, 0);
2248 }
2249
Jack Phamf4baeb12017-02-03 19:01:48 -08002250 goto sm_done;
2251 }
2252
2253 /* Hard reset? */
2254 if (pd->hard_reset_recvd) {
2255 pd->hard_reset_recvd = false;
2256
Jack Pham6de20802017-05-24 13:44:56 -07002257 if (pd->requested_current) {
2258 val.intval = pd->requested_current = 0;
2259 power_supply_set_property(pd->usb_psy,
2260 POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
2261 }
2262
2263 pd->requested_voltage = 5000000;
2264 val.intval = pd->requested_voltage;
2265 power_supply_set_property(pd->usb_psy,
Nicholas Troast7f55c922017-07-25 13:18:03 -07002266 POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, &val);
Jack Pham6de20802017-05-24 13:44:56 -07002267
Jack Phamf4baeb12017-02-03 19:01:48 -08002268 pd->in_pr_swap = false;
Jack Pham857ee682017-05-25 11:53:36 -07002269 val.intval = 0;
2270 power_supply_set_property(pd->usb_psy,
2271 POWER_SUPPLY_PROP_PR_SWAP, &val);
2272
Jack Phamf6c02da2017-01-31 15:23:56 -08002273 pd->in_explicit_contract = false;
2274 pd->selected_pdo = pd->requested_pdo = 0;
2275 pd->rdo = 0;
Jack Phamf4baeb12017-02-03 19:01:48 -08002276 rx_msg_cleanup(pd);
2277 reset_vdm_state(pd);
Jack Phamf6c02da2017-01-31 15:23:56 -08002278 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
Jack Phamf4baeb12017-02-03 19:01:48 -08002279
2280 if (pd->current_pr == PR_SINK) {
2281 usbpd_set_state(pd, PE_SNK_TRANSITION_TO_DEFAULT);
2282 } else {
Jack Pham4b323282017-11-03 12:24:59 -07002283 s64 delta = ktime_ms_delta(ktime_get(),
2284 pd->hard_reset_recvd_time);
Jack Phamf4baeb12017-02-03 19:01:48 -08002285 pd->current_state = PE_SRC_TRANSITION_TO_DEFAULT;
Jack Pham4b323282017-11-03 12:24:59 -07002286 if (delta >= PS_HARD_RESET_TIME)
2287 kick_sm(pd, 0);
2288 else
2289 kick_sm(pd, PS_HARD_RESET_TIME - (int)delta);
Jack Phamf4baeb12017-02-03 19:01:48 -08002290 }
2291
2292 goto sm_done;
2293 }
2294
2295 /* Soft reset? */
2296 if (IS_CTRL(rx_msg, MSG_SOFT_RESET)) {
2297 usbpd_dbg(&pd->dev, "Handle soft reset\n");
2298
2299 if (pd->current_pr == PR_SRC)
2300 pd->current_state = PE_SRC_SOFT_RESET;
2301 else if (pd->current_pr == PR_SINK)
2302 pd->current_state = PE_SNK_SOFT_RESET;
2303 }
2304
2305 switch (pd->current_state) {
2306 case PE_UNKNOWN:
Jack Phamc4be61c2017-10-10 16:59:32 -07002307 val.intval = 0;
2308 power_supply_set_property(pd->usb_psy,
2309 POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val);
2310
Jack Phamf4baeb12017-02-03 19:01:48 -08002311 if (pd->current_pr == PR_SINK) {
2312 usbpd_set_state(pd, PE_SNK_STARTUP);
2313 } else if (pd->current_pr == PR_SRC) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002314 if (!pd->vconn_enabled &&
2315 pd->typec_mode ==
2316 POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE) {
2317 ret = regulator_enable(pd->vconn);
2318 if (ret)
2319 usbpd_err(&pd->dev, "Unable to enable vconn\n");
2320 else
2321 pd->vconn_enabled = true;
2322 }
Vijayavardhan Vennapusa326b4792017-07-13 12:10:50 +05302323 enable_vbus(pd);
Jack Phamf4baeb12017-02-03 19:01:48 -08002324
2325 usbpd_set_state(pd, PE_SRC_STARTUP);
2326 }
2327 break;
2328
2329 case PE_SRC_STARTUP:
2330 usbpd_set_state(pd, PE_SRC_STARTUP);
2331 break;
2332
2333 case PE_SRC_SEND_CAPABILITIES:
2334 ret = pd_send_msg(pd, MSG_SOURCE_CAPABILITIES, default_src_caps,
2335 ARRAY_SIZE(default_src_caps), SOP_MSG);
2336 if (ret) {
2337 pd->caps_count++;
Mayank Rana38e9b252017-03-23 12:35:57 -07002338 if (pd->caps_count >= PD_CAPS_COUNT) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002339 usbpd_dbg(&pd->dev, "Src CapsCounter exceeded, disabling PD\n");
2340 usbpd_set_state(pd, PE_SRC_DISABLED);
2341
Jack Pham9660be92018-04-03 16:06:40 -07002342 val.intval = POWER_SUPPLY_PD_INACTIVE;
Jack Phamf4baeb12017-02-03 19:01:48 -08002343 power_supply_set_property(pd->usb_psy,
2344 POWER_SUPPLY_PROP_PD_ACTIVE,
2345 &val);
2346 break;
2347 }
2348
2349 kick_sm(pd, SRC_CAP_TIME);
2350 break;
2351 }
2352
2353 /* transmit was successful if GoodCRC was received */
2354 pd->caps_count = 0;
2355 pd->hard_reset_count = 0;
2356 pd->pd_connected = true; /* we know peer is PD capable */
2357
2358 /* wait for REQUEST */
2359 pd->current_state = PE_SRC_SEND_CAPABILITIES_WAIT;
2360 kick_sm(pd, SENDER_RESPONSE_TIME);
2361
Jack Pham9660be92018-04-03 16:06:40 -07002362 val.intval = POWER_SUPPLY_PD_ACTIVE;
Jack Phamf4baeb12017-02-03 19:01:48 -08002363 power_supply_set_property(pd->usb_psy,
2364 POWER_SUPPLY_PROP_PD_ACTIVE, &val);
2365 break;
2366
2367 case PE_SRC_SEND_CAPABILITIES_WAIT:
2368 if (IS_DATA(rx_msg, MSG_REQUEST)) {
Jack Phamf3c1bd32017-08-02 18:32:23 -07002369 pd->rdo = *(u32 *)rx_msg->payload;
Jack Phamf4baeb12017-02-03 19:01:48 -08002370 usbpd_set_state(pd, PE_SRC_NEGOTIATE_CAPABILITY);
2371 } else if (rx_msg) {
2372 usbpd_err(&pd->dev, "Unexpected message received\n");
2373 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2374 } else {
2375 usbpd_set_state(pd, PE_SRC_HARD_RESET);
2376 }
2377 break;
2378
2379 case PE_SRC_READY:
2380 if (IS_CTRL(rx_msg, MSG_GET_SOURCE_CAP)) {
Hemant Kumaree2db9b2017-05-30 14:52:18 -07002381 pd->current_state = PE_SRC_SEND_CAPABILITIES;
2382 kick_sm(pd, 0);
Jack Phamf4baeb12017-02-03 19:01:48 -08002383 } else if (IS_CTRL(rx_msg, MSG_GET_SINK_CAP)) {
2384 ret = pd_send_msg(pd, MSG_SINK_CAPABILITIES,
Jack Phamee1f9052017-01-26 12:27:07 -08002385 pd->sink_caps, pd->num_sink_caps,
2386 SOP_MSG);
Jack Pham722527a2018-06-28 23:17:17 -07002387 if (ret)
Jack Phamf4baeb12017-02-03 19:01:48 -08002388 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
Jack Phamf4baeb12017-02-03 19:01:48 -08002389 } else if (IS_DATA(rx_msg, MSG_REQUEST)) {
Jack Phamf3c1bd32017-08-02 18:32:23 -07002390 pd->rdo = *(u32 *)rx_msg->payload;
Jack Phamf4baeb12017-02-03 19:01:48 -08002391 usbpd_set_state(pd, PE_SRC_NEGOTIATE_CAPABILITY);
2392 } else if (IS_CTRL(rx_msg, MSG_DR_SWAP)) {
2393 if (pd->vdm_state == MODE_ENTERED) {
2394 usbpd_set_state(pd, PE_SRC_HARD_RESET);
2395 break;
2396 }
2397
2398 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2399 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002400 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2401 break;
2402 }
2403
2404 dr_swap(pd);
2405 } else if (IS_CTRL(rx_msg, MSG_PR_SWAP)) {
2406 /* lock in current mode */
2407 set_power_role(pd, pd->current_pr);
2408
2409 /* we'll happily accept Src->Sink requests anytime */
2410 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2411 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002412 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2413 break;
2414 }
2415
2416 pd->current_state = PE_PRS_SRC_SNK_TRANSITION_TO_OFF;
2417 kick_sm(pd, SRC_TRANSITION_TIME);
2418 break;
2419 } else if (IS_CTRL(rx_msg, MSG_VCONN_SWAP)) {
2420 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2421 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002422 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2423 break;
2424 }
2425
2426 vconn_swap(pd);
2427 } else if (IS_DATA(rx_msg, MSG_VDM)) {
2428 handle_vdm_rx(pd, rx_msg);
Jack Pham69a427e2017-08-04 12:26:51 -07002429 } else if (rx_msg && pd->spec_rev == USBPD_REV_30) {
2430 /* unhandled messages */
2431 ret = pd_send_msg(pd, MSG_NOT_SUPPORTED, NULL, 0,
2432 SOP_MSG);
Jack Pham722527a2018-06-28 23:17:17 -07002433 if (ret)
Jack Pham69a427e2017-08-04 12:26:51 -07002434 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
Jack Pham69a427e2017-08-04 12:26:51 -07002435 break;
Jack Phamf4baeb12017-02-03 19:01:48 -08002436 } else if (pd->send_pr_swap) {
2437 pd->send_pr_swap = false;
2438 ret = pd_send_msg(pd, MSG_PR_SWAP, NULL, 0, SOP_MSG);
2439 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002440 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2441 break;
2442 }
2443
2444 pd->current_state = PE_PRS_SRC_SNK_SEND_SWAP;
2445 kick_sm(pd, SENDER_RESPONSE_TIME);
2446 } else if (pd->send_dr_swap) {
2447 pd->send_dr_swap = false;
2448 ret = pd_send_msg(pd, MSG_DR_SWAP, NULL, 0, SOP_MSG);
2449 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002450 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2451 break;
2452 }
2453
2454 pd->current_state = PE_DRS_SEND_DR_SWAP;
2455 kick_sm(pd, SENDER_RESPONSE_TIME);
2456 } else {
2457 handle_vdm_tx(pd);
2458 }
2459 break;
2460
2461 case PE_SRC_TRANSITION_TO_DEFAULT:
2462 if (pd->vconn_enabled)
2463 regulator_disable(pd->vconn);
Jack Phamc4be61c2017-10-10 16:59:32 -07002464 pd->vconn_enabled = false;
2465
Jack Phamf4baeb12017-02-03 19:01:48 -08002466 if (pd->vbus_enabled)
2467 regulator_disable(pd->vbus);
Jack Phamc4be61c2017-10-10 16:59:32 -07002468 pd->vbus_enabled = false;
Jack Phamf4baeb12017-02-03 19:01:48 -08002469
2470 if (pd->current_dr != DR_DFP) {
Jack Pham4e9dff72017-04-04 18:05:53 -07002471 extcon_set_state_sync(pd->extcon, EXTCON_USB, 0);
Jack Phamf4baeb12017-02-03 19:01:48 -08002472 pd->current_dr = DR_DFP;
2473 pd_phy_update_roles(pd->current_dr, pd->current_pr);
2474 }
2475
Jack Phamc4be61c2017-10-10 16:59:32 -07002476 /* PE_UNKNOWN will turn on VBUS and go back to PE_SRC_STARTUP */
2477 pd->current_state = PE_UNKNOWN;
2478 kick_sm(pd, SRC_RECOVER_TIME);
Jack Phamf4baeb12017-02-03 19:01:48 -08002479 break;
2480
2481 case PE_SRC_HARD_RESET:
2482 val.intval = 1;
2483 power_supply_set_property(pd->usb_psy,
2484 POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val);
2485
2486 pd_send_hard_reset(pd);
2487 pd->in_explicit_contract = false;
Jack Phamf6c02da2017-01-31 15:23:56 -08002488 pd->rdo = 0;
Jack Phamf4baeb12017-02-03 19:01:48 -08002489 rx_msg_cleanup(pd);
2490 reset_vdm_state(pd);
Jack Phamf6c02da2017-01-31 15:23:56 -08002491 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
Jack Phamf4baeb12017-02-03 19:01:48 -08002492
2493 pd->current_state = PE_SRC_TRANSITION_TO_DEFAULT;
2494 kick_sm(pd, PS_HARD_RESET_TIME);
2495 break;
2496
2497 case PE_SNK_STARTUP:
2498 usbpd_set_state(pd, PE_SNK_STARTUP);
2499 break;
2500
2501 case PE_SNK_DISCOVERY:
2502 if (!rx_msg) {
2503 if (pd->vbus_present)
2504 usbpd_set_state(pd,
2505 PE_SNK_WAIT_FOR_CAPABILITIES);
2506
2507 /*
2508 * Handle disconnection in the middle of PR_Swap.
2509 * Since in psy_changed() if pd->in_pr_swap is true
2510 * we ignore the typec_mode==NONE change since that is
2511 * expected to happen. However if the cable really did
2512 * get disconnected we need to check for it here after
2513 * waiting for VBUS presence times out.
2514 */
2515 if (!pd->typec_mode) {
2516 pd->current_pr = PR_NONE;
2517 kick_sm(pd, 0);
2518 }
2519
2520 break;
2521 }
2522 /* else fall-through */
2523
2524 case PE_SNK_WAIT_FOR_CAPABILITIES:
2525 pd->in_pr_swap = false;
Jack Pham857ee682017-05-25 11:53:36 -07002526 val.intval = 0;
2527 power_supply_set_property(pd->usb_psy,
2528 POWER_SUPPLY_PROP_PR_SWAP, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08002529
2530 if (IS_DATA(rx_msg, MSG_SOURCE_CAPABILITIES)) {
2531 val.intval = 0;
2532 power_supply_set_property(pd->usb_psy,
2533 POWER_SUPPLY_PROP_PD_IN_HARD_RESET,
2534 &val);
2535
2536 /* save the PDOs so userspace can further evaluate */
Jack Phame9e1f132017-10-23 09:47:49 -07002537 memset(&pd->received_pdos, 0,
Jack Phamf4baeb12017-02-03 19:01:48 -08002538 sizeof(pd->received_pdos));
Jack Phame9e1f132017-10-23 09:47:49 -07002539 memcpy(&pd->received_pdos, rx_msg->payload,
2540 min_t(size_t, rx_msg->data_len,
2541 sizeof(pd->received_pdos)));
Jack Phamf4baeb12017-02-03 19:01:48 -08002542 pd->src_cap_id++;
2543
2544 usbpd_set_state(pd, PE_SNK_EVALUATE_CAPABILITY);
Jack Phamf4baeb12017-02-03 19:01:48 -08002545 } else if (pd->hard_reset_count < 3) {
2546 usbpd_set_state(pd, PE_SNK_HARD_RESET);
Jack Phamf4baeb12017-02-03 19:01:48 -08002547 } else {
2548 usbpd_dbg(&pd->dev, "Sink hard reset count exceeded, disabling PD\n");
2549
2550 val.intval = 0;
2551 power_supply_set_property(pd->usb_psy,
2552 POWER_SUPPLY_PROP_PD_IN_HARD_RESET,
2553 &val);
2554
Jack Pham9660be92018-04-03 16:06:40 -07002555 val.intval = POWER_SUPPLY_PD_INACTIVE;
Jack Phamf4baeb12017-02-03 19:01:48 -08002556 power_supply_set_property(pd->usb_psy,
2557 POWER_SUPPLY_PROP_PD_ACTIVE, &val);
2558 }
2559 break;
2560
2561 case PE_SNK_SELECT_CAPABILITY:
2562 if (IS_CTRL(rx_msg, MSG_ACCEPT)) {
Jack Pham78c869a2017-02-14 16:10:28 -08002563 u32 pdo = pd->received_pdos[pd->requested_pdo - 1];
2564 bool same_pps = (pd->selected_pdo == pd->requested_pdo)
2565 && (PD_SRC_PDO_TYPE(pdo) ==
2566 PD_SRC_PDO_TYPE_AUGMENTED);
2567
Jack Phamf4baeb12017-02-03 19:01:48 -08002568 usbpd_set_state(pd, PE_SNK_TRANSITION_SINK);
2569
2570 /* prepare for voltage increase/decrease */
2571 val.intval = pd->requested_voltage;
2572 power_supply_set_property(pd->usb_psy,
2573 pd->requested_voltage >= pd->current_voltage ?
Nicholas Troast7f55c922017-07-25 13:18:03 -07002574 POWER_SUPPLY_PROP_PD_VOLTAGE_MAX :
2575 POWER_SUPPLY_PROP_PD_VOLTAGE_MIN,
Jack Phamf4baeb12017-02-03 19:01:48 -08002576 &val);
2577
2578 /*
Jack Pham78c869a2017-02-14 16:10:28 -08002579 * if changing voltages (not within the same PPS PDO),
2580 * we must lower input current to pSnkStdby (2.5W).
2581 * Calculate it and set PD_CURRENT_MAX accordingly.
Jack Phamf4baeb12017-02-03 19:01:48 -08002582 */
Jack Pham78c869a2017-02-14 16:10:28 -08002583 if (!same_pps &&
2584 pd->requested_voltage != pd->current_voltage) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002585 int mv = max(pd->requested_voltage,
2586 pd->current_voltage) / 1000;
2587 val.intval = (2500000 / mv) * 1000;
2588 power_supply_set_property(pd->usb_psy,
2589 POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
2590 } else {
2591 /* decreasing current? */
2592 ret = power_supply_get_property(pd->usb_psy,
2593 POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
2594 if (!ret &&
2595 pd->requested_current < val.intval) {
2596 val.intval =
2597 pd->requested_current * 1000;
2598 power_supply_set_property(pd->usb_psy,
2599 POWER_SUPPLY_PROP_PD_CURRENT_MAX,
2600 &val);
2601 }
2602 }
2603
2604 pd->selected_pdo = pd->requested_pdo;
2605 } else if (IS_CTRL(rx_msg, MSG_REJECT) ||
2606 IS_CTRL(rx_msg, MSG_WAIT)) {
2607 if (pd->in_explicit_contract)
2608 usbpd_set_state(pd, PE_SNK_READY);
2609 else
2610 usbpd_set_state(pd,
2611 PE_SNK_WAIT_FOR_CAPABILITIES);
2612 } else if (rx_msg) {
2613 usbpd_err(&pd->dev, "Invalid response to sink request\n");
2614 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2615 } else {
2616 /* timed out; go to hard reset */
2617 usbpd_set_state(pd, PE_SNK_HARD_RESET);
2618 }
2619 break;
2620
2621 case PE_SNK_TRANSITION_SINK:
2622 if (IS_CTRL(rx_msg, MSG_PS_RDY)) {
2623 val.intval = pd->requested_voltage;
2624 power_supply_set_property(pd->usb_psy,
2625 pd->requested_voltage >= pd->current_voltage ?
Nicholas Troast7f55c922017-07-25 13:18:03 -07002626 POWER_SUPPLY_PROP_PD_VOLTAGE_MIN :
2627 POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08002628 pd->current_voltage = pd->requested_voltage;
2629
2630 /* resume charging */
2631 val.intval = pd->requested_current * 1000; /* mA->uA */
2632 power_supply_set_property(pd->usb_psy,
2633 POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
2634
2635 usbpd_set_state(pd, PE_SNK_READY);
2636 } else {
2637 /* timed out; go to hard reset */
2638 usbpd_set_state(pd, PE_SNK_HARD_RESET);
2639 }
2640 break;
2641
2642 case PE_SNK_READY:
2643 if (IS_DATA(rx_msg, MSG_SOURCE_CAPABILITIES)) {
2644 /* save the PDOs so userspace can further evaluate */
Jack Phame9e1f132017-10-23 09:47:49 -07002645 memset(&pd->received_pdos, 0,
Jack Phamf4baeb12017-02-03 19:01:48 -08002646 sizeof(pd->received_pdos));
Jack Phame9e1f132017-10-23 09:47:49 -07002647 memcpy(&pd->received_pdos, rx_msg->payload,
2648 min_t(size_t, rx_msg->data_len,
2649 sizeof(pd->received_pdos)));
Jack Phamf4baeb12017-02-03 19:01:48 -08002650 pd->src_cap_id++;
2651
2652 usbpd_set_state(pd, PE_SNK_EVALUATE_CAPABILITY);
2653 } else if (IS_CTRL(rx_msg, MSG_GET_SINK_CAP)) {
2654 ret = pd_send_msg(pd, MSG_SINK_CAPABILITIES,
Jack Phamee1f9052017-01-26 12:27:07 -08002655 pd->sink_caps, pd->num_sink_caps,
2656 SOP_MSG);
Jack Pham722527a2018-06-28 23:17:17 -07002657 if (ret)
Jack Phamf4baeb12017-02-03 19:01:48 -08002658 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
Jack Pham69a427e2017-08-04 12:26:51 -07002659 } else if (IS_CTRL(rx_msg, MSG_GET_SOURCE_CAP) &&
2660 pd->spec_rev == USBPD_REV_20) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002661 ret = pd_send_msg(pd, MSG_SOURCE_CAPABILITIES,
2662 default_src_caps,
2663 ARRAY_SIZE(default_src_caps), SOP_MSG);
2664 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002665 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2666 break;
2667 }
2668 } else if (IS_CTRL(rx_msg, MSG_DR_SWAP)) {
2669 if (pd->vdm_state == MODE_ENTERED) {
2670 usbpd_set_state(pd, PE_SNK_HARD_RESET);
2671 break;
2672 }
2673
2674 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2675 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002676 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2677 break;
2678 }
2679
2680 dr_swap(pd);
Jack Pham69a427e2017-08-04 12:26:51 -07002681 } else if (IS_CTRL(rx_msg, MSG_PR_SWAP) &&
2682 pd->spec_rev == USBPD_REV_20) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002683 /* lock in current mode */
2684 set_power_role(pd, pd->current_pr);
2685
2686 /* TODO: should we Reject in certain circumstances? */
2687 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2688 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002689 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2690 break;
2691 }
2692
2693 pd->in_pr_swap = true;
Jack Pham857ee682017-05-25 11:53:36 -07002694 val.intval = 1;
2695 power_supply_set_property(pd->usb_psy,
2696 POWER_SUPPLY_PROP_PR_SWAP, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08002697 usbpd_set_state(pd, PE_PRS_SNK_SRC_TRANSITION_TO_OFF);
2698 break;
Jack Pham69a427e2017-08-04 12:26:51 -07002699 } else if (IS_CTRL(rx_msg, MSG_VCONN_SWAP) &&
2700 pd->spec_rev == USBPD_REV_20) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002701 /*
2702 * if VCONN is connected to VBUS, make sure we are
2703 * not in high voltage contract, otherwise reject.
2704 */
2705 if (!pd->vconn_is_external &&
2706 (pd->requested_voltage > 5000000)) {
2707 ret = pd_send_msg(pd, MSG_REJECT, NULL, 0,
2708 SOP_MSG);
Jack Pham722527a2018-06-28 23:17:17 -07002709 if (ret)
Jack Phamf4baeb12017-02-03 19:01:48 -08002710 usbpd_set_state(pd,
2711 PE_SNK_SEND_SOFT_RESET);
Jack Phamf4baeb12017-02-03 19:01:48 -08002712
2713 break;
2714 }
2715
2716 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2717 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002718 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2719 break;
2720 }
2721
2722 vconn_swap(pd);
2723 } else if (IS_DATA(rx_msg, MSG_VDM)) {
2724 handle_vdm_rx(pd, rx_msg);
Hemant Kumar018b5982017-08-09 14:14:37 -07002725 } else if (pd->send_get_src_cap_ext && is_sink_tx_ok(pd)) {
2726 pd->send_get_src_cap_ext = false;
2727 ret = pd_send_msg(pd, MSG_GET_SOURCE_CAP_EXTENDED, NULL,
2728 0, SOP_MSG);
2729 if (ret) {
Hemant Kumar018b5982017-08-09 14:14:37 -07002730 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2731 break;
2732 }
2733 kick_sm(pd, SENDER_RESPONSE_TIME);
2734 } else if (rx_msg &&
2735 IS_EXT(rx_msg, MSG_SOURCE_CAPABILITIES_EXTENDED)) {
2736 if (rx_msg->data_len != PD_SRC_CAP_EXT_DB_LEN) {
2737 usbpd_err(&pd->dev, "Invalid src cap ext db\n");
2738 break;
2739 }
2740 memcpy(&pd->src_cap_ext_db, rx_msg->payload,
2741 sizeof(pd->src_cap_ext_db));
2742 complete(&pd->is_ready);
2743 } else if (pd->send_get_pps_status && is_sink_tx_ok(pd)) {
2744 pd->send_get_pps_status = false;
2745 ret = pd_send_msg(pd, MSG_GET_PPS_STATUS, NULL,
2746 0, SOP_MSG);
2747 if (ret) {
Hemant Kumar018b5982017-08-09 14:14:37 -07002748 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2749 break;
2750 }
2751 kick_sm(pd, SENDER_RESPONSE_TIME);
2752 } else if (rx_msg &&
2753 IS_EXT(rx_msg, MSG_PPS_STATUS)) {
2754 if (rx_msg->data_len != sizeof(pd->pps_status_db)) {
2755 usbpd_err(&pd->dev, "Invalid pps status db\n");
2756 break;
2757 }
2758 memcpy(&pd->pps_status_db, rx_msg->payload,
2759 sizeof(pd->pps_status_db));
2760 complete(&pd->is_ready);
Hemant Kumara1875942017-08-09 16:50:14 -07002761 } else if (IS_DATA(rx_msg, MSG_ALERT)) {
Jack Phamda401d72018-06-07 19:29:52 -07002762 u32 ado;
2763
2764 if (rx_msg->data_len != sizeof(ado)) {
Hemant Kumara1875942017-08-09 16:50:14 -07002765 usbpd_err(&pd->dev, "Invalid ado\n");
2766 break;
2767 }
Jack Phamda401d72018-06-07 19:29:52 -07002768 memcpy(&ado, rx_msg->payload, sizeof(ado));
2769 usbpd_dbg(&pd->dev, "Received Alert 0x%08x\n", ado);
2770
2771 /*
2772 * Don't send Get_Status right away so we can coalesce
2773 * multiple Alerts. 150ms should be enough to not get
2774 * in the way of any other AMS that might happen.
2775 */
2776 pd->send_get_status = true;
2777 kick_sm(pd, 150);
2778 } else if (pd->send_get_status && is_sink_tx_ok(pd)) {
2779 pd->send_get_status = false;
2780 ret = pd_send_msg(pd, MSG_GET_STATUS, NULL, 0, SOP_MSG);
Hemant Kumara1875942017-08-09 16:50:14 -07002781 if (ret) {
Hemant Kumara1875942017-08-09 16:50:14 -07002782 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2783 break;
2784 }
2785 kick_sm(pd, SENDER_RESPONSE_TIME);
Jack Phamda401d72018-06-07 19:29:52 -07002786 } else if (rx_msg && IS_EXT(rx_msg, MSG_STATUS)) {
Hemant Kumara1875942017-08-09 16:50:14 -07002787 if (rx_msg->data_len != PD_STATUS_DB_LEN) {
2788 usbpd_err(&pd->dev, "Invalid status db\n");
2789 break;
2790 }
2791 memcpy(&pd->status_db, rx_msg->payload,
2792 sizeof(pd->status_db));
2793 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
Hemant Kumar51ded972017-08-09 17:57:24 -07002794 } else if (pd->send_get_battery_cap && is_sink_tx_ok(pd)) {
2795 pd->send_get_battery_cap = false;
2796 ret = pd_send_ext_msg(pd, MSG_GET_BATTERY_CAP,
2797 &pd->get_battery_cap_db, 1, SOP_MSG);
2798 if (ret) {
Hemant Kumar51ded972017-08-09 17:57:24 -07002799 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2800 break;
2801 }
2802 kick_sm(pd, SENDER_RESPONSE_TIME);
2803 } else if (rx_msg &&
2804 IS_EXT(rx_msg, MSG_BATTERY_CAPABILITIES)) {
2805 if (rx_msg->data_len != PD_BATTERY_CAP_DB_LEN) {
2806 usbpd_err(&pd->dev, "Invalid battery cap db\n");
2807 break;
2808 }
2809 memcpy(&pd->battery_cap_db, rx_msg->payload,
2810 sizeof(pd->battery_cap_db));
2811 complete(&pd->is_ready);
2812 } else if (pd->send_get_battery_status && is_sink_tx_ok(pd)) {
2813 pd->send_get_battery_status = false;
2814 ret = pd_send_ext_msg(pd, MSG_GET_BATTERY_STATUS,
2815 &pd->get_battery_status_db, 1, SOP_MSG);
2816 if (ret) {
Hemant Kumar51ded972017-08-09 17:57:24 -07002817 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2818 break;
2819 }
2820 kick_sm(pd, SENDER_RESPONSE_TIME);
2821 } else if (rx_msg &&
2822 IS_EXT(rx_msg, MSG_BATTERY_STATUS)) {
2823 if (rx_msg->data_len != sizeof(pd->battery_sts_dobj)) {
2824 usbpd_err(&pd->dev, "Invalid bat sts dobj\n");
2825 break;
2826 }
2827 memcpy(&pd->battery_sts_dobj, rx_msg->payload,
2828 sizeof(pd->battery_sts_dobj));
2829 complete(&pd->is_ready);
Jack Pham69a427e2017-08-04 12:26:51 -07002830 } else if (rx_msg && pd->spec_rev == USBPD_REV_30) {
2831 /* unhandled messages */
2832 ret = pd_send_msg(pd, MSG_NOT_SUPPORTED, NULL, 0,
2833 SOP_MSG);
Jack Pham722527a2018-06-28 23:17:17 -07002834 if (ret)
Jack Pham69a427e2017-08-04 12:26:51 -07002835 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
Jack Pham69a427e2017-08-04 12:26:51 -07002836 break;
Jack Phamaf7d3842017-01-26 13:28:19 -08002837 } else if (pd->send_request) {
2838 pd->send_request = false;
2839 usbpd_set_state(pd, PE_SNK_SELECT_CAPABILITY);
Jack Phamf4baeb12017-02-03 19:01:48 -08002840 } else if (pd->send_pr_swap && is_sink_tx_ok(pd)) {
2841 pd->send_pr_swap = false;
2842 ret = pd_send_msg(pd, MSG_PR_SWAP, NULL, 0, SOP_MSG);
2843 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002844 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2845 break;
2846 }
2847
2848 pd->current_state = PE_PRS_SNK_SRC_SEND_SWAP;
2849 kick_sm(pd, SENDER_RESPONSE_TIME);
2850 } else if (pd->send_dr_swap && is_sink_tx_ok(pd)) {
2851 pd->send_dr_swap = false;
2852 ret = pd_send_msg(pd, MSG_DR_SWAP, NULL, 0, SOP_MSG);
2853 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002854 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2855 break;
2856 }
2857
2858 pd->current_state = PE_DRS_SEND_DR_SWAP;
2859 kick_sm(pd, SENDER_RESPONSE_TIME);
2860 } else if (is_sink_tx_ok(pd)) {
2861 handle_vdm_tx(pd);
2862 }
2863 break;
2864
2865 case PE_SNK_TRANSITION_TO_DEFAULT:
2866 usbpd_set_state(pd, PE_SNK_STARTUP);
2867 break;
2868
2869 case PE_SRC_SOFT_RESET:
2870 case PE_SNK_SOFT_RESET:
2871 pd_reset_protocol(pd);
2872
2873 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2874 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002875 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
2876 PE_SRC_HARD_RESET : PE_SNK_HARD_RESET);
2877 break;
2878 }
2879
2880 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
2881 PE_SRC_SEND_CAPABILITIES :
2882 PE_SNK_WAIT_FOR_CAPABILITIES);
2883 break;
2884
2885 case PE_SRC_SEND_SOFT_RESET:
2886 case PE_SNK_SEND_SOFT_RESET:
2887 if (IS_CTRL(rx_msg, MSG_ACCEPT)) {
2888 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
2889 PE_SRC_SEND_CAPABILITIES :
2890 PE_SNK_WAIT_FOR_CAPABILITIES);
2891 } else {
2892 usbpd_err(&pd->dev, "%s: Did not see Accept, do Hard Reset\n",
2893 usbpd_state_strings[pd->current_state]);
2894 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
2895 PE_SRC_HARD_RESET : PE_SNK_HARD_RESET);
2896 }
2897 break;
2898
2899 case PE_SNK_HARD_RESET:
2900 /* prepare charger for VBUS change */
2901 val.intval = 1;
2902 power_supply_set_property(pd->usb_psy,
2903 POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val);
2904
2905 pd->requested_voltage = 5000000;
2906
2907 if (pd->requested_current) {
2908 val.intval = pd->requested_current = 0;
2909 power_supply_set_property(pd->usb_psy,
2910 POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
2911 }
2912
2913 val.intval = pd->requested_voltage;
2914 power_supply_set_property(pd->usb_psy,
Nicholas Troast7f55c922017-07-25 13:18:03 -07002915 POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08002916
2917 pd_send_hard_reset(pd);
2918 pd->in_explicit_contract = false;
Jack Phamf6c02da2017-01-31 15:23:56 -08002919 pd->selected_pdo = pd->requested_pdo = 0;
2920 pd->rdo = 0;
Jack Phamf4baeb12017-02-03 19:01:48 -08002921 reset_vdm_state(pd);
Jack Phamf6c02da2017-01-31 15:23:56 -08002922 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
Jack Phamf4baeb12017-02-03 19:01:48 -08002923 usbpd_set_state(pd, PE_SNK_TRANSITION_TO_DEFAULT);
2924 break;
2925
2926 case PE_DRS_SEND_DR_SWAP:
2927 if (IS_CTRL(rx_msg, MSG_ACCEPT))
2928 dr_swap(pd);
2929
2930 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
2931 PE_SRC_READY : PE_SNK_READY);
2932 break;
2933
2934 case PE_PRS_SRC_SNK_SEND_SWAP:
2935 if (!IS_CTRL(rx_msg, MSG_ACCEPT)) {
2936 pd->current_state = PE_SRC_READY;
2937 break;
2938 }
2939
2940 pd->current_state = PE_PRS_SRC_SNK_TRANSITION_TO_OFF;
2941 kick_sm(pd, SRC_TRANSITION_TIME);
2942 break;
2943
2944 case PE_PRS_SRC_SNK_TRANSITION_TO_OFF:
2945 pd->in_pr_swap = true;
Jack Pham857ee682017-05-25 11:53:36 -07002946 val.intval = 1;
2947 power_supply_set_property(pd->usb_psy,
2948 POWER_SUPPLY_PROP_PR_SWAP, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08002949 pd->in_explicit_contract = false;
2950
2951 if (pd->vbus_enabled) {
2952 regulator_disable(pd->vbus);
2953 pd->vbus_enabled = false;
2954 }
2955
2956 /* PE_PRS_SRC_SNK_Assert_Rd */
2957 pd->current_pr = PR_SINK;
2958 set_power_role(pd, pd->current_pr);
2959 pd_phy_update_roles(pd->current_dr, pd->current_pr);
2960
2961 /* allow time for Vbus discharge, must be < tSrcSwapStdby */
2962 msleep(500);
2963
2964 ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG);
2965 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002966 usbpd_set_state(pd, PE_ERROR_RECOVERY);
2967 break;
2968 }
2969
2970 pd->current_state = PE_PRS_SRC_SNK_WAIT_SOURCE_ON;
2971 kick_sm(pd, PS_SOURCE_ON);
2972 break;
2973
2974 case PE_PRS_SRC_SNK_WAIT_SOURCE_ON:
2975 if (IS_CTRL(rx_msg, MSG_PS_RDY))
2976 usbpd_set_state(pd, PE_SNK_STARTUP);
2977 else
2978 usbpd_set_state(pd, PE_ERROR_RECOVERY);
2979 break;
2980
2981 case PE_PRS_SNK_SRC_SEND_SWAP:
2982 if (!IS_CTRL(rx_msg, MSG_ACCEPT)) {
2983 pd->current_state = PE_SNK_READY;
2984 break;
2985 }
2986
2987 pd->in_pr_swap = true;
Jack Pham857ee682017-05-25 11:53:36 -07002988 val.intval = 1;
2989 power_supply_set_property(pd->usb_psy,
2990 POWER_SUPPLY_PROP_PR_SWAP, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08002991 usbpd_set_state(pd, PE_PRS_SNK_SRC_TRANSITION_TO_OFF);
2992 break;
2993
2994 case PE_PRS_SNK_SRC_TRANSITION_TO_OFF:
2995 if (!IS_CTRL(rx_msg, MSG_PS_RDY)) {
2996 usbpd_set_state(pd, PE_ERROR_RECOVERY);
2997 break;
2998 }
2999
3000 /* PE_PRS_SNK_SRC_Assert_Rp */
3001 pd->current_pr = PR_SRC;
3002 set_power_role(pd, pd->current_pr);
3003 pd->current_state = PE_PRS_SNK_SRC_SOURCE_ON;
3004
3005 /* fall-through */
3006
3007 case PE_PRS_SNK_SRC_SOURCE_ON:
3008 enable_vbus(pd);
Jack Phamf4baeb12017-02-03 19:01:48 -08003009
3010 ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG);
3011 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08003012 usbpd_set_state(pd, PE_ERROR_RECOVERY);
3013 break;
3014 }
3015
3016 usbpd_set_state(pd, PE_SRC_STARTUP);
3017 break;
3018
3019 case PE_VCS_WAIT_FOR_VCONN:
3020 if (IS_CTRL(rx_msg, MSG_PS_RDY)) {
3021 /*
3022 * hopefully redundant check but in case not enabled
3023 * avoids unbalanced regulator disable count
3024 */
3025 if (pd->vconn_enabled)
3026 regulator_disable(pd->vconn);
3027 pd->vconn_enabled = false;
3028
3029 pd->current_state = pd->current_pr == PR_SRC ?
3030 PE_SRC_READY : PE_SNK_READY;
3031 } else {
3032 /* timed out; go to hard reset */
3033 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
3034 PE_SRC_HARD_RESET : PE_SNK_HARD_RESET);
3035 }
3036
3037 break;
3038
3039 default:
3040 usbpd_err(&pd->dev, "Unhandled state %s\n",
3041 usbpd_state_strings[pd->current_state]);
3042 break;
3043 }
3044
3045sm_done:
3046 kfree(rx_msg);
3047
Jack Pham564b4172017-05-24 18:41:53 -07003048 spin_lock_irqsave(&pd->rx_lock, flags);
3049 ret = list_empty(&pd->rx_q);
3050 spin_unlock_irqrestore(&pd->rx_lock, flags);
3051
3052 /* requeue if there are any new/pending RX messages */
3053 if (!ret)
3054 kick_sm(pd, 0);
3055
Jack Phamf4baeb12017-02-03 19:01:48 -08003056 if (!pd->sm_queued)
3057 pm_relax(&pd->dev);
3058}
3059
3060static inline const char *src_current(enum power_supply_typec_mode typec_mode)
3061{
3062 switch (typec_mode) {
3063 case POWER_SUPPLY_TYPEC_SOURCE_DEFAULT:
3064 return "default";
3065 case POWER_SUPPLY_TYPEC_SOURCE_MEDIUM:
3066 return "medium - 1.5A";
3067 case POWER_SUPPLY_TYPEC_SOURCE_HIGH:
3068 return "high - 3.0A";
3069 default:
3070 return "";
3071 }
3072}
3073
3074static int psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr)
3075{
3076 struct usbpd *pd = container_of(nb, struct usbpd, psy_nb);
3077 union power_supply_propval val;
3078 enum power_supply_typec_mode typec_mode;
3079 int ret;
3080
3081 if (ptr != pd->usb_psy || evt != PSY_EVENT_PROP_CHANGED)
3082 return 0;
3083
3084 ret = power_supply_get_property(pd->usb_psy,
3085 POWER_SUPPLY_PROP_TYPEC_MODE, &val);
3086 if (ret) {
3087 usbpd_err(&pd->dev, "Unable to read USB TYPEC_MODE: %d\n", ret);
3088 return ret;
3089 }
3090
3091 typec_mode = val.intval;
3092
3093 ret = power_supply_get_property(pd->usb_psy,
3094 POWER_SUPPLY_PROP_PE_START, &val);
3095 if (ret) {
3096 usbpd_err(&pd->dev, "Unable to read USB PROP_PE_START: %d\n",
3097 ret);
3098 return ret;
3099 }
3100
3101 /* Don't proceed if PE_START=0 as other props may still change */
3102 if (!val.intval && !pd->pd_connected &&
3103 typec_mode != POWER_SUPPLY_TYPEC_NONE)
3104 return 0;
3105
3106 ret = power_supply_get_property(pd->usb_psy,
3107 POWER_SUPPLY_PROP_PRESENT, &val);
3108 if (ret) {
3109 usbpd_err(&pd->dev, "Unable to read USB PRESENT: %d\n", ret);
3110 return ret;
3111 }
3112
3113 pd->vbus_present = val.intval;
3114
3115 ret = power_supply_get_property(pd->usb_psy,
Fenglin Wu80826e02017-04-25 21:45:08 +08003116 POWER_SUPPLY_PROP_REAL_TYPE, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08003117 if (ret) {
3118 usbpd_err(&pd->dev, "Unable to read USB TYPE: %d\n", ret);
3119 return ret;
3120 }
3121
3122 pd->psy_type = val.intval;
3123
3124 /*
3125 * For sink hard reset, state machine needs to know when VBUS changes
3126 * - when in PE_SNK_TRANSITION_TO_DEFAULT, notify when VBUS falls
3127 * - when in PE_SNK_DISCOVERY, notify when VBUS rises
3128 */
3129 if (typec_mode && ((!pd->vbus_present &&
3130 pd->current_state == PE_SNK_TRANSITION_TO_DEFAULT) ||
3131 (pd->vbus_present && pd->current_state == PE_SNK_DISCOVERY))) {
3132 usbpd_dbg(&pd->dev, "hard reset: typec mode:%d present:%d\n",
3133 typec_mode, pd->vbus_present);
3134 pd->typec_mode = typec_mode;
3135 kick_sm(pd, 0);
3136 return 0;
3137 }
3138
3139 if (pd->typec_mode == typec_mode)
3140 return 0;
3141
3142 pd->typec_mode = typec_mode;
3143
3144 usbpd_dbg(&pd->dev, "typec mode:%d present:%d type:%d orientation:%d\n",
3145 typec_mode, pd->vbus_present, pd->psy_type,
3146 usbpd_get_plug_orientation(pd));
3147
3148 switch (typec_mode) {
3149 /* Disconnect */
3150 case POWER_SUPPLY_TYPEC_NONE:
3151 if (pd->in_pr_swap) {
3152 usbpd_dbg(&pd->dev, "Ignoring disconnect due to PR swap\n");
3153 return 0;
3154 }
3155
3156 pd->current_pr = PR_NONE;
3157 break;
3158
3159 /* Sink states */
3160 case POWER_SUPPLY_TYPEC_SOURCE_DEFAULT:
3161 case POWER_SUPPLY_TYPEC_SOURCE_MEDIUM:
3162 case POWER_SUPPLY_TYPEC_SOURCE_HIGH:
3163 usbpd_info(&pd->dev, "Type-C Source (%s) connected\n",
3164 src_current(typec_mode));
3165
3166 /* if waiting for SinkTxOk to start an AMS */
3167 if (pd->spec_rev == USBPD_REV_30 &&
3168 typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH &&
3169 (pd->send_pr_swap || pd->send_dr_swap || pd->vdm_tx))
3170 break;
3171
3172 if (pd->current_pr == PR_SINK)
3173 return 0;
3174
Jack Phamd434a412017-07-24 10:05:05 -07003175 /*
3176 * Unexpected if not in PR swap; need to force disconnect from
3177 * source so we can turn off VBUS, Vconn, PD PHY etc.
3178 */
3179 if (pd->current_pr == PR_SRC) {
3180 usbpd_info(&pd->dev, "Forcing disconnect from source mode\n");
3181 pd->current_pr = PR_NONE;
3182 break;
3183 }
3184
Jack Phamf4baeb12017-02-03 19:01:48 -08003185 pd->current_pr = PR_SINK;
3186 break;
3187
3188 /* Source states */
3189 case POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE:
3190 case POWER_SUPPLY_TYPEC_SINK:
3191 usbpd_info(&pd->dev, "Type-C Sink%s connected\n",
3192 typec_mode == POWER_SUPPLY_TYPEC_SINK ?
3193 "" : " (powered)");
3194
3195 if (pd->current_pr == PR_SRC)
3196 return 0;
3197
3198 pd->current_pr = PR_SRC;
3199 break;
3200
3201 case POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY:
3202 usbpd_info(&pd->dev, "Type-C Debug Accessory connected\n");
3203 break;
3204 case POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER:
3205 usbpd_info(&pd->dev, "Type-C Analog Audio Adapter connected\n");
3206 break;
3207 default:
3208 usbpd_warn(&pd->dev, "Unsupported typec mode:%d\n",
3209 typec_mode);
3210 break;
3211 }
3212
3213 /* queue state machine due to CC state change */
3214 kick_sm(pd, 0);
3215 return 0;
3216}
3217
3218static enum dual_role_property usbpd_dr_properties[] = {
3219 DUAL_ROLE_PROP_SUPPORTED_MODES,
3220 DUAL_ROLE_PROP_MODE,
3221 DUAL_ROLE_PROP_PR,
3222 DUAL_ROLE_PROP_DR,
3223};
3224
3225static int usbpd_dr_get_property(struct dual_role_phy_instance *dual_role,
3226 enum dual_role_property prop, unsigned int *val)
3227{
3228 struct usbpd *pd = dual_role_get_drvdata(dual_role);
3229
3230 if (!pd)
3231 return -ENODEV;
3232
3233 switch (prop) {
3234 case DUAL_ROLE_PROP_MODE:
3235 /* For now associate UFP/DFP with data role only */
3236 if (pd->current_dr == DR_UFP)
3237 *val = DUAL_ROLE_PROP_MODE_UFP;
3238 else if (pd->current_dr == DR_DFP)
3239 *val = DUAL_ROLE_PROP_MODE_DFP;
3240 else
3241 *val = DUAL_ROLE_PROP_MODE_NONE;
3242 break;
3243 case DUAL_ROLE_PROP_PR:
3244 if (pd->current_pr == PR_SRC)
3245 *val = DUAL_ROLE_PROP_PR_SRC;
3246 else if (pd->current_pr == PR_SINK)
3247 *val = DUAL_ROLE_PROP_PR_SNK;
3248 else
3249 *val = DUAL_ROLE_PROP_PR_NONE;
3250 break;
3251 case DUAL_ROLE_PROP_DR:
3252 if (pd->current_dr == DR_UFP)
3253 *val = DUAL_ROLE_PROP_DR_DEVICE;
3254 else if (pd->current_dr == DR_DFP)
3255 *val = DUAL_ROLE_PROP_DR_HOST;
3256 else
3257 *val = DUAL_ROLE_PROP_DR_NONE;
3258 break;
3259 default:
3260 usbpd_warn(&pd->dev, "unsupported property %d\n", prop);
3261 return -ENODATA;
3262 }
3263
3264 return 0;
3265}
3266
3267static int usbpd_dr_set_property(struct dual_role_phy_instance *dual_role,
3268 enum dual_role_property prop, const unsigned int *val)
3269{
3270 struct usbpd *pd = dual_role_get_drvdata(dual_role);
3271 bool do_swap = false;
3272
3273 if (!pd)
3274 return -ENODEV;
3275
3276 switch (prop) {
3277 case DUAL_ROLE_PROP_MODE:
3278 usbpd_dbg(&pd->dev, "Setting mode to %d\n", *val);
3279
3280 /*
3281 * Forces disconnect on CC and re-establishes connection.
3282 * This does not use PD-based PR/DR swap
3283 */
3284 if (*val == DUAL_ROLE_PROP_MODE_UFP)
3285 pd->forced_pr = POWER_SUPPLY_TYPEC_PR_SINK;
3286 else if (*val == DUAL_ROLE_PROP_MODE_DFP)
3287 pd->forced_pr = POWER_SUPPLY_TYPEC_PR_SOURCE;
3288
3289 /* new mode will be applied in disconnect handler */
3290 set_power_role(pd, PR_NONE);
3291
3292 /* wait until it takes effect */
3293 while (pd->forced_pr != POWER_SUPPLY_TYPEC_PR_NONE)
3294 msleep(20);
3295
3296 break;
3297
3298 case DUAL_ROLE_PROP_DR:
3299 usbpd_dbg(&pd->dev, "Setting data_role to %d\n", *val);
3300
3301 if (*val == DUAL_ROLE_PROP_DR_HOST) {
3302 if (pd->current_dr == DR_UFP)
3303 do_swap = true;
3304 } else if (*val == DUAL_ROLE_PROP_DR_DEVICE) {
3305 if (pd->current_dr == DR_DFP)
3306 do_swap = true;
3307 } else {
3308 usbpd_warn(&pd->dev, "setting data_role to 'none' unsupported\n");
3309 return -ENOTSUPP;
3310 }
3311
3312 if (do_swap) {
3313 if (pd->current_state != PE_SRC_READY &&
3314 pd->current_state != PE_SNK_READY) {
3315 usbpd_err(&pd->dev, "data_role swap not allowed: PD not in Ready state\n");
3316 return -EAGAIN;
3317 }
3318
3319 if (pd->current_state == PE_SNK_READY &&
3320 !is_sink_tx_ok(pd)) {
3321 usbpd_err(&pd->dev, "Rp indicates SinkTxNG\n");
3322 return -EAGAIN;
3323 }
3324
Jack Phamaf7d3842017-01-26 13:28:19 -08003325 mutex_lock(&pd->swap_lock);
3326 reinit_completion(&pd->is_ready);
Jack Phamf4baeb12017-02-03 19:01:48 -08003327 pd->send_dr_swap = true;
3328 kick_sm(pd, 0);
3329
3330 /* wait for operation to complete */
Jack Phamaf7d3842017-01-26 13:28:19 -08003331 if (!wait_for_completion_timeout(&pd->is_ready,
Jack Phamf4baeb12017-02-03 19:01:48 -08003332 msecs_to_jiffies(100))) {
3333 usbpd_err(&pd->dev, "data_role swap timed out\n");
Jack Phamaf7d3842017-01-26 13:28:19 -08003334 mutex_unlock(&pd->swap_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08003335 return -ETIMEDOUT;
3336 }
3337
Jack Phamaf7d3842017-01-26 13:28:19 -08003338 mutex_unlock(&pd->swap_lock);
3339
Jack Phamf4baeb12017-02-03 19:01:48 -08003340 if ((*val == DUAL_ROLE_PROP_DR_HOST &&
3341 pd->current_dr != DR_DFP) ||
3342 (*val == DUAL_ROLE_PROP_DR_DEVICE &&
3343 pd->current_dr != DR_UFP)) {
3344 usbpd_err(&pd->dev, "incorrect state (%s) after data_role swap\n",
3345 pd->current_dr == DR_DFP ?
3346 "dfp" : "ufp");
3347 return -EPROTO;
3348 }
3349 }
3350
3351 break;
3352
3353 case DUAL_ROLE_PROP_PR:
3354 usbpd_dbg(&pd->dev, "Setting power_role to %d\n", *val);
3355
3356 if (*val == DUAL_ROLE_PROP_PR_SRC) {
3357 if (pd->current_pr == PR_SINK)
3358 do_swap = true;
3359 } else if (*val == DUAL_ROLE_PROP_PR_SNK) {
3360 if (pd->current_pr == PR_SRC)
3361 do_swap = true;
3362 } else {
3363 usbpd_warn(&pd->dev, "setting power_role to 'none' unsupported\n");
3364 return -ENOTSUPP;
3365 }
3366
3367 if (do_swap) {
3368 if (pd->current_state != PE_SRC_READY &&
3369 pd->current_state != PE_SNK_READY) {
3370 usbpd_err(&pd->dev, "power_role swap not allowed: PD not in Ready state\n");
3371 return -EAGAIN;
3372 }
3373
3374 if (pd->current_state == PE_SNK_READY &&
3375 !is_sink_tx_ok(pd)) {
3376 usbpd_err(&pd->dev, "Rp indicates SinkTxNG\n");
3377 return -EAGAIN;
3378 }
3379
Jack Phamaf7d3842017-01-26 13:28:19 -08003380 mutex_lock(&pd->swap_lock);
3381 reinit_completion(&pd->is_ready);
Jack Phamf4baeb12017-02-03 19:01:48 -08003382 pd->send_pr_swap = true;
3383 kick_sm(pd, 0);
3384
3385 /* wait for operation to complete */
Jack Phamaf7d3842017-01-26 13:28:19 -08003386 if (!wait_for_completion_timeout(&pd->is_ready,
Jack Phamf4baeb12017-02-03 19:01:48 -08003387 msecs_to_jiffies(2000))) {
3388 usbpd_err(&pd->dev, "power_role swap timed out\n");
Jack Phamaf7d3842017-01-26 13:28:19 -08003389 mutex_unlock(&pd->swap_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08003390 return -ETIMEDOUT;
3391 }
3392
Jack Phamaf7d3842017-01-26 13:28:19 -08003393 mutex_unlock(&pd->swap_lock);
3394
Jack Phamf4baeb12017-02-03 19:01:48 -08003395 if ((*val == DUAL_ROLE_PROP_PR_SRC &&
3396 pd->current_pr != PR_SRC) ||
3397 (*val == DUAL_ROLE_PROP_PR_SNK &&
3398 pd->current_pr != PR_SINK)) {
3399 usbpd_err(&pd->dev, "incorrect state (%s) after power_role swap\n",
3400 pd->current_pr == PR_SRC ?
3401 "source" : "sink");
3402 return -EPROTO;
3403 }
3404 }
3405 break;
3406
3407 default:
3408 usbpd_warn(&pd->dev, "unsupported property %d\n", prop);
3409 return -ENOTSUPP;
3410 }
3411
3412 return 0;
3413}
3414
3415static int usbpd_dr_prop_writeable(struct dual_role_phy_instance *dual_role,
3416 enum dual_role_property prop)
3417{
Jack Phame232bde2017-03-02 11:37:00 -08003418 struct usbpd *pd = dual_role_get_drvdata(dual_role);
3419
Jack Phamf4baeb12017-02-03 19:01:48 -08003420 switch (prop) {
3421 case DUAL_ROLE_PROP_MODE:
Jack Phame232bde2017-03-02 11:37:00 -08003422 return 1;
Jack Phamf4baeb12017-02-03 19:01:48 -08003423 case DUAL_ROLE_PROP_DR:
3424 case DUAL_ROLE_PROP_PR:
Jack Phame232bde2017-03-02 11:37:00 -08003425 if (pd)
3426 return pd->current_state == PE_SNK_READY ||
3427 pd->current_state == PE_SRC_READY;
3428 break;
Jack Phamf4baeb12017-02-03 19:01:48 -08003429 default:
3430 break;
3431 }
3432
3433 return 0;
3434}
3435
3436static int usbpd_uevent(struct device *dev, struct kobj_uevent_env *env)
3437{
3438 struct usbpd *pd = dev_get_drvdata(dev);
3439 int i;
3440
3441 add_uevent_var(env, "DATA_ROLE=%s", pd->current_dr == DR_DFP ?
3442 "dfp" : "ufp");
3443
3444 if (pd->current_pr == PR_SINK) {
3445 add_uevent_var(env, "POWER_ROLE=sink");
3446 add_uevent_var(env, "SRC_CAP_ID=%d", pd->src_cap_id);
3447
3448 for (i = 0; i < ARRAY_SIZE(pd->received_pdos); i++)
3449 add_uevent_var(env, "PDO%d=%08x", i,
3450 pd->received_pdos[i]);
3451
3452 add_uevent_var(env, "REQUESTED_PDO=%d", pd->requested_pdo);
3453 add_uevent_var(env, "SELECTED_PDO=%d", pd->selected_pdo);
3454 } else {
3455 add_uevent_var(env, "POWER_ROLE=source");
3456 for (i = 0; i < ARRAY_SIZE(default_src_caps); i++)
3457 add_uevent_var(env, "PDO%d=%08x", i,
3458 default_src_caps[i]);
3459 }
3460
3461 add_uevent_var(env, "RDO=%08x", pd->rdo);
3462 add_uevent_var(env, "CONTRACT=%s", pd->in_explicit_contract ?
3463 "explicit" : "implicit");
3464 add_uevent_var(env, "ALT_MODE=%d", pd->vdm_state == MODE_ENTERED);
3465
Jack Phamda401d72018-06-07 19:29:52 -07003466 add_uevent_var(env, "SDB=%02x %02x %02x %02x %02x", pd->status_db[0],
3467 pd->status_db[1], pd->status_db[2], pd->status_db[3],
3468 pd->status_db[4]);
Hemant Kumara1875942017-08-09 16:50:14 -07003469
Jack Phamf4baeb12017-02-03 19:01:48 -08003470 return 0;
3471}
3472
3473static ssize_t contract_show(struct device *dev, struct device_attribute *attr,
3474 char *buf)
3475{
3476 struct usbpd *pd = dev_get_drvdata(dev);
3477
3478 return snprintf(buf, PAGE_SIZE, "%s\n",
3479 pd->in_explicit_contract ? "explicit" : "implicit");
3480}
3481static DEVICE_ATTR_RO(contract);
3482
3483static ssize_t current_pr_show(struct device *dev,
3484 struct device_attribute *attr, char *buf)
3485{
3486 struct usbpd *pd = dev_get_drvdata(dev);
3487 const char *pr = "none";
3488
3489 if (pd->current_pr == PR_SINK)
3490 pr = "sink";
3491 else if (pd->current_pr == PR_SRC)
3492 pr = "source";
3493
3494 return snprintf(buf, PAGE_SIZE, "%s\n", pr);
3495}
3496static DEVICE_ATTR_RO(current_pr);
3497
3498static ssize_t initial_pr_show(struct device *dev,
3499 struct device_attribute *attr, char *buf)
3500{
3501 struct usbpd *pd = dev_get_drvdata(dev);
3502 const char *pr = "none";
3503
3504 if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT)
3505 pr = "sink";
3506 else if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SINK)
3507 pr = "source";
3508
3509 return snprintf(buf, PAGE_SIZE, "%s\n", pr);
3510}
3511static DEVICE_ATTR_RO(initial_pr);
3512
3513static ssize_t current_dr_show(struct device *dev,
3514 struct device_attribute *attr, char *buf)
3515{
3516 struct usbpd *pd = dev_get_drvdata(dev);
3517 const char *dr = "none";
3518
3519 if (pd->current_dr == DR_UFP)
3520 dr = "ufp";
3521 else if (pd->current_dr == DR_DFP)
3522 dr = "dfp";
3523
3524 return snprintf(buf, PAGE_SIZE, "%s\n", dr);
3525}
3526static DEVICE_ATTR_RO(current_dr);
3527
3528static ssize_t initial_dr_show(struct device *dev,
3529 struct device_attribute *attr, char *buf)
3530{
3531 struct usbpd *pd = dev_get_drvdata(dev);
3532 const char *dr = "none";
3533
3534 if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT)
3535 dr = "ufp";
3536 else if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SINK)
3537 dr = "dfp";
3538
3539 return snprintf(buf, PAGE_SIZE, "%s\n", dr);
3540}
3541static DEVICE_ATTR_RO(initial_dr);
3542
3543static ssize_t src_cap_id_show(struct device *dev,
3544 struct device_attribute *attr, char *buf)
3545{
3546 struct usbpd *pd = dev_get_drvdata(dev);
3547
3548 return snprintf(buf, PAGE_SIZE, "%d\n", pd->src_cap_id);
3549}
3550static DEVICE_ATTR_RO(src_cap_id);
3551
3552/* Dump received source PDOs in human-readable format */
3553static ssize_t pdo_h_show(struct device *dev, struct device_attribute *attr,
3554 char *buf)
3555{
3556 struct usbpd *pd = dev_get_drvdata(dev);
3557 int i;
3558 ssize_t cnt = 0;
3559
3560 for (i = 0; i < ARRAY_SIZE(pd->received_pdos); i++) {
3561 u32 pdo = pd->received_pdos[i];
3562
3563 if (pdo == 0)
3564 break;
3565
3566 cnt += scnprintf(&buf[cnt], PAGE_SIZE - cnt, "PDO %d\n", i + 1);
3567
3568 if (PD_SRC_PDO_TYPE(pdo) == PD_SRC_PDO_TYPE_FIXED) {
3569 cnt += scnprintf(&buf[cnt], PAGE_SIZE - cnt,
3570 "\tFixed supply\n"
3571 "\tDual-Role Power:%d\n"
3572 "\tUSB Suspend Supported:%d\n"
3573 "\tExternally Powered:%d\n"
3574 "\tUSB Communications Capable:%d\n"
3575 "\tData Role Swap:%d\n"
3576 "\tPeak Current:%d\n"
3577 "\tVoltage:%d (mV)\n"
3578 "\tMax Current:%d (mA)\n",
3579 PD_SRC_PDO_FIXED_PR_SWAP(pdo),
3580 PD_SRC_PDO_FIXED_USB_SUSP(pdo),
3581 PD_SRC_PDO_FIXED_EXT_POWERED(pdo),
3582 PD_SRC_PDO_FIXED_USB_COMM(pdo),
3583 PD_SRC_PDO_FIXED_DR_SWAP(pdo),
3584 PD_SRC_PDO_FIXED_PEAK_CURR(pdo),
3585 PD_SRC_PDO_FIXED_VOLTAGE(pdo) * 50,
3586 PD_SRC_PDO_FIXED_MAX_CURR(pdo) * 10);
3587 } else if (PD_SRC_PDO_TYPE(pdo) == PD_SRC_PDO_TYPE_BATTERY) {
3588 cnt += scnprintf(&buf[cnt], PAGE_SIZE - cnt,
3589 "\tBattery supply\n"
3590 "\tMax Voltage:%d (mV)\n"
3591 "\tMin Voltage:%d (mV)\n"
3592 "\tMax Power:%d (mW)\n",
3593 PD_SRC_PDO_VAR_BATT_MAX_VOLT(pdo) * 50,
3594 PD_SRC_PDO_VAR_BATT_MIN_VOLT(pdo) * 50,
3595 PD_SRC_PDO_VAR_BATT_MAX(pdo) * 250);
3596 } else if (PD_SRC_PDO_TYPE(pdo) == PD_SRC_PDO_TYPE_VARIABLE) {
3597 cnt += scnprintf(&buf[cnt], PAGE_SIZE - cnt,
3598 "\tVariable supply\n"
3599 "\tMax Voltage:%d (mV)\n"
3600 "\tMin Voltage:%d (mV)\n"
3601 "\tMax Current:%d (mA)\n",
3602 PD_SRC_PDO_VAR_BATT_MAX_VOLT(pdo) * 50,
3603 PD_SRC_PDO_VAR_BATT_MIN_VOLT(pdo) * 50,
3604 PD_SRC_PDO_VAR_BATT_MAX(pdo) * 10);
3605 } else if (PD_SRC_PDO_TYPE(pdo) == PD_SRC_PDO_TYPE_AUGMENTED) {
3606 cnt += scnprintf(&buf[cnt], PAGE_SIZE - cnt,
3607 "\tProgrammable Power supply\n"
3608 "\tMax Voltage:%d (mV)\n"
3609 "\tMin Voltage:%d (mV)\n"
3610 "\tMax Current:%d (mA)\n",
3611 PD_APDO_MAX_VOLT(pdo) * 100,
3612 PD_APDO_MIN_VOLT(pdo) * 100,
3613 PD_APDO_MAX_CURR(pdo) * 50);
3614 } else {
3615 cnt += scnprintf(&buf[cnt], PAGE_SIZE - cnt,
3616 "Invalid PDO\n");
3617 }
3618
3619 buf[cnt++] = '\n';
3620 }
3621
3622 return cnt;
3623}
3624static DEVICE_ATTR_RO(pdo_h);
3625
3626static ssize_t pdo_n_show(struct device *dev, struct device_attribute *attr,
3627 char *buf);
3628
3629#define PDO_ATTR(n) { \
3630 .attr = { .name = __stringify(pdo##n), .mode = 0444 }, \
3631 .show = pdo_n_show, \
3632}
3633static struct device_attribute dev_attr_pdos[] = {
3634 PDO_ATTR(1),
3635 PDO_ATTR(2),
3636 PDO_ATTR(3),
3637 PDO_ATTR(4),
3638 PDO_ATTR(5),
3639 PDO_ATTR(6),
3640 PDO_ATTR(7),
3641};
3642
3643static ssize_t pdo_n_show(struct device *dev, struct device_attribute *attr,
3644 char *buf)
3645{
3646 struct usbpd *pd = dev_get_drvdata(dev);
3647 int i;
3648
3649 for (i = 0; i < ARRAY_SIZE(dev_attr_pdos); i++)
3650 if (attr == &dev_attr_pdos[i])
3651 /* dump the PDO as a hex string */
3652 return snprintf(buf, PAGE_SIZE, "%08x\n",
3653 pd->received_pdos[i]);
3654
3655 usbpd_err(&pd->dev, "Invalid PDO index\n");
3656 return -EINVAL;
3657}
3658
3659static ssize_t select_pdo_store(struct device *dev,
3660 struct device_attribute *attr, const char *buf, size_t size)
3661{
3662 struct usbpd *pd = dev_get_drvdata(dev);
3663 int src_cap_id;
3664 int pdo, uv = 0, ua = 0;
3665 int ret;
3666
Jack Phamaf7d3842017-01-26 13:28:19 -08003667 mutex_lock(&pd->swap_lock);
3668
Jack Phamf4baeb12017-02-03 19:01:48 -08003669 /* Only allowed if we are already in explicit sink contract */
3670 if (pd->current_state != PE_SNK_READY || !is_sink_tx_ok(pd)) {
3671 usbpd_err(&pd->dev, "select_pdo: Cannot select new PDO yet\n");
Jack Phamaf7d3842017-01-26 13:28:19 -08003672 ret = -EBUSY;
3673 goto out;
Jack Phamf4baeb12017-02-03 19:01:48 -08003674 }
3675
3676 ret = sscanf(buf, "%d %d %d %d", &src_cap_id, &pdo, &uv, &ua);
3677 if (ret != 2 && ret != 4) {
3678 usbpd_err(&pd->dev, "select_pdo: Must specify <src cap id> <PDO> [<uV> <uA>]\n");
Jack Phamaf7d3842017-01-26 13:28:19 -08003679 ret = -EINVAL;
3680 goto out;
Jack Phamf4baeb12017-02-03 19:01:48 -08003681 }
3682
3683 if (src_cap_id != pd->src_cap_id) {
3684 usbpd_err(&pd->dev, "select_pdo: src_cap_id mismatch. Requested:%d, current:%d\n",
3685 src_cap_id, pd->src_cap_id);
Jack Phamaf7d3842017-01-26 13:28:19 -08003686 ret = -EINVAL;
3687 goto out;
Jack Phamf4baeb12017-02-03 19:01:48 -08003688 }
3689
3690 if (pdo < 1 || pdo > 7) {
3691 usbpd_err(&pd->dev, "select_pdo: invalid PDO:%d\n", pdo);
Jack Phamaf7d3842017-01-26 13:28:19 -08003692 ret = -EINVAL;
3693 goto out;
Jack Phamf4baeb12017-02-03 19:01:48 -08003694 }
3695
3696 ret = pd_select_pdo(pd, pdo, uv, ua);
3697 if (ret)
Jack Phamaf7d3842017-01-26 13:28:19 -08003698 goto out;
Jack Phamf4baeb12017-02-03 19:01:48 -08003699
Jack Phamaf7d3842017-01-26 13:28:19 -08003700 reinit_completion(&pd->is_ready);
3701 pd->send_request = true;
3702 kick_sm(pd, 0);
Jack Phamf4baeb12017-02-03 19:01:48 -08003703
Jack Phamaf7d3842017-01-26 13:28:19 -08003704 /* wait for operation to complete */
3705 if (!wait_for_completion_timeout(&pd->is_ready,
3706 msecs_to_jiffies(1000))) {
3707 usbpd_err(&pd->dev, "select_pdo: request timed out\n");
3708 ret = -ETIMEDOUT;
3709 goto out;
3710 }
3711
3712 /* determine if request was accepted/rejected */
3713 if (pd->selected_pdo != pd->requested_pdo ||
3714 pd->current_voltage != pd->requested_voltage) {
3715 usbpd_err(&pd->dev, "select_pdo: request rejected\n");
3716 ret = -EINVAL;
3717 }
3718
3719out:
3720 pd->send_request = false;
3721 mutex_unlock(&pd->swap_lock);
3722 return ret ? ret : size;
Jack Phamf4baeb12017-02-03 19:01:48 -08003723}
3724
3725static ssize_t select_pdo_show(struct device *dev,
3726 struct device_attribute *attr, char *buf)
3727{
3728 struct usbpd *pd = dev_get_drvdata(dev);
3729
3730 return snprintf(buf, PAGE_SIZE, "%d\n", pd->selected_pdo);
3731}
3732static DEVICE_ATTR_RW(select_pdo);
3733
3734static ssize_t rdo_show(struct device *dev, struct device_attribute *attr,
3735 char *buf)
3736{
3737 struct usbpd *pd = dev_get_drvdata(dev);
3738
3739 /* dump the RDO as a hex string */
3740 return snprintf(buf, PAGE_SIZE, "%08x\n", pd->rdo);
3741}
3742static DEVICE_ATTR_RO(rdo);
3743
3744static ssize_t rdo_h_show(struct device *dev, struct device_attribute *attr,
3745 char *buf)
3746{
3747 struct usbpd *pd = dev_get_drvdata(dev);
3748 int pos = PD_RDO_OBJ_POS(pd->rdo);
Jack Pham6452ab12018-04-04 18:43:34 -07003749 int type = PD_SRC_PDO_TYPE(pd->received_pdos[pos - 1]);
Jack Phamf4baeb12017-02-03 19:01:48 -08003750 int len;
3751
3752 len = scnprintf(buf, PAGE_SIZE, "Request Data Object\n"
3753 "\tObj Pos:%d\n"
3754 "\tGiveback:%d\n"
3755 "\tCapability Mismatch:%d\n"
3756 "\tUSB Communications Capable:%d\n"
3757 "\tNo USB Suspend:%d\n",
3758 PD_RDO_OBJ_POS(pd->rdo),
3759 PD_RDO_GIVEBACK(pd->rdo),
3760 PD_RDO_MISMATCH(pd->rdo),
3761 PD_RDO_USB_COMM(pd->rdo),
3762 PD_RDO_NO_USB_SUSP(pd->rdo));
3763
3764 switch (type) {
3765 case PD_SRC_PDO_TYPE_FIXED:
3766 case PD_SRC_PDO_TYPE_VARIABLE:
3767 len += scnprintf(buf + len, PAGE_SIZE - len,
3768 "(Fixed/Variable)\n"
3769 "\tOperating Current:%d (mA)\n"
3770 "\t%s Current:%d (mA)\n",
3771 PD_RDO_FIXED_CURR(pd->rdo) * 10,
3772 PD_RDO_GIVEBACK(pd->rdo) ? "Min" : "Max",
3773 PD_RDO_FIXED_CURR_MINMAX(pd->rdo) * 10);
3774 break;
3775
3776 case PD_SRC_PDO_TYPE_BATTERY:
3777 len += scnprintf(buf + len, PAGE_SIZE - len,
3778 "(Battery)\n"
3779 "\tOperating Power:%d (mW)\n"
3780 "\t%s Power:%d (mW)\n",
3781 PD_RDO_FIXED_CURR(pd->rdo) * 250,
3782 PD_RDO_GIVEBACK(pd->rdo) ? "Min" : "Max",
3783 PD_RDO_FIXED_CURR_MINMAX(pd->rdo) * 250);
3784 break;
3785
3786 case PD_SRC_PDO_TYPE_AUGMENTED:
3787 len += scnprintf(buf + len, PAGE_SIZE - len,
3788 "(Programmable)\n"
3789 "\tOutput Voltage:%d (mV)\n"
3790 "\tOperating Current:%d (mA)\n",
3791 PD_RDO_PROG_VOLTAGE(pd->rdo) * 20,
3792 PD_RDO_PROG_CURR(pd->rdo) * 50);
3793 break;
3794 }
3795
3796 return len;
3797}
3798static DEVICE_ATTR_RO(rdo_h);
3799
3800static ssize_t hard_reset_store(struct device *dev,
3801 struct device_attribute *attr, const char *buf, size_t size)
3802{
3803 struct usbpd *pd = dev_get_drvdata(dev);
3804 int val = 0;
3805
3806 if (sscanf(buf, "%d\n", &val) != 1)
3807 return -EINVAL;
3808
3809 if (val)
3810 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
3811 PE_SRC_HARD_RESET : PE_SNK_HARD_RESET);
3812
3813 return size;
3814}
3815static DEVICE_ATTR_WO(hard_reset);
3816
Hemant Kumar018b5982017-08-09 14:14:37 -07003817static int trigger_tx_msg(struct usbpd *pd, bool *msg_tx_flag)
3818{
3819 int ret = 0;
3820
3821 /* Only allowed if we are already in explicit sink contract */
3822 if (pd->current_state != PE_SNK_READY || !is_sink_tx_ok(pd)) {
3823 usbpd_err(&pd->dev, "%s: Cannot send msg\n", __func__);
3824 ret = -EBUSY;
3825 goto out;
3826 }
3827
3828 reinit_completion(&pd->is_ready);
3829 *msg_tx_flag = true;
3830 kick_sm(pd, 0);
3831
3832 /* wait for operation to complete */
3833 if (!wait_for_completion_timeout(&pd->is_ready,
3834 msecs_to_jiffies(1000))) {
3835 usbpd_err(&pd->dev, "%s: request timed out\n", __func__);
3836 ret = -ETIMEDOUT;
3837 }
3838
3839out:
3840 *msg_tx_flag = false;
3841 return ret;
3842
3843}
3844
3845static ssize_t get_src_cap_ext_show(struct device *dev,
3846 struct device_attribute *attr, char *buf)
3847{
3848 int i, ret, len = 0;
3849 struct usbpd *pd = dev_get_drvdata(dev);
3850
3851 if (pd->spec_rev == USBPD_REV_20)
3852 return -EINVAL;
3853
3854 ret = trigger_tx_msg(pd, &pd->send_get_src_cap_ext);
3855 if (ret)
3856 return ret;
3857
3858 for (i = 0; i < PD_SRC_CAP_EXT_DB_LEN; i++)
Jack Pham408bc5c2018-06-13 11:57:49 -07003859 len += snprintf(buf + len, PAGE_SIZE - len, "%s0x%02x",
3860 i ? " " : "", pd->src_cap_ext_db[i]);
3861
3862 buf[len++] = '\n';
3863 buf[len] = '\0';
3864
Hemant Kumar018b5982017-08-09 14:14:37 -07003865 return len;
3866}
3867static DEVICE_ATTR_RO(get_src_cap_ext);
3868
Jack Phamda401d72018-06-07 19:29:52 -07003869static ssize_t get_status_show(struct device *dev,
3870 struct device_attribute *attr, char *buf)
3871{
3872 int i, ret, len = 0;
3873 struct usbpd *pd = dev_get_drvdata(dev);
3874
3875 if (pd->spec_rev == USBPD_REV_20)
3876 return -EINVAL;
3877
3878 ret = trigger_tx_msg(pd, &pd->send_get_status);
3879 if (ret)
3880 return ret;
3881
3882 for (i = 0; i < PD_STATUS_DB_LEN; i++)
3883 len += snprintf(buf + len, PAGE_SIZE - len, "%s0x%02x",
3884 i ? " " : "", pd->status_db[i]);
3885
3886 buf[len++] = '\n';
3887 buf[len] = '\0';
3888
3889 return len;
3890}
3891static DEVICE_ATTR_RO(get_status);
3892
Hemant Kumar018b5982017-08-09 14:14:37 -07003893static ssize_t get_pps_status_show(struct device *dev,
3894 struct device_attribute *attr, char *buf)
3895{
3896 int ret;
3897 struct usbpd *pd = dev_get_drvdata(dev);
3898
3899 if (pd->spec_rev == USBPD_REV_20)
3900 return -EINVAL;
3901
3902 ret = trigger_tx_msg(pd, &pd->send_get_pps_status);
3903 if (ret)
3904 return ret;
3905
Jack Pham408bc5c2018-06-13 11:57:49 -07003906 return snprintf(buf, PAGE_SIZE, "0x%08x\n", pd->pps_status_db);
Hemant Kumar018b5982017-08-09 14:14:37 -07003907}
3908static DEVICE_ATTR_RO(get_pps_status);
3909
Hemant Kumar51ded972017-08-09 17:57:24 -07003910static ssize_t get_battery_cap_store(struct device *dev,
3911 struct device_attribute *attr, const char *buf, size_t size)
3912{
3913 struct usbpd *pd = dev_get_drvdata(dev);
3914 int val, ret;
3915
3916 if (pd->spec_rev == USBPD_REV_20 || sscanf(buf, "%d\n", &val) != 1) {
3917 pd->get_battery_cap_db = -EINVAL;
3918 return -EINVAL;
3919 }
3920
3921 pd->get_battery_cap_db = val;
3922
3923 ret = trigger_tx_msg(pd, &pd->send_get_battery_cap);
3924
3925 return ret ? ret : size;
3926}
3927
3928static ssize_t get_battery_cap_show(struct device *dev,
3929 struct device_attribute *attr, char *buf)
3930{
3931 int i, len = 0;
3932 struct usbpd *pd = dev_get_drvdata(dev);
3933
3934 if (pd->get_battery_cap_db == -EINVAL)
3935 return -EINVAL;
3936
3937 for (i = 0; i < PD_BATTERY_CAP_DB_LEN; i++)
Jack Pham408bc5c2018-06-13 11:57:49 -07003938 len += snprintf(buf + len, PAGE_SIZE - len, "%s0x%02x",
3939 i ? " " : "", pd->battery_cap_db[i]);
3940
3941 buf[len++] = '\n';
3942 buf[len] = '\0';
3943
Hemant Kumar51ded972017-08-09 17:57:24 -07003944 return len;
3945}
3946static DEVICE_ATTR_RW(get_battery_cap);
3947
3948static ssize_t get_battery_status_store(struct device *dev,
3949 struct device_attribute *attr, const char *buf, size_t size)
3950{
3951 struct usbpd *pd = dev_get_drvdata(dev);
3952 int val, ret;
3953
3954 if (pd->spec_rev == USBPD_REV_20 || sscanf(buf, "%d\n", &val) != 1) {
3955 pd->get_battery_status_db = -EINVAL;
3956 return -EINVAL;
3957 }
3958
3959 pd->get_battery_status_db = val;
3960
3961 ret = trigger_tx_msg(pd, &pd->send_get_battery_status);
3962
3963 return ret ? ret : size;
3964}
3965
3966static ssize_t get_battery_status_show(struct device *dev,
3967 struct device_attribute *attr, char *buf)
3968{
3969 struct usbpd *pd = dev_get_drvdata(dev);
3970
3971 if (pd->get_battery_status_db == -EINVAL)
3972 return -EINVAL;
3973
Jack Pham408bc5c2018-06-13 11:57:49 -07003974 return snprintf(buf, PAGE_SIZE, "0x%08x\n", pd->battery_sts_dobj);
Hemant Kumar51ded972017-08-09 17:57:24 -07003975}
3976static DEVICE_ATTR_RW(get_battery_status);
3977
Jack Phamf4baeb12017-02-03 19:01:48 -08003978static struct attribute *usbpd_attrs[] = {
3979 &dev_attr_contract.attr,
3980 &dev_attr_initial_pr.attr,
3981 &dev_attr_current_pr.attr,
3982 &dev_attr_initial_dr.attr,
3983 &dev_attr_current_dr.attr,
3984 &dev_attr_src_cap_id.attr,
3985 &dev_attr_pdo_h.attr,
3986 &dev_attr_pdos[0].attr,
3987 &dev_attr_pdos[1].attr,
3988 &dev_attr_pdos[2].attr,
3989 &dev_attr_pdos[3].attr,
3990 &dev_attr_pdos[4].attr,
3991 &dev_attr_pdos[5].attr,
3992 &dev_attr_pdos[6].attr,
3993 &dev_attr_select_pdo.attr,
3994 &dev_attr_rdo.attr,
3995 &dev_attr_rdo_h.attr,
3996 &dev_attr_hard_reset.attr,
Hemant Kumar018b5982017-08-09 14:14:37 -07003997 &dev_attr_get_src_cap_ext.attr,
Jack Phamda401d72018-06-07 19:29:52 -07003998 &dev_attr_get_status.attr,
Hemant Kumar018b5982017-08-09 14:14:37 -07003999 &dev_attr_get_pps_status.attr,
Hemant Kumar51ded972017-08-09 17:57:24 -07004000 &dev_attr_get_battery_cap.attr,
4001 &dev_attr_get_battery_status.attr,
Jack Phamf4baeb12017-02-03 19:01:48 -08004002 NULL,
4003};
4004ATTRIBUTE_GROUPS(usbpd);
4005
4006static struct class usbpd_class = {
4007 .name = "usbpd",
4008 .owner = THIS_MODULE,
4009 .dev_uevent = usbpd_uevent,
4010 .dev_groups = usbpd_groups,
4011};
4012
4013static int match_usbpd_device(struct device *dev, const void *data)
4014{
4015 return dev->parent == data;
4016}
4017
4018static void devm_usbpd_put(struct device *dev, void *res)
4019{
4020 struct usbpd **ppd = res;
4021
4022 put_device(&(*ppd)->dev);
4023}
4024
4025struct usbpd *devm_usbpd_get_by_phandle(struct device *dev, const char *phandle)
4026{
4027 struct usbpd **ptr, *pd = NULL;
4028 struct device_node *pd_np;
4029 struct platform_device *pdev;
4030 struct device *pd_dev;
4031
4032 if (!usbpd_class.p) /* usbpd_init() not yet called */
4033 return ERR_PTR(-EAGAIN);
4034
4035 if (!dev->of_node)
4036 return ERR_PTR(-EINVAL);
4037
4038 pd_np = of_parse_phandle(dev->of_node, phandle, 0);
4039 if (!pd_np)
4040 return ERR_PTR(-ENXIO);
4041
4042 pdev = of_find_device_by_node(pd_np);
4043 if (!pdev)
4044 return ERR_PTR(-ENODEV);
4045
4046 pd_dev = class_find_device(&usbpd_class, NULL, &pdev->dev,
4047 match_usbpd_device);
4048 if (!pd_dev) {
4049 platform_device_put(pdev);
4050 /* device was found but maybe hadn't probed yet, so defer */
4051 return ERR_PTR(-EPROBE_DEFER);
4052 }
4053
4054 ptr = devres_alloc(devm_usbpd_put, sizeof(*ptr), GFP_KERNEL);
4055 if (!ptr) {
4056 put_device(pd_dev);
4057 platform_device_put(pdev);
4058 return ERR_PTR(-ENOMEM);
4059 }
4060
4061 pd = dev_get_drvdata(pd_dev);
4062 if (!pd)
4063 return ERR_PTR(-EPROBE_DEFER);
4064
4065 *ptr = pd;
4066 devres_add(dev, ptr);
4067
4068 return pd;
4069}
4070EXPORT_SYMBOL(devm_usbpd_get_by_phandle);
4071
Jack Phamde7f11e2018-11-14 12:01:02 -08004072static void usbpd_release(struct device *dev)
4073{
4074 struct usbpd *pd = container_of(dev, struct usbpd, dev);
4075
4076 kfree(pd);
4077}
4078
Jack Phamf4baeb12017-02-03 19:01:48 -08004079static int num_pd_instances;
4080
4081/**
4082 * usbpd_create - Create a new instance of USB PD protocol/policy engine
4083 * @parent - parent device to associate with
4084 *
4085 * This creates a new usbpd class device which manages the state of a
4086 * USB PD-capable port. The parent device that is passed in should be
4087 * associated with the physical device port, e.g. a PD PHY.
4088 *
4089 * Return: struct usbpd pointer, or an ERR_PTR value
4090 */
4091struct usbpd *usbpd_create(struct device *parent)
4092{
4093 int ret;
4094 struct usbpd *pd;
4095
4096 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
4097 if (!pd)
4098 return ERR_PTR(-ENOMEM);
4099
4100 device_initialize(&pd->dev);
4101 pd->dev.class = &usbpd_class;
4102 pd->dev.parent = parent;
Jack Phamde7f11e2018-11-14 12:01:02 -08004103 pd->dev.release = usbpd_release;
Jack Phamf4baeb12017-02-03 19:01:48 -08004104 dev_set_drvdata(&pd->dev, pd);
4105
4106 ret = dev_set_name(&pd->dev, "usbpd%d", num_pd_instances++);
4107 if (ret)
4108 goto free_pd;
4109
4110 ret = device_init_wakeup(&pd->dev, true);
4111 if (ret)
4112 goto free_pd;
4113
4114 ret = device_add(&pd->dev);
4115 if (ret)
4116 goto free_pd;
4117
Hemant Kumar86bd10f2017-05-24 12:25:15 -07004118 pd->wq = alloc_ordered_workqueue("usbpd_wq", WQ_FREEZABLE | WQ_HIGHPRI);
Jack Phamf4baeb12017-02-03 19:01:48 -08004119 if (!pd->wq) {
4120 ret = -ENOMEM;
4121 goto del_pd;
4122 }
4123 INIT_WORK(&pd->sm_work, usbpd_sm);
4124 hrtimer_init(&pd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
4125 pd->timer.function = pd_timeout;
Jack Phamaf7d3842017-01-26 13:28:19 -08004126 mutex_init(&pd->swap_lock);
Mayank Rana83443202017-08-31 15:38:03 -07004127 mutex_init(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08004128
4129 pd->usb_psy = power_supply_get_by_name("usb");
4130 if (!pd->usb_psy) {
4131 usbpd_dbg(&pd->dev, "Could not get USB power_supply, deferring probe\n");
4132 ret = -EPROBE_DEFER;
4133 goto destroy_wq;
4134 }
4135
Pratham Pratap033a2d92017-11-14 20:57:05 +05304136 if (get_connector_type(pd) == POWER_SUPPLY_CONNECTOR_MICRO_USB) {
4137 usbpd_dbg(&pd->dev, "USB connector is microAB hence failing pdphy_probe\n");
4138 ret = -EINVAL;
4139 goto put_psy;
4140 }
Jack Phamf4baeb12017-02-03 19:01:48 -08004141 /*
4142 * associate extcon with the parent dev as it could have a DT
4143 * node which will be useful for extcon_get_edev_by_phandle()
4144 */
4145 pd->extcon = devm_extcon_dev_allocate(parent, usbpd_extcon_cable);
4146 if (IS_ERR(pd->extcon)) {
4147 usbpd_err(&pd->dev, "failed to allocate extcon device\n");
4148 ret = PTR_ERR(pd->extcon);
4149 goto put_psy;
4150 }
4151
4152 pd->extcon->mutually_exclusive = usbpd_extcon_exclusive;
4153 ret = devm_extcon_dev_register(parent, pd->extcon);
4154 if (ret) {
4155 usbpd_err(&pd->dev, "failed to register extcon device\n");
4156 goto put_psy;
4157 }
4158
Jack Pham4e9dff72017-04-04 18:05:53 -07004159 /* Support reporting polarity and speed via properties */
4160 extcon_set_property_capability(pd->extcon, EXTCON_USB,
4161 EXTCON_PROP_USB_TYPEC_POLARITY);
4162 extcon_set_property_capability(pd->extcon, EXTCON_USB,
Vijayavardhan Vennapusadaeb5ac2018-07-13 13:04:17 +05304163 EXTCON_PROP_USB_PD_CONTRACT);
4164 extcon_set_property_capability(pd->extcon, EXTCON_USB,
Jack Pham4e9dff72017-04-04 18:05:53 -07004165 EXTCON_PROP_USB_SS);
4166 extcon_set_property_capability(pd->extcon, EXTCON_USB_HOST,
4167 EXTCON_PROP_USB_TYPEC_POLARITY);
4168 extcon_set_property_capability(pd->extcon, EXTCON_USB_HOST,
4169 EXTCON_PROP_USB_SS);
4170
Jack Phamf4baeb12017-02-03 19:01:48 -08004171 pd->vbus = devm_regulator_get(parent, "vbus");
4172 if (IS_ERR(pd->vbus)) {
4173 ret = PTR_ERR(pd->vbus);
4174 goto put_psy;
4175 }
4176
4177 pd->vconn = devm_regulator_get(parent, "vconn");
4178 if (IS_ERR(pd->vconn)) {
4179 ret = PTR_ERR(pd->vconn);
4180 goto put_psy;
4181 }
4182
rbandi20d026b2020-03-18 10:15:47 -07004183 /*
4184 * Need to set is_sxr_dp_sink to TRUE only when device tree node is
4185 * present, and sim_vid_display string is present in
4186 * boot_command_line string.
4187 */
4188 if (sxr_dp_mode)
4189 pd->is_sxr_dp_sink = device_property_present(parent,
4190 "qcom,sxr1130-sxr-dp-sink");
4191
Jack Phamf4baeb12017-02-03 19:01:48 -08004192 pd->vconn_is_external = device_property_present(parent,
4193 "qcom,vconn-uses-external-source");
4194
Jack Phamee1f9052017-01-26 12:27:07 -08004195 pd->num_sink_caps = device_property_read_u32_array(parent,
4196 "qcom,default-sink-caps", NULL, 0);
Vijayavardhan Vennapusa248d7232017-02-14 15:32:07 +05304197 if (pd->num_sink_caps > 0) {
Jack Phamee1f9052017-01-26 12:27:07 -08004198 int i;
4199 u32 sink_caps[14];
4200
4201 if (pd->num_sink_caps % 2 || pd->num_sink_caps > 14) {
4202 ret = -EINVAL;
4203 usbpd_err(&pd->dev, "default-sink-caps must be be specified as voltage/current, max 7 pairs\n");
4204 goto put_psy;
4205 }
4206
4207 ret = device_property_read_u32_array(parent,
4208 "qcom,default-sink-caps", sink_caps,
4209 pd->num_sink_caps);
4210 if (ret) {
4211 usbpd_err(&pd->dev, "Error reading default-sink-caps\n");
4212 goto put_psy;
4213 }
4214
4215 pd->num_sink_caps /= 2;
4216
4217 for (i = 0; i < pd->num_sink_caps; i++) {
4218 int v = sink_caps[i * 2] / 50;
4219 int c = sink_caps[i * 2 + 1] / 10;
4220
4221 pd->sink_caps[i] =
4222 PD_SNK_PDO_FIXED(0, 0, 0, 0, 0, v, c);
4223 }
4224
4225 /* First PDO includes additional capabilities */
4226 pd->sink_caps[0] |= PD_SNK_PDO_FIXED(1, 0, 0, 1, 1, 0, 0);
4227 } else {
4228 memcpy(pd->sink_caps, default_snk_caps,
4229 sizeof(default_snk_caps));
4230 pd->num_sink_caps = ARRAY_SIZE(default_snk_caps);
4231 }
4232
Jack Phamf4baeb12017-02-03 19:01:48 -08004233 /*
4234 * Register the Android dual-role class (/sys/class/dual_role_usb/).
4235 * The first instance should be named "otg_default" as that's what
4236 * Android expects.
4237 * Note this is different than the /sys/class/usbpd/ created above.
4238 */
4239 pd->dr_desc.name = (num_pd_instances == 1) ?
4240 "otg_default" : dev_name(&pd->dev);
4241 pd->dr_desc.supported_modes = DUAL_ROLE_SUPPORTED_MODES_DFP_AND_UFP;
4242 pd->dr_desc.properties = usbpd_dr_properties;
4243 pd->dr_desc.num_properties = ARRAY_SIZE(usbpd_dr_properties);
4244 pd->dr_desc.get_property = usbpd_dr_get_property;
4245 pd->dr_desc.set_property = usbpd_dr_set_property;
4246 pd->dr_desc.property_is_writeable = usbpd_dr_prop_writeable;
4247
4248 pd->dual_role = devm_dual_role_instance_register(&pd->dev,
4249 &pd->dr_desc);
4250 if (IS_ERR(pd->dual_role)) {
4251 usbpd_err(&pd->dev, "could not register dual_role instance\n");
4252 goto put_psy;
4253 } else {
4254 pd->dual_role->drv_data = pd;
4255 }
4256
4257 pd->current_pr = PR_NONE;
4258 pd->current_dr = DR_NONE;
4259 list_add_tail(&pd->instance, &_usbpd);
4260
4261 spin_lock_init(&pd->rx_lock);
4262 INIT_LIST_HEAD(&pd->rx_q);
4263 INIT_LIST_HEAD(&pd->svid_handlers);
Jack Phamaf7d3842017-01-26 13:28:19 -08004264 init_completion(&pd->is_ready);
Jack Phamf3c1bd32017-08-02 18:32:23 -07004265 init_completion(&pd->tx_chunk_request);
Jack Phamf4baeb12017-02-03 19:01:48 -08004266
4267 pd->psy_nb.notifier_call = psy_changed;
4268 ret = power_supply_reg_notifier(&pd->psy_nb);
4269 if (ret)
4270 goto del_inst;
4271
4272 /* force read initial power_supply values */
4273 psy_changed(&pd->psy_nb, PSY_EVENT_PROP_CHANGED, pd->usb_psy);
4274
4275 return pd;
4276
4277del_inst:
4278 list_del(&pd->instance);
4279put_psy:
4280 power_supply_put(pd->usb_psy);
4281destroy_wq:
4282 destroy_workqueue(pd->wq);
4283del_pd:
4284 device_del(&pd->dev);
4285free_pd:
4286 num_pd_instances--;
Jack Phamde7f11e2018-11-14 12:01:02 -08004287 put_device(&pd->dev);
Jack Phamf4baeb12017-02-03 19:01:48 -08004288 return ERR_PTR(ret);
4289}
4290EXPORT_SYMBOL(usbpd_create);
4291
4292/**
4293 * usbpd_destroy - Removes and frees a usbpd instance
4294 * @pd: the instance to destroy
4295 */
4296void usbpd_destroy(struct usbpd *pd)
4297{
4298 if (!pd)
4299 return;
4300
4301 list_del(&pd->instance);
4302 power_supply_unreg_notifier(&pd->psy_nb);
4303 power_supply_put(pd->usb_psy);
4304 destroy_workqueue(pd->wq);
Jack Phamde7f11e2018-11-14 12:01:02 -08004305 device_unregister(&pd->dev);
Jack Phamf4baeb12017-02-03 19:01:48 -08004306}
4307EXPORT_SYMBOL(usbpd_destroy);
4308
4309static int __init usbpd_init(void)
4310{
rbandi20d026b2020-03-18 10:15:47 -07004311 char *cmdline;
4312
4313 cmdline = strnstr(boot_command_line,
4314 "msm_drm.dsi_display0=dsi_sim_vid_display",
4315 strlen(boot_command_line));
4316 sxr_dp_mode = false;
4317 if (cmdline)
4318 sxr_dp_mode = true;
4319
Jack Phamf4baeb12017-02-03 19:01:48 -08004320 usbpd_ipc_log = ipc_log_context_create(NUM_LOG_PAGES, "usb_pd", 0);
4321 return class_register(&usbpd_class);
4322}
4323module_init(usbpd_init);
4324
4325static void __exit usbpd_exit(void)
4326{
4327 class_unregister(&usbpd_class);
4328}
4329module_exit(usbpd_exit);
4330
4331MODULE_DESCRIPTION("USB Power Delivery Policy Engine");
4332MODULE_LICENSE("GPL v2");