aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-04 20:55:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-04 20:55:35 -0400
commitac9053d2dcb9e8c3fa35ce458dfca8fddc141680 (patch)
tree3ffa30d58dac22ee0a80e2dd32f41b71da91132b /include/linux
parentf9ca6a561d40115696a54f16085c4edb17effc74 (diff)
parent5267c5e09c25e2ee6242b37833a9bdf9d97f54a2 (diff)
Merge tag 'usb-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
Pull USB/PHY updates from Greg KH: "Here is the big set of USB and PHY driver patches for 4.17-rc1. Lots of USB typeC work happened this round, with code moving from the staging directory into the "real" part of the kernel, as well as new infrastructure being added to be able to handle the different types of "roles" that typeC requires. There is also the normal huge set of USB gadget controller and driver updates, along with XHCI changes, and a raft of other tiny fixes all over the USB tree. And the PHY driver updates are merged in here as well as they interacted with the USB drivers in some places. All of these have been in linux-next for a while with no reported issues" * tag 'usb-4.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (250 commits) Revert "USB: serial: ftdi_sio: add Id for Physik Instrumente E-870" usb: musb: gadget: misplaced out of bounds check usb: chipidea: imx: Fix ULPI on imx53 usb: chipidea: imx: Cleanup ci_hdrc_imx_platform_flag usb: chipidea: usbmisc: small clean up usb: chipidea: usbmisc: evdo can be set e/o reset usb: chipidea: usbmisc: evdo is only specific to OTG port USB: serial: ftdi_sio: add Id for Physik Instrumente E-870 usb: dwc3: gadget: never call ->complete() from ->ep_queue() usb: gadget: udc: core: update usb_ep_queue() documentation usb: host: Remove the deprecated ATH79 USB host config options usb: roles: Fix return value check in intel_xhci_usb_probe() USB: gadget: f_midi: fixing a possible double-free in f_midi usb: core: Add USB_QUIRK_DELAY_CTRL_MSG to usbcore quirks usb: core: Copy parameter string correctly and remove superfluous null check USB: announce bcdDevice as well as idVendor, idProduct. USB:fix USB3 devices behind USB3 hubs not resuming at hibernate thaw usb: hub: Reduce warning to notice on power loss USB: serial: ftdi_sio: add support for Harman FirmwareHubEmulator USB: serial: cp210x: add ELDAT Easywave RX09 id ...
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/device.h22
-rw-r--r--include/linux/phy/phy.h31
-rw-r--r--include/linux/usb/composite.h3
-rw-r--r--include/linux/usb/gadget.h1
-rw-r--r--include/linux/usb/hcd.h8
-rw-r--r--include/linux/usb/pd.h185
-rw-r--r--include/linux/usb/pd_ado.h42
-rw-r--r--include/linux/usb/pd_ext_sdb.h31
-rw-r--r--include/linux/usb/role.h53
-rw-r--r--include/linux/usb/tcpm.h15
-rw-r--r--include/linux/usb/typec.h28
-rw-r--r--include/linux/usb/typec_mux.h55
12 files changed, 443 insertions, 31 deletions
diff --git a/include/linux/device.h b/include/linux/device.h
index abf952c82c6d..4b5a4925b780 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -730,6 +730,28 @@ struct device_dma_parameters {
730}; 730};
731 731
732/** 732/**
733 * struct device_connection - Device Connection Descriptor
734 * @endpoint: The names of the two devices connected together
735 * @id: Unique identifier for the connection
736 * @list: List head, private, for internal use only
737 */
738struct device_connection {
739 const char *endpoint[2];
740 const char *id;
741 struct list_head list;
742};
743
744void *device_connection_find_match(struct device *dev, const char *con_id,
745 void *data,
746 void *(*match)(struct device_connection *con,
747 int ep, void *data));
748
749struct device *device_connection_find(struct device *dev, const char *con_id);
750
751void device_connection_add(struct device_connection *con);
752void device_connection_remove(struct device_connection *con);
753
754/**
733 * enum device_link_state - Device link states. 755 * enum device_link_state - Device link states.
734 * @DL_STATE_NONE: The presence of the drivers is not being tracked. 756 * @DL_STATE_NONE: The presence of the drivers is not being tracked.
735 * @DL_STATE_DORMANT: None of the supplier/consumer drivers is present. 757 * @DL_STATE_DORMANT: None of the supplier/consumer drivers is present.
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index 4f8423a948d5..c9d14eeee7f5 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -25,7 +25,15 @@ struct phy;
25enum phy_mode { 25enum phy_mode {
26 PHY_MODE_INVALID, 26 PHY_MODE_INVALID,
27 PHY_MODE_USB_HOST, 27 PHY_MODE_USB_HOST,
28 PHY_MODE_USB_HOST_LS,
29 PHY_MODE_USB_HOST_FS,
30 PHY_MODE_USB_HOST_HS,
31 PHY_MODE_USB_HOST_SS,
28 PHY_MODE_USB_DEVICE, 32 PHY_MODE_USB_DEVICE,
33 PHY_MODE_USB_DEVICE_LS,
34 PHY_MODE_USB_DEVICE_FS,
35 PHY_MODE_USB_DEVICE_HS,
36 PHY_MODE_USB_DEVICE_SS,
29 PHY_MODE_USB_OTG, 37 PHY_MODE_USB_OTG,
30 PHY_MODE_SGMII, 38 PHY_MODE_SGMII,
31 PHY_MODE_10GKR, 39 PHY_MODE_10GKR,
@@ -61,6 +69,7 @@ struct phy_ops {
61 */ 69 */
62struct phy_attrs { 70struct phy_attrs {
63 u32 bus_width; 71 u32 bus_width;
72 enum phy_mode mode;
64}; 73};
65 74
66/** 75/**
@@ -72,7 +81,8 @@ struct phy_attrs {
72 * @mutex: mutex to protect phy_ops 81 * @mutex: mutex to protect phy_ops
73 * @init_count: used to protect when the PHY is used by multiple consumers 82 * @init_count: used to protect when the PHY is used by multiple consumers
74 * @power_count: used to protect when the PHY is used by multiple consumers 83 * @power_count: used to protect when the PHY is used by multiple consumers
75 * @phy_attrs: used to specify PHY specific attributes 84 * @attrs: used to specify PHY specific attributes
85 * @pwr: power regulator associated with the phy
76 */ 86 */
77struct phy { 87struct phy {
78 struct device dev; 88 struct device dev;
@@ -88,9 +98,10 @@ struct phy {
88/** 98/**
89 * struct phy_provider - represents the phy provider 99 * struct phy_provider - represents the phy provider
90 * @dev: phy provider device 100 * @dev: phy provider device
101 * @children: can be used to override the default (dev->of_node) child node
91 * @owner: the module owner having of_xlate 102 * @owner: the module owner having of_xlate
92 * @of_xlate: function pointer to obtain phy instance from phy pointer
93 * @list: to maintain a linked list of PHY providers 103 * @list: to maintain a linked list of PHY providers
104 * @of_xlate: function pointer to obtain phy instance from phy pointer
94 */ 105 */
95struct phy_provider { 106struct phy_provider {
96 struct device *dev; 107 struct device *dev;
@@ -101,6 +112,13 @@ struct phy_provider {
101 struct of_phandle_args *args); 112 struct of_phandle_args *args);
102}; 113};
103 114
115/**
116 * struct phy_lookup - PHY association in list of phys managed by the phy driver
117 * @node: list node
118 * @dev_id: the device of the association
119 * @con_id: connection ID string on device
120 * @phy: the phy of the association
121 */
104struct phy_lookup { 122struct phy_lookup {
105 struct list_head node; 123 struct list_head node;
106 const char *dev_id; 124 const char *dev_id;
@@ -144,6 +162,10 @@ int phy_exit(struct phy *phy);
144int phy_power_on(struct phy *phy); 162int phy_power_on(struct phy *phy);
145int phy_power_off(struct phy *phy); 163int phy_power_off(struct phy *phy);
146int phy_set_mode(struct phy *phy, enum phy_mode mode); 164int phy_set_mode(struct phy *phy, enum phy_mode mode);
165static inline enum phy_mode phy_get_mode(struct phy *phy)
166{
167 return phy->attrs.mode;
168}
147int phy_reset(struct phy *phy); 169int phy_reset(struct phy *phy);
148int phy_calibrate(struct phy *phy); 170int phy_calibrate(struct phy *phy);
149static inline int phy_get_bus_width(struct phy *phy) 171static inline int phy_get_bus_width(struct phy *phy)
@@ -260,6 +282,11 @@ static inline int phy_set_mode(struct phy *phy, enum phy_mode mode)
260 return -ENOSYS; 282 return -ENOSYS;
261} 283}
262 284
285static inline enum phy_mode phy_get_mode(struct phy *phy)
286{
287 return PHY_MODE_INVALID;
288}
289
263static inline int phy_reset(struct phy *phy) 290static inline int phy_reset(struct phy *phy)
264{ 291{
265 if (!phy) 292 if (!phy)
diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h
index cef0e44601f8..4b6b9283fa7b 100644
--- a/include/linux/usb/composite.h
+++ b/include/linux/usb/composite.h
@@ -54,6 +54,9 @@
54/* big enough to hold our biggest descriptor */ 54/* big enough to hold our biggest descriptor */
55#define USB_COMP_EP0_BUFSIZ 1024 55#define USB_COMP_EP0_BUFSIZ 1024
56 56
57/* OS feature descriptor length <= 4kB */
58#define USB_COMP_EP0_OS_DESC_BUFSIZ 4096
59
57#define USB_MS_TO_HS_INTERVAL(x) (ilog2((x * 1000 / 125)) + 1) 60#define USB_MS_TO_HS_INTERVAL(x) (ilog2((x * 1000 / 125)) + 1)
58struct usb_configuration; 61struct usb_configuration;
59 62
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 66a5cff7ee14..e3424234b23a 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -129,6 +129,7 @@ struct usb_ep_ops {
129 int (*enable) (struct usb_ep *ep, 129 int (*enable) (struct usb_ep *ep,
130 const struct usb_endpoint_descriptor *desc); 130 const struct usb_endpoint_descriptor *desc);
131 int (*disable) (struct usb_ep *ep); 131 int (*disable) (struct usb_ep *ep);
132 void (*dispose) (struct usb_ep *ep);
132 133
133 struct usb_request *(*alloc_request) (struct usb_ep *ep, 134 struct usb_request *(*alloc_request) (struct usb_ep *ep,
134 gfp_t gfp_flags); 135 gfp_t gfp_flags);
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 176900528822..aef50cb2ed1b 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -103,7 +103,7 @@ struct usb_hcd {
103 * other external phys should be software-transparent 103 * other external phys should be software-transparent
104 */ 104 */
105 struct usb_phy *usb_phy; 105 struct usb_phy *usb_phy;
106 struct phy *phy; 106 struct usb_phy_roothub *phy_roothub;
107 107
108 /* Flags that need to be manipulated atomically because they can 108 /* Flags that need to be manipulated atomically because they can
109 * change while the host controller is running. Always use 109 * change while the host controller is running. Always use
@@ -151,6 +151,12 @@ struct usb_hcd {
151 unsigned msix_enabled:1; /* driver has MSI-X enabled? */ 151 unsigned msix_enabled:1; /* driver has MSI-X enabled? */
152 unsigned msi_enabled:1; /* driver has MSI enabled? */ 152 unsigned msi_enabled:1; /* driver has MSI enabled? */
153 unsigned remove_phy:1; /* auto-remove USB phy */ 153 unsigned remove_phy:1; /* auto-remove USB phy */
154 /*
155 * do not manage the PHY state in the HCD core, instead let the driver
156 * handle this (for example if the PHY can only be turned on after a
157 * specific event)
158 */
159 unsigned skip_phy_initialization:1;
154 160
155 /* The next flag is a stopgap, to be removed when all the HCDs 161 /* The next flag is a stopgap, to be removed when all the HCDs
156 * support the new root-hub polling mechanism. */ 162 * support the new root-hub polling mechanism. */
diff --git a/include/linux/usb/pd.h b/include/linux/usb/pd.h
index b3d41d7409b3..ff359bdfdc7b 100644
--- a/include/linux/usb/pd.h
+++ b/include/linux/usb/pd.h
@@ -35,6 +35,13 @@ enum pd_ctrl_msg_type {
35 PD_CTRL_WAIT = 12, 35 PD_CTRL_WAIT = 12,
36 PD_CTRL_SOFT_RESET = 13, 36 PD_CTRL_SOFT_RESET = 13,
37 /* 14-15 Reserved */ 37 /* 14-15 Reserved */
38 PD_CTRL_NOT_SUPP = 16,
39 PD_CTRL_GET_SOURCE_CAP_EXT = 17,
40 PD_CTRL_GET_STATUS = 18,
41 PD_CTRL_FR_SWAP = 19,
42 PD_CTRL_GET_PPS_STATUS = 20,
43 PD_CTRL_GET_COUNTRY_CODES = 21,
44 /* 22-31 Reserved */
38}; 45};
39 46
40enum pd_data_msg_type { 47enum pd_data_msg_type {
@@ -43,13 +50,39 @@ enum pd_data_msg_type {
43 PD_DATA_REQUEST = 2, 50 PD_DATA_REQUEST = 2,
44 PD_DATA_BIST = 3, 51 PD_DATA_BIST = 3,
45 PD_DATA_SINK_CAP = 4, 52 PD_DATA_SINK_CAP = 4,
46 /* 5-14 Reserved */ 53 PD_DATA_BATT_STATUS = 5,
54 PD_DATA_ALERT = 6,
55 PD_DATA_GET_COUNTRY_INFO = 7,
56 /* 8-14 Reserved */
47 PD_DATA_VENDOR_DEF = 15, 57 PD_DATA_VENDOR_DEF = 15,
58 /* 16-31 Reserved */
59};
60
61enum pd_ext_msg_type {
62 /* 0 Reserved */
63 PD_EXT_SOURCE_CAP_EXT = 1,
64 PD_EXT_STATUS = 2,
65 PD_EXT_GET_BATT_CAP = 3,
66 PD_EXT_GET_BATT_STATUS = 4,
67 PD_EXT_BATT_CAP = 5,
68 PD_EXT_GET_MANUFACTURER_INFO = 6,
69 PD_EXT_MANUFACTURER_INFO = 7,
70 PD_EXT_SECURITY_REQUEST = 8,
71 PD_EXT_SECURITY_RESPONSE = 9,
72 PD_EXT_FW_UPDATE_REQUEST = 10,
73 PD_EXT_FW_UPDATE_RESPONSE = 11,
74 PD_EXT_PPS_STATUS = 12,
75 PD_EXT_COUNTRY_INFO = 13,
76 PD_EXT_COUNTRY_CODES = 14,
77 /* 15-31 Reserved */
48}; 78};
49 79
50#define PD_REV10 0x0 80#define PD_REV10 0x0
51#define PD_REV20 0x1 81#define PD_REV20 0x1
82#define PD_REV30 0x2
83#define PD_MAX_REV PD_REV30
52 84
85#define PD_HEADER_EXT_HDR BIT(15)
53#define PD_HEADER_CNT_SHIFT 12 86#define PD_HEADER_CNT_SHIFT 12
54#define PD_HEADER_CNT_MASK 0x7 87#define PD_HEADER_CNT_MASK 0x7
55#define PD_HEADER_ID_SHIFT 9 88#define PD_HEADER_ID_SHIFT 9
@@ -59,18 +92,19 @@ enum pd_data_msg_type {
59#define PD_HEADER_REV_MASK 0x3 92#define PD_HEADER_REV_MASK 0x3
60#define PD_HEADER_DATA_ROLE BIT(5) 93#define PD_HEADER_DATA_ROLE BIT(5)
61#define PD_HEADER_TYPE_SHIFT 0 94#define PD_HEADER_TYPE_SHIFT 0
62#define PD_HEADER_TYPE_MASK 0xf 95#define PD_HEADER_TYPE_MASK 0x1f
63 96
64#define PD_HEADER(type, pwr, data, id, cnt) \ 97#define PD_HEADER(type, pwr, data, rev, id, cnt, ext_hdr) \
65 ((((type) & PD_HEADER_TYPE_MASK) << PD_HEADER_TYPE_SHIFT) | \ 98 ((((type) & PD_HEADER_TYPE_MASK) << PD_HEADER_TYPE_SHIFT) | \
66 ((pwr) == TYPEC_SOURCE ? PD_HEADER_PWR_ROLE : 0) | \ 99 ((pwr) == TYPEC_SOURCE ? PD_HEADER_PWR_ROLE : 0) | \
67 ((data) == TYPEC_HOST ? PD_HEADER_DATA_ROLE : 0) | \ 100 ((data) == TYPEC_HOST ? PD_HEADER_DATA_ROLE : 0) | \
68 (PD_REV20 << PD_HEADER_REV_SHIFT) | \ 101 (rev << PD_HEADER_REV_SHIFT) | \
69 (((id) & PD_HEADER_ID_MASK) << PD_HEADER_ID_SHIFT) | \ 102 (((id) & PD_HEADER_ID_MASK) << PD_HEADER_ID_SHIFT) | \
70 (((cnt) & PD_HEADER_CNT_MASK) << PD_HEADER_CNT_SHIFT)) 103 (((cnt) & PD_HEADER_CNT_MASK) << PD_HEADER_CNT_SHIFT) | \
104 ((ext_hdr) ? PD_HEADER_EXT_HDR : 0))
71 105
72#define PD_HEADER_LE(type, pwr, data, id, cnt) \ 106#define PD_HEADER_LE(type, pwr, data, id, cnt) \
73 cpu_to_le16(PD_HEADER((type), (pwr), (data), (id), (cnt))) 107 cpu_to_le16(PD_HEADER((type), (pwr), (data), PD_REV20, (id), (cnt), (0)))
74 108
75static inline unsigned int pd_header_cnt(u16 header) 109static inline unsigned int pd_header_cnt(u16 header)
76{ 110{
@@ -102,16 +136,75 @@ static inline unsigned int pd_header_msgid_le(__le16 header)
102 return pd_header_msgid(le16_to_cpu(header)); 136 return pd_header_msgid(le16_to_cpu(header));
103} 137}
104 138
139static inline unsigned int pd_header_rev(u16 header)
140{
141 return (header >> PD_HEADER_REV_SHIFT) & PD_HEADER_REV_MASK;
142}
143
144static inline unsigned int pd_header_rev_le(__le16 header)
145{
146 return pd_header_rev(le16_to_cpu(header));
147}
148
149#define PD_EXT_HDR_CHUNKED BIT(15)
150#define PD_EXT_HDR_CHUNK_NUM_SHIFT 11
151#define PD_EXT_HDR_CHUNK_NUM_MASK 0xf
152#define PD_EXT_HDR_REQ_CHUNK BIT(10)
153#define PD_EXT_HDR_DATA_SIZE_SHIFT 0
154#define PD_EXT_HDR_DATA_SIZE_MASK 0x1ff
155
156#define PD_EXT_HDR(data_size, req_chunk, chunk_num, chunked) \
157 ((((data_size) & PD_EXT_HDR_DATA_SIZE_MASK) << PD_EXT_HDR_DATA_SIZE_SHIFT) | \
158 ((req_chunk) ? PD_EXT_HDR_REQ_CHUNK : 0) | \
159 (((chunk_num) & PD_EXT_HDR_CHUNK_NUM_MASK) << PD_EXT_HDR_CHUNK_NUM_SHIFT) | \
160 ((chunked) ? PD_EXT_HDR_CHUNKED : 0))
161
162#define PD_EXT_HDR_LE(data_size, req_chunk, chunk_num, chunked) \
163 cpu_to_le16(PD_EXT_HDR((data_size), (req_chunk), (chunk_num), (chunked)))
164
165static inline unsigned int pd_ext_header_chunk_num(u16 ext_header)
166{
167 return (ext_header >> PD_EXT_HDR_CHUNK_NUM_SHIFT) &
168 PD_EXT_HDR_CHUNK_NUM_MASK;
169}
170
171static inline unsigned int pd_ext_header_data_size(u16 ext_header)
172{
173 return (ext_header >> PD_EXT_HDR_DATA_SIZE_SHIFT) &
174 PD_EXT_HDR_DATA_SIZE_MASK;
175}
176
177static inline unsigned int pd_ext_header_data_size_le(__le16 ext_header)
178{
179 return pd_ext_header_data_size(le16_to_cpu(ext_header));
180}
181
105#define PD_MAX_PAYLOAD 7 182#define PD_MAX_PAYLOAD 7
183#define PD_EXT_MAX_CHUNK_DATA 26
106 184
107/** 185/**
108 * struct pd_message - PD message as seen on wire 186 * struct pd_chunked_ext_message_data - PD chunked extended message data as
109 * @header: PD message header 187 * seen on wire
110 * @payload: PD message payload 188 * @header: PD extended message header
111 */ 189 * @data: PD extended message data
190 */
191struct pd_chunked_ext_message_data {
192 __le16 header;
193 u8 data[PD_EXT_MAX_CHUNK_DATA];
194} __packed;
195
196/**
197 * struct pd_message - PD message as seen on wire
198 * @header: PD message header
199 * @payload: PD message payload
200 * @ext_msg: PD message chunked extended message data
201 */
112struct pd_message { 202struct pd_message {
113 __le16 header; 203 __le16 header;
114 __le32 payload[PD_MAX_PAYLOAD]; 204 union {
205 __le32 payload[PD_MAX_PAYLOAD];
206 struct pd_chunked_ext_message_data ext_msg;
207 };
115} __packed; 208} __packed;
116 209
117/* PDO: Power Data Object */ 210/* PDO: Power Data Object */
@@ -121,6 +214,7 @@ enum pd_pdo_type {
121 PDO_TYPE_FIXED = 0, 214 PDO_TYPE_FIXED = 0,
122 PDO_TYPE_BATT = 1, 215 PDO_TYPE_BATT = 1,
123 PDO_TYPE_VAR = 2, 216 PDO_TYPE_VAR = 2,
217 PDO_TYPE_APDO = 3,
124}; 218};
125 219
126#define PDO_TYPE_SHIFT 30 220#define PDO_TYPE_SHIFT 30
@@ -174,6 +268,34 @@ enum pd_pdo_type {
174 (PDO_TYPE(PDO_TYPE_VAR) | PDO_VAR_MIN_VOLT(min_mv) | \ 268 (PDO_TYPE(PDO_TYPE_VAR) | PDO_VAR_MIN_VOLT(min_mv) | \
175 PDO_VAR_MAX_VOLT(max_mv) | PDO_VAR_MAX_CURR(max_ma)) 269 PDO_VAR_MAX_VOLT(max_mv) | PDO_VAR_MAX_CURR(max_ma))
176 270
271enum pd_apdo_type {
272 APDO_TYPE_PPS = 0,
273};
274
275#define PDO_APDO_TYPE_SHIFT 28 /* Only valid value currently is 0x0 - PPS */
276#define PDO_APDO_TYPE_MASK 0x3
277
278#define PDO_APDO_TYPE(t) ((t) << PDO_APDO_TYPE_SHIFT)
279
280#define PDO_PPS_APDO_MAX_VOLT_SHIFT 17 /* 100mV units */
281#define PDO_PPS_APDO_MIN_VOLT_SHIFT 8 /* 100mV units */
282#define PDO_PPS_APDO_MAX_CURR_SHIFT 0 /* 50mA units */
283
284#define PDO_PPS_APDO_VOLT_MASK 0xff
285#define PDO_PPS_APDO_CURR_MASK 0x7f
286
287#define PDO_PPS_APDO_MIN_VOLT(mv) \
288 ((((mv) / 100) & PDO_PPS_APDO_VOLT_MASK) << PDO_PPS_APDO_MIN_VOLT_SHIFT)
289#define PDO_PPS_APDO_MAX_VOLT(mv) \
290 ((((mv) / 100) & PDO_PPS_APDO_VOLT_MASK) << PDO_PPS_APDO_MAX_VOLT_SHIFT)
291#define PDO_PPS_APDO_MAX_CURR(ma) \
292 ((((ma) / 50) & PDO_PPS_APDO_CURR_MASK) << PDO_PPS_APDO_MAX_CURR_SHIFT)
293
294#define PDO_PPS_APDO(min_mv, max_mv, max_ma) \
295 (PDO_TYPE(PDO_TYPE_APDO) | PDO_APDO_TYPE(APDO_TYPE_PPS) | \
296 PDO_PPS_APDO_MIN_VOLT(min_mv) | PDO_PPS_APDO_MAX_VOLT(max_mv) | \
297 PDO_PPS_APDO_MAX_CURR(max_ma))
298
177static inline enum pd_pdo_type pdo_type(u32 pdo) 299static inline enum pd_pdo_type pdo_type(u32 pdo)
178{ 300{
179 return (pdo >> PDO_TYPE_SHIFT) & PDO_TYPE_MASK; 301 return (pdo >> PDO_TYPE_SHIFT) & PDO_TYPE_MASK;
@@ -204,6 +326,29 @@ static inline unsigned int pdo_max_power(u32 pdo)
204 return ((pdo >> PDO_BATT_MAX_PWR_SHIFT) & PDO_PWR_MASK) * 250; 326 return ((pdo >> PDO_BATT_MAX_PWR_SHIFT) & PDO_PWR_MASK) * 250;
205} 327}
206 328
329static inline enum pd_apdo_type pdo_apdo_type(u32 pdo)
330{
331 return (pdo >> PDO_APDO_TYPE_SHIFT) & PDO_APDO_TYPE_MASK;
332}
333
334static inline unsigned int pdo_pps_apdo_min_voltage(u32 pdo)
335{
336 return ((pdo >> PDO_PPS_APDO_MIN_VOLT_SHIFT) &
337 PDO_PPS_APDO_VOLT_MASK) * 100;
338}
339
340static inline unsigned int pdo_pps_apdo_max_voltage(u32 pdo)
341{
342 return ((pdo >> PDO_PPS_APDO_MAX_VOLT_SHIFT) &
343 PDO_PPS_APDO_VOLT_MASK) * 100;
344}
345
346static inline unsigned int pdo_pps_apdo_max_current(u32 pdo)
347{
348 return ((pdo >> PDO_PPS_APDO_MAX_CURR_SHIFT) &
349 PDO_PPS_APDO_CURR_MASK) * 50;
350}
351
207/* RDO: Request Data Object */ 352/* RDO: Request Data Object */
208#define RDO_OBJ_POS_SHIFT 28 353#define RDO_OBJ_POS_SHIFT 28
209#define RDO_OBJ_POS_MASK 0x7 354#define RDO_OBJ_POS_MASK 0x7
@@ -237,6 +382,24 @@ static inline unsigned int pdo_max_power(u32 pdo)
237 (RDO_OBJ(idx) | (flags) | \ 382 (RDO_OBJ(idx) | (flags) | \
238 RDO_BATT_OP_PWR(op_mw) | RDO_BATT_MAX_PWR(max_mw)) 383 RDO_BATT_OP_PWR(op_mw) | RDO_BATT_MAX_PWR(max_mw))
239 384
385#define RDO_PROG_VOLT_MASK 0x7ff
386#define RDO_PROG_CURR_MASK 0x7f
387
388#define RDO_PROG_VOLT_SHIFT 9
389#define RDO_PROG_CURR_SHIFT 0
390
391#define RDO_PROG_VOLT_MV_STEP 20
392#define RDO_PROG_CURR_MA_STEP 50
393
394#define PDO_PROG_OUT_VOLT(mv) \
395 ((((mv) / RDO_PROG_VOLT_MV_STEP) & RDO_PROG_VOLT_MASK) << RDO_PROG_VOLT_SHIFT)
396#define PDO_PROG_OP_CURR(ma) \
397 ((((ma) / RDO_PROG_CURR_MA_STEP) & RDO_PROG_CURR_MASK) << RDO_PROG_CURR_SHIFT)
398
399#define RDO_PROG(idx, out_mv, op_ma, flags) \
400 (RDO_OBJ(idx) | (flags) | \
401 PDO_PROG_OUT_VOLT(out_mv) | PDO_PROG_OP_CURR(op_ma))
402
240static inline unsigned int rdo_index(u32 rdo) 403static inline unsigned int rdo_index(u32 rdo)
241{ 404{
242 return (rdo >> RDO_OBJ_POS_SHIFT) & RDO_OBJ_POS_MASK; 405 return (rdo >> RDO_OBJ_POS_SHIFT) & RDO_OBJ_POS_MASK;
diff --git a/include/linux/usb/pd_ado.h b/include/linux/usb/pd_ado.h
new file mode 100644
index 000000000000..9aa1cf31c93c
--- /dev/null
+++ b/include/linux/usb/pd_ado.h
@@ -0,0 +1,42 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2017 Dialog Semiconductor
4 *
5 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
6 */
7
8#ifndef __LINUX_USB_PD_ADO_H
9#define __LINUX_USB_PD_ADO_H
10
11/* ADO : Alert Data Object */
12#define USB_PD_ADO_TYPE_SHIFT 24
13#define USB_PD_ADO_TYPE_MASK 0xff
14#define USB_PD_ADO_FIXED_BATT_SHIFT 20
15#define USB_PD_ADO_FIXED_BATT_MASK 0xf
16#define USB_PD_ADO_HOT_SWAP_BATT_SHIFT 16
17#define USB_PD_ADO_HOT_SWAP_BATT_MASK 0xf
18
19#define USB_PD_ADO_TYPE_BATT_STATUS_CHANGE BIT(1)
20#define USB_PD_ADO_TYPE_OCP BIT(2)
21#define USB_PD_ADO_TYPE_OTP BIT(3)
22#define USB_PD_ADO_TYPE_OP_COND_CHANGE BIT(4)
23#define USB_PD_ADO_TYPE_SRC_INPUT_CHANGE BIT(5)
24#define USB_PD_ADO_TYPE_OVP BIT(6)
25
26static inline unsigned int usb_pd_ado_type(u32 ado)
27{
28 return (ado >> USB_PD_ADO_TYPE_SHIFT) & USB_PD_ADO_TYPE_MASK;
29}
30
31static inline unsigned int usb_pd_ado_fixed_batt(u32 ado)
32{
33 return (ado >> USB_PD_ADO_FIXED_BATT_SHIFT) &
34 USB_PD_ADO_FIXED_BATT_MASK;
35}
36
37static inline unsigned int usb_pd_ado_hot_swap_batt(u32 ado)
38{
39 return (ado >> USB_PD_ADO_HOT_SWAP_BATT_SHIFT) &
40 USB_PD_ADO_HOT_SWAP_BATT_MASK;
41}
42#endif /* __LINUX_USB_PD_ADO_H */
diff --git a/include/linux/usb/pd_ext_sdb.h b/include/linux/usb/pd_ext_sdb.h
new file mode 100644
index 000000000000..0eb83ce19597
--- /dev/null
+++ b/include/linux/usb/pd_ext_sdb.h
@@ -0,0 +1,31 @@
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2017 Dialog Semiconductor
4 *
5 * Author: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
6 */
7
8#ifndef __LINUX_USB_PD_EXT_SDB_H
9#define __LINUX_USB_PD_EXT_SDB_H
10
11/* SDB : Status Data Block */
12enum usb_pd_ext_sdb_fields {
13 USB_PD_EXT_SDB_INTERNAL_TEMP = 0,
14 USB_PD_EXT_SDB_PRESENT_INPUT,
15 USB_PD_EXT_SDB_PRESENT_BATT_INPUT,
16 USB_PD_EXT_SDB_EVENT_FLAGS,
17 USB_PD_EXT_SDB_TEMP_STATUS,
18 USB_PD_EXT_SDB_DATA_SIZE,
19};
20
21/* Event Flags */
22#define USB_PD_EXT_SDB_EVENT_OCP BIT(1)
23#define USB_PD_EXT_SDB_EVENT_OTP BIT(2)
24#define USB_PD_EXT_SDB_EVENT_OVP BIT(3)
25#define USB_PD_EXT_SDB_EVENT_CF_CV_MODE BIT(4)
26
27#define USB_PD_EXT_SDB_PPS_EVENTS (USB_PD_EXT_SDB_EVENT_OCP | \
28 USB_PD_EXT_SDB_EVENT_OTP | \
29 USB_PD_EXT_SDB_EVENT_OVP)
30
31#endif /* __LINUX_USB_PD_EXT_SDB_H */
diff --git a/include/linux/usb/role.h b/include/linux/usb/role.h
new file mode 100644
index 000000000000..edc51be4a77c
--- /dev/null
+++ b/include/linux/usb/role.h
@@ -0,0 +1,53 @@
1// SPDX-License-Identifier: GPL-2.0
2
3#ifndef __LINUX_USB_ROLE_H
4#define __LINUX_USB_ROLE_H
5
6#include <linux/device.h>
7
8struct usb_role_switch;
9
10enum usb_role {
11 USB_ROLE_NONE,
12 USB_ROLE_HOST,
13 USB_ROLE_DEVICE,
14};
15
16typedef int (*usb_role_switch_set_t)(struct device *dev, enum usb_role role);
17typedef enum usb_role (*usb_role_switch_get_t)(struct device *dev);
18
19/**
20 * struct usb_role_switch_desc - USB Role Switch Descriptor
21 * @usb2_port: Optional reference to the host controller port device (USB2)
22 * @usb3_port: Optional reference to the host controller port device (USB3)
23 * @udc: Optional reference to the peripheral controller device
24 * @set: Callback for setting the role
25 * @get: Callback for getting the role (optional)
26 * @allow_userspace_control: If true userspace may change the role through sysfs
27 *
28 * @usb2_port and @usb3_port will point to the USB host port and @udc to the USB
29 * device controller behind the USB connector with the role switch. If
30 * @usb2_port, @usb3_port and @udc are included in the description, the
31 * reference count for them should be incremented by the caller of
32 * usb_role_switch_register() before registering the switch.
33 */
34struct usb_role_switch_desc {
35 struct device *usb2_port;
36 struct device *usb3_port;
37 struct device *udc;
38 usb_role_switch_set_t set;
39 usb_role_switch_get_t get;
40 bool allow_userspace_control;
41};
42
43int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role);
44enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw);
45struct usb_role_switch *usb_role_switch_get(struct device *dev);
46void usb_role_switch_put(struct usb_role_switch *sw);
47
48struct usb_role_switch *
49usb_role_switch_register(struct device *parent,
50 const struct usb_role_switch_desc *desc);
51void usb_role_switch_unregister(struct usb_role_switch *sw);
52
53#endif /* __LINUX_USB_ROLE_H */
diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h
index ca1c0b57f03f..f0d839daeaea 100644
--- a/include/linux/usb/tcpm.h
+++ b/include/linux/usb/tcpm.h
@@ -91,17 +91,13 @@ struct tcpc_config {
91 unsigned int operating_snk_mw; 91 unsigned int operating_snk_mw;
92 92
93 enum typec_port_type type; 93 enum typec_port_type type;
94 enum typec_port_data data;
94 enum typec_role default_role; 95 enum typec_role default_role;
95 bool try_role_hw; /* try.{src,snk} implemented in hardware */ 96 bool try_role_hw; /* try.{src,snk} implemented in hardware */
96 97
97 const struct typec_altmode_desc *alt_modes; 98 const struct typec_altmode_desc *alt_modes;
98}; 99};
99 100
100enum tcpc_usb_switch {
101 TCPC_USB_SWITCH_CONNECT,
102 TCPC_USB_SWITCH_DISCONNECT,
103};
104
105/* Mux state attributes */ 101/* Mux state attributes */
106#define TCPC_MUX_USB_ENABLED BIT(0) /* USB enabled */ 102#define TCPC_MUX_USB_ENABLED BIT(0) /* USB enabled */
107#define TCPC_MUX_DP_ENABLED BIT(1) /* DP enabled */ 103#define TCPC_MUX_DP_ENABLED BIT(1) /* DP enabled */
@@ -116,14 +112,6 @@ enum tcpc_mux_mode {
116 TCPC_MUX_DP_ENABLED, 112 TCPC_MUX_DP_ENABLED,
117}; 113};
118 114
119struct tcpc_mux_dev {
120 int (*set)(struct tcpc_mux_dev *dev, enum tcpc_mux_mode mux_mode,
121 enum tcpc_usb_switch usb_config,
122 enum typec_cc_polarity polarity);
123 bool dfp_only;
124 void *priv_data;
125};
126
127/** 115/**
128 * struct tcpc_dev - Port configuration and callback functions 116 * struct tcpc_dev - Port configuration and callback functions
129 * @config: Pointer to port configuration 117 * @config: Pointer to port configuration
@@ -175,7 +163,6 @@ struct tcpc_dev {
175 int (*try_role)(struct tcpc_dev *dev, int role); 163 int (*try_role)(struct tcpc_dev *dev, int role);
176 int (*pd_transmit)(struct tcpc_dev *dev, enum tcpm_transmit_type type, 164 int (*pd_transmit)(struct tcpc_dev *dev, enum tcpm_transmit_type type,
177 const struct pd_message *msg); 165 const struct pd_message *msg);
178 struct tcpc_mux_dev *mux;
179}; 166};
180 167
181struct tcpm_port; 168struct tcpm_port;
diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
index 0d44ce6af08f..672b39bb0adc 100644
--- a/include/linux/usb/typec.h
+++ b/include/linux/usb/typec.h
@@ -22,9 +22,15 @@ struct typec_port;
22struct fwnode_handle; 22struct fwnode_handle;
23 23
24enum typec_port_type { 24enum typec_port_type {
25 TYPEC_PORT_SRC,
26 TYPEC_PORT_SNK,
27 TYPEC_PORT_DRP,
28};
29
30enum typec_port_data {
25 TYPEC_PORT_DFP, 31 TYPEC_PORT_DFP,
26 TYPEC_PORT_UFP, 32 TYPEC_PORT_UFP,
27 TYPEC_PORT_DRP, 33 TYPEC_PORT_DRD,
28}; 34};
29 35
30enum typec_plug_type { 36enum typec_plug_type {
@@ -60,6 +66,12 @@ enum typec_accessory {
60 66
61#define TYPEC_MAX_ACCESSORY 3 67#define TYPEC_MAX_ACCESSORY 3
62 68
69enum typec_orientation {
70 TYPEC_ORIENTATION_NONE,
71 TYPEC_ORIENTATION_NORMAL,
72 TYPEC_ORIENTATION_REVERSE,
73};
74
63/* 75/*
64 * struct usb_pd_identity - USB Power Delivery identity data 76 * struct usb_pd_identity - USB Power Delivery identity data
65 * @id_header: ID Header VDO 77 * @id_header: ID Header VDO
@@ -180,11 +192,14 @@ struct typec_partner_desc {
180 192
181/* 193/*
182 * struct typec_capability - USB Type-C Port Capabilities 194 * struct typec_capability - USB Type-C Port Capabilities
183 * @role: DFP (Host-only), UFP (Device-only) or DRP (Dual Role) 195 * @type: Supported power role of the port
196 * @data: Supported data role of the port
184 * @revision: USB Type-C Specification release. Binary coded decimal 197 * @revision: USB Type-C Specification release. Binary coded decimal
185 * @pd_revision: USB Power Delivery Specification revision if supported 198 * @pd_revision: USB Power Delivery Specification revision if supported
186 * @prefer_role: Initial role preference 199 * @prefer_role: Initial role preference (DRP ports).
187 * @accessory: Supported Accessory Modes 200 * @accessory: Supported Accessory Modes
201 * @sw: Cable plug orientation switch
202 * @mux: Multiplexer switch for Alternate/Accessory Modes
188 * @fwnode: Optional fwnode of the port 203 * @fwnode: Optional fwnode of the port
189 * @try_role: Set data role preference for DRP port 204 * @try_role: Set data role preference for DRP port
190 * @dr_set: Set Data Role 205 * @dr_set: Set Data Role
@@ -197,11 +212,14 @@ struct typec_partner_desc {
197 */ 212 */
198struct typec_capability { 213struct typec_capability {
199 enum typec_port_type type; 214 enum typec_port_type type;
215 enum typec_port_data data;
200 u16 revision; /* 0120H = "1.2" */ 216 u16 revision; /* 0120H = "1.2" */
201 u16 pd_revision; /* 0300H = "3.0" */ 217 u16 pd_revision; /* 0300H = "3.0" */
202 int prefer_role; 218 int prefer_role;
203 enum typec_accessory accessory[TYPEC_MAX_ACCESSORY]; 219 enum typec_accessory accessory[TYPEC_MAX_ACCESSORY];
204 220
221 struct typec_switch *sw;
222 struct typec_mux *mux;
205 struct fwnode_handle *fwnode; 223 struct fwnode_handle *fwnode;
206 224
207 int (*try_role)(const struct typec_capability *, 225 int (*try_role)(const struct typec_capability *,
@@ -245,4 +263,8 @@ void typec_set_pwr_role(struct typec_port *port, enum typec_role role);
245void typec_set_vconn_role(struct typec_port *port, enum typec_role role); 263void typec_set_vconn_role(struct typec_port *port, enum typec_role role);
246void typec_set_pwr_opmode(struct typec_port *port, enum typec_pwr_opmode mode); 264void typec_set_pwr_opmode(struct typec_port *port, enum typec_pwr_opmode mode);
247 265
266int typec_set_orientation(struct typec_port *port,
267 enum typec_orientation orientation);
268int typec_set_mode(struct typec_port *port, int mode);
269
248#endif /* __LINUX_USB_TYPEC_H */ 270#endif /* __LINUX_USB_TYPEC_H */
diff --git a/include/linux/usb/typec_mux.h b/include/linux/usb/typec_mux.h
new file mode 100644
index 000000000000..12c1b057834b
--- /dev/null
+++ b/include/linux/usb/typec_mux.h
@@ -0,0 +1,55 @@
1// SPDX-License-Identifier: GPL-2.0
2
3#ifndef __USB_TYPEC_MUX
4#define __USB_TYPEC_MUX
5
6#include <linux/list.h>
7#include <linux/usb/typec.h>
8
9struct device;
10
11/**
12 * struct typec_switch - USB Type-C cable orientation switch
13 * @dev: Switch device
14 * @entry: List entry
15 * @set: Callback to the driver for setting the orientation
16 *
17 * USB Type-C pin flipper switch routing the correct data pairs from the
18 * connector to the USB controller depending on the orientation of the cable
19 * plug.
20 */
21struct typec_switch {
22 struct device *dev;
23 struct list_head entry;
24
25 int (*set)(struct typec_switch *sw, enum typec_orientation orientation);
26};
27
28/**
29 * struct typec_switch - USB Type-C connector pin mux
30 * @dev: Mux device
31 * @entry: List entry
32 * @set: Callback to the driver for setting the state of the mux
33 *
34 * Pin Multiplexer/DeMultiplexer switch routing the USB Type-C connector pins to
35 * different components depending on the requested mode of operation. Used with
36 * Accessory/Alternate modes.
37 */
38struct typec_mux {
39 struct device *dev;
40 struct list_head entry;
41
42 int (*set)(struct typec_mux *mux, int state);
43};
44
45struct typec_switch *typec_switch_get(struct device *dev);
46void typec_switch_put(struct typec_switch *sw);
47int typec_switch_register(struct typec_switch *sw);
48void typec_switch_unregister(struct typec_switch *sw);
49
50struct typec_mux *typec_mux_get(struct device *dev);
51void typec_mux_put(struct typec_mux *mux);
52int typec_mux_register(struct typec_mux *mux);
53void typec_mux_unregister(struct typec_mux *mux);
54
55#endif /* __USB_TYPEC_MUX */