blob: 10d11acdb22e74ea27e88b4d00e05880103cec01 [file] [log] [blame]
Vijayavardhan Vennapusa2dec2b22018-04-12 17:25:19 +05301/* Copyright (c) 2016-2018, 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
Jack Phamf4baeb12017-02-03 19:01:48 -080045enum usbpd_state {
46 PE_UNKNOWN,
47 PE_ERROR_RECOVERY,
48 PE_SRC_DISABLED,
49 PE_SRC_STARTUP,
50 PE_SRC_SEND_CAPABILITIES,
51 PE_SRC_SEND_CAPABILITIES_WAIT, /* substate to wait for Request */
52 PE_SRC_NEGOTIATE_CAPABILITY,
53 PE_SRC_TRANSITION_SUPPLY,
54 PE_SRC_READY,
55 PE_SRC_HARD_RESET,
56 PE_SRC_SOFT_RESET,
57 PE_SRC_SEND_SOFT_RESET,
58 PE_SRC_DISCOVERY,
59 PE_SRC_TRANSITION_TO_DEFAULT,
60 PE_SNK_STARTUP,
61 PE_SNK_DISCOVERY,
62 PE_SNK_WAIT_FOR_CAPABILITIES,
63 PE_SNK_EVALUATE_CAPABILITY,
64 PE_SNK_SELECT_CAPABILITY,
65 PE_SNK_TRANSITION_SINK,
66 PE_SNK_READY,
67 PE_SNK_HARD_RESET,
68 PE_SNK_SOFT_RESET,
69 PE_SNK_SEND_SOFT_RESET,
70 PE_SNK_TRANSITION_TO_DEFAULT,
71 PE_DRS_SEND_DR_SWAP,
72 PE_PRS_SNK_SRC_SEND_SWAP,
73 PE_PRS_SNK_SRC_TRANSITION_TO_OFF,
74 PE_PRS_SNK_SRC_SOURCE_ON,
75 PE_PRS_SRC_SNK_SEND_SWAP,
76 PE_PRS_SRC_SNK_TRANSITION_TO_OFF,
77 PE_PRS_SRC_SNK_WAIT_SOURCE_ON,
78 PE_VCS_WAIT_FOR_VCONN,
79};
80
81static const char * const usbpd_state_strings[] = {
82 "UNKNOWN",
83 "ERROR_RECOVERY",
84 "SRC_Disabled",
85 "SRC_Startup",
86 "SRC_Send_Capabilities",
87 "SRC_Send_Capabilities (Wait for Request)",
88 "SRC_Negotiate_Capability",
89 "SRC_Transition_Supply",
90 "SRC_Ready",
91 "SRC_Hard_Reset",
92 "SRC_Soft_Reset",
93 "SRC_Send_Soft_Reset",
94 "SRC_Discovery",
95 "SRC_Transition_to_default",
96 "SNK_Startup",
97 "SNK_Discovery",
98 "SNK_Wait_for_Capabilities",
99 "SNK_Evaluate_Capability",
100 "SNK_Select_Capability",
101 "SNK_Transition_Sink",
102 "SNK_Ready",
103 "SNK_Hard_Reset",
104 "SNK_Soft_Reset",
105 "SNK_Send_Soft_Reset",
106 "SNK_Transition_to_default",
107 "DRS_Send_DR_Swap",
108 "PRS_SNK_SRC_Send_Swap",
109 "PRS_SNK_SRC_Transition_to_off",
110 "PRS_SNK_SRC_Source_on",
111 "PRS_SRC_SNK_Send_Swap",
112 "PRS_SRC_SNK_Transition_to_off",
113 "PRS_SRC_SNK_Wait_Source_on",
114 "VCS_Wait_for_VCONN",
115};
116
117enum usbpd_control_msg_type {
118 MSG_RESERVED = 0,
119 MSG_GOODCRC,
120 MSG_GOTOMIN,
121 MSG_ACCEPT,
122 MSG_REJECT,
123 MSG_PING,
124 MSG_PS_RDY,
125 MSG_GET_SOURCE_CAP,
126 MSG_GET_SINK_CAP,
127 MSG_DR_SWAP,
128 MSG_PR_SWAP,
129 MSG_VCONN_SWAP,
130 MSG_WAIT,
131 MSG_SOFT_RESET,
Jack Phamf3c1bd32017-08-02 18:32:23 -0700132 MSG_NOT_SUPPORTED = 0x10,
133 MSG_GET_SOURCE_CAP_EXTENDED,
134 MSG_GET_STATUS,
135 MSG_FR_SWAP,
136 MSG_GET_PPS_STATUS,
137 MSG_GET_COUNTRY_CODES,
Jack Phamf4baeb12017-02-03 19:01:48 -0800138};
139
Jack Pham722527a2018-06-28 23:17:17 -0700140static const char * const usbpd_control_msg_strings[] = {
141 "", "GoodCRC", "GotoMin", "Accept", "Reject", "Ping", "PS_RDY",
142 "Get_Source_Cap", "Get_Sink_Cap", "DR_Swap", "PR_Swap", "VCONN_Swap",
143 "Wait", "Soft_Reset", "", "", "Not_Supported",
144 "Get_Source_Cap_Extended", "Get_Status", "FR_Swap", "Get_PPS_Status",
145 "Get_Country_Codes",
146};
147
Jack Phamf4baeb12017-02-03 19:01:48 -0800148enum usbpd_data_msg_type {
149 MSG_SOURCE_CAPABILITIES = 1,
150 MSG_REQUEST,
151 MSG_BIST,
152 MSG_SINK_CAPABILITIES,
Jack Phamf3c1bd32017-08-02 18:32:23 -0700153 MSG_BATTERY_STATUS,
154 MSG_ALERT,
155 MSG_GET_COUNTRY_INFO,
Jack Phamf4baeb12017-02-03 19:01:48 -0800156 MSG_VDM = 0xF,
157};
158
Jack Pham722527a2018-06-28 23:17:17 -0700159static const char * const usbpd_data_msg_strings[] = {
160 "", "Source_Capabilities", "Request", "BIST", "Sink_Capabilities",
161 "Battery_Status", "Alert", "Get_Country_Info", "", "", "", "", "", "",
162 "", "Vendor_Defined",
163};
164
Jack Phamf3c1bd32017-08-02 18:32:23 -0700165enum usbpd_ext_msg_type {
166 MSG_SOURCE_CAPABILITIES_EXTENDED = 1,
167 MSG_STATUS,
168 MSG_GET_BATTERY_CAP,
169 MSG_GET_BATTERY_STATUS,
170 MSG_BATTERY_CAPABILITIES,
171 MSG_GET_MANUFACTURER_INFO,
172 MSG_MANUFACTURER_INFO,
173 MSG_SECURITY_REQUEST,
174 MSG_SECURITY_RESPONSE,
175 MSG_FIRMWARE_UPDATE_REQUEST,
176 MSG_FIRMWARE_UPDATE_RESPONSE,
177 MSG_PPS_STATUS,
178 MSG_COUNTRY_INFO,
179 MSG_COUNTRY_CODES,
180};
181
Jack Pham722527a2018-06-28 23:17:17 -0700182static const char * const usbpd_ext_msg_strings[] = {
183 "", "Source_Capabilities_Extended", "Status", "Get_Battery_Cap",
184 "Get_Battery_Status", "Get_Manufacturer_Info", "Manufacturer_Info",
185 "Security_Request", "Security_Response", "Firmware_Update_Request",
186 "Firmware_Update_Response", "PPS_Status", "Country_Info",
187 "Country_Codes",
188};
189
190static inline const char *msg_to_string(u8 id, bool is_data, bool is_ext)
191{
192 if (is_ext) {
193 if (id < ARRAY_SIZE(usbpd_ext_msg_strings))
194 return usbpd_ext_msg_strings[id];
195 } else if (is_data) {
196 if (id < ARRAY_SIZE(usbpd_data_msg_strings))
197 return usbpd_data_msg_strings[id];
198 } else if (id < ARRAY_SIZE(usbpd_control_msg_strings)) {
199 return usbpd_control_msg_strings[id];
200 }
201
202 return "Invalid";
203}
204
Jack Phamf4baeb12017-02-03 19:01:48 -0800205enum vdm_state {
206 VDM_NONE,
207 DISCOVERED_ID,
208 DISCOVERED_SVIDS,
209 DISCOVERED_MODES,
210 MODE_ENTERED,
211 MODE_EXITED,
212};
213
214static void *usbpd_ipc_log;
215#define usbpd_dbg(dev, fmt, ...) do { \
216 ipc_log_string(usbpd_ipc_log, "%s: %s: " fmt, dev_name(dev), __func__, \
217 ##__VA_ARGS__); \
218 dev_dbg(dev, fmt, ##__VA_ARGS__); \
219 } while (0)
220
221#define usbpd_info(dev, fmt, ...) do { \
222 ipc_log_string(usbpd_ipc_log, "%s: %s: " fmt, dev_name(dev), __func__, \
223 ##__VA_ARGS__); \
224 dev_info(dev, fmt, ##__VA_ARGS__); \
225 } while (0)
226
227#define usbpd_warn(dev, fmt, ...) do { \
228 ipc_log_string(usbpd_ipc_log, "%s: %s: " fmt, dev_name(dev), __func__, \
229 ##__VA_ARGS__); \
230 dev_warn(dev, fmt, ##__VA_ARGS__); \
231 } while (0)
232
233#define usbpd_err(dev, fmt, ...) do { \
234 ipc_log_string(usbpd_ipc_log, "%s: %s: " fmt, dev_name(dev), __func__, \
235 ##__VA_ARGS__); \
236 dev_err(dev, fmt, ##__VA_ARGS__); \
237 } while (0)
238
239#define NUM_LOG_PAGES 10
240
241/* Timeouts (in ms) */
242#define ERROR_RECOVERY_TIME 25
243#define SENDER_RESPONSE_TIME 26
244#define SINK_WAIT_CAP_TIME 500
245#define PS_TRANSITION_TIME 450
246#define SRC_CAP_TIME 120
247#define SRC_TRANSITION_TIME 25
248#define SRC_RECOVER_TIME 750
249#define PS_HARD_RESET_TIME 25
250#define PS_SOURCE_ON 400
251#define PS_SOURCE_OFF 750
Jack Pham35121342017-07-06 00:12:15 -0700252#define FIRST_SOURCE_CAP_TIME 200
Jack Phamf4baeb12017-02-03 19:01:48 -0800253#define VDM_BUSY_TIME 50
254#define VCONN_ON_TIME 100
255
256/* tPSHardReset + tSafe0V */
257#define SNK_HARD_RESET_VBUS_OFF_TIME (35 + 650)
258
259/* tSrcRecover + tSrcTurnOn */
260#define SNK_HARD_RESET_VBUS_ON_TIME (1000 + 275)
261
262#define PD_CAPS_COUNT 50
263
264#define PD_MAX_MSG_ID 7
265
Hemant Kumar796534e2017-05-30 15:54:55 -0700266#define PD_MAX_DATA_OBJ 7
267
Hemant Kumar018b5982017-08-09 14:14:37 -0700268#define PD_SRC_CAP_EXT_DB_LEN 24
Hemant Kumara1875942017-08-09 16:50:14 -0700269#define PD_STATUS_DB_LEN 5
Hemant Kumar51ded972017-08-09 17:57:24 -0700270#define PD_BATTERY_CAP_DB_LEN 9
Hemant Kumar018b5982017-08-09 14:14:37 -0700271
Jack Phamf3c1bd32017-08-02 18:32:23 -0700272#define PD_MAX_EXT_MSG_LEN 260
273#define PD_MAX_EXT_MSG_LEGACY_LEN 26
274
Jack Phamf4baeb12017-02-03 19:01:48 -0800275#define PD_MSG_HDR(type, dr, pr, id, cnt, rev) \
Jack Phamf3c1bd32017-08-02 18:32:23 -0700276 (((type) & 0x1F) | ((dr) << 5) | (rev << 6) | \
Jack Phamf4baeb12017-02-03 19:01:48 -0800277 ((pr) << 8) | ((id) << 9) | ((cnt) << 12))
Jack Phamf3c1bd32017-08-02 18:32:23 -0700278#define PD_MSG_HDR_COUNT(hdr) (((hdr) >> 12) & 7)
279#define PD_MSG_HDR_TYPE(hdr) ((hdr) & 0x1F)
280#define PD_MSG_HDR_ID(hdr) (((hdr) >> 9) & 7)
281#define PD_MSG_HDR_REV(hdr) (((hdr) >> 6) & 3)
282#define PD_MSG_HDR_EXTENDED BIT(15)
283#define PD_MSG_HDR_IS_EXTENDED(hdr) ((hdr) & PD_MSG_HDR_EXTENDED)
284
285#define PD_MSG_EXT_HDR(chunked, num, req, size) \
286 (((chunked) << 15) | (((num) & 0xF) << 11) | \
287 ((req) << 10) | ((size) & 0x1FF))
288#define PD_MSG_EXT_HDR_IS_CHUNKED(ehdr) ((ehdr) & 0x8000)
289#define PD_MSG_EXT_HDR_CHUNK_NUM(ehdr) (((ehdr) >> 11) & 0xF)
290#define PD_MSG_EXT_HDR_REQ_CHUNK(ehdr) ((ehdr) & 0x400)
291#define PD_MSG_EXT_HDR_DATA_SIZE(ehdr) ((ehdr) & 0x1FF)
Jack Phamf4baeb12017-02-03 19:01:48 -0800292
293#define PD_RDO_FIXED(obj, gb, mismatch, usb_comm, no_usb_susp, curr1, curr2) \
294 (((obj) << 28) | ((gb) << 27) | ((mismatch) << 26) | \
295 ((usb_comm) << 25) | ((no_usb_susp) << 24) | \
296 ((curr1) << 10) | (curr2))
297
298#define PD_RDO_AUGMENTED(obj, mismatch, usb_comm, no_usb_susp, volt, curr) \
299 (((obj) << 28) | ((mismatch) << 26) | ((usb_comm) << 25) | \
300 ((no_usb_susp) << 24) | ((volt) << 9) | (curr))
301
302#define PD_RDO_OBJ_POS(rdo) ((rdo) >> 28 & 7)
303#define PD_RDO_GIVEBACK(rdo) ((rdo) >> 27 & 1)
304#define PD_RDO_MISMATCH(rdo) ((rdo) >> 26 & 1)
305#define PD_RDO_USB_COMM(rdo) ((rdo) >> 25 & 1)
306#define PD_RDO_NO_USB_SUSP(rdo) ((rdo) >> 24 & 1)
307#define PD_RDO_FIXED_CURR(rdo) ((rdo) >> 10 & 0x3FF)
308#define PD_RDO_FIXED_CURR_MINMAX(rdo) ((rdo) & 0x3FF)
309#define PD_RDO_PROG_VOLTAGE(rdo) ((rdo) >> 9 & 0x7FF)
310#define PD_RDO_PROG_CURR(rdo) ((rdo) & 0x7F)
311
312#define PD_SRC_PDO_TYPE(pdo) (((pdo) >> 30) & 3)
313#define PD_SRC_PDO_TYPE_FIXED 0
314#define PD_SRC_PDO_TYPE_BATTERY 1
315#define PD_SRC_PDO_TYPE_VARIABLE 2
316#define PD_SRC_PDO_TYPE_AUGMENTED 3
317
318#define PD_SRC_PDO_FIXED_PR_SWAP(pdo) (((pdo) >> 29) & 1)
319#define PD_SRC_PDO_FIXED_USB_SUSP(pdo) (((pdo) >> 28) & 1)
320#define PD_SRC_PDO_FIXED_EXT_POWERED(pdo) (((pdo) >> 27) & 1)
321#define PD_SRC_PDO_FIXED_USB_COMM(pdo) (((pdo) >> 26) & 1)
322#define PD_SRC_PDO_FIXED_DR_SWAP(pdo) (((pdo) >> 25) & 1)
323#define PD_SRC_PDO_FIXED_PEAK_CURR(pdo) (((pdo) >> 20) & 3)
324#define PD_SRC_PDO_FIXED_VOLTAGE(pdo) (((pdo) >> 10) & 0x3FF)
325#define PD_SRC_PDO_FIXED_MAX_CURR(pdo) ((pdo) & 0x3FF)
326
327#define PD_SRC_PDO_VAR_BATT_MAX_VOLT(pdo) (((pdo) >> 20) & 0x3FF)
328#define PD_SRC_PDO_VAR_BATT_MIN_VOLT(pdo) (((pdo) >> 10) & 0x3FF)
329#define PD_SRC_PDO_VAR_BATT_MAX(pdo) ((pdo) & 0x3FF)
330
331#define PD_APDO_PPS(pdo) (((pdo) >> 28) & 3)
332#define PD_APDO_MAX_VOLT(pdo) (((pdo) >> 17) & 0xFF)
333#define PD_APDO_MIN_VOLT(pdo) (((pdo) >> 8) & 0xFF)
334#define PD_APDO_MAX_CURR(pdo) ((pdo) & 0x7F)
335
336/* Vendor Defined Messages */
337#define MAX_CRC_RECEIVE_TIME 9 /* ~(2 * tReceive_max(1.1ms) * # retry 4) */
338#define MAX_VDM_RESPONSE_TIME 60 /* 2 * tVDMSenderResponse_max(30ms) */
339#define MAX_VDM_BUSY_TIME 100 /* 2 * tVDMBusy (50ms) */
340
Jack Phamee1f9052017-01-26 12:27:07 -0800341#define PD_SNK_PDO_FIXED(prs, hc, uc, usb_comm, drs, volt, curr) \
342 (((prs) << 29) | ((hc) << 28) | ((uc) << 27) | ((usb_comm) << 26) | \
343 ((drs) << 25) | ((volt) << 10) | (curr))
344
Jack Phamf4baeb12017-02-03 19:01:48 -0800345/* VDM header is the first 32-bit object following the 16-bit PD header */
346#define VDM_HDR_SVID(hdr) ((hdr) >> 16)
347#define VDM_IS_SVDM(hdr) ((hdr) & 0x8000)
348#define SVDM_HDR_OBJ_POS(hdr) (((hdr) >> 8) & 0x7)
349#define SVDM_HDR_CMD_TYPE(hdr) (((hdr) >> 6) & 0x3)
350#define SVDM_HDR_CMD(hdr) ((hdr) & 0x1f)
351
352#define SVDM_HDR(svid, ver, obj, cmd_type, cmd) \
353 (((svid) << 16) | (1 << 15) | ((ver) << 13) \
354 | ((obj) << 8) | ((cmd_type) << 6) | (cmd))
355
356/* discover id response vdo bit fields */
357#define ID_HDR_USB_HOST BIT(31)
358#define ID_HDR_USB_DEVICE BIT(30)
359#define ID_HDR_MODAL_OPR BIT(26)
360#define ID_HDR_PRODUCT_TYPE(n) ((n) >> 27)
361#define ID_HDR_PRODUCT_PER_MASK (2 << 27)
362#define ID_HDR_PRODUCT_HUB 1
363#define ID_HDR_PRODUCT_PER 2
364#define ID_HDR_PRODUCT_AMA 5
365#define ID_HDR_VID 0x05c6 /* qcom */
366#define PROD_VDO_PID 0x0a00 /* TBD */
367
368static bool check_vsafe0v = true;
369module_param(check_vsafe0v, bool, 0600);
370
371static int min_sink_current = 900;
372module_param(min_sink_current, int, 0600);
373
374static const u32 default_src_caps[] = { 0x36019096 }; /* VSafe5V @ 1.5A */
Jack Phamee1f9052017-01-26 12:27:07 -0800375static const u32 default_snk_caps[] = { 0x2601912C }; /* VSafe5V @ 3A */
Jack Phamf4baeb12017-02-03 19:01:48 -0800376
377struct vdm_tx {
Jack Phamf3c1bd32017-08-02 18:32:23 -0700378 u32 data[PD_MAX_DATA_OBJ];
Jack Phamf4baeb12017-02-03 19:01:48 -0800379 int size;
380};
381
382struct rx_msg {
Jack Phamf3c1bd32017-08-02 18:32:23 -0700383 u16 hdr;
384 u16 data_len; /* size of payload in bytes */
Jack Phamf4baeb12017-02-03 19:01:48 -0800385 struct list_head entry;
Jack Phamf3c1bd32017-08-02 18:32:23 -0700386 u8 payload[];
Jack Phamf4baeb12017-02-03 19:01:48 -0800387};
388
Jack Phamf3c1bd32017-08-02 18:32:23 -0700389#define IS_DATA(m, t) ((m) && !PD_MSG_HDR_IS_EXTENDED((m)->hdr) && \
390 PD_MSG_HDR_COUNT((m)->hdr) && \
391 (PD_MSG_HDR_TYPE((m)->hdr) == (t)))
392#define IS_CTRL(m, t) ((m) && !PD_MSG_HDR_COUNT((m)->hdr) && \
393 (PD_MSG_HDR_TYPE((m)->hdr) == (t)))
394#define IS_EXT(m, t) ((m) && PD_MSG_HDR_IS_EXTENDED((m)->hdr) && \
395 (PD_MSG_HDR_TYPE((m)->hdr) == (t)))
Jack Phamf4baeb12017-02-03 19:01:48 -0800396
397struct usbpd {
398 struct device dev;
399 struct workqueue_struct *wq;
400 struct work_struct sm_work;
401 struct hrtimer timer;
402 bool sm_queued;
403
404 struct extcon_dev *extcon;
405
406 enum usbpd_state current_state;
407 bool hard_reset_recvd;
Jack Pham4b323282017-11-03 12:24:59 -0700408 ktime_t hard_reset_recvd_time;
Jack Phamf4baeb12017-02-03 19:01:48 -0800409 struct list_head rx_q;
410 spinlock_t rx_lock;
Jack Phamf3c1bd32017-08-02 18:32:23 -0700411 struct rx_msg *rx_ext_msg;
Jack Phamf4baeb12017-02-03 19:01:48 -0800412
Hemant Kumar796534e2017-05-30 15:54:55 -0700413 u32 received_pdos[PD_MAX_DATA_OBJ];
Jack Phamf6c02da2017-01-31 15:23:56 -0800414 u16 src_cap_id;
Jack Phamf4baeb12017-02-03 19:01:48 -0800415 u8 selected_pdo;
416 u8 requested_pdo;
417 u32 rdo; /* can be either source or sink */
418 int current_voltage; /* uV */
419 int requested_voltage; /* uV */
420 int requested_current; /* mA */
421 bool pd_connected;
422 bool in_explicit_contract;
423 bool peer_usb_comm;
424 bool peer_pr_swap;
425 bool peer_dr_swap;
426
Jack Phamee1f9052017-01-26 12:27:07 -0800427 u32 sink_caps[7];
428 int num_sink_caps;
429
Jack Phamf4baeb12017-02-03 19:01:48 -0800430 struct power_supply *usb_psy;
431 struct notifier_block psy_nb;
432
433 enum power_supply_typec_mode typec_mode;
434 enum power_supply_type psy_type;
435 enum power_supply_typec_power_role forced_pr;
436 bool vbus_present;
437
438 enum pd_spec_rev spec_rev;
439 enum data_role current_dr;
440 enum power_role current_pr;
441 bool in_pr_swap;
442 bool pd_phy_opened;
Jack Phamaf7d3842017-01-26 13:28:19 -0800443 bool send_request;
444 struct completion is_ready;
Jack Phamf3c1bd32017-08-02 18:32:23 -0700445 struct completion tx_chunk_request;
446 u8 next_tx_chunk;
Jack Phamf4baeb12017-02-03 19:01:48 -0800447
Jack Phamaf7d3842017-01-26 13:28:19 -0800448 struct mutex swap_lock;
Jack Phamf4baeb12017-02-03 19:01:48 -0800449 struct dual_role_phy_instance *dual_role;
450 struct dual_role_phy_desc dr_desc;
451 bool send_pr_swap;
452 bool send_dr_swap;
453
454 struct regulator *vbus;
455 struct regulator *vconn;
456 bool vbus_enabled;
457 bool vconn_enabled;
458 bool vconn_is_external;
459
460 u8 tx_msgid;
461 u8 rx_msgid;
462 int caps_count;
463 int hard_reset_count;
464
465 enum vdm_state vdm_state;
466 u16 *discovered_svids;
467 int num_svids;
468 struct vdm_tx *vdm_tx;
469 struct vdm_tx *vdm_tx_retry;
Mayank Rana83443202017-08-31 15:38:03 -0700470 struct mutex svid_handler_lock;
Jack Phamf4baeb12017-02-03 19:01:48 -0800471 struct list_head svid_handlers;
472
473 struct list_head instance;
Mayank Rana6af43422017-07-18 12:09:02 -0700474
Liangliang Lu7e9fffa2018-06-26 12:45:14 +0800475 bool has_dp;
Mayank Rana6af43422017-07-18 12:09:02 -0700476 u16 ss_lane_svid;
Hemant Kumar018b5982017-08-09 14:14:37 -0700477
478 /* ext msg support */
479 bool send_get_src_cap_ext;
480 u8 src_cap_ext_db[PD_SRC_CAP_EXT_DB_LEN];
481 bool send_get_pps_status;
482 u32 pps_status_db;
Jack Phamda401d72018-06-07 19:29:52 -0700483 bool send_get_status;
Hemant Kumara1875942017-08-09 16:50:14 -0700484 u8 status_db[PD_STATUS_DB_LEN];
Hemant Kumar51ded972017-08-09 17:57:24 -0700485 bool send_get_battery_cap;
486 u8 get_battery_cap_db;
487 u8 battery_cap_db[PD_BATTERY_CAP_DB_LEN];
488 u8 get_battery_status_db;
489 bool send_get_battery_status;
490 u32 battery_sts_dobj;
Jack Phamf4baeb12017-02-03 19:01:48 -0800491};
492
493static LIST_HEAD(_usbpd); /* useful for debugging */
494
495static const unsigned int usbpd_extcon_cable[] = {
496 EXTCON_USB,
497 EXTCON_USB_HOST,
Liangliang Lu7e9fffa2018-06-26 12:45:14 +0800498 EXTCON_DISP_DP,
Jack Phamf4baeb12017-02-03 19:01:48 -0800499 EXTCON_NONE,
500};
501
502/* EXTCON_USB and EXTCON_USB_HOST are mutually exclusive */
503static const u32 usbpd_extcon_exclusive[] = {0x3, 0};
504
505enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd)
506{
507 int ret;
508 union power_supply_propval val;
509
510 ret = power_supply_get_property(pd->usb_psy,
511 POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION, &val);
512 if (ret)
513 return ORIENTATION_NONE;
514
515 return val.intval;
516}
517EXPORT_SYMBOL(usbpd_get_plug_orientation);
518
Pratham Pratap033a2d92017-11-14 20:57:05 +0530519static unsigned int get_connector_type(struct usbpd *pd)
520{
521 int ret;
522 union power_supply_propval val;
523
524 ret = power_supply_get_property(pd->usb_psy,
525 POWER_SUPPLY_PROP_CONNECTOR_TYPE, &val);
526
527 if (ret) {
528 dev_err(&pd->dev, "Unable to read CONNECTOR TYPE: %d\n", ret);
529 return ret;
530 }
531 return val.intval;
532}
533
Jack Phamf4baeb12017-02-03 19:01:48 -0800534static inline void stop_usb_host(struct usbpd *pd)
535{
Jack Pham4e9dff72017-04-04 18:05:53 -0700536 extcon_set_state_sync(pd->extcon, EXTCON_USB_HOST, 0);
Jack Phamf4baeb12017-02-03 19:01:48 -0800537}
538
539static inline void start_usb_host(struct usbpd *pd, bool ss)
540{
541 enum plug_orientation cc = usbpd_get_plug_orientation(pd);
Jack Pham4e9dff72017-04-04 18:05:53 -0700542 union extcon_property_value val;
Jack Phamf4baeb12017-02-03 19:01:48 -0800543
Jack Pham4e9dff72017-04-04 18:05:53 -0700544 val.intval = (cc == ORIENTATION_CC2);
545 extcon_set_property(pd->extcon, EXTCON_USB_HOST,
546 EXTCON_PROP_USB_TYPEC_POLARITY, val);
547
548 val.intval = ss;
549 extcon_set_property(pd->extcon, EXTCON_USB_HOST,
550 EXTCON_PROP_USB_SS, val);
551
552 extcon_set_state_sync(pd->extcon, EXTCON_USB_HOST, 1);
Jack Phamf4baeb12017-02-03 19:01:48 -0800553}
554
555static inline void stop_usb_peripheral(struct usbpd *pd)
556{
Jack Pham4e9dff72017-04-04 18:05:53 -0700557 extcon_set_state_sync(pd->extcon, EXTCON_USB, 0);
Jack Phamf4baeb12017-02-03 19:01:48 -0800558}
559
560static inline void start_usb_peripheral(struct usbpd *pd)
561{
562 enum plug_orientation cc = usbpd_get_plug_orientation(pd);
Jack Pham4e9dff72017-04-04 18:05:53 -0700563 union extcon_property_value val;
Jack Phamf4baeb12017-02-03 19:01:48 -0800564
Jack Pham4e9dff72017-04-04 18:05:53 -0700565 val.intval = (cc == ORIENTATION_CC2);
566 extcon_set_property(pd->extcon, EXTCON_USB,
567 EXTCON_PROP_USB_TYPEC_POLARITY, val);
568
569 val.intval = 1;
570 extcon_set_property(pd->extcon, EXTCON_USB, EXTCON_PROP_USB_SS, val);
571
Vijayavardhan Vennapusa79cdf0a2018-08-17 15:37:13 +0530572 val.intval =
573 pd->typec_mode > POWER_SUPPLY_TYPEC_SOURCE_DEFAULT ? 1 : 0;
Vijayavardhan Vennapusadaeb5ac2018-07-13 13:04:17 +0530574 extcon_set_property(pd->extcon, EXTCON_USB,
575 EXTCON_PROP_USB_PD_CONTRACT, val);
Vijayavardhan Vennapusa79cdf0a2018-08-17 15:37:13 +0530576 extcon_set_state_sync(pd->extcon, EXTCON_USB, 1);
Vijayavardhan Vennapusadaeb5ac2018-07-13 13:04:17 +0530577}
578
Mayank Rana6af43422017-07-18 12:09:02 -0700579/**
580 * This API allows client driver to request for releasing SS lanes. It should
581 * not be called from atomic context.
582 *
583 * @pd - USBPD handler
584 * @hdlr - client's handler
585 *
586 * @returns int - Success - 0, else negative error code
587 */
588static int usbpd_release_ss_lane(struct usbpd *pd,
589 struct usbpd_svid_handler *hdlr)
590{
591 int ret = 0;
592
593 if (!hdlr || !pd)
594 return -EINVAL;
595
596 usbpd_dbg(&pd->dev, "hdlr:%pK svid:%d", hdlr, hdlr->svid);
597 /*
598 * If USB SS lanes are already used by one client, and other client is
599 * requesting for same or same client requesting again, return -EBUSY.
600 */
601 if (pd->ss_lane_svid) {
602 usbpd_dbg(&pd->dev, "-EBUSY: ss_lanes are already used by(%d)",
603 pd->ss_lane_svid);
604 ret = -EBUSY;
605 goto err_exit;
606 }
607
608 ret = extcon_blocking_sync(pd->extcon, EXTCON_USB_HOST, 0);
609 if (ret) {
610 usbpd_err(&pd->dev, "err(%d) for releasing ss lane", ret);
611 goto err_exit;
612 }
613
614 pd->ss_lane_svid = hdlr->svid;
615
Liangliang Lu7e9fffa2018-06-26 12:45:14 +0800616 /* DP 4 Lane mode */
617 ret = extcon_blocking_sync(pd->extcon, EXTCON_DISP_DP, 4);
618 if (ret) {
619 usbpd_err(&pd->dev, "err(%d) for notify DP 4 Lane", ret);
620 goto err_exit;
621 }
622
Mayank Rana6af43422017-07-18 12:09:02 -0700623err_exit:
624 return ret;
625}
626
Jack Phamf4baeb12017-02-03 19:01:48 -0800627static int set_power_role(struct usbpd *pd, enum power_role pr)
628{
629 union power_supply_propval val = {0};
630
631 switch (pr) {
632 case PR_NONE:
633 val.intval = POWER_SUPPLY_TYPEC_PR_NONE;
634 break;
635 case PR_SINK:
636 val.intval = POWER_SUPPLY_TYPEC_PR_SINK;
637 break;
638 case PR_SRC:
639 val.intval = POWER_SUPPLY_TYPEC_PR_SOURCE;
640 break;
641 }
642
643 return power_supply_set_property(pd->usb_psy,
644 POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &val);
645}
646
647static struct usbpd_svid_handler *find_svid_handler(struct usbpd *pd, u16 svid)
648{
649 struct usbpd_svid_handler *handler;
650
Mayank Rana83443202017-08-31 15:38:03 -0700651 mutex_lock(&pd->svid_handler_lock);
652 list_for_each_entry(handler, &pd->svid_handlers, entry) {
653 if (svid == handler->svid) {
654 mutex_unlock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -0800655 return handler;
Mayank Rana83443202017-08-31 15:38:03 -0700656 }
657 }
Jack Phamf4baeb12017-02-03 19:01:48 -0800658
Mayank Rana83443202017-08-31 15:38:03 -0700659 mutex_unlock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -0800660 return NULL;
661}
662
663/* Reset protocol layer */
664static inline void pd_reset_protocol(struct usbpd *pd)
665{
666 /*
667 * first Rx ID should be 0; set this to a sentinel of -1 so that in
668 * phy_msg_received() we can check if we had seen it before.
669 */
670 pd->rx_msgid = -1;
671 pd->tx_msgid = 0;
Jack Phamaf7d3842017-01-26 13:28:19 -0800672 pd->send_request = false;
673 pd->send_pr_swap = false;
674 pd->send_dr_swap = false;
Jack Phamf4baeb12017-02-03 19:01:48 -0800675}
676
Jack Phame95cfc72017-08-01 17:36:50 -0700677static int pd_send_msg(struct usbpd *pd, u8 msg_type, const u32 *data,
678 size_t num_data, enum pd_sop_type sop)
Jack Phamf4baeb12017-02-03 19:01:48 -0800679{
680 int ret;
681 u16 hdr;
682
Jack Pham4b323282017-11-03 12:24:59 -0700683 if (pd->hard_reset_recvd)
684 return -EBUSY;
685
Jack Phame95cfc72017-08-01 17:36:50 -0700686 hdr = PD_MSG_HDR(msg_type, pd->current_dr, pd->current_pr,
Jack Phamf4baeb12017-02-03 19:01:48 -0800687 pd->tx_msgid, num_data, pd->spec_rev);
Jack Phamf4baeb12017-02-03 19:01:48 -0800688
Jack Pham7dfd7612017-08-01 18:04:13 -0700689 ret = pd_phy_write(hdr, (u8 *)data, num_data * sizeof(u32), sop);
Jack Pham722527a2018-06-28 23:17:17 -0700690 if (ret) {
691 usbpd_err(&pd->dev, "Error sending %s: %d\n",
692 msg_to_string(msg_type, num_data, false),
693 ret);
Jack Phamf4baeb12017-02-03 19:01:48 -0800694 return ret;
Jack Pham722527a2018-06-28 23:17:17 -0700695 }
Jack Phamcc119752017-06-07 15:35:57 -0700696
697 pd->tx_msgid = (pd->tx_msgid + 1) & PD_MAX_MSG_ID;
Jack Phamf4baeb12017-02-03 19:01:48 -0800698 return 0;
699}
700
Hemant Kumar51ded972017-08-09 17:57:24 -0700701static int pd_send_ext_msg(struct usbpd *pd, u8 msg_type,
702 const u8 *data, size_t data_len, enum pd_sop_type sop)
703{
704 int ret;
705 size_t len_remain, chunk_len;
706 u8 chunked_payload[PD_MAX_DATA_OBJ * sizeof(u32)] = {0};
707 u16 hdr;
708 u16 ext_hdr;
709 u8 num_objs;
710
711 if (data_len > PD_MAX_EXT_MSG_LEN) {
712 usbpd_warn(&pd->dev, "Extended message length exceeds max, truncating...\n");
713 data_len = PD_MAX_EXT_MSG_LEN;
714 }
715
716 pd->next_tx_chunk = 0;
717 len_remain = data_len;
718 do {
719 ext_hdr = PD_MSG_EXT_HDR(1, pd->next_tx_chunk++, 0, data_len);
720 memcpy(chunked_payload, &ext_hdr, sizeof(ext_hdr));
721
722 chunk_len = min_t(size_t, len_remain,
723 PD_MAX_EXT_MSG_LEGACY_LEN);
724 memcpy(chunked_payload + sizeof(ext_hdr), data, chunk_len);
725
726 num_objs = DIV_ROUND_UP(chunk_len + sizeof(u16), sizeof(u32));
727 len_remain -= chunk_len;
728
729 reinit_completion(&pd->tx_chunk_request);
730 hdr = PD_MSG_HDR(msg_type, pd->current_dr, pd->current_pr,
731 pd->tx_msgid, num_objs, pd->spec_rev) |
732 PD_MSG_HDR_EXTENDED;
733 ret = pd_phy_write(hdr, chunked_payload,
734 num_objs * sizeof(u32), sop);
Jack Pham722527a2018-06-28 23:17:17 -0700735 if (ret) {
736 usbpd_err(&pd->dev, "Error sending %s: %d\n",
737 usbpd_ext_msg_strings[msg_type],
738 ret);
Hemant Kumar51ded972017-08-09 17:57:24 -0700739 return ret;
Jack Pham722527a2018-06-28 23:17:17 -0700740 }
Hemant Kumar51ded972017-08-09 17:57:24 -0700741
742 pd->tx_msgid = (pd->tx_msgid + 1) & PD_MAX_MSG_ID;
743
744 /* Wait for request chunk */
745 if (len_remain &&
746 !wait_for_completion_timeout(&pd->tx_chunk_request,
747 msecs_to_jiffies(SENDER_RESPONSE_TIME))) {
748 usbpd_err(&pd->dev, "Timed out waiting for chunk request\n");
749 return -EPROTO;
750 }
751 } while (len_remain);
752
753 return 0;
754}
755
Jack Phamf4baeb12017-02-03 19:01:48 -0800756static int pd_select_pdo(struct usbpd *pd, int pdo_pos, int uv, int ua)
757{
758 int curr;
759 int max_current;
760 bool mismatch = false;
761 u8 type;
762 u32 pdo = pd->received_pdos[pdo_pos - 1];
763
764 type = PD_SRC_PDO_TYPE(pdo);
765 if (type == PD_SRC_PDO_TYPE_FIXED) {
766 curr = max_current = PD_SRC_PDO_FIXED_MAX_CURR(pdo) * 10;
767
768 /*
769 * Check if the PDO has enough current, otherwise set the
770 * Capability Mismatch flag
771 */
772 if (curr < min_sink_current) {
773 mismatch = true;
774 max_current = min_sink_current;
775 }
776
777 pd->requested_voltage =
778 PD_SRC_PDO_FIXED_VOLTAGE(pdo) * 50 * 1000;
779 pd->rdo = PD_RDO_FIXED(pdo_pos, 0, mismatch, 1, 1, curr / 10,
780 max_current / 10);
781 } else if (type == PD_SRC_PDO_TYPE_AUGMENTED) {
782 if ((uv / 100000) > PD_APDO_MAX_VOLT(pdo) ||
783 (uv / 100000) < PD_APDO_MIN_VOLT(pdo) ||
784 (ua / 50000) > PD_APDO_MAX_CURR(pdo) || (ua < 0)) {
785 usbpd_err(&pd->dev, "uv (%d) and ua (%d) out of range of APDO\n",
786 uv, ua);
787 return -EINVAL;
788 }
789
790 curr = ua / 1000;
791 pd->requested_voltage = uv;
792 pd->rdo = PD_RDO_AUGMENTED(pdo_pos, mismatch, 1, 1,
793 uv / 20000, ua / 50000);
794 } else {
795 usbpd_err(&pd->dev, "Only Fixed or Programmable PDOs supported\n");
796 return -ENOTSUPP;
797 }
798
799 /* Can't sink more than 5V if VCONN is sourced from the VBUS input */
800 if (pd->vconn_enabled && !pd->vconn_is_external &&
801 pd->requested_voltage > 5000000)
802 return -ENOTSUPP;
803
804 pd->requested_current = curr;
805 pd->requested_pdo = pdo_pos;
806
807 return 0;
808}
809
810static int pd_eval_src_caps(struct usbpd *pd)
811{
Hemant Kumarbe746222017-07-20 13:51:49 -0700812 int i;
Jack Phamf4baeb12017-02-03 19:01:48 -0800813 union power_supply_propval val;
Jack Pham9660be92018-04-03 16:06:40 -0700814 bool pps_found = false;
Jack Phamf4baeb12017-02-03 19:01:48 -0800815 u32 first_pdo = pd->received_pdos[0];
816
817 if (PD_SRC_PDO_TYPE(first_pdo) != PD_SRC_PDO_TYPE_FIXED) {
818 usbpd_err(&pd->dev, "First src_cap invalid! %08x\n", first_pdo);
819 return -EINVAL;
820 }
821
822 pd->peer_usb_comm = PD_SRC_PDO_FIXED_USB_COMM(first_pdo);
823 pd->peer_pr_swap = PD_SRC_PDO_FIXED_PR_SWAP(first_pdo);
824 pd->peer_dr_swap = PD_SRC_PDO_FIXED_DR_SWAP(first_pdo);
825
826 val.intval = PD_SRC_PDO_FIXED_USB_SUSP(first_pdo);
827 power_supply_set_property(pd->usb_psy,
828 POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED, &val);
829
Jack Pham9660be92018-04-03 16:06:40 -0700830 /* Check for PPS APDOs */
831 if (pd->spec_rev == USBPD_REV_30) {
Hemant Kumarbe746222017-07-20 13:51:49 -0700832 for (i = 1; i < PD_MAX_DATA_OBJ; i++) {
833 if ((PD_SRC_PDO_TYPE(pd->received_pdos[i]) ==
Hemant Kumar796534e2017-05-30 15:54:55 -0700834 PD_SRC_PDO_TYPE_AUGMENTED) &&
Hemant Kumarbe746222017-07-20 13:51:49 -0700835 !PD_APDO_PPS(pd->received_pdos[i])) {
836 pps_found = true;
837 break;
838 }
839 }
Jack Pham9660be92018-04-03 16:06:40 -0700840
841 /* downgrade to 2.0 if no PPS */
842 if (!pps_found && !rev3_sink_only)
Hemant Kumarbe746222017-07-20 13:51:49 -0700843 pd->spec_rev = USBPD_REV_20;
Hemant Kumar796534e2017-05-30 15:54:55 -0700844 }
845
Jack Pham9660be92018-04-03 16:06:40 -0700846 val.intval = pps_found ?
847 POWER_SUPPLY_PD_PPS_ACTIVE :
848 POWER_SUPPLY_PD_ACTIVE;
849 power_supply_set_property(pd->usb_psy,
850 POWER_SUPPLY_PROP_PD_ACTIVE, &val);
851
Jack Phamf4baeb12017-02-03 19:01:48 -0800852 /* Select the first PDO (vSafe5V) immediately. */
853 pd_select_pdo(pd, 1, 0, 0);
854
855 return 0;
856}
857
858static void pd_send_hard_reset(struct usbpd *pd)
859{
Jack Pham857ee682017-05-25 11:53:36 -0700860 union power_supply_propval val = {0};
861
Jack Phamf4baeb12017-02-03 19:01:48 -0800862 usbpd_dbg(&pd->dev, "send hard reset");
863
864 /* Force CC logic to source/sink to keep Rp/Rd unchanged */
865 set_power_role(pd, pd->current_pr);
866 pd->hard_reset_count++;
Jack Pham7dfd7612017-08-01 18:04:13 -0700867 pd_phy_signal(HARD_RESET_SIG);
Jack Phamf4baeb12017-02-03 19:01:48 -0800868 pd->in_pr_swap = false;
Jack Pham857ee682017-05-25 11:53:36 -0700869 power_supply_set_property(pd->usb_psy, POWER_SUPPLY_PROP_PR_SWAP, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -0800870}
871
872static void kick_sm(struct usbpd *pd, int ms)
873{
874 pm_stay_awake(&pd->dev);
875 pd->sm_queued = true;
876
877 if (ms)
878 hrtimer_start(&pd->timer, ms_to_ktime(ms), HRTIMER_MODE_REL);
879 else
880 queue_work(pd->wq, &pd->sm_work);
881}
882
Jack Phame95cfc72017-08-01 17:36:50 -0700883static void phy_sig_received(struct usbpd *pd, enum pd_sig_type sig)
Jack Phamf4baeb12017-02-03 19:01:48 -0800884{
Jack Pham9411cbb2017-06-06 11:10:03 -0700885 union power_supply_propval val = {1};
886
Jack Phame95cfc72017-08-01 17:36:50 -0700887 if (sig != HARD_RESET_SIG) {
888 usbpd_err(&pd->dev, "invalid signal (%d) received\n", sig);
Jack Phamf4baeb12017-02-03 19:01:48 -0800889 return;
890 }
891
Jack Pham4b323282017-11-03 12:24:59 -0700892 pd->hard_reset_recvd = true;
893 pd->hard_reset_recvd_time = ktime_get();
894
895 usbpd_err(&pd->dev, "hard reset received\n");
Jack Phamf4baeb12017-02-03 19:01:48 -0800896
897 /* Force CC logic to source/sink to keep Rp/Rd unchanged */
898 set_power_role(pd, pd->current_pr);
Jack Pham9411cbb2017-06-06 11:10:03 -0700899 power_supply_set_property(pd->usb_psy,
900 POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val);
901
Jack Phamf4baeb12017-02-03 19:01:48 -0800902 kick_sm(pd, 0);
903}
904
Jack Phamf3c1bd32017-08-02 18:32:23 -0700905struct pd_request_chunk {
906 struct work_struct w;
907 struct usbpd *pd;
908 u8 msg_type;
909 u8 chunk_num;
910 enum pd_sop_type sop;
911};
912
913static void pd_request_chunk_work(struct work_struct *w)
914{
915 struct pd_request_chunk *req =
916 container_of(w, struct pd_request_chunk, w);
917 struct usbpd *pd = req->pd;
918 unsigned long flags;
919 int ret;
920 u8 payload[4] = {0}; /* ext_hdr + padding */
921 u16 hdr = PD_MSG_HDR(req->msg_type, pd->current_dr, pd->current_pr,
922 pd->tx_msgid, 1, pd->spec_rev) | PD_MSG_HDR_EXTENDED;
923
924 *(u16 *)payload = PD_MSG_EXT_HDR(1, req->chunk_num, 1, 0);
925
926 ret = pd_phy_write(hdr, payload, sizeof(payload), req->sop);
927 if (!ret) {
928 pd->tx_msgid = (pd->tx_msgid + 1) & PD_MAX_MSG_ID;
929 } else {
930 usbpd_err(&pd->dev, "could not send chunk request\n");
931
932 /* queue what we have anyway */
933 spin_lock_irqsave(&pd->rx_lock, flags);
934 list_add_tail(&pd->rx_ext_msg->entry, &pd->rx_q);
935 spin_unlock_irqrestore(&pd->rx_lock, flags);
936
937 pd->rx_ext_msg = NULL;
938 }
939
940 kfree(req);
941}
942
943static struct rx_msg *pd_ext_msg_received(struct usbpd *pd, u16 header, u8 *buf,
944 size_t len, enum pd_sop_type sop)
945{
946 struct rx_msg *rx_msg;
947 u16 bytes_to_copy;
948 u16 ext_hdr = *(u16 *)buf;
949 u8 chunk_num;
950
951 if (!PD_MSG_EXT_HDR_IS_CHUNKED(ext_hdr)) {
952 usbpd_err(&pd->dev, "unchunked extended messages unsupported\n");
953 return NULL;
954 }
955
956 /* request for next Tx chunk */
957 if (PD_MSG_EXT_HDR_REQ_CHUNK(ext_hdr)) {
958 if (PD_MSG_EXT_HDR_DATA_SIZE(ext_hdr) ||
959 PD_MSG_EXT_HDR_CHUNK_NUM(ext_hdr) !=
960 pd->next_tx_chunk) {
961 usbpd_err(&pd->dev, "invalid request chunk ext header 0x%02x\n",
962 ext_hdr);
963 return NULL;
964 }
965
966 if (!completion_done(&pd->tx_chunk_request))
967 complete(&pd->tx_chunk_request);
968
969 return NULL;
970 }
971
972 chunk_num = PD_MSG_EXT_HDR_CHUNK_NUM(ext_hdr);
973 if (!chunk_num) {
974 /* allocate new message if first chunk */
975 rx_msg = kzalloc(sizeof(*rx_msg) +
976 PD_MSG_EXT_HDR_DATA_SIZE(ext_hdr),
Jack Phama27be8f2017-11-02 10:51:48 -0700977 GFP_ATOMIC);
Jack Phamf3c1bd32017-08-02 18:32:23 -0700978 if (!rx_msg)
979 return NULL;
980
981 rx_msg->hdr = header;
982 rx_msg->data_len = PD_MSG_EXT_HDR_DATA_SIZE(ext_hdr);
983
984 if (rx_msg->data_len > PD_MAX_EXT_MSG_LEN) {
985 usbpd_warn(&pd->dev, "Extended message length exceeds max, truncating...\n");
986 rx_msg->data_len = PD_MAX_EXT_MSG_LEN;
987 }
988 } else {
989 if (!pd->rx_ext_msg) {
990 usbpd_err(&pd->dev, "missing first rx_ext_msg chunk\n");
991 return NULL;
992 }
993
994 rx_msg = pd->rx_ext_msg;
995 }
996
997 /*
998 * The amount to copy is derived as follows:
999 *
1000 * - if extended data_len < 26, then copy data_len bytes
1001 * - for chunks 0..N-2, copy 26 bytes
1002 * - for the last chunk (N-1), copy the remainder
1003 */
1004 bytes_to_copy =
1005 min((rx_msg->data_len - chunk_num * PD_MAX_EXT_MSG_LEGACY_LEN),
1006 PD_MAX_EXT_MSG_LEGACY_LEN);
1007
1008 /* check against received length to avoid overrun */
1009 if (bytes_to_copy > len - sizeof(ext_hdr)) {
Vijayavardhan Vennapusab7ce6542018-05-07 16:59:53 +05301010 usbpd_warn(&pd->dev, "not enough bytes in chunk, expected:%u received:%zu\n",
Jack Phamf3c1bd32017-08-02 18:32:23 -07001011 bytes_to_copy, len - sizeof(ext_hdr));
1012 bytes_to_copy = len - sizeof(ext_hdr);
1013 }
1014
1015 memcpy(rx_msg->payload + chunk_num * PD_MAX_EXT_MSG_LEGACY_LEN, buf + 2,
1016 bytes_to_copy);
1017
1018 /* request next chunk? */
1019 if ((rx_msg->data_len - chunk_num * PD_MAX_EXT_MSG_LEGACY_LEN) >
1020 PD_MAX_EXT_MSG_LEGACY_LEN) {
1021 struct pd_request_chunk *req;
1022
1023 if (pd->rx_ext_msg && pd->rx_ext_msg != rx_msg) {
1024 usbpd_dbg(&pd->dev, "stale previous rx_ext_msg?\n");
1025 kfree(pd->rx_ext_msg);
1026 }
1027
1028 pd->rx_ext_msg = rx_msg;
1029
Jack Phama27be8f2017-11-02 10:51:48 -07001030 req = kzalloc(sizeof(*req), GFP_ATOMIC);
Jack Phamf3c1bd32017-08-02 18:32:23 -07001031 if (!req)
1032 goto queue_rx; /* return what we have anyway */
1033
1034 INIT_WORK(&req->w, pd_request_chunk_work);
1035 req->pd = pd;
1036 req->msg_type = PD_MSG_HDR_TYPE(header);
1037 req->chunk_num = chunk_num + 1;
1038 req->sop = sop;
1039 queue_work(pd->wq, &req->w);
1040
1041 return NULL;
1042 }
1043
1044queue_rx:
1045 pd->rx_ext_msg = NULL;
1046 return rx_msg; /* queue it for usbpd_sm */
1047}
1048
Jack Phame95cfc72017-08-01 17:36:50 -07001049static void phy_msg_received(struct usbpd *pd, enum pd_sop_type sop,
Jack Phamf4baeb12017-02-03 19:01:48 -08001050 u8 *buf, size_t len)
1051{
1052 struct rx_msg *rx_msg;
1053 unsigned long flags;
1054 u16 header;
Jack Pham722527a2018-06-28 23:17:17 -07001055 u8 msg_type, num_objs;
Jack Phamf4baeb12017-02-03 19:01:48 -08001056
Jack Phame95cfc72017-08-01 17:36:50 -07001057 if (sop != SOP_MSG) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001058 usbpd_err(&pd->dev, "invalid msg type (%d) received; only SOP supported\n",
Jack Phame95cfc72017-08-01 17:36:50 -07001059 sop);
Jack Phamf4baeb12017-02-03 19:01:48 -08001060 return;
1061 }
1062
1063 if (len < 2) {
1064 usbpd_err(&pd->dev, "invalid message received, len=%zd\n", len);
1065 return;
1066 }
1067
1068 header = *((u16 *)buf);
1069 buf += sizeof(u16);
1070 len -= sizeof(u16);
1071
1072 if (len % 4 != 0) {
1073 usbpd_err(&pd->dev, "len=%zd not multiple of 4\n", len);
1074 return;
1075 }
1076
1077 /* if MSGID already seen, discard */
1078 if (PD_MSG_HDR_ID(header) == pd->rx_msgid &&
1079 PD_MSG_HDR_TYPE(header) != MSG_SOFT_RESET) {
1080 usbpd_dbg(&pd->dev, "MessageID already seen, discarding\n");
1081 return;
1082 }
1083
1084 pd->rx_msgid = PD_MSG_HDR_ID(header);
1085
1086 /* discard Pings */
1087 if (PD_MSG_HDR_TYPE(header) == MSG_PING && !len)
1088 return;
1089
1090 /* check header's count field to see if it matches len */
1091 if (PD_MSG_HDR_COUNT(header) != (len / 4)) {
1092 usbpd_err(&pd->dev, "header count (%d) mismatch, len=%zd\n",
1093 PD_MSG_HDR_COUNT(header), len);
1094 return;
1095 }
1096
Hemant Kumarbe746222017-07-20 13:51:49 -07001097 /* if spec rev differs (i.e. is older), update PHY */
1098 if (PD_MSG_HDR_REV(header) < pd->spec_rev)
1099 pd->spec_rev = PD_MSG_HDR_REV(header);
1100
Jack Pham722527a2018-06-28 23:17:17 -07001101 msg_type = PD_MSG_HDR_TYPE(header);
1102 num_objs = PD_MSG_HDR_COUNT(header);
1103 usbpd_dbg(&pd->dev, "%s type(%d) num_objs(%d)\n",
1104 msg_to_string(msg_type, num_objs,
1105 PD_MSG_HDR_IS_EXTENDED(header)),
1106 msg_type, num_objs);
Jack Phamf4baeb12017-02-03 19:01:48 -08001107
Jack Phamf3c1bd32017-08-02 18:32:23 -07001108 if (!PD_MSG_HDR_IS_EXTENDED(header)) {
Jack Phama27be8f2017-11-02 10:51:48 -07001109 rx_msg = kzalloc(sizeof(*rx_msg) + len, GFP_ATOMIC);
Jack Phamf3c1bd32017-08-02 18:32:23 -07001110 if (!rx_msg)
1111 return;
1112
1113 rx_msg->hdr = header;
1114 rx_msg->data_len = len;
1115 memcpy(rx_msg->payload, buf, len);
1116 } else {
1117 rx_msg = pd_ext_msg_received(pd, header, buf, len, sop);
1118 if (!rx_msg)
1119 return;
1120 }
Jack Phamf4baeb12017-02-03 19:01:48 -08001121
1122 spin_lock_irqsave(&pd->rx_lock, flags);
1123 list_add_tail(&rx_msg->entry, &pd->rx_q);
1124 spin_unlock_irqrestore(&pd->rx_lock, flags);
1125
Jack Phamf4baeb12017-02-03 19:01:48 -08001126 kick_sm(pd, 0);
1127}
1128
1129static void phy_shutdown(struct usbpd *pd)
1130{
1131 usbpd_dbg(&pd->dev, "shutdown");
Jack Pham0ab02962017-10-12 15:33:50 -07001132
1133 if (pd->vconn_enabled) {
1134 regulator_disable(pd->vconn);
1135 pd->vconn_enabled = false;
1136 }
1137
1138 if (pd->vbus_enabled) {
1139 regulator_disable(pd->vbus);
1140 pd->vbus_enabled = false;
1141 }
Jack Phamf4baeb12017-02-03 19:01:48 -08001142}
1143
1144static enum hrtimer_restart pd_timeout(struct hrtimer *timer)
1145{
1146 struct usbpd *pd = container_of(timer, struct usbpd, timer);
1147
1148 usbpd_dbg(&pd->dev, "timeout");
1149 queue_work(pd->wq, &pd->sm_work);
1150
1151 return HRTIMER_NORESTART;
1152}
1153
Jack Pham8cbf8ea2018-06-28 23:15:11 -07001154static void log_decoded_request(struct usbpd *pd, u32 rdo)
1155{
1156 const u32 *pdos;
1157 int pos = PD_RDO_OBJ_POS(rdo);
1158 int type;
1159
1160 usbpd_dbg(&pd->dev, "RDO: 0x%08x\n", pd->rdo);
1161
1162 if (pd->current_pr == PR_SINK)
1163 pdos = pd->received_pdos;
1164 else
1165 pdos = default_src_caps;
1166
1167 type = PD_SRC_PDO_TYPE(pdos[pos - 1]);
1168
1169 switch (type) {
1170 case PD_SRC_PDO_TYPE_FIXED:
1171 case PD_SRC_PDO_TYPE_VARIABLE:
1172 usbpd_dbg(&pd->dev, "Request Fixed/Variable PDO:%d Volt:%dmV OpCurr:%dmA Curr:%dmA\n",
1173 pos,
1174 PD_SRC_PDO_FIXED_VOLTAGE(pdos[pos - 1]) * 50,
1175 PD_RDO_FIXED_CURR(rdo) * 10,
1176 PD_RDO_FIXED_CURR_MINMAX(rdo) * 10);
1177 break;
1178
1179 case PD_SRC_PDO_TYPE_BATTERY:
1180 usbpd_dbg(&pd->dev, "Request Battery PDO:%d OpPow:%dmW Pow:%dmW\n",
1181 pos,
1182 PD_RDO_FIXED_CURR(rdo) * 250,
1183 PD_RDO_FIXED_CURR_MINMAX(rdo) * 250);
1184 break;
1185
1186 case PD_SRC_PDO_TYPE_AUGMENTED:
1187 usbpd_dbg(&pd->dev, "Request PPS PDO:%d Volt:%dmV Curr:%dmA\n",
1188 pos,
1189 PD_RDO_PROG_VOLTAGE(rdo) * 20,
1190 PD_RDO_PROG_CURR(rdo) * 50);
1191 break;
1192 }
1193}
1194
Jack Phamf4baeb12017-02-03 19:01:48 -08001195/* Enters new state and executes actions on entry */
1196static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
1197{
1198 struct pd_phy_params phy_params = {
1199 .signal_cb = phy_sig_received,
1200 .msg_rx_cb = phy_msg_received,
1201 .shutdown_cb = phy_shutdown,
1202 .frame_filter_val = FRAME_FILTER_EN_SOP |
1203 FRAME_FILTER_EN_HARD_RESET,
Jack Phamf4baeb12017-02-03 19:01:48 -08001204 };
1205 union power_supply_propval val = {0};
1206 unsigned long flags;
1207 int ret;
1208
Jack Pham4b323282017-11-03 12:24:59 -07001209 if (pd->hard_reset_recvd) /* let usbpd_sm handle it */
1210 return;
1211
Jack Phamf4baeb12017-02-03 19:01:48 -08001212 usbpd_dbg(&pd->dev, "%s -> %s\n",
1213 usbpd_state_strings[pd->current_state],
1214 usbpd_state_strings[next_state]);
1215
1216 pd->current_state = next_state;
1217
1218 switch (next_state) {
1219 case PE_ERROR_RECOVERY: /* perform hard disconnect/reconnect */
1220 pd->in_pr_swap = false;
1221 pd->current_pr = PR_NONE;
1222 set_power_role(pd, PR_NONE);
1223 pd->typec_mode = POWER_SUPPLY_TYPEC_NONE;
1224 kick_sm(pd, 0);
1225 break;
1226
1227 /* Source states */
Jack Phamb9200bb2017-04-19 00:25:32 -07001228 case PE_SRC_DISABLED:
1229 /* are we still connected? */
1230 if (pd->typec_mode == POWER_SUPPLY_TYPEC_NONE) {
1231 pd->current_pr = PR_NONE;
1232 kick_sm(pd, 0);
1233 }
1234
1235 break;
1236
Jack Phamf4baeb12017-02-03 19:01:48 -08001237 case PE_SRC_STARTUP:
1238 if (pd->current_dr == DR_NONE) {
1239 pd->current_dr = DR_DFP;
Mayank Rana38e9b252017-03-23 12:35:57 -07001240 start_usb_host(pd, true);
Mayank Rana6af43422017-07-18 12:09:02 -07001241 pd->ss_lane_svid = 0x0;
Jack Phamf4baeb12017-02-03 19:01:48 -08001242 }
1243
1244 dual_role_instance_changed(pd->dual_role);
1245
1246 /* Set CC back to DRP toggle for the next disconnect */
1247 val.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
1248 power_supply_set_property(pd->usb_psy,
1249 POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &val);
1250
Hemant Kumarbe746222017-07-20 13:51:49 -07001251 /* support only PD 2.0 as a source */
1252 pd->spec_rev = USBPD_REV_20;
Jack Phamf4baeb12017-02-03 19:01:48 -08001253 pd_reset_protocol(pd);
1254
1255 if (!pd->in_pr_swap) {
1256 if (pd->pd_phy_opened) {
1257 pd_phy_close();
1258 pd->pd_phy_opened = false;
1259 }
1260
1261 phy_params.data_role = pd->current_dr;
1262 phy_params.power_role = pd->current_pr;
Jack Phamf4baeb12017-02-03 19:01:48 -08001263
1264 ret = pd_phy_open(&phy_params);
1265 if (ret) {
1266 WARN_ON_ONCE(1);
1267 usbpd_err(&pd->dev, "error opening PD PHY %d\n",
1268 ret);
1269 pd->current_state = PE_UNKNOWN;
1270 return;
1271 }
1272
1273 pd->pd_phy_opened = true;
Jack Phamf4baeb12017-02-03 19:01:48 -08001274 }
1275
Jack Phamf4baeb12017-02-03 19:01:48 -08001276 if (pd->in_pr_swap) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001277 pd->in_pr_swap = false;
Jack Pham857ee682017-05-25 11:53:36 -07001278 val.intval = 0;
1279 power_supply_set_property(pd->usb_psy,
1280 POWER_SUPPLY_PROP_PR_SWAP, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08001281 }
1282
Jack Pham35121342017-07-06 00:12:15 -07001283 /*
1284 * A sink might remove its terminations (during some Type-C
1285 * compliance tests or a sink attempting to do Try.SRC)
1286 * at this point just after we enabled VBUS. Sending PD
1287 * messages now would delay detecting the detach beyond the
1288 * required timing. Instead, delay sending out the first
1289 * source capabilities to allow for the other side to
1290 * completely settle CC debounce and allow HW to detect detach
1291 * sooner in the meantime. PD spec allows up to
1292 * tFirstSourceCap (250ms).
1293 */
1294 pd->current_state = PE_SRC_SEND_CAPABILITIES;
1295 kick_sm(pd, FIRST_SOURCE_CAP_TIME);
1296 break;
Jack Phamf4baeb12017-02-03 19:01:48 -08001297
1298 case PE_SRC_SEND_CAPABILITIES:
1299 kick_sm(pd, 0);
1300 break;
1301
1302 case PE_SRC_NEGOTIATE_CAPABILITY:
Jack Pham8cbf8ea2018-06-28 23:15:11 -07001303 log_decoded_request(pd, pd->rdo);
1304
Jack Phamf4baeb12017-02-03 19:01:48 -08001305 if (PD_RDO_OBJ_POS(pd->rdo) != 1 ||
1306 PD_RDO_FIXED_CURR(pd->rdo) >
1307 PD_SRC_PDO_FIXED_MAX_CURR(*default_src_caps) ||
1308 PD_RDO_FIXED_CURR_MINMAX(pd->rdo) >
1309 PD_SRC_PDO_FIXED_MAX_CURR(*default_src_caps)) {
1310 /* send Reject */
1311 ret = pd_send_msg(pd, MSG_REJECT, NULL, 0, SOP_MSG);
1312 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001313 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
1314 break;
1315 }
1316
1317 usbpd_err(&pd->dev, "Invalid request: %08x\n", pd->rdo);
1318
1319 if (pd->in_explicit_contract)
1320 usbpd_set_state(pd, PE_SRC_READY);
1321 else
1322 /*
1323 * bypass PE_SRC_Capability_Response and
1324 * PE_SRC_Wait_New_Capabilities in this
1325 * implementation for simplicity.
1326 */
1327 usbpd_set_state(pd, PE_SRC_SEND_CAPABILITIES);
1328 break;
1329 }
1330
1331 /* PE_SRC_TRANSITION_SUPPLY pseudo-state */
1332 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
1333 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001334 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
1335 break;
1336 }
1337
1338 /* tSrcTransition required after ACCEPT */
1339 usleep_range(SRC_TRANSITION_TIME * USEC_PER_MSEC,
1340 (SRC_TRANSITION_TIME + 5) * USEC_PER_MSEC);
1341
1342 /*
1343 * Normally a voltage change should occur within tSrcReady
1344 * but since we only support VSafe5V there is nothing more to
1345 * prepare from the power supply so send PS_RDY right away.
1346 */
1347 ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG);
1348 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001349 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
1350 break;
1351 }
1352
1353 usbpd_set_state(pd, PE_SRC_READY);
1354 break;
1355
1356 case PE_SRC_READY:
1357 pd->in_explicit_contract = true;
Jack Phambe0f20c2017-10-05 12:51:26 -07001358
1359 if (pd->vdm_tx)
1360 kick_sm(pd, 0);
1361 else if (pd->current_dr == DR_DFP && pd->vdm_state == VDM_NONE)
1362 usbpd_send_svdm(pd, USBPD_SID,
1363 USBPD_SVDM_DISCOVER_IDENTITY,
1364 SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0);
Jack Phamf4baeb12017-02-03 19:01:48 -08001365
1366 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
Jack Phamaf7d3842017-01-26 13:28:19 -08001367 complete(&pd->is_ready);
Jack Phamf4baeb12017-02-03 19:01:48 -08001368 dual_role_instance_changed(pd->dual_role);
1369 break;
1370
1371 case PE_SRC_HARD_RESET:
1372 case PE_SNK_HARD_RESET:
Jack Phamb9200bb2017-04-19 00:25:32 -07001373 /* are we still connected? */
1374 if (pd->typec_mode == POWER_SUPPLY_TYPEC_NONE)
1375 pd->current_pr = PR_NONE;
1376
Jack Phamf4baeb12017-02-03 19:01:48 -08001377 /* hard reset may sleep; handle it in the workqueue */
1378 kick_sm(pd, 0);
1379 break;
1380
1381 case PE_SRC_SEND_SOFT_RESET:
1382 case PE_SNK_SEND_SOFT_RESET:
1383 pd_reset_protocol(pd);
1384
1385 ret = pd_send_msg(pd, MSG_SOFT_RESET, NULL, 0, SOP_MSG);
1386 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001387 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
1388 PE_SRC_HARD_RESET : PE_SNK_HARD_RESET);
1389 break;
1390 }
1391
1392 /* wait for ACCEPT */
1393 kick_sm(pd, SENDER_RESPONSE_TIME);
1394 break;
1395
1396 /* Sink states */
1397 case PE_SNK_STARTUP:
1398 if (pd->current_dr == DR_NONE || pd->current_dr == DR_UFP) {
1399 pd->current_dr = DR_UFP;
1400
1401 if (pd->psy_type == POWER_SUPPLY_TYPE_USB ||
Vijayavardhan Vennapusa34a1f1d2017-05-31 12:00:37 +05301402 pd->psy_type == POWER_SUPPLY_TYPE_USB_CDP ||
Hemant Kumarbbf7d052017-07-13 12:08:49 -07001403 pd->psy_type == POWER_SUPPLY_TYPE_USB_FLOAT ||
Vijayavardhan Vennapusa34a1f1d2017-05-31 12:00:37 +05301404 usb_compliance_mode)
Jack Phamf4baeb12017-02-03 19:01:48 -08001405 start_usb_peripheral(pd);
1406 }
1407
1408 dual_role_instance_changed(pd->dual_role);
1409
1410 ret = power_supply_get_property(pd->usb_psy,
1411 POWER_SUPPLY_PROP_PD_ALLOWED, &val);
1412 if (ret) {
1413 usbpd_err(&pd->dev, "Unable to read USB PROP_PD_ALLOWED: %d\n",
1414 ret);
1415 break;
1416 }
1417
Vijayavardhan Vennapusa49f21ce2017-06-05 14:47:56 +05301418 if (!val.intval || disable_usb_pd)
Jack Phamf4baeb12017-02-03 19:01:48 -08001419 break;
1420
Hemant Kumarbe746222017-07-20 13:51:49 -07001421 /*
1422 * support up to PD 3.0 as a sink; if source is 2.0
1423 * phy_msg_received() will handle the downgrade.
1424 */
1425 pd->spec_rev = USBPD_REV_30;
Jack Phamf4baeb12017-02-03 19:01:48 -08001426 pd_reset_protocol(pd);
1427
1428 if (!pd->in_pr_swap) {
1429 if (pd->pd_phy_opened) {
1430 pd_phy_close();
1431 pd->pd_phy_opened = false;
1432 }
1433
1434 phy_params.data_role = pd->current_dr;
1435 phy_params.power_role = pd->current_pr;
Jack Phamf4baeb12017-02-03 19:01:48 -08001436
1437 ret = pd_phy_open(&phy_params);
1438 if (ret) {
1439 WARN_ON_ONCE(1);
1440 usbpd_err(&pd->dev, "error opening PD PHY %d\n",
1441 ret);
1442 pd->current_state = PE_UNKNOWN;
1443 return;
1444 }
1445
1446 pd->pd_phy_opened = true;
Jack Phamf4baeb12017-02-03 19:01:48 -08001447 }
1448
1449 pd->current_voltage = pd->requested_voltage = 5000000;
1450 val.intval = pd->requested_voltage; /* set max range to 5V */
1451 power_supply_set_property(pd->usb_psy,
Nicholas Troast7f55c922017-07-25 13:18:03 -07001452 POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08001453
1454 if (!pd->vbus_present) {
1455 pd->current_state = PE_SNK_DISCOVERY;
1456 /* max time for hard reset to turn vbus back on */
1457 kick_sm(pd, SNK_HARD_RESET_VBUS_ON_TIME);
1458 break;
1459 }
1460
1461 pd->current_state = PE_SNK_WAIT_FOR_CAPABILITIES;
1462 /* fall-through */
1463
1464 case PE_SNK_WAIT_FOR_CAPABILITIES:
1465 spin_lock_irqsave(&pd->rx_lock, flags);
1466 if (list_empty(&pd->rx_q))
1467 kick_sm(pd, SINK_WAIT_CAP_TIME);
1468 spin_unlock_irqrestore(&pd->rx_lock, flags);
1469 break;
1470
1471 case PE_SNK_EVALUATE_CAPABILITY:
1472 pd->pd_connected = true; /* we know peer is PD capable */
1473 pd->hard_reset_count = 0;
1474
1475 /* evaluate PDOs and select one */
1476 ret = pd_eval_src_caps(pd);
1477 if (ret < 0) {
1478 usbpd_err(&pd->dev, "Invalid src_caps received. Skipping request\n");
1479 break;
1480 }
1481 pd->current_state = PE_SNK_SELECT_CAPABILITY;
1482 /* fall-through */
1483
1484 case PE_SNK_SELECT_CAPABILITY:
Jack Pham8cbf8ea2018-06-28 23:15:11 -07001485 log_decoded_request(pd, pd->rdo);
1486
Jack Phamf4baeb12017-02-03 19:01:48 -08001487 ret = pd_send_msg(pd, MSG_REQUEST, &pd->rdo, 1, SOP_MSG);
1488 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001489 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
1490 break;
1491 }
1492
1493 /* wait for ACCEPT */
1494 kick_sm(pd, SENDER_RESPONSE_TIME);
1495 break;
1496
1497 case PE_SNK_TRANSITION_SINK:
1498 /* wait for PS_RDY */
1499 kick_sm(pd, PS_TRANSITION_TIME);
1500 break;
1501
1502 case PE_SNK_READY:
1503 pd->in_explicit_contract = true;
Jack Phambe0f20c2017-10-05 12:51:26 -07001504
1505 if (pd->vdm_tx)
1506 kick_sm(pd, 0);
1507 else if (pd->current_dr == DR_DFP && pd->vdm_state == VDM_NONE)
1508 usbpd_send_svdm(pd, USBPD_SID,
1509 USBPD_SVDM_DISCOVER_IDENTITY,
1510 SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0);
1511
Jack Phamf4baeb12017-02-03 19:01:48 -08001512 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
Jack Phamaf7d3842017-01-26 13:28:19 -08001513 complete(&pd->is_ready);
Jack Phamf4baeb12017-02-03 19:01:48 -08001514 dual_role_instance_changed(pd->dual_role);
1515 break;
1516
1517 case PE_SNK_TRANSITION_TO_DEFAULT:
1518 if (pd->current_dr != DR_UFP) {
1519 stop_usb_host(pd);
1520 start_usb_peripheral(pd);
1521 pd->current_dr = DR_UFP;
1522 pd_phy_update_roles(pd->current_dr, pd->current_pr);
1523 }
1524 if (pd->vconn_enabled) {
1525 regulator_disable(pd->vconn);
1526 pd->vconn_enabled = false;
1527 }
1528
1529 /* max time for hard reset to turn vbus off */
1530 kick_sm(pd, SNK_HARD_RESET_VBUS_OFF_TIME);
1531 break;
1532
1533 case PE_PRS_SNK_SRC_TRANSITION_TO_OFF:
1534 val.intval = pd->requested_current = 0; /* suspend charging */
1535 power_supply_set_property(pd->usb_psy,
1536 POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
1537
1538 pd->in_explicit_contract = false;
1539
1540 /*
1541 * need to update PR bit in message header so that
1542 * proper GoodCRC is sent when receiving next PS_RDY
1543 */
1544 pd_phy_update_roles(pd->current_dr, PR_SRC);
1545
1546 /* wait for PS_RDY */
1547 kick_sm(pd, PS_SOURCE_OFF);
1548 break;
1549
1550 default:
1551 usbpd_dbg(&pd->dev, "No action for state %s\n",
1552 usbpd_state_strings[pd->current_state]);
1553 break;
1554 }
1555}
1556
1557int usbpd_register_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr)
1558{
1559 if (find_svid_handler(pd, hdlr->svid)) {
1560 usbpd_err(&pd->dev, "SVID 0x%04x already registered\n",
1561 hdlr->svid);
1562 return -EINVAL;
1563 }
1564
1565 /* require connect/disconnect callbacks be implemented */
1566 if (!hdlr->connect || !hdlr->disconnect) {
1567 usbpd_err(&pd->dev, "SVID 0x%04x connect/disconnect must be non-NULL\n",
1568 hdlr->svid);
1569 return -EINVAL;
1570 }
1571
Mayank Rana83443202017-08-31 15:38:03 -07001572 usbpd_dbg(&pd->dev, "registered handler(%pK) for SVID 0x%04x\n",
1573 hdlr, hdlr->svid);
1574 mutex_lock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08001575 list_add_tail(&hdlr->entry, &pd->svid_handlers);
Mayank Rana83443202017-08-31 15:38:03 -07001576 mutex_unlock(&pd->svid_handler_lock);
Mayank Rana6af43422017-07-18 12:09:02 -07001577 hdlr->request_usb_ss_lane = usbpd_release_ss_lane;
Jack Phamf4baeb12017-02-03 19:01:48 -08001578
1579 /* already connected with this SVID discovered? */
1580 if (pd->vdm_state >= DISCOVERED_SVIDS) {
1581 int i;
1582
1583 for (i = 0; i < pd->num_svids; i++) {
1584 if (pd->discovered_svids[i] == hdlr->svid) {
1585 hdlr->connect(hdlr);
1586 hdlr->discovered = true;
1587 break;
1588 }
1589 }
1590 }
1591
1592 return 0;
1593}
1594EXPORT_SYMBOL(usbpd_register_svid);
1595
1596void usbpd_unregister_svid(struct usbpd *pd, struct usbpd_svid_handler *hdlr)
1597{
Mayank Rana83443202017-08-31 15:38:03 -07001598
1599 usbpd_dbg(&pd->dev, "unregistered handler(%pK) for SVID 0x%04x\n",
1600 hdlr, hdlr->svid);
1601 mutex_lock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08001602 list_del_init(&hdlr->entry);
Mayank Rana83443202017-08-31 15:38:03 -07001603 mutex_unlock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08001604}
1605EXPORT_SYMBOL(usbpd_unregister_svid);
1606
1607int usbpd_send_vdm(struct usbpd *pd, u32 vdm_hdr, const u32 *vdos, int num_vdos)
1608{
1609 struct vdm_tx *vdm_tx;
1610
1611 if (!pd->in_explicit_contract || pd->vdm_tx)
1612 return -EBUSY;
1613
1614 vdm_tx = kzalloc(sizeof(*vdm_tx), GFP_KERNEL);
1615 if (!vdm_tx)
1616 return -ENOMEM;
1617
1618 vdm_tx->data[0] = vdm_hdr;
1619 if (vdos && num_vdos)
1620 memcpy(&vdm_tx->data[1], vdos, num_vdos * sizeof(u32));
1621 vdm_tx->size = num_vdos + 1; /* include the header */
1622
1623 /* VDM will get sent in PE_SRC/SNK_READY state handling */
1624 pd->vdm_tx = vdm_tx;
1625
1626 /* slight delay before queuing to prioritize handling of incoming VDM */
1627 kick_sm(pd, 2);
1628
1629 return 0;
1630}
1631EXPORT_SYMBOL(usbpd_send_vdm);
1632
1633int usbpd_send_svdm(struct usbpd *pd, u16 svid, u8 cmd,
1634 enum usbpd_svdm_cmd_type cmd_type, int obj_pos,
1635 const u32 *vdos, int num_vdos)
1636{
1637 u32 svdm_hdr = SVDM_HDR(svid, 0, obj_pos, cmd_type, cmd);
1638
1639 usbpd_dbg(&pd->dev, "VDM tx: svid:%x cmd:%x cmd_type:%x svdm_hdr:%x\n",
1640 svid, cmd, cmd_type, svdm_hdr);
1641
1642 return usbpd_send_vdm(pd, svdm_hdr, vdos, num_vdos);
1643}
1644EXPORT_SYMBOL(usbpd_send_svdm);
1645
1646static void handle_vdm_rx(struct usbpd *pd, struct rx_msg *rx_msg)
1647{
Jack Phamf3c1bd32017-08-02 18:32:23 -07001648 u32 vdm_hdr =
1649 rx_msg->data_len >= sizeof(u32) ? ((u32 *)rx_msg->payload)[0] : 0;
1650
1651 u32 *vdos = (u32 *)&rx_msg->payload[sizeof(u32)];
Jack Phamf4baeb12017-02-03 19:01:48 -08001652 u16 svid = VDM_HDR_SVID(vdm_hdr);
1653 u16 *psvid;
Jack Phamf3c1bd32017-08-02 18:32:23 -07001654 u8 i, num_vdos = PD_MSG_HDR_COUNT(rx_msg->hdr) - 1;
Jack Phamf4baeb12017-02-03 19:01:48 -08001655 u8 cmd = SVDM_HDR_CMD(vdm_hdr);
1656 u8 cmd_type = SVDM_HDR_CMD_TYPE(vdm_hdr);
Jack Phamf4baeb12017-02-03 19:01:48 -08001657 struct usbpd_svid_handler *handler;
1658
Liangliang Lu7e9fffa2018-06-26 12:45:14 +08001659 usbpd_dbg(&pd->dev,
1660 "VDM rx: svid:%x cmd:%x cmd_type:%x vdm_hdr:%x has_dp: %s\n",
1661 svid, cmd, cmd_type, vdm_hdr,
1662 pd->has_dp ? "true" : "false");
1663
1664 if ((svid == 0xFF01) && (pd->has_dp == false)) {
1665 pd->has_dp = true;
1666
1667 /* Set to USB and DP cocurrency mode */
1668 extcon_blocking_sync(pd->extcon, EXTCON_DISP_DP, 2);
1669 }
Jack Phamf4baeb12017-02-03 19:01:48 -08001670
1671 /* if it's a supported SVID, pass the message to the handler */
1672 handler = find_svid_handler(pd, svid);
1673
1674 /* Unstructured VDM */
1675 if (!VDM_IS_SVDM(vdm_hdr)) {
1676 if (handler && handler->vdm_received)
1677 handler->vdm_received(handler, vdm_hdr, vdos, num_vdos);
1678 return;
1679 }
1680
1681 /* if this interrupts a previous exchange, abort queued response */
1682 if (cmd_type == SVDM_CMD_TYPE_INITIATOR && pd->vdm_tx) {
Vijayavardhan Vennapusa2dec2b22018-04-12 17:25:19 +05301683 /*
1684 * Drop ATTENTION command unless atleast one SVID handler is
1685 * discovered/connected.
1686 */
1687 if (cmd == USBPD_SVDM_ATTENTION && handler &&
1688 !handler->discovered) {
1689 usbpd_dbg(&pd->dev, "Send vdm command again queued SVDM tx (SVID:0x%04x)\n",
1690 VDM_HDR_SVID(pd->vdm_tx->data[0]));
1691 kick_sm(pd, 0);
1692 return;
1693 }
1694
Jack Phamf4baeb12017-02-03 19:01:48 -08001695 usbpd_dbg(&pd->dev, "Discarding previously queued SVDM tx (SVID:0x%04x)\n",
1696 VDM_HDR_SVID(pd->vdm_tx->data[0]));
1697
1698 kfree(pd->vdm_tx);
1699 pd->vdm_tx = NULL;
1700 }
1701
1702 if (handler && handler->svdm_received) {
1703 handler->svdm_received(handler, cmd, cmd_type, vdos, num_vdos);
1704 return;
1705 }
1706
1707 /* Standard Discovery or unhandled messages go here */
1708 switch (cmd_type) {
1709 case SVDM_CMD_TYPE_INITIATOR:
1710 if (svid == USBPD_SID && cmd == USBPD_SVDM_DISCOVER_IDENTITY) {
1711 u32 tx_vdos[3] = {
1712 ID_HDR_USB_HOST | ID_HDR_USB_DEVICE |
1713 ID_HDR_PRODUCT_PER_MASK | ID_HDR_VID,
1714 0x0, /* TBD: Cert Stat VDO */
1715 (PROD_VDO_PID << 16),
1716 /* TBD: Get these from gadget */
1717 };
1718
1719 usbpd_send_svdm(pd, USBPD_SID, cmd,
1720 SVDM_CMD_TYPE_RESP_ACK, 0, tx_vdos, 3);
1721 } else if (cmd != USBPD_SVDM_ATTENTION) {
1722 usbpd_send_svdm(pd, svid, cmd, SVDM_CMD_TYPE_RESP_NAK,
1723 SVDM_HDR_OBJ_POS(vdm_hdr), NULL, 0);
1724 }
1725 break;
1726
1727 case SVDM_CMD_TYPE_RESP_ACK:
1728 if (svid != USBPD_SID) {
1729 usbpd_err(&pd->dev, "unhandled ACK for SVID:0x%x\n",
1730 svid);
1731 break;
1732 }
1733
1734 switch (cmd) {
1735 case USBPD_SVDM_DISCOVER_IDENTITY:
1736 kfree(pd->vdm_tx_retry);
1737 pd->vdm_tx_retry = NULL;
1738
1739 pd->vdm_state = DISCOVERED_ID;
1740 usbpd_send_svdm(pd, USBPD_SID,
1741 USBPD_SVDM_DISCOVER_SVIDS,
1742 SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0);
1743 break;
1744
1745 case USBPD_SVDM_DISCOVER_SVIDS:
1746 pd->vdm_state = DISCOVERED_SVIDS;
1747
1748 kfree(pd->vdm_tx_retry);
1749 pd->vdm_tx_retry = NULL;
1750
1751 if (!pd->discovered_svids) {
1752 pd->num_svids = 2 * num_vdos;
1753 pd->discovered_svids = kcalloc(pd->num_svids,
1754 sizeof(u16),
1755 GFP_KERNEL);
1756 if (!pd->discovered_svids) {
1757 usbpd_err(&pd->dev, "unable to allocate SVIDs\n");
1758 break;
1759 }
1760
1761 psvid = pd->discovered_svids;
1762 } else { /* handle > 12 SVIDs */
1763 void *ptr;
1764 size_t oldsize = pd->num_svids * sizeof(u16);
1765 size_t newsize = oldsize +
1766 (2 * num_vdos * sizeof(u16));
1767
1768 ptr = krealloc(pd->discovered_svids, newsize,
1769 GFP_KERNEL);
1770 if (!ptr) {
1771 usbpd_err(&pd->dev, "unable to realloc SVIDs\n");
1772 break;
1773 }
1774
1775 pd->discovered_svids = ptr;
1776 psvid = pd->discovered_svids + pd->num_svids;
1777 memset(psvid, 0, (2 * num_vdos));
1778 pd->num_svids += 2 * num_vdos;
1779 }
1780
1781 /* convert 32-bit VDOs to list of 16-bit SVIDs */
1782 for (i = 0; i < num_vdos * 2; i++) {
1783 /*
1784 * Within each 32-bit VDO,
1785 * SVID[i]: upper 16-bits
1786 * SVID[i+1]: lower 16-bits
1787 * where i is even.
1788 */
1789 if (!(i & 1))
1790 svid = vdos[i >> 1] >> 16;
1791 else
1792 svid = vdos[i >> 1] & 0xFFFF;
1793
1794 /*
1795 * There are some devices that incorrectly
1796 * swap the order of SVIDs within a VDO. So in
1797 * case of an odd-number of SVIDs it could end
1798 * up with SVID[i] as 0 while SVID[i+1] is
1799 * non-zero. Just skip over the zero ones.
1800 */
1801 if (svid) {
1802 usbpd_dbg(&pd->dev, "Discovered SVID: 0x%04x\n",
1803 svid);
1804 *psvid++ = svid;
1805 }
1806 }
1807
1808 /* if more than 12 SVIDs, resend the request */
1809 if (num_vdos == 6 && vdos[5] != 0) {
1810 usbpd_send_svdm(pd, USBPD_SID,
1811 USBPD_SVDM_DISCOVER_SVIDS,
1812 SVDM_CMD_TYPE_INITIATOR, 0,
1813 NULL, 0);
1814 break;
1815 }
1816
1817 /* now that all SVIDs are discovered, notify handlers */
1818 for (i = 0; i < pd->num_svids; i++) {
1819 svid = pd->discovered_svids[i];
1820 if (svid) {
1821 handler = find_svid_handler(pd, svid);
1822 if (handler) {
1823 handler->connect(handler);
1824 handler->discovered = true;
1825 }
1826 }
Jack Phamf4baeb12017-02-03 19:01:48 -08001827 }
Jack Phamf4baeb12017-02-03 19:01:48 -08001828 break;
1829
1830 default:
1831 usbpd_dbg(&pd->dev, "unhandled ACK for command:0x%x\n",
1832 cmd);
1833 break;
1834 }
1835 break;
1836
1837 case SVDM_CMD_TYPE_RESP_NAK:
1838 usbpd_info(&pd->dev, "VDM NAK received for SVID:0x%04x command:0x%x\n",
1839 svid, cmd);
1840
1841 switch (cmd) {
1842 case USBPD_SVDM_DISCOVER_IDENTITY:
1843 case USBPD_SVDM_DISCOVER_SVIDS:
Jack Phamf4baeb12017-02-03 19:01:48 -08001844 break;
1845 default:
1846 break;
1847 }
1848
1849 break;
1850
1851 case SVDM_CMD_TYPE_RESP_BUSY:
1852 switch (cmd) {
1853 case USBPD_SVDM_DISCOVER_IDENTITY:
1854 case USBPD_SVDM_DISCOVER_SVIDS:
1855 if (!pd->vdm_tx_retry) {
1856 usbpd_err(&pd->dev, "Discover command %d VDM was unexpectedly freed\n",
1857 cmd);
1858 break;
1859 }
1860
1861 /* wait tVDMBusy, then retry */
1862 pd->vdm_tx = pd->vdm_tx_retry;
1863 pd->vdm_tx_retry = NULL;
1864 kick_sm(pd, VDM_BUSY_TIME);
1865 break;
1866 default:
1867 break;
1868 }
1869 break;
1870 }
1871}
1872
1873static void handle_vdm_tx(struct usbpd *pd)
1874{
1875 int ret;
1876 unsigned long flags;
1877
1878 /* only send one VDM at a time */
1879 if (pd->vdm_tx) {
1880 u32 vdm_hdr = pd->vdm_tx->data[0];
1881
1882 /* bail out and try again later if a message just arrived */
1883 spin_lock_irqsave(&pd->rx_lock, flags);
1884 if (!list_empty(&pd->rx_q)) {
1885 spin_unlock_irqrestore(&pd->rx_lock, flags);
1886 return;
1887 }
1888 spin_unlock_irqrestore(&pd->rx_lock, flags);
1889
1890 ret = pd_send_msg(pd, MSG_VDM, pd->vdm_tx->data,
1891 pd->vdm_tx->size, SOP_MSG);
1892 if (ret) {
1893 usbpd_err(&pd->dev, "Error (%d) sending VDM command %d\n",
1894 ret, SVDM_HDR_CMD(pd->vdm_tx->data[0]));
1895
1896 /* retry when hitting PE_SRC/SNK_Ready again */
1897 if (ret != -EBUSY)
1898 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
1899 PE_SRC_SEND_SOFT_RESET :
1900 PE_SNK_SEND_SOFT_RESET);
1901
1902 return;
1903 }
1904
1905 /*
1906 * special case: keep initiated Discover ID/SVIDs
1907 * around in case we need to re-try when receiving BUSY
1908 */
1909 if (VDM_IS_SVDM(vdm_hdr) &&
1910 SVDM_HDR_CMD_TYPE(vdm_hdr) == SVDM_CMD_TYPE_INITIATOR &&
1911 SVDM_HDR_CMD(vdm_hdr) <= USBPD_SVDM_DISCOVER_SVIDS) {
1912 if (pd->vdm_tx_retry) {
1913 usbpd_dbg(&pd->dev, "Previous Discover VDM command %d not ACKed/NAKed\n",
1914 SVDM_HDR_CMD(
1915 pd->vdm_tx_retry->data[0]));
1916 kfree(pd->vdm_tx_retry);
1917 }
1918 pd->vdm_tx_retry = pd->vdm_tx;
1919 } else {
1920 kfree(pd->vdm_tx);
1921 }
1922
1923 pd->vdm_tx = NULL;
1924 }
1925}
1926
1927static void reset_vdm_state(struct usbpd *pd)
1928{
1929 struct usbpd_svid_handler *handler;
1930
Mayank Rana83443202017-08-31 15:38:03 -07001931 mutex_lock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08001932 list_for_each_entry(handler, &pd->svid_handlers, entry) {
1933 if (handler->discovered) {
1934 handler->disconnect(handler);
1935 handler->discovered = false;
1936 }
1937 }
1938
Mayank Rana83443202017-08-31 15:38:03 -07001939 mutex_unlock(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08001940 pd->vdm_state = VDM_NONE;
1941 kfree(pd->vdm_tx_retry);
1942 pd->vdm_tx_retry = NULL;
1943 kfree(pd->discovered_svids);
1944 pd->discovered_svids = NULL;
1945 pd->num_svids = 0;
1946 kfree(pd->vdm_tx);
1947 pd->vdm_tx = NULL;
Vijayavardhan Vennapusadea32272018-04-05 14:25:39 +05301948 pd->ss_lane_svid = 0x0;
Jack Phamf4baeb12017-02-03 19:01:48 -08001949}
1950
1951static void dr_swap(struct usbpd *pd)
1952{
1953 reset_vdm_state(pd);
Mayank Rana45b0bc42017-07-25 15:38:05 -07001954 usbpd_dbg(&pd->dev, "dr_swap: current_dr(%d)\n", pd->current_dr);
Jack Phamf4baeb12017-02-03 19:01:48 -08001955
1956 if (pd->current_dr == DR_DFP) {
1957 stop_usb_host(pd);
1958 start_usb_peripheral(pd);
1959 pd->current_dr = DR_UFP;
1960 } else if (pd->current_dr == DR_UFP) {
1961 stop_usb_peripheral(pd);
Mayank Rana45b0bc42017-07-25 15:38:05 -07001962 start_usb_host(pd, true);
Jack Phamf4baeb12017-02-03 19:01:48 -08001963 pd->current_dr = DR_DFP;
1964
Jack Phamf4baeb12017-02-03 19:01:48 -08001965 usbpd_send_svdm(pd, USBPD_SID, USBPD_SVDM_DISCOVER_IDENTITY,
1966 SVDM_CMD_TYPE_INITIATOR, 0, NULL, 0);
1967 }
1968
1969 pd_phy_update_roles(pd->current_dr, pd->current_pr);
Jack Phame232bde2017-03-02 11:37:00 -08001970 dual_role_instance_changed(pd->dual_role);
Jack Phamf4baeb12017-02-03 19:01:48 -08001971}
1972
1973
1974static void vconn_swap(struct usbpd *pd)
1975{
1976 int ret;
1977
1978 if (pd->vconn_enabled) {
1979 pd->current_state = PE_VCS_WAIT_FOR_VCONN;
1980 kick_sm(pd, VCONN_ON_TIME);
1981 } else {
1982 ret = regulator_enable(pd->vconn);
1983 if (ret) {
1984 usbpd_err(&pd->dev, "Unable to enable vconn\n");
1985 return;
1986 }
1987
1988 pd->vconn_enabled = true;
1989
1990 /*
1991 * Small delay to ensure Vconn has ramped up. This is well
1992 * below tVCONNSourceOn (100ms) so we still send PS_RDY within
1993 * the allowed time.
1994 */
1995 usleep_range(5000, 10000);
1996
1997 ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG);
1998 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08001999 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
2000 PE_SRC_SEND_SOFT_RESET :
2001 PE_SNK_SEND_SOFT_RESET);
2002 return;
2003 }
2004 }
2005}
2006
2007static int enable_vbus(struct usbpd *pd)
2008{
2009 union power_supply_propval val = {0};
2010 int count = 100;
2011 int ret;
2012
2013 if (!check_vsafe0v)
2014 goto enable_reg;
2015
2016 /*
2017 * Check to make sure there's no lingering charge on
2018 * VBUS before enabling it as a source. If so poll here
2019 * until it goes below VSafe0V (0.8V) before proceeding.
2020 */
2021 while (count--) {
2022 ret = power_supply_get_property(pd->usb_psy,
2023 POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
2024 if (ret || val.intval <= 800000)
2025 break;
2026 usleep_range(20000, 30000);
2027 }
2028
2029 if (count < 99)
2030 msleep(100); /* need to wait an additional tCCDebounce */
2031
2032enable_reg:
2033 ret = regulator_enable(pd->vbus);
2034 if (ret)
2035 usbpd_err(&pd->dev, "Unable to enable vbus (%d)\n", ret);
2036 else
2037 pd->vbus_enabled = true;
2038
Vijayavardhan Vennapusaa9e32702018-07-03 15:47:18 +05302039 count = 10;
2040 /*
2041 * Check to make sure VBUS voltage reaches above Vsafe5Vmin (4.75v)
2042 * before proceeding.
2043 */
2044 while (count--) {
2045 ret = power_supply_get_property(pd->usb_psy,
2046 POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
2047 if (ret || val.intval >= 4750000) /*vsafe5Vmin*/
2048 break;
2049 usleep_range(10000, 12000); /* Delay between two reads */
2050 }
2051
2052 if (ret)
2053 msleep(100); /* Delay to wait for VBUS ramp up if read fails */
2054
Jack Phamf4baeb12017-02-03 19:01:48 -08002055 return ret;
2056}
2057
2058static inline void rx_msg_cleanup(struct usbpd *pd)
2059{
2060 struct rx_msg *msg, *tmp;
2061 unsigned long flags;
2062
2063 spin_lock_irqsave(&pd->rx_lock, flags);
2064 list_for_each_entry_safe(msg, tmp, &pd->rx_q, entry) {
2065 list_del(&msg->entry);
2066 kfree(msg);
2067 }
2068 spin_unlock_irqrestore(&pd->rx_lock, flags);
2069}
2070
2071/* For PD 3.0, check SinkTxOk before allowing initiating AMS */
2072static inline bool is_sink_tx_ok(struct usbpd *pd)
2073{
2074 if (pd->spec_rev == USBPD_REV_30)
2075 return pd->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH;
2076
2077 return true;
2078}
2079
2080/* Handles current state and determines transitions */
2081static void usbpd_sm(struct work_struct *w)
2082{
2083 struct usbpd *pd = container_of(w, struct usbpd, sm_work);
2084 union power_supply_propval val = {0};
2085 int ret;
2086 struct rx_msg *rx_msg = NULL;
2087 unsigned long flags;
2088
2089 usbpd_dbg(&pd->dev, "handle state %s\n",
2090 usbpd_state_strings[pd->current_state]);
2091
2092 hrtimer_cancel(&pd->timer);
2093 pd->sm_queued = false;
2094
2095 spin_lock_irqsave(&pd->rx_lock, flags);
2096 if (!list_empty(&pd->rx_q)) {
2097 rx_msg = list_first_entry(&pd->rx_q, struct rx_msg, entry);
2098 list_del(&rx_msg->entry);
2099 }
2100 spin_unlock_irqrestore(&pd->rx_lock, flags);
2101
2102 /* Disconnect? */
2103 if (pd->current_pr == PR_NONE) {
2104 if (pd->current_state == PE_UNKNOWN)
2105 goto sm_done;
2106
Hemant Kumar86bd10f2017-05-24 12:25:15 -07002107 if (pd->vconn_enabled) {
2108 regulator_disable(pd->vconn);
2109 pd->vconn_enabled = false;
2110 }
2111
Jack Phamf4baeb12017-02-03 19:01:48 -08002112 usbpd_info(&pd->dev, "USB Type-C disconnect\n");
2113
2114 if (pd->pd_phy_opened) {
2115 pd_phy_close();
2116 pd->pd_phy_opened = false;
2117 }
2118
2119 pd->in_pr_swap = false;
2120 pd->pd_connected = false;
2121 pd->in_explicit_contract = false;
2122 pd->hard_reset_recvd = false;
2123 pd->caps_count = 0;
2124 pd->hard_reset_count = 0;
Jack Phamf4baeb12017-02-03 19:01:48 -08002125 pd->requested_voltage = 0;
2126 pd->requested_current = 0;
Jack Phamf6c02da2017-01-31 15:23:56 -08002127 pd->selected_pdo = pd->requested_pdo = 0;
Jack Phamf4baeb12017-02-03 19:01:48 -08002128 memset(&pd->received_pdos, 0, sizeof(pd->received_pdos));
2129 rx_msg_cleanup(pd);
2130
Jack Phamf4baeb12017-02-03 19:01:48 -08002131 power_supply_set_property(pd->usb_psy,
2132 POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val);
2133
2134 power_supply_set_property(pd->usb_psy,
2135 POWER_SUPPLY_PROP_PD_USB_SUSPEND_SUPPORTED,
2136 &val);
2137
2138 power_supply_set_property(pd->usb_psy,
2139 POWER_SUPPLY_PROP_PD_ACTIVE, &val);
2140
2141 if (pd->vbus_enabled) {
2142 regulator_disable(pd->vbus);
2143 pd->vbus_enabled = false;
2144 }
2145
Mayank Rana86cb20292017-06-01 11:36:07 -07002146 reset_vdm_state(pd);
Jack Phamf4baeb12017-02-03 19:01:48 -08002147 if (pd->current_dr == DR_UFP)
2148 stop_usb_peripheral(pd);
2149 else if (pd->current_dr == DR_DFP)
2150 stop_usb_host(pd);
2151
Jack Phamf4baeb12017-02-03 19:01:48 -08002152 pd->current_dr = DR_NONE;
2153
Jack Phamf4baeb12017-02-03 19:01:48 -08002154 if (pd->current_state == PE_ERROR_RECOVERY)
2155 /* forced disconnect, wait before resetting to DRP */
2156 usleep_range(ERROR_RECOVERY_TIME * USEC_PER_MSEC,
2157 (ERROR_RECOVERY_TIME + 5) * USEC_PER_MSEC);
2158
Jack Pham01c5cfd2017-06-06 22:22:18 -07002159 val.intval = 0;
2160 power_supply_set_property(pd->usb_psy,
2161 POWER_SUPPLY_PROP_PR_SWAP, &val);
2162
Jack Phamf4baeb12017-02-03 19:01:48 -08002163 /* set due to dual_role class "mode" change */
2164 if (pd->forced_pr != POWER_SUPPLY_TYPEC_PR_NONE)
2165 val.intval = pd->forced_pr;
Hemant Kumarbe746222017-07-20 13:51:49 -07002166 else if (rev3_sink_only)
2167 val.intval = POWER_SUPPLY_TYPEC_PR_SINK;
Jack Phamf4baeb12017-02-03 19:01:48 -08002168 else
2169 /* Set CC back to DRP toggle */
2170 val.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
2171
2172 power_supply_set_property(pd->usb_psy,
2173 POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &val);
2174 pd->forced_pr = POWER_SUPPLY_TYPEC_PR_NONE;
2175
2176 pd->current_state = PE_UNKNOWN;
2177
2178 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
2179 dual_role_instance_changed(pd->dual_role);
2180
Liangliang Lu7e9fffa2018-06-26 12:45:14 +08002181 if (pd->has_dp) {
2182 pd->has_dp = false;
2183
2184 /* Set to USB only mode when cable disconnected */
2185 extcon_blocking_sync(pd->extcon, EXTCON_DISP_DP, 0);
2186 }
2187
Jack Phamf4baeb12017-02-03 19:01:48 -08002188 goto sm_done;
2189 }
2190
2191 /* Hard reset? */
2192 if (pd->hard_reset_recvd) {
2193 pd->hard_reset_recvd = false;
2194
Jack Pham6de20802017-05-24 13:44:56 -07002195 if (pd->requested_current) {
2196 val.intval = pd->requested_current = 0;
2197 power_supply_set_property(pd->usb_psy,
2198 POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
2199 }
2200
2201 pd->requested_voltage = 5000000;
2202 val.intval = pd->requested_voltage;
2203 power_supply_set_property(pd->usb_psy,
Nicholas Troast7f55c922017-07-25 13:18:03 -07002204 POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, &val);
Jack Pham6de20802017-05-24 13:44:56 -07002205
Jack Phamf4baeb12017-02-03 19:01:48 -08002206 pd->in_pr_swap = false;
Jack Pham857ee682017-05-25 11:53:36 -07002207 val.intval = 0;
2208 power_supply_set_property(pd->usb_psy,
2209 POWER_SUPPLY_PROP_PR_SWAP, &val);
2210
Jack Phamf6c02da2017-01-31 15:23:56 -08002211 pd->in_explicit_contract = false;
2212 pd->selected_pdo = pd->requested_pdo = 0;
2213 pd->rdo = 0;
Jack Phamf4baeb12017-02-03 19:01:48 -08002214 rx_msg_cleanup(pd);
2215 reset_vdm_state(pd);
Jack Phamf6c02da2017-01-31 15:23:56 -08002216 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
Jack Phamf4baeb12017-02-03 19:01:48 -08002217
2218 if (pd->current_pr == PR_SINK) {
2219 usbpd_set_state(pd, PE_SNK_TRANSITION_TO_DEFAULT);
2220 } else {
Jack Pham4b323282017-11-03 12:24:59 -07002221 s64 delta = ktime_ms_delta(ktime_get(),
2222 pd->hard_reset_recvd_time);
Jack Phamf4baeb12017-02-03 19:01:48 -08002223 pd->current_state = PE_SRC_TRANSITION_TO_DEFAULT;
Jack Pham4b323282017-11-03 12:24:59 -07002224 if (delta >= PS_HARD_RESET_TIME)
2225 kick_sm(pd, 0);
2226 else
2227 kick_sm(pd, PS_HARD_RESET_TIME - (int)delta);
Jack Phamf4baeb12017-02-03 19:01:48 -08002228 }
2229
2230 goto sm_done;
2231 }
2232
2233 /* Soft reset? */
2234 if (IS_CTRL(rx_msg, MSG_SOFT_RESET)) {
2235 usbpd_dbg(&pd->dev, "Handle soft reset\n");
2236
2237 if (pd->current_pr == PR_SRC)
2238 pd->current_state = PE_SRC_SOFT_RESET;
2239 else if (pd->current_pr == PR_SINK)
2240 pd->current_state = PE_SNK_SOFT_RESET;
2241 }
2242
2243 switch (pd->current_state) {
2244 case PE_UNKNOWN:
Jack Phamc4be61c2017-10-10 16:59:32 -07002245 val.intval = 0;
2246 power_supply_set_property(pd->usb_psy,
2247 POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val);
2248
Jack Phamf4baeb12017-02-03 19:01:48 -08002249 if (pd->current_pr == PR_SINK) {
2250 usbpd_set_state(pd, PE_SNK_STARTUP);
2251 } else if (pd->current_pr == PR_SRC) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002252 if (!pd->vconn_enabled &&
2253 pd->typec_mode ==
2254 POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE) {
2255 ret = regulator_enable(pd->vconn);
2256 if (ret)
2257 usbpd_err(&pd->dev, "Unable to enable vconn\n");
2258 else
2259 pd->vconn_enabled = true;
2260 }
Vijayavardhan Vennapusa326b4792017-07-13 12:10:50 +05302261 enable_vbus(pd);
Jack Phamf4baeb12017-02-03 19:01:48 -08002262
2263 usbpd_set_state(pd, PE_SRC_STARTUP);
2264 }
2265 break;
2266
2267 case PE_SRC_STARTUP:
2268 usbpd_set_state(pd, PE_SRC_STARTUP);
2269 break;
2270
2271 case PE_SRC_SEND_CAPABILITIES:
2272 ret = pd_send_msg(pd, MSG_SOURCE_CAPABILITIES, default_src_caps,
2273 ARRAY_SIZE(default_src_caps), SOP_MSG);
2274 if (ret) {
2275 pd->caps_count++;
Mayank Rana38e9b252017-03-23 12:35:57 -07002276 if (pd->caps_count >= PD_CAPS_COUNT) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002277 usbpd_dbg(&pd->dev, "Src CapsCounter exceeded, disabling PD\n");
2278 usbpd_set_state(pd, PE_SRC_DISABLED);
2279
Jack Pham9660be92018-04-03 16:06:40 -07002280 val.intval = POWER_SUPPLY_PD_INACTIVE;
Jack Phamf4baeb12017-02-03 19:01:48 -08002281 power_supply_set_property(pd->usb_psy,
2282 POWER_SUPPLY_PROP_PD_ACTIVE,
2283 &val);
2284 break;
2285 }
2286
2287 kick_sm(pd, SRC_CAP_TIME);
2288 break;
2289 }
2290
2291 /* transmit was successful if GoodCRC was received */
2292 pd->caps_count = 0;
2293 pd->hard_reset_count = 0;
2294 pd->pd_connected = true; /* we know peer is PD capable */
2295
2296 /* wait for REQUEST */
2297 pd->current_state = PE_SRC_SEND_CAPABILITIES_WAIT;
2298 kick_sm(pd, SENDER_RESPONSE_TIME);
2299
Jack Pham9660be92018-04-03 16:06:40 -07002300 val.intval = POWER_SUPPLY_PD_ACTIVE;
Jack Phamf4baeb12017-02-03 19:01:48 -08002301 power_supply_set_property(pd->usb_psy,
2302 POWER_SUPPLY_PROP_PD_ACTIVE, &val);
2303 break;
2304
2305 case PE_SRC_SEND_CAPABILITIES_WAIT:
2306 if (IS_DATA(rx_msg, MSG_REQUEST)) {
Jack Phamf3c1bd32017-08-02 18:32:23 -07002307 pd->rdo = *(u32 *)rx_msg->payload;
Jack Phamf4baeb12017-02-03 19:01:48 -08002308 usbpd_set_state(pd, PE_SRC_NEGOTIATE_CAPABILITY);
2309 } else if (rx_msg) {
2310 usbpd_err(&pd->dev, "Unexpected message received\n");
2311 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2312 } else {
2313 usbpd_set_state(pd, PE_SRC_HARD_RESET);
2314 }
2315 break;
2316
2317 case PE_SRC_READY:
2318 if (IS_CTRL(rx_msg, MSG_GET_SOURCE_CAP)) {
Hemant Kumaree2db9b2017-05-30 14:52:18 -07002319 pd->current_state = PE_SRC_SEND_CAPABILITIES;
2320 kick_sm(pd, 0);
Jack Phamf4baeb12017-02-03 19:01:48 -08002321 } else if (IS_CTRL(rx_msg, MSG_GET_SINK_CAP)) {
2322 ret = pd_send_msg(pd, MSG_SINK_CAPABILITIES,
Jack Phamee1f9052017-01-26 12:27:07 -08002323 pd->sink_caps, pd->num_sink_caps,
2324 SOP_MSG);
Jack Pham722527a2018-06-28 23:17:17 -07002325 if (ret)
Jack Phamf4baeb12017-02-03 19:01:48 -08002326 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
Jack Phamf4baeb12017-02-03 19:01:48 -08002327 } else if (IS_DATA(rx_msg, MSG_REQUEST)) {
Jack Phamf3c1bd32017-08-02 18:32:23 -07002328 pd->rdo = *(u32 *)rx_msg->payload;
Jack Phamf4baeb12017-02-03 19:01:48 -08002329 usbpd_set_state(pd, PE_SRC_NEGOTIATE_CAPABILITY);
2330 } else if (IS_CTRL(rx_msg, MSG_DR_SWAP)) {
2331 if (pd->vdm_state == MODE_ENTERED) {
2332 usbpd_set_state(pd, PE_SRC_HARD_RESET);
2333 break;
2334 }
2335
2336 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2337 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002338 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2339 break;
2340 }
2341
2342 dr_swap(pd);
2343 } else if (IS_CTRL(rx_msg, MSG_PR_SWAP)) {
2344 /* lock in current mode */
2345 set_power_role(pd, pd->current_pr);
2346
2347 /* we'll happily accept Src->Sink requests anytime */
2348 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2349 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002350 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2351 break;
2352 }
2353
2354 pd->current_state = PE_PRS_SRC_SNK_TRANSITION_TO_OFF;
2355 kick_sm(pd, SRC_TRANSITION_TIME);
2356 break;
2357 } else if (IS_CTRL(rx_msg, MSG_VCONN_SWAP)) {
2358 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2359 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002360 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2361 break;
2362 }
2363
2364 vconn_swap(pd);
2365 } else if (IS_DATA(rx_msg, MSG_VDM)) {
2366 handle_vdm_rx(pd, rx_msg);
Jack Pham69a427e2017-08-04 12:26:51 -07002367 } else if (rx_msg && pd->spec_rev == USBPD_REV_30) {
2368 /* unhandled messages */
2369 ret = pd_send_msg(pd, MSG_NOT_SUPPORTED, NULL, 0,
2370 SOP_MSG);
Jack Pham722527a2018-06-28 23:17:17 -07002371 if (ret)
Jack Pham69a427e2017-08-04 12:26:51 -07002372 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
Jack Pham69a427e2017-08-04 12:26:51 -07002373 break;
Jack Phamf4baeb12017-02-03 19:01:48 -08002374 } else if (pd->send_pr_swap) {
2375 pd->send_pr_swap = false;
2376 ret = pd_send_msg(pd, MSG_PR_SWAP, NULL, 0, SOP_MSG);
2377 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002378 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2379 break;
2380 }
2381
2382 pd->current_state = PE_PRS_SRC_SNK_SEND_SWAP;
2383 kick_sm(pd, SENDER_RESPONSE_TIME);
2384 } else if (pd->send_dr_swap) {
2385 pd->send_dr_swap = false;
2386 ret = pd_send_msg(pd, MSG_DR_SWAP, NULL, 0, SOP_MSG);
2387 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002388 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2389 break;
2390 }
2391
2392 pd->current_state = PE_DRS_SEND_DR_SWAP;
2393 kick_sm(pd, SENDER_RESPONSE_TIME);
2394 } else {
2395 handle_vdm_tx(pd);
2396 }
2397 break;
2398
2399 case PE_SRC_TRANSITION_TO_DEFAULT:
2400 if (pd->vconn_enabled)
2401 regulator_disable(pd->vconn);
Jack Phamc4be61c2017-10-10 16:59:32 -07002402 pd->vconn_enabled = false;
2403
Jack Phamf4baeb12017-02-03 19:01:48 -08002404 if (pd->vbus_enabled)
2405 regulator_disable(pd->vbus);
Jack Phamc4be61c2017-10-10 16:59:32 -07002406 pd->vbus_enabled = false;
Jack Phamf4baeb12017-02-03 19:01:48 -08002407
2408 if (pd->current_dr != DR_DFP) {
Jack Pham4e9dff72017-04-04 18:05:53 -07002409 extcon_set_state_sync(pd->extcon, EXTCON_USB, 0);
Jack Phamf4baeb12017-02-03 19:01:48 -08002410 pd->current_dr = DR_DFP;
2411 pd_phy_update_roles(pd->current_dr, pd->current_pr);
2412 }
2413
Jack Phamc4be61c2017-10-10 16:59:32 -07002414 /* PE_UNKNOWN will turn on VBUS and go back to PE_SRC_STARTUP */
2415 pd->current_state = PE_UNKNOWN;
2416 kick_sm(pd, SRC_RECOVER_TIME);
Jack Phamf4baeb12017-02-03 19:01:48 -08002417 break;
2418
2419 case PE_SRC_HARD_RESET:
2420 val.intval = 1;
2421 power_supply_set_property(pd->usb_psy,
2422 POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val);
2423
2424 pd_send_hard_reset(pd);
2425 pd->in_explicit_contract = false;
Jack Phamf6c02da2017-01-31 15:23:56 -08002426 pd->rdo = 0;
Jack Phamf4baeb12017-02-03 19:01:48 -08002427 rx_msg_cleanup(pd);
2428 reset_vdm_state(pd);
Jack Phamf6c02da2017-01-31 15:23:56 -08002429 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
Jack Phamf4baeb12017-02-03 19:01:48 -08002430
2431 pd->current_state = PE_SRC_TRANSITION_TO_DEFAULT;
2432 kick_sm(pd, PS_HARD_RESET_TIME);
2433 break;
2434
2435 case PE_SNK_STARTUP:
2436 usbpd_set_state(pd, PE_SNK_STARTUP);
2437 break;
2438
2439 case PE_SNK_DISCOVERY:
2440 if (!rx_msg) {
2441 if (pd->vbus_present)
2442 usbpd_set_state(pd,
2443 PE_SNK_WAIT_FOR_CAPABILITIES);
2444
2445 /*
2446 * Handle disconnection in the middle of PR_Swap.
2447 * Since in psy_changed() if pd->in_pr_swap is true
2448 * we ignore the typec_mode==NONE change since that is
2449 * expected to happen. However if the cable really did
2450 * get disconnected we need to check for it here after
2451 * waiting for VBUS presence times out.
2452 */
2453 if (!pd->typec_mode) {
2454 pd->current_pr = PR_NONE;
2455 kick_sm(pd, 0);
2456 }
2457
2458 break;
2459 }
2460 /* else fall-through */
2461
2462 case PE_SNK_WAIT_FOR_CAPABILITIES:
2463 pd->in_pr_swap = false;
Jack Pham857ee682017-05-25 11:53:36 -07002464 val.intval = 0;
2465 power_supply_set_property(pd->usb_psy,
2466 POWER_SUPPLY_PROP_PR_SWAP, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08002467
2468 if (IS_DATA(rx_msg, MSG_SOURCE_CAPABILITIES)) {
2469 val.intval = 0;
2470 power_supply_set_property(pd->usb_psy,
2471 POWER_SUPPLY_PROP_PD_IN_HARD_RESET,
2472 &val);
2473
2474 /* save the PDOs so userspace can further evaluate */
Jack Phame9e1f132017-10-23 09:47:49 -07002475 memset(&pd->received_pdos, 0,
Jack Phamf4baeb12017-02-03 19:01:48 -08002476 sizeof(pd->received_pdos));
Jack Phame9e1f132017-10-23 09:47:49 -07002477 memcpy(&pd->received_pdos, rx_msg->payload,
2478 min_t(size_t, rx_msg->data_len,
2479 sizeof(pd->received_pdos)));
Jack Phamf4baeb12017-02-03 19:01:48 -08002480 pd->src_cap_id++;
2481
2482 usbpd_set_state(pd, PE_SNK_EVALUATE_CAPABILITY);
Jack Phamf4baeb12017-02-03 19:01:48 -08002483 } else if (pd->hard_reset_count < 3) {
2484 usbpd_set_state(pd, PE_SNK_HARD_RESET);
Jack Phamf4baeb12017-02-03 19:01:48 -08002485 } else {
2486 usbpd_dbg(&pd->dev, "Sink hard reset count exceeded, disabling PD\n");
2487
2488 val.intval = 0;
2489 power_supply_set_property(pd->usb_psy,
2490 POWER_SUPPLY_PROP_PD_IN_HARD_RESET,
2491 &val);
2492
Jack Pham9660be92018-04-03 16:06:40 -07002493 val.intval = POWER_SUPPLY_PD_INACTIVE;
Jack Phamf4baeb12017-02-03 19:01:48 -08002494 power_supply_set_property(pd->usb_psy,
2495 POWER_SUPPLY_PROP_PD_ACTIVE, &val);
2496 }
2497 break;
2498
2499 case PE_SNK_SELECT_CAPABILITY:
2500 if (IS_CTRL(rx_msg, MSG_ACCEPT)) {
Jack Pham78c869a2017-02-14 16:10:28 -08002501 u32 pdo = pd->received_pdos[pd->requested_pdo - 1];
2502 bool same_pps = (pd->selected_pdo == pd->requested_pdo)
2503 && (PD_SRC_PDO_TYPE(pdo) ==
2504 PD_SRC_PDO_TYPE_AUGMENTED);
2505
Jack Phamf4baeb12017-02-03 19:01:48 -08002506 usbpd_set_state(pd, PE_SNK_TRANSITION_SINK);
2507
2508 /* prepare for voltage increase/decrease */
2509 val.intval = pd->requested_voltage;
2510 power_supply_set_property(pd->usb_psy,
2511 pd->requested_voltage >= pd->current_voltage ?
Nicholas Troast7f55c922017-07-25 13:18:03 -07002512 POWER_SUPPLY_PROP_PD_VOLTAGE_MAX :
2513 POWER_SUPPLY_PROP_PD_VOLTAGE_MIN,
Jack Phamf4baeb12017-02-03 19:01:48 -08002514 &val);
2515
2516 /*
Jack Pham78c869a2017-02-14 16:10:28 -08002517 * if changing voltages (not within the same PPS PDO),
2518 * we must lower input current to pSnkStdby (2.5W).
2519 * Calculate it and set PD_CURRENT_MAX accordingly.
Jack Phamf4baeb12017-02-03 19:01:48 -08002520 */
Jack Pham78c869a2017-02-14 16:10:28 -08002521 if (!same_pps &&
2522 pd->requested_voltage != pd->current_voltage) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002523 int mv = max(pd->requested_voltage,
2524 pd->current_voltage) / 1000;
2525 val.intval = (2500000 / mv) * 1000;
2526 power_supply_set_property(pd->usb_psy,
2527 POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
2528 } else {
2529 /* decreasing current? */
2530 ret = power_supply_get_property(pd->usb_psy,
2531 POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
2532 if (!ret &&
2533 pd->requested_current < val.intval) {
2534 val.intval =
2535 pd->requested_current * 1000;
2536 power_supply_set_property(pd->usb_psy,
2537 POWER_SUPPLY_PROP_PD_CURRENT_MAX,
2538 &val);
2539 }
2540 }
2541
2542 pd->selected_pdo = pd->requested_pdo;
2543 } else if (IS_CTRL(rx_msg, MSG_REJECT) ||
2544 IS_CTRL(rx_msg, MSG_WAIT)) {
2545 if (pd->in_explicit_contract)
2546 usbpd_set_state(pd, PE_SNK_READY);
2547 else
2548 usbpd_set_state(pd,
2549 PE_SNK_WAIT_FOR_CAPABILITIES);
2550 } else if (rx_msg) {
2551 usbpd_err(&pd->dev, "Invalid response to sink request\n");
2552 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2553 } else {
2554 /* timed out; go to hard reset */
2555 usbpd_set_state(pd, PE_SNK_HARD_RESET);
2556 }
2557 break;
2558
2559 case PE_SNK_TRANSITION_SINK:
2560 if (IS_CTRL(rx_msg, MSG_PS_RDY)) {
2561 val.intval = pd->requested_voltage;
2562 power_supply_set_property(pd->usb_psy,
2563 pd->requested_voltage >= pd->current_voltage ?
Nicholas Troast7f55c922017-07-25 13:18:03 -07002564 POWER_SUPPLY_PROP_PD_VOLTAGE_MIN :
2565 POWER_SUPPLY_PROP_PD_VOLTAGE_MAX, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08002566 pd->current_voltage = pd->requested_voltage;
2567
2568 /* resume charging */
2569 val.intval = pd->requested_current * 1000; /* mA->uA */
2570 power_supply_set_property(pd->usb_psy,
2571 POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
2572
2573 usbpd_set_state(pd, PE_SNK_READY);
2574 } else {
2575 /* timed out; go to hard reset */
2576 usbpd_set_state(pd, PE_SNK_HARD_RESET);
2577 }
2578 break;
2579
2580 case PE_SNK_READY:
2581 if (IS_DATA(rx_msg, MSG_SOURCE_CAPABILITIES)) {
2582 /* save the PDOs so userspace can further evaluate */
Jack Phame9e1f132017-10-23 09:47:49 -07002583 memset(&pd->received_pdos, 0,
Jack Phamf4baeb12017-02-03 19:01:48 -08002584 sizeof(pd->received_pdos));
Jack Phame9e1f132017-10-23 09:47:49 -07002585 memcpy(&pd->received_pdos, rx_msg->payload,
2586 min_t(size_t, rx_msg->data_len,
2587 sizeof(pd->received_pdos)));
Jack Phamf4baeb12017-02-03 19:01:48 -08002588 pd->src_cap_id++;
2589
2590 usbpd_set_state(pd, PE_SNK_EVALUATE_CAPABILITY);
2591 } else if (IS_CTRL(rx_msg, MSG_GET_SINK_CAP)) {
2592 ret = pd_send_msg(pd, MSG_SINK_CAPABILITIES,
Jack Phamee1f9052017-01-26 12:27:07 -08002593 pd->sink_caps, pd->num_sink_caps,
2594 SOP_MSG);
Jack Pham722527a2018-06-28 23:17:17 -07002595 if (ret)
Jack Phamf4baeb12017-02-03 19:01:48 -08002596 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
Jack Pham69a427e2017-08-04 12:26:51 -07002597 } else if (IS_CTRL(rx_msg, MSG_GET_SOURCE_CAP) &&
2598 pd->spec_rev == USBPD_REV_20) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002599 ret = pd_send_msg(pd, MSG_SOURCE_CAPABILITIES,
2600 default_src_caps,
2601 ARRAY_SIZE(default_src_caps), SOP_MSG);
2602 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002603 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2604 break;
2605 }
2606 } else if (IS_CTRL(rx_msg, MSG_DR_SWAP)) {
2607 if (pd->vdm_state == MODE_ENTERED) {
2608 usbpd_set_state(pd, PE_SNK_HARD_RESET);
2609 break;
2610 }
2611
2612 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2613 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002614 usbpd_set_state(pd, PE_SRC_SEND_SOFT_RESET);
2615 break;
2616 }
2617
2618 dr_swap(pd);
Jack Pham69a427e2017-08-04 12:26:51 -07002619 } else if (IS_CTRL(rx_msg, MSG_PR_SWAP) &&
2620 pd->spec_rev == USBPD_REV_20) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002621 /* lock in current mode */
2622 set_power_role(pd, pd->current_pr);
2623
2624 /* TODO: should we Reject in certain circumstances? */
2625 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2626 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002627 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2628 break;
2629 }
2630
2631 pd->in_pr_swap = true;
Jack Pham857ee682017-05-25 11:53:36 -07002632 val.intval = 1;
2633 power_supply_set_property(pd->usb_psy,
2634 POWER_SUPPLY_PROP_PR_SWAP, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08002635 usbpd_set_state(pd, PE_PRS_SNK_SRC_TRANSITION_TO_OFF);
2636 break;
Jack Pham69a427e2017-08-04 12:26:51 -07002637 } else if (IS_CTRL(rx_msg, MSG_VCONN_SWAP) &&
2638 pd->spec_rev == USBPD_REV_20) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002639 /*
2640 * if VCONN is connected to VBUS, make sure we are
2641 * not in high voltage contract, otherwise reject.
2642 */
2643 if (!pd->vconn_is_external &&
2644 (pd->requested_voltage > 5000000)) {
2645 ret = pd_send_msg(pd, MSG_REJECT, NULL, 0,
2646 SOP_MSG);
Jack Pham722527a2018-06-28 23:17:17 -07002647 if (ret)
Jack Phamf4baeb12017-02-03 19:01:48 -08002648 usbpd_set_state(pd,
2649 PE_SNK_SEND_SOFT_RESET);
Jack Phamf4baeb12017-02-03 19:01:48 -08002650
2651 break;
2652 }
2653
2654 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2655 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002656 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2657 break;
2658 }
2659
2660 vconn_swap(pd);
2661 } else if (IS_DATA(rx_msg, MSG_VDM)) {
2662 handle_vdm_rx(pd, rx_msg);
Hemant Kumar018b5982017-08-09 14:14:37 -07002663 } else if (pd->send_get_src_cap_ext && is_sink_tx_ok(pd)) {
2664 pd->send_get_src_cap_ext = false;
2665 ret = pd_send_msg(pd, MSG_GET_SOURCE_CAP_EXTENDED, NULL,
2666 0, SOP_MSG);
2667 if (ret) {
Hemant Kumar018b5982017-08-09 14:14:37 -07002668 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2669 break;
2670 }
2671 kick_sm(pd, SENDER_RESPONSE_TIME);
2672 } else if (rx_msg &&
2673 IS_EXT(rx_msg, MSG_SOURCE_CAPABILITIES_EXTENDED)) {
2674 if (rx_msg->data_len != PD_SRC_CAP_EXT_DB_LEN) {
2675 usbpd_err(&pd->dev, "Invalid src cap ext db\n");
2676 break;
2677 }
2678 memcpy(&pd->src_cap_ext_db, rx_msg->payload,
2679 sizeof(pd->src_cap_ext_db));
2680 complete(&pd->is_ready);
2681 } else if (pd->send_get_pps_status && is_sink_tx_ok(pd)) {
2682 pd->send_get_pps_status = false;
2683 ret = pd_send_msg(pd, MSG_GET_PPS_STATUS, NULL,
2684 0, SOP_MSG);
2685 if (ret) {
Hemant Kumar018b5982017-08-09 14:14:37 -07002686 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2687 break;
2688 }
2689 kick_sm(pd, SENDER_RESPONSE_TIME);
2690 } else if (rx_msg &&
2691 IS_EXT(rx_msg, MSG_PPS_STATUS)) {
2692 if (rx_msg->data_len != sizeof(pd->pps_status_db)) {
2693 usbpd_err(&pd->dev, "Invalid pps status db\n");
2694 break;
2695 }
2696 memcpy(&pd->pps_status_db, rx_msg->payload,
2697 sizeof(pd->pps_status_db));
2698 complete(&pd->is_ready);
Hemant Kumara1875942017-08-09 16:50:14 -07002699 } else if (IS_DATA(rx_msg, MSG_ALERT)) {
Jack Phamda401d72018-06-07 19:29:52 -07002700 u32 ado;
2701
2702 if (rx_msg->data_len != sizeof(ado)) {
Hemant Kumara1875942017-08-09 16:50:14 -07002703 usbpd_err(&pd->dev, "Invalid ado\n");
2704 break;
2705 }
Jack Phamda401d72018-06-07 19:29:52 -07002706 memcpy(&ado, rx_msg->payload, sizeof(ado));
2707 usbpd_dbg(&pd->dev, "Received Alert 0x%08x\n", ado);
2708
2709 /*
2710 * Don't send Get_Status right away so we can coalesce
2711 * multiple Alerts. 150ms should be enough to not get
2712 * in the way of any other AMS that might happen.
2713 */
2714 pd->send_get_status = true;
2715 kick_sm(pd, 150);
2716 } else if (pd->send_get_status && is_sink_tx_ok(pd)) {
2717 pd->send_get_status = false;
2718 ret = pd_send_msg(pd, MSG_GET_STATUS, NULL, 0, SOP_MSG);
Hemant Kumara1875942017-08-09 16:50:14 -07002719 if (ret) {
Hemant Kumara1875942017-08-09 16:50:14 -07002720 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2721 break;
2722 }
2723 kick_sm(pd, SENDER_RESPONSE_TIME);
Jack Phamda401d72018-06-07 19:29:52 -07002724 } else if (rx_msg && IS_EXT(rx_msg, MSG_STATUS)) {
Hemant Kumara1875942017-08-09 16:50:14 -07002725 if (rx_msg->data_len != PD_STATUS_DB_LEN) {
2726 usbpd_err(&pd->dev, "Invalid status db\n");
2727 break;
2728 }
2729 memcpy(&pd->status_db, rx_msg->payload,
2730 sizeof(pd->status_db));
2731 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
Hemant Kumar51ded972017-08-09 17:57:24 -07002732 } else if (pd->send_get_battery_cap && is_sink_tx_ok(pd)) {
2733 pd->send_get_battery_cap = false;
2734 ret = pd_send_ext_msg(pd, MSG_GET_BATTERY_CAP,
2735 &pd->get_battery_cap_db, 1, SOP_MSG);
2736 if (ret) {
Hemant Kumar51ded972017-08-09 17:57:24 -07002737 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2738 break;
2739 }
2740 kick_sm(pd, SENDER_RESPONSE_TIME);
2741 } else if (rx_msg &&
2742 IS_EXT(rx_msg, MSG_BATTERY_CAPABILITIES)) {
2743 if (rx_msg->data_len != PD_BATTERY_CAP_DB_LEN) {
2744 usbpd_err(&pd->dev, "Invalid battery cap db\n");
2745 break;
2746 }
2747 memcpy(&pd->battery_cap_db, rx_msg->payload,
2748 sizeof(pd->battery_cap_db));
2749 complete(&pd->is_ready);
2750 } else if (pd->send_get_battery_status && is_sink_tx_ok(pd)) {
2751 pd->send_get_battery_status = false;
2752 ret = pd_send_ext_msg(pd, MSG_GET_BATTERY_STATUS,
2753 &pd->get_battery_status_db, 1, SOP_MSG);
2754 if (ret) {
Hemant Kumar51ded972017-08-09 17:57:24 -07002755 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2756 break;
2757 }
2758 kick_sm(pd, SENDER_RESPONSE_TIME);
2759 } else if (rx_msg &&
2760 IS_EXT(rx_msg, MSG_BATTERY_STATUS)) {
2761 if (rx_msg->data_len != sizeof(pd->battery_sts_dobj)) {
2762 usbpd_err(&pd->dev, "Invalid bat sts dobj\n");
2763 break;
2764 }
2765 memcpy(&pd->battery_sts_dobj, rx_msg->payload,
2766 sizeof(pd->battery_sts_dobj));
2767 complete(&pd->is_ready);
Jack Pham69a427e2017-08-04 12:26:51 -07002768 } else if (rx_msg && pd->spec_rev == USBPD_REV_30) {
2769 /* unhandled messages */
2770 ret = pd_send_msg(pd, MSG_NOT_SUPPORTED, NULL, 0,
2771 SOP_MSG);
Jack Pham722527a2018-06-28 23:17:17 -07002772 if (ret)
Jack Pham69a427e2017-08-04 12:26:51 -07002773 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
Jack Pham69a427e2017-08-04 12:26:51 -07002774 break;
Jack Phamaf7d3842017-01-26 13:28:19 -08002775 } else if (pd->send_request) {
2776 pd->send_request = false;
2777 usbpd_set_state(pd, PE_SNK_SELECT_CAPABILITY);
Jack Phamf4baeb12017-02-03 19:01:48 -08002778 } else if (pd->send_pr_swap && is_sink_tx_ok(pd)) {
2779 pd->send_pr_swap = false;
2780 ret = pd_send_msg(pd, MSG_PR_SWAP, NULL, 0, SOP_MSG);
2781 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002782 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2783 break;
2784 }
2785
2786 pd->current_state = PE_PRS_SNK_SRC_SEND_SWAP;
2787 kick_sm(pd, SENDER_RESPONSE_TIME);
2788 } else if (pd->send_dr_swap && is_sink_tx_ok(pd)) {
2789 pd->send_dr_swap = false;
2790 ret = pd_send_msg(pd, MSG_DR_SWAP, NULL, 0, SOP_MSG);
2791 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002792 usbpd_set_state(pd, PE_SNK_SEND_SOFT_RESET);
2793 break;
2794 }
2795
2796 pd->current_state = PE_DRS_SEND_DR_SWAP;
2797 kick_sm(pd, SENDER_RESPONSE_TIME);
2798 } else if (is_sink_tx_ok(pd)) {
2799 handle_vdm_tx(pd);
2800 }
2801 break;
2802
2803 case PE_SNK_TRANSITION_TO_DEFAULT:
2804 usbpd_set_state(pd, PE_SNK_STARTUP);
2805 break;
2806
2807 case PE_SRC_SOFT_RESET:
2808 case PE_SNK_SOFT_RESET:
2809 pd_reset_protocol(pd);
2810
2811 ret = pd_send_msg(pd, MSG_ACCEPT, NULL, 0, SOP_MSG);
2812 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002813 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
2814 PE_SRC_HARD_RESET : PE_SNK_HARD_RESET);
2815 break;
2816 }
2817
2818 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
2819 PE_SRC_SEND_CAPABILITIES :
2820 PE_SNK_WAIT_FOR_CAPABILITIES);
2821 break;
2822
2823 case PE_SRC_SEND_SOFT_RESET:
2824 case PE_SNK_SEND_SOFT_RESET:
2825 if (IS_CTRL(rx_msg, MSG_ACCEPT)) {
2826 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
2827 PE_SRC_SEND_CAPABILITIES :
2828 PE_SNK_WAIT_FOR_CAPABILITIES);
2829 } else {
2830 usbpd_err(&pd->dev, "%s: Did not see Accept, do Hard Reset\n",
2831 usbpd_state_strings[pd->current_state]);
2832 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
2833 PE_SRC_HARD_RESET : PE_SNK_HARD_RESET);
2834 }
2835 break;
2836
2837 case PE_SNK_HARD_RESET:
2838 /* prepare charger for VBUS change */
2839 val.intval = 1;
2840 power_supply_set_property(pd->usb_psy,
2841 POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val);
2842
2843 pd->requested_voltage = 5000000;
2844
2845 if (pd->requested_current) {
2846 val.intval = pd->requested_current = 0;
2847 power_supply_set_property(pd->usb_psy,
2848 POWER_SUPPLY_PROP_PD_CURRENT_MAX, &val);
2849 }
2850
2851 val.intval = pd->requested_voltage;
2852 power_supply_set_property(pd->usb_psy,
Nicholas Troast7f55c922017-07-25 13:18:03 -07002853 POWER_SUPPLY_PROP_PD_VOLTAGE_MIN, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08002854
2855 pd_send_hard_reset(pd);
2856 pd->in_explicit_contract = false;
Jack Phamf6c02da2017-01-31 15:23:56 -08002857 pd->selected_pdo = pd->requested_pdo = 0;
2858 pd->rdo = 0;
Jack Phamf4baeb12017-02-03 19:01:48 -08002859 reset_vdm_state(pd);
Jack Phamf6c02da2017-01-31 15:23:56 -08002860 kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
Jack Phamf4baeb12017-02-03 19:01:48 -08002861 usbpd_set_state(pd, PE_SNK_TRANSITION_TO_DEFAULT);
2862 break;
2863
2864 case PE_DRS_SEND_DR_SWAP:
2865 if (IS_CTRL(rx_msg, MSG_ACCEPT))
2866 dr_swap(pd);
2867
2868 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
2869 PE_SRC_READY : PE_SNK_READY);
2870 break;
2871
2872 case PE_PRS_SRC_SNK_SEND_SWAP:
2873 if (!IS_CTRL(rx_msg, MSG_ACCEPT)) {
2874 pd->current_state = PE_SRC_READY;
2875 break;
2876 }
2877
2878 pd->current_state = PE_PRS_SRC_SNK_TRANSITION_TO_OFF;
2879 kick_sm(pd, SRC_TRANSITION_TIME);
2880 break;
2881
2882 case PE_PRS_SRC_SNK_TRANSITION_TO_OFF:
2883 pd->in_pr_swap = true;
Jack Pham857ee682017-05-25 11:53:36 -07002884 val.intval = 1;
2885 power_supply_set_property(pd->usb_psy,
2886 POWER_SUPPLY_PROP_PR_SWAP, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08002887 pd->in_explicit_contract = false;
2888
2889 if (pd->vbus_enabled) {
2890 regulator_disable(pd->vbus);
2891 pd->vbus_enabled = false;
2892 }
2893
2894 /* PE_PRS_SRC_SNK_Assert_Rd */
2895 pd->current_pr = PR_SINK;
2896 set_power_role(pd, pd->current_pr);
2897 pd_phy_update_roles(pd->current_dr, pd->current_pr);
2898
2899 /* allow time for Vbus discharge, must be < tSrcSwapStdby */
2900 msleep(500);
2901
2902 ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG);
2903 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002904 usbpd_set_state(pd, PE_ERROR_RECOVERY);
2905 break;
2906 }
2907
2908 pd->current_state = PE_PRS_SRC_SNK_WAIT_SOURCE_ON;
2909 kick_sm(pd, PS_SOURCE_ON);
2910 break;
2911
2912 case PE_PRS_SRC_SNK_WAIT_SOURCE_ON:
2913 if (IS_CTRL(rx_msg, MSG_PS_RDY))
2914 usbpd_set_state(pd, PE_SNK_STARTUP);
2915 else
2916 usbpd_set_state(pd, PE_ERROR_RECOVERY);
2917 break;
2918
2919 case PE_PRS_SNK_SRC_SEND_SWAP:
2920 if (!IS_CTRL(rx_msg, MSG_ACCEPT)) {
2921 pd->current_state = PE_SNK_READY;
2922 break;
2923 }
2924
2925 pd->in_pr_swap = true;
Jack Pham857ee682017-05-25 11:53:36 -07002926 val.intval = 1;
2927 power_supply_set_property(pd->usb_psy,
2928 POWER_SUPPLY_PROP_PR_SWAP, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08002929 usbpd_set_state(pd, PE_PRS_SNK_SRC_TRANSITION_TO_OFF);
2930 break;
2931
2932 case PE_PRS_SNK_SRC_TRANSITION_TO_OFF:
2933 if (!IS_CTRL(rx_msg, MSG_PS_RDY)) {
2934 usbpd_set_state(pd, PE_ERROR_RECOVERY);
2935 break;
2936 }
2937
2938 /* PE_PRS_SNK_SRC_Assert_Rp */
2939 pd->current_pr = PR_SRC;
2940 set_power_role(pd, pd->current_pr);
2941 pd->current_state = PE_PRS_SNK_SRC_SOURCE_ON;
2942
2943 /* fall-through */
2944
2945 case PE_PRS_SNK_SRC_SOURCE_ON:
2946 enable_vbus(pd);
Jack Phamf4baeb12017-02-03 19:01:48 -08002947
2948 ret = pd_send_msg(pd, MSG_PS_RDY, NULL, 0, SOP_MSG);
2949 if (ret) {
Jack Phamf4baeb12017-02-03 19:01:48 -08002950 usbpd_set_state(pd, PE_ERROR_RECOVERY);
2951 break;
2952 }
2953
2954 usbpd_set_state(pd, PE_SRC_STARTUP);
2955 break;
2956
2957 case PE_VCS_WAIT_FOR_VCONN:
2958 if (IS_CTRL(rx_msg, MSG_PS_RDY)) {
2959 /*
2960 * hopefully redundant check but in case not enabled
2961 * avoids unbalanced regulator disable count
2962 */
2963 if (pd->vconn_enabled)
2964 regulator_disable(pd->vconn);
2965 pd->vconn_enabled = false;
2966
2967 pd->current_state = pd->current_pr == PR_SRC ?
2968 PE_SRC_READY : PE_SNK_READY;
2969 } else {
2970 /* timed out; go to hard reset */
2971 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
2972 PE_SRC_HARD_RESET : PE_SNK_HARD_RESET);
2973 }
2974
2975 break;
2976
2977 default:
2978 usbpd_err(&pd->dev, "Unhandled state %s\n",
2979 usbpd_state_strings[pd->current_state]);
2980 break;
2981 }
2982
2983sm_done:
2984 kfree(rx_msg);
2985
Jack Pham564b4172017-05-24 18:41:53 -07002986 spin_lock_irqsave(&pd->rx_lock, flags);
2987 ret = list_empty(&pd->rx_q);
2988 spin_unlock_irqrestore(&pd->rx_lock, flags);
2989
2990 /* requeue if there are any new/pending RX messages */
2991 if (!ret)
2992 kick_sm(pd, 0);
2993
Jack Phamf4baeb12017-02-03 19:01:48 -08002994 if (!pd->sm_queued)
2995 pm_relax(&pd->dev);
2996}
2997
2998static inline const char *src_current(enum power_supply_typec_mode typec_mode)
2999{
3000 switch (typec_mode) {
3001 case POWER_SUPPLY_TYPEC_SOURCE_DEFAULT:
3002 return "default";
3003 case POWER_SUPPLY_TYPEC_SOURCE_MEDIUM:
3004 return "medium - 1.5A";
3005 case POWER_SUPPLY_TYPEC_SOURCE_HIGH:
3006 return "high - 3.0A";
3007 default:
3008 return "";
3009 }
3010}
3011
3012static int psy_changed(struct notifier_block *nb, unsigned long evt, void *ptr)
3013{
3014 struct usbpd *pd = container_of(nb, struct usbpd, psy_nb);
3015 union power_supply_propval val;
3016 enum power_supply_typec_mode typec_mode;
3017 int ret;
3018
3019 if (ptr != pd->usb_psy || evt != PSY_EVENT_PROP_CHANGED)
3020 return 0;
3021
3022 ret = power_supply_get_property(pd->usb_psy,
3023 POWER_SUPPLY_PROP_TYPEC_MODE, &val);
3024 if (ret) {
3025 usbpd_err(&pd->dev, "Unable to read USB TYPEC_MODE: %d\n", ret);
3026 return ret;
3027 }
3028
3029 typec_mode = val.intval;
3030
3031 ret = power_supply_get_property(pd->usb_psy,
3032 POWER_SUPPLY_PROP_PE_START, &val);
3033 if (ret) {
3034 usbpd_err(&pd->dev, "Unable to read USB PROP_PE_START: %d\n",
3035 ret);
3036 return ret;
3037 }
3038
3039 /* Don't proceed if PE_START=0 as other props may still change */
3040 if (!val.intval && !pd->pd_connected &&
3041 typec_mode != POWER_SUPPLY_TYPEC_NONE)
3042 return 0;
3043
3044 ret = power_supply_get_property(pd->usb_psy,
3045 POWER_SUPPLY_PROP_PRESENT, &val);
3046 if (ret) {
3047 usbpd_err(&pd->dev, "Unable to read USB PRESENT: %d\n", ret);
3048 return ret;
3049 }
3050
3051 pd->vbus_present = val.intval;
3052
3053 ret = power_supply_get_property(pd->usb_psy,
Fenglin Wu80826e02017-04-25 21:45:08 +08003054 POWER_SUPPLY_PROP_REAL_TYPE, &val);
Jack Phamf4baeb12017-02-03 19:01:48 -08003055 if (ret) {
3056 usbpd_err(&pd->dev, "Unable to read USB TYPE: %d\n", ret);
3057 return ret;
3058 }
3059
3060 pd->psy_type = val.intval;
3061
3062 /*
3063 * For sink hard reset, state machine needs to know when VBUS changes
3064 * - when in PE_SNK_TRANSITION_TO_DEFAULT, notify when VBUS falls
3065 * - when in PE_SNK_DISCOVERY, notify when VBUS rises
3066 */
3067 if (typec_mode && ((!pd->vbus_present &&
3068 pd->current_state == PE_SNK_TRANSITION_TO_DEFAULT) ||
3069 (pd->vbus_present && pd->current_state == PE_SNK_DISCOVERY))) {
3070 usbpd_dbg(&pd->dev, "hard reset: typec mode:%d present:%d\n",
3071 typec_mode, pd->vbus_present);
3072 pd->typec_mode = typec_mode;
3073 kick_sm(pd, 0);
3074 return 0;
3075 }
3076
3077 if (pd->typec_mode == typec_mode)
3078 return 0;
3079
3080 pd->typec_mode = typec_mode;
3081
3082 usbpd_dbg(&pd->dev, "typec mode:%d present:%d type:%d orientation:%d\n",
3083 typec_mode, pd->vbus_present, pd->psy_type,
3084 usbpd_get_plug_orientation(pd));
3085
3086 switch (typec_mode) {
3087 /* Disconnect */
3088 case POWER_SUPPLY_TYPEC_NONE:
3089 if (pd->in_pr_swap) {
3090 usbpd_dbg(&pd->dev, "Ignoring disconnect due to PR swap\n");
3091 return 0;
3092 }
3093
3094 pd->current_pr = PR_NONE;
3095 break;
3096
3097 /* Sink states */
3098 case POWER_SUPPLY_TYPEC_SOURCE_DEFAULT:
3099 case POWER_SUPPLY_TYPEC_SOURCE_MEDIUM:
3100 case POWER_SUPPLY_TYPEC_SOURCE_HIGH:
3101 usbpd_info(&pd->dev, "Type-C Source (%s) connected\n",
3102 src_current(typec_mode));
3103
3104 /* if waiting for SinkTxOk to start an AMS */
3105 if (pd->spec_rev == USBPD_REV_30 &&
3106 typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH &&
3107 (pd->send_pr_swap || pd->send_dr_swap || pd->vdm_tx))
3108 break;
3109
3110 if (pd->current_pr == PR_SINK)
3111 return 0;
3112
Jack Phamd434a412017-07-24 10:05:05 -07003113 /*
3114 * Unexpected if not in PR swap; need to force disconnect from
3115 * source so we can turn off VBUS, Vconn, PD PHY etc.
3116 */
3117 if (pd->current_pr == PR_SRC) {
3118 usbpd_info(&pd->dev, "Forcing disconnect from source mode\n");
3119 pd->current_pr = PR_NONE;
3120 break;
3121 }
3122
Jack Phamf4baeb12017-02-03 19:01:48 -08003123 pd->current_pr = PR_SINK;
3124 break;
3125
3126 /* Source states */
3127 case POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE:
3128 case POWER_SUPPLY_TYPEC_SINK:
3129 usbpd_info(&pd->dev, "Type-C Sink%s connected\n",
3130 typec_mode == POWER_SUPPLY_TYPEC_SINK ?
3131 "" : " (powered)");
3132
3133 if (pd->current_pr == PR_SRC)
3134 return 0;
3135
3136 pd->current_pr = PR_SRC;
3137 break;
3138
3139 case POWER_SUPPLY_TYPEC_SINK_DEBUG_ACCESSORY:
3140 usbpd_info(&pd->dev, "Type-C Debug Accessory connected\n");
3141 break;
3142 case POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER:
3143 usbpd_info(&pd->dev, "Type-C Analog Audio Adapter connected\n");
3144 break;
3145 default:
3146 usbpd_warn(&pd->dev, "Unsupported typec mode:%d\n",
3147 typec_mode);
3148 break;
3149 }
3150
3151 /* queue state machine due to CC state change */
3152 kick_sm(pd, 0);
3153 return 0;
3154}
3155
3156static enum dual_role_property usbpd_dr_properties[] = {
3157 DUAL_ROLE_PROP_SUPPORTED_MODES,
3158 DUAL_ROLE_PROP_MODE,
3159 DUAL_ROLE_PROP_PR,
3160 DUAL_ROLE_PROP_DR,
3161};
3162
3163static int usbpd_dr_get_property(struct dual_role_phy_instance *dual_role,
3164 enum dual_role_property prop, unsigned int *val)
3165{
3166 struct usbpd *pd = dual_role_get_drvdata(dual_role);
3167
3168 if (!pd)
3169 return -ENODEV;
3170
3171 switch (prop) {
3172 case DUAL_ROLE_PROP_MODE:
3173 /* For now associate UFP/DFP with data role only */
3174 if (pd->current_dr == DR_UFP)
3175 *val = DUAL_ROLE_PROP_MODE_UFP;
3176 else if (pd->current_dr == DR_DFP)
3177 *val = DUAL_ROLE_PROP_MODE_DFP;
3178 else
3179 *val = DUAL_ROLE_PROP_MODE_NONE;
3180 break;
3181 case DUAL_ROLE_PROP_PR:
3182 if (pd->current_pr == PR_SRC)
3183 *val = DUAL_ROLE_PROP_PR_SRC;
3184 else if (pd->current_pr == PR_SINK)
3185 *val = DUAL_ROLE_PROP_PR_SNK;
3186 else
3187 *val = DUAL_ROLE_PROP_PR_NONE;
3188 break;
3189 case DUAL_ROLE_PROP_DR:
3190 if (pd->current_dr == DR_UFP)
3191 *val = DUAL_ROLE_PROP_DR_DEVICE;
3192 else if (pd->current_dr == DR_DFP)
3193 *val = DUAL_ROLE_PROP_DR_HOST;
3194 else
3195 *val = DUAL_ROLE_PROP_DR_NONE;
3196 break;
3197 default:
3198 usbpd_warn(&pd->dev, "unsupported property %d\n", prop);
3199 return -ENODATA;
3200 }
3201
3202 return 0;
3203}
3204
3205static int usbpd_dr_set_property(struct dual_role_phy_instance *dual_role,
3206 enum dual_role_property prop, const unsigned int *val)
3207{
3208 struct usbpd *pd = dual_role_get_drvdata(dual_role);
3209 bool do_swap = false;
3210
3211 if (!pd)
3212 return -ENODEV;
3213
3214 switch (prop) {
3215 case DUAL_ROLE_PROP_MODE:
3216 usbpd_dbg(&pd->dev, "Setting mode to %d\n", *val);
3217
3218 /*
3219 * Forces disconnect on CC and re-establishes connection.
3220 * This does not use PD-based PR/DR swap
3221 */
3222 if (*val == DUAL_ROLE_PROP_MODE_UFP)
3223 pd->forced_pr = POWER_SUPPLY_TYPEC_PR_SINK;
3224 else if (*val == DUAL_ROLE_PROP_MODE_DFP)
3225 pd->forced_pr = POWER_SUPPLY_TYPEC_PR_SOURCE;
3226
3227 /* new mode will be applied in disconnect handler */
3228 set_power_role(pd, PR_NONE);
3229
3230 /* wait until it takes effect */
3231 while (pd->forced_pr != POWER_SUPPLY_TYPEC_PR_NONE)
3232 msleep(20);
3233
3234 break;
3235
3236 case DUAL_ROLE_PROP_DR:
3237 usbpd_dbg(&pd->dev, "Setting data_role to %d\n", *val);
3238
3239 if (*val == DUAL_ROLE_PROP_DR_HOST) {
3240 if (pd->current_dr == DR_UFP)
3241 do_swap = true;
3242 } else if (*val == DUAL_ROLE_PROP_DR_DEVICE) {
3243 if (pd->current_dr == DR_DFP)
3244 do_swap = true;
3245 } else {
3246 usbpd_warn(&pd->dev, "setting data_role to 'none' unsupported\n");
3247 return -ENOTSUPP;
3248 }
3249
3250 if (do_swap) {
3251 if (pd->current_state != PE_SRC_READY &&
3252 pd->current_state != PE_SNK_READY) {
3253 usbpd_err(&pd->dev, "data_role swap not allowed: PD not in Ready state\n");
3254 return -EAGAIN;
3255 }
3256
3257 if (pd->current_state == PE_SNK_READY &&
3258 !is_sink_tx_ok(pd)) {
3259 usbpd_err(&pd->dev, "Rp indicates SinkTxNG\n");
3260 return -EAGAIN;
3261 }
3262
Jack Phamaf7d3842017-01-26 13:28:19 -08003263 mutex_lock(&pd->swap_lock);
3264 reinit_completion(&pd->is_ready);
Jack Phamf4baeb12017-02-03 19:01:48 -08003265 pd->send_dr_swap = true;
3266 kick_sm(pd, 0);
3267
3268 /* wait for operation to complete */
Jack Phamaf7d3842017-01-26 13:28:19 -08003269 if (!wait_for_completion_timeout(&pd->is_ready,
Jack Phamf4baeb12017-02-03 19:01:48 -08003270 msecs_to_jiffies(100))) {
3271 usbpd_err(&pd->dev, "data_role swap timed out\n");
Jack Phamaf7d3842017-01-26 13:28:19 -08003272 mutex_unlock(&pd->swap_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08003273 return -ETIMEDOUT;
3274 }
3275
Jack Phamaf7d3842017-01-26 13:28:19 -08003276 mutex_unlock(&pd->swap_lock);
3277
Jack Phamf4baeb12017-02-03 19:01:48 -08003278 if ((*val == DUAL_ROLE_PROP_DR_HOST &&
3279 pd->current_dr != DR_DFP) ||
3280 (*val == DUAL_ROLE_PROP_DR_DEVICE &&
3281 pd->current_dr != DR_UFP)) {
3282 usbpd_err(&pd->dev, "incorrect state (%s) after data_role swap\n",
3283 pd->current_dr == DR_DFP ?
3284 "dfp" : "ufp");
3285 return -EPROTO;
3286 }
3287 }
3288
3289 break;
3290
3291 case DUAL_ROLE_PROP_PR:
3292 usbpd_dbg(&pd->dev, "Setting power_role to %d\n", *val);
3293
3294 if (*val == DUAL_ROLE_PROP_PR_SRC) {
3295 if (pd->current_pr == PR_SINK)
3296 do_swap = true;
3297 } else if (*val == DUAL_ROLE_PROP_PR_SNK) {
3298 if (pd->current_pr == PR_SRC)
3299 do_swap = true;
3300 } else {
3301 usbpd_warn(&pd->dev, "setting power_role to 'none' unsupported\n");
3302 return -ENOTSUPP;
3303 }
3304
3305 if (do_swap) {
3306 if (pd->current_state != PE_SRC_READY &&
3307 pd->current_state != PE_SNK_READY) {
3308 usbpd_err(&pd->dev, "power_role swap not allowed: PD not in Ready state\n");
3309 return -EAGAIN;
3310 }
3311
3312 if (pd->current_state == PE_SNK_READY &&
3313 !is_sink_tx_ok(pd)) {
3314 usbpd_err(&pd->dev, "Rp indicates SinkTxNG\n");
3315 return -EAGAIN;
3316 }
3317
Jack Phamaf7d3842017-01-26 13:28:19 -08003318 mutex_lock(&pd->swap_lock);
3319 reinit_completion(&pd->is_ready);
Jack Phamf4baeb12017-02-03 19:01:48 -08003320 pd->send_pr_swap = true;
3321 kick_sm(pd, 0);
3322
3323 /* wait for operation to complete */
Jack Phamaf7d3842017-01-26 13:28:19 -08003324 if (!wait_for_completion_timeout(&pd->is_ready,
Jack Phamf4baeb12017-02-03 19:01:48 -08003325 msecs_to_jiffies(2000))) {
3326 usbpd_err(&pd->dev, "power_role swap timed out\n");
Jack Phamaf7d3842017-01-26 13:28:19 -08003327 mutex_unlock(&pd->swap_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08003328 return -ETIMEDOUT;
3329 }
3330
Jack Phamaf7d3842017-01-26 13:28:19 -08003331 mutex_unlock(&pd->swap_lock);
3332
Jack Phamf4baeb12017-02-03 19:01:48 -08003333 if ((*val == DUAL_ROLE_PROP_PR_SRC &&
3334 pd->current_pr != PR_SRC) ||
3335 (*val == DUAL_ROLE_PROP_PR_SNK &&
3336 pd->current_pr != PR_SINK)) {
3337 usbpd_err(&pd->dev, "incorrect state (%s) after power_role swap\n",
3338 pd->current_pr == PR_SRC ?
3339 "source" : "sink");
3340 return -EPROTO;
3341 }
3342 }
3343 break;
3344
3345 default:
3346 usbpd_warn(&pd->dev, "unsupported property %d\n", prop);
3347 return -ENOTSUPP;
3348 }
3349
3350 return 0;
3351}
3352
3353static int usbpd_dr_prop_writeable(struct dual_role_phy_instance *dual_role,
3354 enum dual_role_property prop)
3355{
Jack Phame232bde2017-03-02 11:37:00 -08003356 struct usbpd *pd = dual_role_get_drvdata(dual_role);
3357
Jack Phamf4baeb12017-02-03 19:01:48 -08003358 switch (prop) {
3359 case DUAL_ROLE_PROP_MODE:
Jack Phame232bde2017-03-02 11:37:00 -08003360 return 1;
Jack Phamf4baeb12017-02-03 19:01:48 -08003361 case DUAL_ROLE_PROP_DR:
3362 case DUAL_ROLE_PROP_PR:
Jack Phame232bde2017-03-02 11:37:00 -08003363 if (pd)
3364 return pd->current_state == PE_SNK_READY ||
3365 pd->current_state == PE_SRC_READY;
3366 break;
Jack Phamf4baeb12017-02-03 19:01:48 -08003367 default:
3368 break;
3369 }
3370
3371 return 0;
3372}
3373
3374static int usbpd_uevent(struct device *dev, struct kobj_uevent_env *env)
3375{
3376 struct usbpd *pd = dev_get_drvdata(dev);
3377 int i;
3378
3379 add_uevent_var(env, "DATA_ROLE=%s", pd->current_dr == DR_DFP ?
3380 "dfp" : "ufp");
3381
3382 if (pd->current_pr == PR_SINK) {
3383 add_uevent_var(env, "POWER_ROLE=sink");
3384 add_uevent_var(env, "SRC_CAP_ID=%d", pd->src_cap_id);
3385
3386 for (i = 0; i < ARRAY_SIZE(pd->received_pdos); i++)
3387 add_uevent_var(env, "PDO%d=%08x", i,
3388 pd->received_pdos[i]);
3389
3390 add_uevent_var(env, "REQUESTED_PDO=%d", pd->requested_pdo);
3391 add_uevent_var(env, "SELECTED_PDO=%d", pd->selected_pdo);
3392 } else {
3393 add_uevent_var(env, "POWER_ROLE=source");
3394 for (i = 0; i < ARRAY_SIZE(default_src_caps); i++)
3395 add_uevent_var(env, "PDO%d=%08x", i,
3396 default_src_caps[i]);
3397 }
3398
3399 add_uevent_var(env, "RDO=%08x", pd->rdo);
3400 add_uevent_var(env, "CONTRACT=%s", pd->in_explicit_contract ?
3401 "explicit" : "implicit");
3402 add_uevent_var(env, "ALT_MODE=%d", pd->vdm_state == MODE_ENTERED);
3403
Jack Phamda401d72018-06-07 19:29:52 -07003404 add_uevent_var(env, "SDB=%02x %02x %02x %02x %02x", pd->status_db[0],
3405 pd->status_db[1], pd->status_db[2], pd->status_db[3],
3406 pd->status_db[4]);
Hemant Kumara1875942017-08-09 16:50:14 -07003407
Jack Phamf4baeb12017-02-03 19:01:48 -08003408 return 0;
3409}
3410
3411static ssize_t contract_show(struct device *dev, struct device_attribute *attr,
3412 char *buf)
3413{
3414 struct usbpd *pd = dev_get_drvdata(dev);
3415
3416 return snprintf(buf, PAGE_SIZE, "%s\n",
3417 pd->in_explicit_contract ? "explicit" : "implicit");
3418}
3419static DEVICE_ATTR_RO(contract);
3420
3421static ssize_t current_pr_show(struct device *dev,
3422 struct device_attribute *attr, char *buf)
3423{
3424 struct usbpd *pd = dev_get_drvdata(dev);
3425 const char *pr = "none";
3426
3427 if (pd->current_pr == PR_SINK)
3428 pr = "sink";
3429 else if (pd->current_pr == PR_SRC)
3430 pr = "source";
3431
3432 return snprintf(buf, PAGE_SIZE, "%s\n", pr);
3433}
3434static DEVICE_ATTR_RO(current_pr);
3435
3436static ssize_t initial_pr_show(struct device *dev,
3437 struct device_attribute *attr, char *buf)
3438{
3439 struct usbpd *pd = dev_get_drvdata(dev);
3440 const char *pr = "none";
3441
3442 if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT)
3443 pr = "sink";
3444 else if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SINK)
3445 pr = "source";
3446
3447 return snprintf(buf, PAGE_SIZE, "%s\n", pr);
3448}
3449static DEVICE_ATTR_RO(initial_pr);
3450
3451static ssize_t current_dr_show(struct device *dev,
3452 struct device_attribute *attr, char *buf)
3453{
3454 struct usbpd *pd = dev_get_drvdata(dev);
3455 const char *dr = "none";
3456
3457 if (pd->current_dr == DR_UFP)
3458 dr = "ufp";
3459 else if (pd->current_dr == DR_DFP)
3460 dr = "dfp";
3461
3462 return snprintf(buf, PAGE_SIZE, "%s\n", dr);
3463}
3464static DEVICE_ATTR_RO(current_dr);
3465
3466static ssize_t initial_dr_show(struct device *dev,
3467 struct device_attribute *attr, char *buf)
3468{
3469 struct usbpd *pd = dev_get_drvdata(dev);
3470 const char *dr = "none";
3471
3472 if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT)
3473 dr = "ufp";
3474 else if (pd->typec_mode >= POWER_SUPPLY_TYPEC_SINK)
3475 dr = "dfp";
3476
3477 return snprintf(buf, PAGE_SIZE, "%s\n", dr);
3478}
3479static DEVICE_ATTR_RO(initial_dr);
3480
3481static ssize_t src_cap_id_show(struct device *dev,
3482 struct device_attribute *attr, char *buf)
3483{
3484 struct usbpd *pd = dev_get_drvdata(dev);
3485
3486 return snprintf(buf, PAGE_SIZE, "%d\n", pd->src_cap_id);
3487}
3488static DEVICE_ATTR_RO(src_cap_id);
3489
3490/* Dump received source PDOs in human-readable format */
3491static ssize_t pdo_h_show(struct device *dev, struct device_attribute *attr,
3492 char *buf)
3493{
3494 struct usbpd *pd = dev_get_drvdata(dev);
3495 int i;
3496 ssize_t cnt = 0;
3497
3498 for (i = 0; i < ARRAY_SIZE(pd->received_pdos); i++) {
3499 u32 pdo = pd->received_pdos[i];
3500
3501 if (pdo == 0)
3502 break;
3503
3504 cnt += scnprintf(&buf[cnt], PAGE_SIZE - cnt, "PDO %d\n", i + 1);
3505
3506 if (PD_SRC_PDO_TYPE(pdo) == PD_SRC_PDO_TYPE_FIXED) {
3507 cnt += scnprintf(&buf[cnt], PAGE_SIZE - cnt,
3508 "\tFixed supply\n"
3509 "\tDual-Role Power:%d\n"
3510 "\tUSB Suspend Supported:%d\n"
3511 "\tExternally Powered:%d\n"
3512 "\tUSB Communications Capable:%d\n"
3513 "\tData Role Swap:%d\n"
3514 "\tPeak Current:%d\n"
3515 "\tVoltage:%d (mV)\n"
3516 "\tMax Current:%d (mA)\n",
3517 PD_SRC_PDO_FIXED_PR_SWAP(pdo),
3518 PD_SRC_PDO_FIXED_USB_SUSP(pdo),
3519 PD_SRC_PDO_FIXED_EXT_POWERED(pdo),
3520 PD_SRC_PDO_FIXED_USB_COMM(pdo),
3521 PD_SRC_PDO_FIXED_DR_SWAP(pdo),
3522 PD_SRC_PDO_FIXED_PEAK_CURR(pdo),
3523 PD_SRC_PDO_FIXED_VOLTAGE(pdo) * 50,
3524 PD_SRC_PDO_FIXED_MAX_CURR(pdo) * 10);
3525 } else if (PD_SRC_PDO_TYPE(pdo) == PD_SRC_PDO_TYPE_BATTERY) {
3526 cnt += scnprintf(&buf[cnt], PAGE_SIZE - cnt,
3527 "\tBattery supply\n"
3528 "\tMax Voltage:%d (mV)\n"
3529 "\tMin Voltage:%d (mV)\n"
3530 "\tMax Power:%d (mW)\n",
3531 PD_SRC_PDO_VAR_BATT_MAX_VOLT(pdo) * 50,
3532 PD_SRC_PDO_VAR_BATT_MIN_VOLT(pdo) * 50,
3533 PD_SRC_PDO_VAR_BATT_MAX(pdo) * 250);
3534 } else if (PD_SRC_PDO_TYPE(pdo) == PD_SRC_PDO_TYPE_VARIABLE) {
3535 cnt += scnprintf(&buf[cnt], PAGE_SIZE - cnt,
3536 "\tVariable supply\n"
3537 "\tMax Voltage:%d (mV)\n"
3538 "\tMin Voltage:%d (mV)\n"
3539 "\tMax Current:%d (mA)\n",
3540 PD_SRC_PDO_VAR_BATT_MAX_VOLT(pdo) * 50,
3541 PD_SRC_PDO_VAR_BATT_MIN_VOLT(pdo) * 50,
3542 PD_SRC_PDO_VAR_BATT_MAX(pdo) * 10);
3543 } else if (PD_SRC_PDO_TYPE(pdo) == PD_SRC_PDO_TYPE_AUGMENTED) {
3544 cnt += scnprintf(&buf[cnt], PAGE_SIZE - cnt,
3545 "\tProgrammable Power supply\n"
3546 "\tMax Voltage:%d (mV)\n"
3547 "\tMin Voltage:%d (mV)\n"
3548 "\tMax Current:%d (mA)\n",
3549 PD_APDO_MAX_VOLT(pdo) * 100,
3550 PD_APDO_MIN_VOLT(pdo) * 100,
3551 PD_APDO_MAX_CURR(pdo) * 50);
3552 } else {
3553 cnt += scnprintf(&buf[cnt], PAGE_SIZE - cnt,
3554 "Invalid PDO\n");
3555 }
3556
3557 buf[cnt++] = '\n';
3558 }
3559
3560 return cnt;
3561}
3562static DEVICE_ATTR_RO(pdo_h);
3563
3564static ssize_t pdo_n_show(struct device *dev, struct device_attribute *attr,
3565 char *buf);
3566
3567#define PDO_ATTR(n) { \
3568 .attr = { .name = __stringify(pdo##n), .mode = 0444 }, \
3569 .show = pdo_n_show, \
3570}
3571static struct device_attribute dev_attr_pdos[] = {
3572 PDO_ATTR(1),
3573 PDO_ATTR(2),
3574 PDO_ATTR(3),
3575 PDO_ATTR(4),
3576 PDO_ATTR(5),
3577 PDO_ATTR(6),
3578 PDO_ATTR(7),
3579};
3580
3581static ssize_t pdo_n_show(struct device *dev, struct device_attribute *attr,
3582 char *buf)
3583{
3584 struct usbpd *pd = dev_get_drvdata(dev);
3585 int i;
3586
3587 for (i = 0; i < ARRAY_SIZE(dev_attr_pdos); i++)
3588 if (attr == &dev_attr_pdos[i])
3589 /* dump the PDO as a hex string */
3590 return snprintf(buf, PAGE_SIZE, "%08x\n",
3591 pd->received_pdos[i]);
3592
3593 usbpd_err(&pd->dev, "Invalid PDO index\n");
3594 return -EINVAL;
3595}
3596
3597static ssize_t select_pdo_store(struct device *dev,
3598 struct device_attribute *attr, const char *buf, size_t size)
3599{
3600 struct usbpd *pd = dev_get_drvdata(dev);
3601 int src_cap_id;
3602 int pdo, uv = 0, ua = 0;
3603 int ret;
3604
Jack Phamaf7d3842017-01-26 13:28:19 -08003605 mutex_lock(&pd->swap_lock);
3606
Jack Phamf4baeb12017-02-03 19:01:48 -08003607 /* Only allowed if we are already in explicit sink contract */
3608 if (pd->current_state != PE_SNK_READY || !is_sink_tx_ok(pd)) {
3609 usbpd_err(&pd->dev, "select_pdo: Cannot select new PDO yet\n");
Jack Phamaf7d3842017-01-26 13:28:19 -08003610 ret = -EBUSY;
3611 goto out;
Jack Phamf4baeb12017-02-03 19:01:48 -08003612 }
3613
3614 ret = sscanf(buf, "%d %d %d %d", &src_cap_id, &pdo, &uv, &ua);
3615 if (ret != 2 && ret != 4) {
3616 usbpd_err(&pd->dev, "select_pdo: Must specify <src cap id> <PDO> [<uV> <uA>]\n");
Jack Phamaf7d3842017-01-26 13:28:19 -08003617 ret = -EINVAL;
3618 goto out;
Jack Phamf4baeb12017-02-03 19:01:48 -08003619 }
3620
3621 if (src_cap_id != pd->src_cap_id) {
3622 usbpd_err(&pd->dev, "select_pdo: src_cap_id mismatch. Requested:%d, current:%d\n",
3623 src_cap_id, pd->src_cap_id);
Jack Phamaf7d3842017-01-26 13:28:19 -08003624 ret = -EINVAL;
3625 goto out;
Jack Phamf4baeb12017-02-03 19:01:48 -08003626 }
3627
3628 if (pdo < 1 || pdo > 7) {
3629 usbpd_err(&pd->dev, "select_pdo: invalid PDO:%d\n", pdo);
Jack Phamaf7d3842017-01-26 13:28:19 -08003630 ret = -EINVAL;
3631 goto out;
Jack Phamf4baeb12017-02-03 19:01:48 -08003632 }
3633
3634 ret = pd_select_pdo(pd, pdo, uv, ua);
3635 if (ret)
Jack Phamaf7d3842017-01-26 13:28:19 -08003636 goto out;
Jack Phamf4baeb12017-02-03 19:01:48 -08003637
Jack Phamaf7d3842017-01-26 13:28:19 -08003638 reinit_completion(&pd->is_ready);
3639 pd->send_request = true;
3640 kick_sm(pd, 0);
Jack Phamf4baeb12017-02-03 19:01:48 -08003641
Jack Phamaf7d3842017-01-26 13:28:19 -08003642 /* wait for operation to complete */
3643 if (!wait_for_completion_timeout(&pd->is_ready,
3644 msecs_to_jiffies(1000))) {
3645 usbpd_err(&pd->dev, "select_pdo: request timed out\n");
3646 ret = -ETIMEDOUT;
3647 goto out;
3648 }
3649
3650 /* determine if request was accepted/rejected */
3651 if (pd->selected_pdo != pd->requested_pdo ||
3652 pd->current_voltage != pd->requested_voltage) {
3653 usbpd_err(&pd->dev, "select_pdo: request rejected\n");
3654 ret = -EINVAL;
3655 }
3656
3657out:
3658 pd->send_request = false;
3659 mutex_unlock(&pd->swap_lock);
3660 return ret ? ret : size;
Jack Phamf4baeb12017-02-03 19:01:48 -08003661}
3662
3663static ssize_t select_pdo_show(struct device *dev,
3664 struct device_attribute *attr, char *buf)
3665{
3666 struct usbpd *pd = dev_get_drvdata(dev);
3667
3668 return snprintf(buf, PAGE_SIZE, "%d\n", pd->selected_pdo);
3669}
3670static DEVICE_ATTR_RW(select_pdo);
3671
3672static ssize_t rdo_show(struct device *dev, struct device_attribute *attr,
3673 char *buf)
3674{
3675 struct usbpd *pd = dev_get_drvdata(dev);
3676
3677 /* dump the RDO as a hex string */
3678 return snprintf(buf, PAGE_SIZE, "%08x\n", pd->rdo);
3679}
3680static DEVICE_ATTR_RO(rdo);
3681
3682static ssize_t rdo_h_show(struct device *dev, struct device_attribute *attr,
3683 char *buf)
3684{
3685 struct usbpd *pd = dev_get_drvdata(dev);
3686 int pos = PD_RDO_OBJ_POS(pd->rdo);
Jack Pham6452ab12018-04-04 18:43:34 -07003687 int type = PD_SRC_PDO_TYPE(pd->received_pdos[pos - 1]);
Jack Phamf4baeb12017-02-03 19:01:48 -08003688 int len;
3689
3690 len = scnprintf(buf, PAGE_SIZE, "Request Data Object\n"
3691 "\tObj Pos:%d\n"
3692 "\tGiveback:%d\n"
3693 "\tCapability Mismatch:%d\n"
3694 "\tUSB Communications Capable:%d\n"
3695 "\tNo USB Suspend:%d\n",
3696 PD_RDO_OBJ_POS(pd->rdo),
3697 PD_RDO_GIVEBACK(pd->rdo),
3698 PD_RDO_MISMATCH(pd->rdo),
3699 PD_RDO_USB_COMM(pd->rdo),
3700 PD_RDO_NO_USB_SUSP(pd->rdo));
3701
3702 switch (type) {
3703 case PD_SRC_PDO_TYPE_FIXED:
3704 case PD_SRC_PDO_TYPE_VARIABLE:
3705 len += scnprintf(buf + len, PAGE_SIZE - len,
3706 "(Fixed/Variable)\n"
3707 "\tOperating Current:%d (mA)\n"
3708 "\t%s Current:%d (mA)\n",
3709 PD_RDO_FIXED_CURR(pd->rdo) * 10,
3710 PD_RDO_GIVEBACK(pd->rdo) ? "Min" : "Max",
3711 PD_RDO_FIXED_CURR_MINMAX(pd->rdo) * 10);
3712 break;
3713
3714 case PD_SRC_PDO_TYPE_BATTERY:
3715 len += scnprintf(buf + len, PAGE_SIZE - len,
3716 "(Battery)\n"
3717 "\tOperating Power:%d (mW)\n"
3718 "\t%s Power:%d (mW)\n",
3719 PD_RDO_FIXED_CURR(pd->rdo) * 250,
3720 PD_RDO_GIVEBACK(pd->rdo) ? "Min" : "Max",
3721 PD_RDO_FIXED_CURR_MINMAX(pd->rdo) * 250);
3722 break;
3723
3724 case PD_SRC_PDO_TYPE_AUGMENTED:
3725 len += scnprintf(buf + len, PAGE_SIZE - len,
3726 "(Programmable)\n"
3727 "\tOutput Voltage:%d (mV)\n"
3728 "\tOperating Current:%d (mA)\n",
3729 PD_RDO_PROG_VOLTAGE(pd->rdo) * 20,
3730 PD_RDO_PROG_CURR(pd->rdo) * 50);
3731 break;
3732 }
3733
3734 return len;
3735}
3736static DEVICE_ATTR_RO(rdo_h);
3737
3738static ssize_t hard_reset_store(struct device *dev,
3739 struct device_attribute *attr, const char *buf, size_t size)
3740{
3741 struct usbpd *pd = dev_get_drvdata(dev);
3742 int val = 0;
3743
3744 if (sscanf(buf, "%d\n", &val) != 1)
3745 return -EINVAL;
3746
3747 if (val)
3748 usbpd_set_state(pd, pd->current_pr == PR_SRC ?
3749 PE_SRC_HARD_RESET : PE_SNK_HARD_RESET);
3750
3751 return size;
3752}
3753static DEVICE_ATTR_WO(hard_reset);
3754
Hemant Kumar018b5982017-08-09 14:14:37 -07003755static int trigger_tx_msg(struct usbpd *pd, bool *msg_tx_flag)
3756{
3757 int ret = 0;
3758
3759 /* Only allowed if we are already in explicit sink contract */
3760 if (pd->current_state != PE_SNK_READY || !is_sink_tx_ok(pd)) {
3761 usbpd_err(&pd->dev, "%s: Cannot send msg\n", __func__);
3762 ret = -EBUSY;
3763 goto out;
3764 }
3765
3766 reinit_completion(&pd->is_ready);
3767 *msg_tx_flag = true;
3768 kick_sm(pd, 0);
3769
3770 /* wait for operation to complete */
3771 if (!wait_for_completion_timeout(&pd->is_ready,
3772 msecs_to_jiffies(1000))) {
3773 usbpd_err(&pd->dev, "%s: request timed out\n", __func__);
3774 ret = -ETIMEDOUT;
3775 }
3776
3777out:
3778 *msg_tx_flag = false;
3779 return ret;
3780
3781}
3782
3783static ssize_t get_src_cap_ext_show(struct device *dev,
3784 struct device_attribute *attr, char *buf)
3785{
3786 int i, ret, len = 0;
3787 struct usbpd *pd = dev_get_drvdata(dev);
3788
3789 if (pd->spec_rev == USBPD_REV_20)
3790 return -EINVAL;
3791
3792 ret = trigger_tx_msg(pd, &pd->send_get_src_cap_ext);
3793 if (ret)
3794 return ret;
3795
3796 for (i = 0; i < PD_SRC_CAP_EXT_DB_LEN; i++)
Jack Pham408bc5c2018-06-13 11:57:49 -07003797 len += snprintf(buf + len, PAGE_SIZE - len, "%s0x%02x",
3798 i ? " " : "", pd->src_cap_ext_db[i]);
3799
3800 buf[len++] = '\n';
3801 buf[len] = '\0';
3802
Hemant Kumar018b5982017-08-09 14:14:37 -07003803 return len;
3804}
3805static DEVICE_ATTR_RO(get_src_cap_ext);
3806
Jack Phamda401d72018-06-07 19:29:52 -07003807static ssize_t get_status_show(struct device *dev,
3808 struct device_attribute *attr, char *buf)
3809{
3810 int i, ret, len = 0;
3811 struct usbpd *pd = dev_get_drvdata(dev);
3812
3813 if (pd->spec_rev == USBPD_REV_20)
3814 return -EINVAL;
3815
3816 ret = trigger_tx_msg(pd, &pd->send_get_status);
3817 if (ret)
3818 return ret;
3819
3820 for (i = 0; i < PD_STATUS_DB_LEN; i++)
3821 len += snprintf(buf + len, PAGE_SIZE - len, "%s0x%02x",
3822 i ? " " : "", pd->status_db[i]);
3823
3824 buf[len++] = '\n';
3825 buf[len] = '\0';
3826
3827 return len;
3828}
3829static DEVICE_ATTR_RO(get_status);
3830
Hemant Kumar018b5982017-08-09 14:14:37 -07003831static ssize_t get_pps_status_show(struct device *dev,
3832 struct device_attribute *attr, char *buf)
3833{
3834 int ret;
3835 struct usbpd *pd = dev_get_drvdata(dev);
3836
3837 if (pd->spec_rev == USBPD_REV_20)
3838 return -EINVAL;
3839
3840 ret = trigger_tx_msg(pd, &pd->send_get_pps_status);
3841 if (ret)
3842 return ret;
3843
Jack Pham408bc5c2018-06-13 11:57:49 -07003844 return snprintf(buf, PAGE_SIZE, "0x%08x\n", pd->pps_status_db);
Hemant Kumar018b5982017-08-09 14:14:37 -07003845}
3846static DEVICE_ATTR_RO(get_pps_status);
3847
Hemant Kumar51ded972017-08-09 17:57:24 -07003848static ssize_t get_battery_cap_store(struct device *dev,
3849 struct device_attribute *attr, const char *buf, size_t size)
3850{
3851 struct usbpd *pd = dev_get_drvdata(dev);
3852 int val, ret;
3853
3854 if (pd->spec_rev == USBPD_REV_20 || sscanf(buf, "%d\n", &val) != 1) {
3855 pd->get_battery_cap_db = -EINVAL;
3856 return -EINVAL;
3857 }
3858
3859 pd->get_battery_cap_db = val;
3860
3861 ret = trigger_tx_msg(pd, &pd->send_get_battery_cap);
3862
3863 return ret ? ret : size;
3864}
3865
3866static ssize_t get_battery_cap_show(struct device *dev,
3867 struct device_attribute *attr, char *buf)
3868{
3869 int i, len = 0;
3870 struct usbpd *pd = dev_get_drvdata(dev);
3871
3872 if (pd->get_battery_cap_db == -EINVAL)
3873 return -EINVAL;
3874
3875 for (i = 0; i < PD_BATTERY_CAP_DB_LEN; i++)
Jack Pham408bc5c2018-06-13 11:57:49 -07003876 len += snprintf(buf + len, PAGE_SIZE - len, "%s0x%02x",
3877 i ? " " : "", pd->battery_cap_db[i]);
3878
3879 buf[len++] = '\n';
3880 buf[len] = '\0';
3881
Hemant Kumar51ded972017-08-09 17:57:24 -07003882 return len;
3883}
3884static DEVICE_ATTR_RW(get_battery_cap);
3885
3886static ssize_t get_battery_status_store(struct device *dev,
3887 struct device_attribute *attr, const char *buf, size_t size)
3888{
3889 struct usbpd *pd = dev_get_drvdata(dev);
3890 int val, ret;
3891
3892 if (pd->spec_rev == USBPD_REV_20 || sscanf(buf, "%d\n", &val) != 1) {
3893 pd->get_battery_status_db = -EINVAL;
3894 return -EINVAL;
3895 }
3896
3897 pd->get_battery_status_db = val;
3898
3899 ret = trigger_tx_msg(pd, &pd->send_get_battery_status);
3900
3901 return ret ? ret : size;
3902}
3903
3904static ssize_t get_battery_status_show(struct device *dev,
3905 struct device_attribute *attr, char *buf)
3906{
3907 struct usbpd *pd = dev_get_drvdata(dev);
3908
3909 if (pd->get_battery_status_db == -EINVAL)
3910 return -EINVAL;
3911
Jack Pham408bc5c2018-06-13 11:57:49 -07003912 return snprintf(buf, PAGE_SIZE, "0x%08x\n", pd->battery_sts_dobj);
Hemant Kumar51ded972017-08-09 17:57:24 -07003913}
3914static DEVICE_ATTR_RW(get_battery_status);
3915
Jack Phamf4baeb12017-02-03 19:01:48 -08003916static struct attribute *usbpd_attrs[] = {
3917 &dev_attr_contract.attr,
3918 &dev_attr_initial_pr.attr,
3919 &dev_attr_current_pr.attr,
3920 &dev_attr_initial_dr.attr,
3921 &dev_attr_current_dr.attr,
3922 &dev_attr_src_cap_id.attr,
3923 &dev_attr_pdo_h.attr,
3924 &dev_attr_pdos[0].attr,
3925 &dev_attr_pdos[1].attr,
3926 &dev_attr_pdos[2].attr,
3927 &dev_attr_pdos[3].attr,
3928 &dev_attr_pdos[4].attr,
3929 &dev_attr_pdos[5].attr,
3930 &dev_attr_pdos[6].attr,
3931 &dev_attr_select_pdo.attr,
3932 &dev_attr_rdo.attr,
3933 &dev_attr_rdo_h.attr,
3934 &dev_attr_hard_reset.attr,
Hemant Kumar018b5982017-08-09 14:14:37 -07003935 &dev_attr_get_src_cap_ext.attr,
Jack Phamda401d72018-06-07 19:29:52 -07003936 &dev_attr_get_status.attr,
Hemant Kumar018b5982017-08-09 14:14:37 -07003937 &dev_attr_get_pps_status.attr,
Hemant Kumar51ded972017-08-09 17:57:24 -07003938 &dev_attr_get_battery_cap.attr,
3939 &dev_attr_get_battery_status.attr,
Jack Phamf4baeb12017-02-03 19:01:48 -08003940 NULL,
3941};
3942ATTRIBUTE_GROUPS(usbpd);
3943
3944static struct class usbpd_class = {
3945 .name = "usbpd",
3946 .owner = THIS_MODULE,
3947 .dev_uevent = usbpd_uevent,
3948 .dev_groups = usbpd_groups,
3949};
3950
3951static int match_usbpd_device(struct device *dev, const void *data)
3952{
3953 return dev->parent == data;
3954}
3955
3956static void devm_usbpd_put(struct device *dev, void *res)
3957{
3958 struct usbpd **ppd = res;
3959
3960 put_device(&(*ppd)->dev);
3961}
3962
3963struct usbpd *devm_usbpd_get_by_phandle(struct device *dev, const char *phandle)
3964{
3965 struct usbpd **ptr, *pd = NULL;
3966 struct device_node *pd_np;
3967 struct platform_device *pdev;
3968 struct device *pd_dev;
3969
3970 if (!usbpd_class.p) /* usbpd_init() not yet called */
3971 return ERR_PTR(-EAGAIN);
3972
3973 if (!dev->of_node)
3974 return ERR_PTR(-EINVAL);
3975
3976 pd_np = of_parse_phandle(dev->of_node, phandle, 0);
3977 if (!pd_np)
3978 return ERR_PTR(-ENXIO);
3979
3980 pdev = of_find_device_by_node(pd_np);
3981 if (!pdev)
3982 return ERR_PTR(-ENODEV);
3983
3984 pd_dev = class_find_device(&usbpd_class, NULL, &pdev->dev,
3985 match_usbpd_device);
3986 if (!pd_dev) {
3987 platform_device_put(pdev);
3988 /* device was found but maybe hadn't probed yet, so defer */
3989 return ERR_PTR(-EPROBE_DEFER);
3990 }
3991
3992 ptr = devres_alloc(devm_usbpd_put, sizeof(*ptr), GFP_KERNEL);
3993 if (!ptr) {
3994 put_device(pd_dev);
3995 platform_device_put(pdev);
3996 return ERR_PTR(-ENOMEM);
3997 }
3998
3999 pd = dev_get_drvdata(pd_dev);
4000 if (!pd)
4001 return ERR_PTR(-EPROBE_DEFER);
4002
4003 *ptr = pd;
4004 devres_add(dev, ptr);
4005
4006 return pd;
4007}
4008EXPORT_SYMBOL(devm_usbpd_get_by_phandle);
4009
4010static int num_pd_instances;
4011
4012/**
4013 * usbpd_create - Create a new instance of USB PD protocol/policy engine
4014 * @parent - parent device to associate with
4015 *
4016 * This creates a new usbpd class device which manages the state of a
4017 * USB PD-capable port. The parent device that is passed in should be
4018 * associated with the physical device port, e.g. a PD PHY.
4019 *
4020 * Return: struct usbpd pointer, or an ERR_PTR value
4021 */
4022struct usbpd *usbpd_create(struct device *parent)
4023{
4024 int ret;
4025 struct usbpd *pd;
4026
4027 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
4028 if (!pd)
4029 return ERR_PTR(-ENOMEM);
4030
4031 device_initialize(&pd->dev);
4032 pd->dev.class = &usbpd_class;
4033 pd->dev.parent = parent;
4034 dev_set_drvdata(&pd->dev, pd);
4035
4036 ret = dev_set_name(&pd->dev, "usbpd%d", num_pd_instances++);
4037 if (ret)
4038 goto free_pd;
4039
4040 ret = device_init_wakeup(&pd->dev, true);
4041 if (ret)
4042 goto free_pd;
4043
4044 ret = device_add(&pd->dev);
4045 if (ret)
4046 goto free_pd;
4047
Hemant Kumar86bd10f2017-05-24 12:25:15 -07004048 pd->wq = alloc_ordered_workqueue("usbpd_wq", WQ_FREEZABLE | WQ_HIGHPRI);
Jack Phamf4baeb12017-02-03 19:01:48 -08004049 if (!pd->wq) {
4050 ret = -ENOMEM;
4051 goto del_pd;
4052 }
4053 INIT_WORK(&pd->sm_work, usbpd_sm);
4054 hrtimer_init(&pd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
4055 pd->timer.function = pd_timeout;
Jack Phamaf7d3842017-01-26 13:28:19 -08004056 mutex_init(&pd->swap_lock);
Mayank Rana83443202017-08-31 15:38:03 -07004057 mutex_init(&pd->svid_handler_lock);
Jack Phamf4baeb12017-02-03 19:01:48 -08004058
4059 pd->usb_psy = power_supply_get_by_name("usb");
4060 if (!pd->usb_psy) {
4061 usbpd_dbg(&pd->dev, "Could not get USB power_supply, deferring probe\n");
4062 ret = -EPROBE_DEFER;
4063 goto destroy_wq;
4064 }
4065
Pratham Pratap033a2d92017-11-14 20:57:05 +05304066 if (get_connector_type(pd) == POWER_SUPPLY_CONNECTOR_MICRO_USB) {
4067 usbpd_dbg(&pd->dev, "USB connector is microAB hence failing pdphy_probe\n");
4068 ret = -EINVAL;
4069 goto put_psy;
4070 }
Jack Phamf4baeb12017-02-03 19:01:48 -08004071 /*
4072 * associate extcon with the parent dev as it could have a DT
4073 * node which will be useful for extcon_get_edev_by_phandle()
4074 */
4075 pd->extcon = devm_extcon_dev_allocate(parent, usbpd_extcon_cable);
4076 if (IS_ERR(pd->extcon)) {
4077 usbpd_err(&pd->dev, "failed to allocate extcon device\n");
4078 ret = PTR_ERR(pd->extcon);
4079 goto put_psy;
4080 }
4081
4082 pd->extcon->mutually_exclusive = usbpd_extcon_exclusive;
4083 ret = devm_extcon_dev_register(parent, pd->extcon);
4084 if (ret) {
4085 usbpd_err(&pd->dev, "failed to register extcon device\n");
4086 goto put_psy;
4087 }
4088
Jack Pham4e9dff72017-04-04 18:05:53 -07004089 /* Support reporting polarity and speed via properties */
4090 extcon_set_property_capability(pd->extcon, EXTCON_USB,
4091 EXTCON_PROP_USB_TYPEC_POLARITY);
4092 extcon_set_property_capability(pd->extcon, EXTCON_USB,
Vijayavardhan Vennapusadaeb5ac2018-07-13 13:04:17 +05304093 EXTCON_PROP_USB_PD_CONTRACT);
4094 extcon_set_property_capability(pd->extcon, EXTCON_USB,
Jack Pham4e9dff72017-04-04 18:05:53 -07004095 EXTCON_PROP_USB_SS);
4096 extcon_set_property_capability(pd->extcon, EXTCON_USB_HOST,
4097 EXTCON_PROP_USB_TYPEC_POLARITY);
4098 extcon_set_property_capability(pd->extcon, EXTCON_USB_HOST,
4099 EXTCON_PROP_USB_SS);
4100
Jack Phamf4baeb12017-02-03 19:01:48 -08004101 pd->vbus = devm_regulator_get(parent, "vbus");
4102 if (IS_ERR(pd->vbus)) {
4103 ret = PTR_ERR(pd->vbus);
4104 goto put_psy;
4105 }
4106
4107 pd->vconn = devm_regulator_get(parent, "vconn");
4108 if (IS_ERR(pd->vconn)) {
4109 ret = PTR_ERR(pd->vconn);
4110 goto put_psy;
4111 }
4112
4113 pd->vconn_is_external = device_property_present(parent,
4114 "qcom,vconn-uses-external-source");
4115
Jack Phamee1f9052017-01-26 12:27:07 -08004116 pd->num_sink_caps = device_property_read_u32_array(parent,
4117 "qcom,default-sink-caps", NULL, 0);
Vijayavardhan Vennapusa248d7232017-02-14 15:32:07 +05304118 if (pd->num_sink_caps > 0) {
Jack Phamee1f9052017-01-26 12:27:07 -08004119 int i;
4120 u32 sink_caps[14];
4121
4122 if (pd->num_sink_caps % 2 || pd->num_sink_caps > 14) {
4123 ret = -EINVAL;
4124 usbpd_err(&pd->dev, "default-sink-caps must be be specified as voltage/current, max 7 pairs\n");
4125 goto put_psy;
4126 }
4127
4128 ret = device_property_read_u32_array(parent,
4129 "qcom,default-sink-caps", sink_caps,
4130 pd->num_sink_caps);
4131 if (ret) {
4132 usbpd_err(&pd->dev, "Error reading default-sink-caps\n");
4133 goto put_psy;
4134 }
4135
4136 pd->num_sink_caps /= 2;
4137
4138 for (i = 0; i < pd->num_sink_caps; i++) {
4139 int v = sink_caps[i * 2] / 50;
4140 int c = sink_caps[i * 2 + 1] / 10;
4141
4142 pd->sink_caps[i] =
4143 PD_SNK_PDO_FIXED(0, 0, 0, 0, 0, v, c);
4144 }
4145
4146 /* First PDO includes additional capabilities */
4147 pd->sink_caps[0] |= PD_SNK_PDO_FIXED(1, 0, 0, 1, 1, 0, 0);
4148 } else {
4149 memcpy(pd->sink_caps, default_snk_caps,
4150 sizeof(default_snk_caps));
4151 pd->num_sink_caps = ARRAY_SIZE(default_snk_caps);
4152 }
4153
Jack Phamf4baeb12017-02-03 19:01:48 -08004154 /*
4155 * Register the Android dual-role class (/sys/class/dual_role_usb/).
4156 * The first instance should be named "otg_default" as that's what
4157 * Android expects.
4158 * Note this is different than the /sys/class/usbpd/ created above.
4159 */
4160 pd->dr_desc.name = (num_pd_instances == 1) ?
4161 "otg_default" : dev_name(&pd->dev);
4162 pd->dr_desc.supported_modes = DUAL_ROLE_SUPPORTED_MODES_DFP_AND_UFP;
4163 pd->dr_desc.properties = usbpd_dr_properties;
4164 pd->dr_desc.num_properties = ARRAY_SIZE(usbpd_dr_properties);
4165 pd->dr_desc.get_property = usbpd_dr_get_property;
4166 pd->dr_desc.set_property = usbpd_dr_set_property;
4167 pd->dr_desc.property_is_writeable = usbpd_dr_prop_writeable;
4168
4169 pd->dual_role = devm_dual_role_instance_register(&pd->dev,
4170 &pd->dr_desc);
4171 if (IS_ERR(pd->dual_role)) {
4172 usbpd_err(&pd->dev, "could not register dual_role instance\n");
4173 goto put_psy;
4174 } else {
4175 pd->dual_role->drv_data = pd;
4176 }
4177
4178 pd->current_pr = PR_NONE;
4179 pd->current_dr = DR_NONE;
4180 list_add_tail(&pd->instance, &_usbpd);
4181
4182 spin_lock_init(&pd->rx_lock);
4183 INIT_LIST_HEAD(&pd->rx_q);
4184 INIT_LIST_HEAD(&pd->svid_handlers);
Jack Phamaf7d3842017-01-26 13:28:19 -08004185 init_completion(&pd->is_ready);
Jack Phamf3c1bd32017-08-02 18:32:23 -07004186 init_completion(&pd->tx_chunk_request);
Jack Phamf4baeb12017-02-03 19:01:48 -08004187
4188 pd->psy_nb.notifier_call = psy_changed;
4189 ret = power_supply_reg_notifier(&pd->psy_nb);
4190 if (ret)
4191 goto del_inst;
4192
4193 /* force read initial power_supply values */
4194 psy_changed(&pd->psy_nb, PSY_EVENT_PROP_CHANGED, pd->usb_psy);
4195
4196 return pd;
4197
4198del_inst:
4199 list_del(&pd->instance);
4200put_psy:
4201 power_supply_put(pd->usb_psy);
4202destroy_wq:
4203 destroy_workqueue(pd->wq);
4204del_pd:
4205 device_del(&pd->dev);
4206free_pd:
4207 num_pd_instances--;
4208 kfree(pd);
4209 return ERR_PTR(ret);
4210}
4211EXPORT_SYMBOL(usbpd_create);
4212
4213/**
4214 * usbpd_destroy - Removes and frees a usbpd instance
4215 * @pd: the instance to destroy
4216 */
4217void usbpd_destroy(struct usbpd *pd)
4218{
4219 if (!pd)
4220 return;
4221
4222 list_del(&pd->instance);
4223 power_supply_unreg_notifier(&pd->psy_nb);
4224 power_supply_put(pd->usb_psy);
4225 destroy_workqueue(pd->wq);
4226 device_del(&pd->dev);
4227 kfree(pd);
4228}
4229EXPORT_SYMBOL(usbpd_destroy);
4230
4231static int __init usbpd_init(void)
4232{
4233 usbpd_ipc_log = ipc_log_context_create(NUM_LOG_PAGES, "usb_pd", 0);
4234 return class_register(&usbpd_class);
4235}
4236module_init(usbpd_init);
4237
4238static void __exit usbpd_exit(void)
4239{
4240 class_unregister(&usbpd_class);
4241}
4242module_exit(usbpd_exit);
4243
4244MODULE_DESCRIPTION("USB Power Delivery Policy Engine");
4245MODULE_LICENSE("GPL v2");