diff options
Diffstat (limited to 'include/linux/usb')
| -rw-r--r-- | include/linux/usb/hcd.h | 8 | ||||
| -rw-r--r-- | include/linux/usb/pd.h | 185 | ||||
| -rw-r--r-- | include/linux/usb/pd_ado.h | 42 | ||||
| -rw-r--r-- | include/linux/usb/pd_ext_sdb.h | 31 | ||||
| -rw-r--r-- | include/linux/usb/quirks.h | 3 | ||||
| -rw-r--r-- | include/linux/usb/role.h | 53 | ||||
| -rw-r--r-- | include/linux/usb/tcpm.h | 15 | ||||
| -rw-r--r-- | include/linux/usb/typec.h | 28 | ||||
| -rw-r--r-- | include/linux/usb/typec_mux.h | 55 |
9 files changed, 391 insertions, 29 deletions
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 | ||
| 40 | enum pd_data_msg_type { | 47 | enum 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 | |||
| 61 | enum 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 | ||
| 75 | static inline unsigned int pd_header_cnt(u16 header) | 109 | static 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 | ||
| 139 | static inline unsigned int pd_header_rev(u16 header) | ||
| 140 | { | ||
| 141 | return (header >> PD_HEADER_REV_SHIFT) & PD_HEADER_REV_MASK; | ||
| 142 | } | ||
| 143 | |||
| 144 | static 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 | |||
| 165 | static 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 | |||
| 171 | static 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 | |||
| 177 | static 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 | */ | ||
| 191 | struct 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 | */ | ||
| 112 | struct pd_message { | 202 | struct 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 | ||
| 271 | enum 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 | |||
| 177 | static inline enum pd_pdo_type pdo_type(u32 pdo) | 299 | static 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 | ||
| 329 | static inline enum pd_apdo_type pdo_apdo_type(u32 pdo) | ||
| 330 | { | ||
| 331 | return (pdo >> PDO_APDO_TYPE_SHIFT) & PDO_APDO_TYPE_MASK; | ||
| 332 | } | ||
| 333 | |||
| 334 | static 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 | |||
| 340 | static 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 | |||
| 346 | static 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 | |||
| 240 | static inline unsigned int rdo_index(u32 rdo) | 403 | static 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 | |||
| 26 | static 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 | |||
| 31 | static 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 | |||
| 37 | static 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 */ | ||
| 12 | enum 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/quirks.h b/include/linux/usb/quirks.h index f1fcec2fd5f8..b7a99ce56bc9 100644 --- a/include/linux/usb/quirks.h +++ b/include/linux/usb/quirks.h | |||
| @@ -63,4 +63,7 @@ | |||
| 63 | */ | 63 | */ |
| 64 | #define USB_QUIRK_DISCONNECT_SUSPEND BIT(12) | 64 | #define USB_QUIRK_DISCONNECT_SUSPEND BIT(12) |
| 65 | 65 | ||
| 66 | /* Device needs a pause after every control message. */ | ||
| 67 | #define USB_QUIRK_DELAY_CTRL_MSG BIT(13) | ||
| 68 | |||
| 66 | #endif /* __LINUX_USB_QUIRKS_H */ | 69 | #endif /* __LINUX_USB_QUIRKS_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 | |||
| 8 | struct usb_role_switch; | ||
| 9 | |||
| 10 | enum usb_role { | ||
| 11 | USB_ROLE_NONE, | ||
| 12 | USB_ROLE_HOST, | ||
| 13 | USB_ROLE_DEVICE, | ||
| 14 | }; | ||
| 15 | |||
| 16 | typedef int (*usb_role_switch_set_t)(struct device *dev, enum usb_role role); | ||
| 17 | typedef 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 | */ | ||
| 34 | struct 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 | |||
| 43 | int usb_role_switch_set_role(struct usb_role_switch *sw, enum usb_role role); | ||
| 44 | enum usb_role usb_role_switch_get_role(struct usb_role_switch *sw); | ||
| 45 | struct usb_role_switch *usb_role_switch_get(struct device *dev); | ||
| 46 | void usb_role_switch_put(struct usb_role_switch *sw); | ||
| 47 | |||
| 48 | struct usb_role_switch * | ||
| 49 | usb_role_switch_register(struct device *parent, | ||
| 50 | const struct usb_role_switch_desc *desc); | ||
| 51 | void 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 | ||
| 100 | enum 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 | ||
| 119 | struct 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 | ||
| 181 | struct tcpm_port; | 168 | struct 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; | |||
| 22 | struct fwnode_handle; | 22 | struct fwnode_handle; |
| 23 | 23 | ||
| 24 | enum typec_port_type { | 24 | enum typec_port_type { |
| 25 | TYPEC_PORT_SRC, | ||
| 26 | TYPEC_PORT_SNK, | ||
| 27 | TYPEC_PORT_DRP, | ||
| 28 | }; | ||
| 29 | |||
| 30 | enum 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 | ||
| 30 | enum typec_plug_type { | 36 | enum 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 | ||
| 69 | enum 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 | */ |
| 198 | struct typec_capability { | 213 | struct 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); | |||
| 245 | void typec_set_vconn_role(struct typec_port *port, enum typec_role role); | 263 | void typec_set_vconn_role(struct typec_port *port, enum typec_role role); |
| 246 | void typec_set_pwr_opmode(struct typec_port *port, enum typec_pwr_opmode mode); | 264 | void typec_set_pwr_opmode(struct typec_port *port, enum typec_pwr_opmode mode); |
| 247 | 265 | ||
| 266 | int typec_set_orientation(struct typec_port *port, | ||
| 267 | enum typec_orientation orientation); | ||
| 268 | int 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 | |||
| 9 | struct 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 | */ | ||
| 21 | struct 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 | */ | ||
| 38 | struct typec_mux { | ||
| 39 | struct device *dev; | ||
| 40 | struct list_head entry; | ||
| 41 | |||
| 42 | int (*set)(struct typec_mux *mux, int state); | ||
| 43 | }; | ||
| 44 | |||
| 45 | struct typec_switch *typec_switch_get(struct device *dev); | ||
| 46 | void typec_switch_put(struct typec_switch *sw); | ||
| 47 | int typec_switch_register(struct typec_switch *sw); | ||
| 48 | void typec_switch_unregister(struct typec_switch *sw); | ||
| 49 | |||
| 50 | struct typec_mux *typec_mux_get(struct device *dev); | ||
| 51 | void typec_mux_put(struct typec_mux *mux); | ||
| 52 | int typec_mux_register(struct typec_mux *mux); | ||
| 53 | void typec_mux_unregister(struct typec_mux *mux); | ||
| 54 | |||
| 55 | #endif /* __USB_TYPEC_MUX */ | ||
