Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

typec: tcpm: Add PD Rev 3.0 definitions to PD header

This commit adds definitions for PD Rev 3.0 messages, including
APDO PPS and extended message support for TCPM.

Signed-off-by: Adam Thomson <Adam.Thomson.Opensource@diasemi.com>
Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Adam Thomson and committed by
Greg Kroah-Hartman
ccefd976 ad81b15d

+174 -11
+174 -11
include/linux/usb/pd.h
··· 35 35 PD_CTRL_WAIT = 12, 36 36 PD_CTRL_SOFT_RESET = 13, 37 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 47 enum pd_data_msg_type { ··· 50 43 PD_DATA_REQUEST = 2, 51 44 PD_DATA_BIST = 3, 52 45 PD_DATA_SINK_CAP = 4, 53 - /* 5-14 Reserved */ 46 + PD_DATA_BATT_STATUS = 5, 47 + PD_DATA_ALERT = 6, 48 + PD_DATA_GET_COUNTRY_INFO = 7, 49 + /* 8-14 Reserved */ 54 50 PD_DATA_VENDOR_DEF = 15, 51 + /* 16-31 Reserved */ 52 + }; 53 + 54 + enum pd_ext_msg_type { 55 + /* 0 Reserved */ 56 + PD_EXT_SOURCE_CAP_EXT = 1, 57 + PD_EXT_STATUS = 2, 58 + PD_EXT_GET_BATT_CAP = 3, 59 + PD_EXT_GET_BATT_STATUS = 4, 60 + PD_EXT_BATT_CAP = 5, 61 + PD_EXT_GET_MANUFACTURER_INFO = 6, 62 + PD_EXT_MANUFACTURER_INFO = 7, 63 + PD_EXT_SECURITY_REQUEST = 8, 64 + PD_EXT_SECURITY_RESPONSE = 9, 65 + PD_EXT_FW_UPDATE_REQUEST = 10, 66 + PD_EXT_FW_UPDATE_RESPONSE = 11, 67 + PD_EXT_PPS_STATUS = 12, 68 + PD_EXT_COUNTRY_INFO = 13, 69 + PD_EXT_COUNTRY_CODES = 14, 70 + /* 15-31 Reserved */ 55 71 }; 56 72 57 73 #define PD_REV10 0x0 58 74 #define PD_REV20 0x1 75 + #define PD_REV30 0x2 76 + #define PD_MAX_REV PD_REV30 59 77 78 + #define PD_HEADER_EXT_HDR BIT(15) 60 79 #define PD_HEADER_CNT_SHIFT 12 61 80 #define PD_HEADER_CNT_MASK 0x7 62 81 #define PD_HEADER_ID_SHIFT 9 ··· 92 59 #define PD_HEADER_REV_MASK 0x3 93 60 #define PD_HEADER_DATA_ROLE BIT(5) 94 61 #define PD_HEADER_TYPE_SHIFT 0 95 - #define PD_HEADER_TYPE_MASK 0xf 62 + #define PD_HEADER_TYPE_MASK 0x1f 96 63 97 - #define PD_HEADER(type, pwr, data, id, cnt) \ 64 + #define PD_HEADER(type, pwr, data, rev, id, cnt, ext_hdr) \ 98 65 ((((type) & PD_HEADER_TYPE_MASK) << PD_HEADER_TYPE_SHIFT) | \ 99 66 ((pwr) == TYPEC_SOURCE ? PD_HEADER_PWR_ROLE : 0) | \ 100 67 ((data) == TYPEC_HOST ? PD_HEADER_DATA_ROLE : 0) | \ 101 - (PD_REV20 << PD_HEADER_REV_SHIFT) | \ 68 + (rev << PD_HEADER_REV_SHIFT) | \ 102 69 (((id) & PD_HEADER_ID_MASK) << PD_HEADER_ID_SHIFT) | \ 103 - (((cnt) & PD_HEADER_CNT_MASK) << PD_HEADER_CNT_SHIFT)) 70 + (((cnt) & PD_HEADER_CNT_MASK) << PD_HEADER_CNT_SHIFT) | \ 71 + ((ext_hdr) ? PD_HEADER_EXT_HDR : 0)) 104 72 105 73 #define PD_HEADER_LE(type, pwr, data, id, cnt) \ 106 - cpu_to_le16(PD_HEADER((type), (pwr), (data), (id), (cnt))) 74 + cpu_to_le16(PD_HEADER((type), (pwr), (data), PD_REV20, (id), (cnt), (0))) 107 75 108 76 static inline unsigned int pd_header_cnt(u16 header) 109 77 { ··· 136 102 return pd_header_msgid(le16_to_cpu(header)); 137 103 } 138 104 105 + static inline unsigned int pd_header_rev(u16 header) 106 + { 107 + return (header >> PD_HEADER_REV_SHIFT) & PD_HEADER_REV_MASK; 108 + } 109 + 110 + static inline unsigned int pd_header_rev_le(__le16 header) 111 + { 112 + return pd_header_rev(le16_to_cpu(header)); 113 + } 114 + 115 + #define PD_EXT_HDR_CHUNKED BIT(15) 116 + #define PD_EXT_HDR_CHUNK_NUM_SHIFT 11 117 + #define PD_EXT_HDR_CHUNK_NUM_MASK 0xf 118 + #define PD_EXT_HDR_REQ_CHUNK BIT(10) 119 + #define PD_EXT_HDR_DATA_SIZE_SHIFT 0 120 + #define PD_EXT_HDR_DATA_SIZE_MASK 0x1ff 121 + 122 + #define PD_EXT_HDR(data_size, req_chunk, chunk_num, chunked) \ 123 + ((((data_size) & PD_EXT_HDR_DATA_SIZE_MASK) << PD_EXT_HDR_DATA_SIZE_SHIFT) | \ 124 + ((req_chunk) ? PD_EXT_HDR_REQ_CHUNK : 0) | \ 125 + (((chunk_num) & PD_EXT_HDR_CHUNK_NUM_MASK) << PD_EXT_HDR_CHUNK_NUM_SHIFT) | \ 126 + ((chunked) ? PD_EXT_HDR_CHUNKED : 0)) 127 + 128 + #define PD_EXT_HDR_LE(data_size, req_chunk, chunk_num, chunked) \ 129 + cpu_to_le16(PD_EXT_HDR((data_size), (req_chunk), (chunk_num), (chunked))) 130 + 131 + static inline unsigned int pd_ext_header_chunk_num(u16 ext_header) 132 + { 133 + return (ext_header >> PD_EXT_HDR_CHUNK_NUM_SHIFT) & 134 + PD_EXT_HDR_CHUNK_NUM_MASK; 135 + } 136 + 137 + static inline unsigned int pd_ext_header_data_size(u16 ext_header) 138 + { 139 + return (ext_header >> PD_EXT_HDR_DATA_SIZE_SHIFT) & 140 + PD_EXT_HDR_DATA_SIZE_MASK; 141 + } 142 + 143 + static inline unsigned int pd_ext_header_data_size_le(__le16 ext_header) 144 + { 145 + return pd_ext_header_data_size(le16_to_cpu(ext_header)); 146 + } 147 + 139 148 #define PD_MAX_PAYLOAD 7 149 + #define PD_EXT_MAX_CHUNK_DATA 26 140 150 141 151 /** 142 - * struct pd_message - PD message as seen on wire 143 - * @header: PD message header 144 - * @payload: PD message payload 145 - */ 152 + * struct pd_chunked_ext_message_data - PD chunked extended message data as 153 + * seen on wire 154 + * @header: PD extended message header 155 + * @data: PD extended message data 156 + */ 157 + struct pd_chunked_ext_message_data { 158 + __le16 header; 159 + u8 data[PD_EXT_MAX_CHUNK_DATA]; 160 + } __packed; 161 + 162 + /** 163 + * struct pd_message - PD message as seen on wire 164 + * @header: PD message header 165 + * @payload: PD message payload 166 + * @ext_msg: PD message chunked extended message data 167 + */ 146 168 struct pd_message { 147 169 __le16 header; 148 - __le32 payload[PD_MAX_PAYLOAD]; 170 + union { 171 + __le32 payload[PD_MAX_PAYLOAD]; 172 + struct pd_chunked_ext_message_data ext_msg; 173 + }; 149 174 } __packed; 150 175 151 176 /* PDO: Power Data Object */ ··· 214 121 PDO_TYPE_FIXED = 0, 215 122 PDO_TYPE_BATT = 1, 216 123 PDO_TYPE_VAR = 2, 124 + PDO_TYPE_APDO = 3, 217 125 }; 218 126 219 127 #define PDO_TYPE_SHIFT 30 ··· 268 174 (PDO_TYPE(PDO_TYPE_VAR) | PDO_VAR_MIN_VOLT(min_mv) | \ 269 175 PDO_VAR_MAX_VOLT(max_mv) | PDO_VAR_MAX_CURR(max_ma)) 270 176 177 + enum pd_apdo_type { 178 + APDO_TYPE_PPS = 0, 179 + }; 180 + 181 + #define PDO_APDO_TYPE_SHIFT 28 /* Only valid value currently is 0x0 - PPS */ 182 + #define PDO_APDO_TYPE_MASK 0x3 183 + 184 + #define PDO_APDO_TYPE(t) ((t) << PDO_APDO_TYPE_SHIFT) 185 + 186 + #define PDO_PPS_APDO_MAX_VOLT_SHIFT 17 /* 100mV units */ 187 + #define PDO_PPS_APDO_MIN_VOLT_SHIFT 8 /* 100mV units */ 188 + #define PDO_PPS_APDO_MAX_CURR_SHIFT 0 /* 50mA units */ 189 + 190 + #define PDO_PPS_APDO_VOLT_MASK 0xff 191 + #define PDO_PPS_APDO_CURR_MASK 0x7f 192 + 193 + #define PDO_PPS_APDO_MIN_VOLT(mv) \ 194 + ((((mv) / 100) & PDO_PPS_APDO_VOLT_MASK) << PDO_PPS_APDO_MIN_VOLT_SHIFT) 195 + #define PDO_PPS_APDO_MAX_VOLT(mv) \ 196 + ((((mv) / 100) & PDO_PPS_APDO_VOLT_MASK) << PDO_PPS_APDO_MAX_VOLT_SHIFT) 197 + #define PDO_PPS_APDO_MAX_CURR(ma) \ 198 + ((((ma) / 50) & PDO_PPS_APDO_CURR_MASK) << PDO_PPS_APDO_MAX_CURR_SHIFT) 199 + 200 + #define PDO_PPS_APDO(min_mv, max_mv, max_ma) \ 201 + (PDO_TYPE(PDO_TYPE_APDO) | PDO_APDO_TYPE(APDO_TYPE_PPS) | \ 202 + PDO_PPS_APDO_MIN_VOLT(min_mv) | PDO_PPS_APDO_MAX_VOLT(max_mv) | \ 203 + PDO_PPS_APDO_MAX_CURR(max_ma)) 204 + 271 205 static inline enum pd_pdo_type pdo_type(u32 pdo) 272 206 { 273 207 return (pdo >> PDO_TYPE_SHIFT) & PDO_TYPE_MASK; ··· 324 202 static inline unsigned int pdo_max_power(u32 pdo) 325 203 { 326 204 return ((pdo >> PDO_BATT_MAX_PWR_SHIFT) & PDO_PWR_MASK) * 250; 205 + } 206 + 207 + static inline enum pd_apdo_type pdo_apdo_type(u32 pdo) 208 + { 209 + return (pdo >> PDO_APDO_TYPE_SHIFT) & PDO_APDO_TYPE_MASK; 210 + } 211 + 212 + static inline unsigned int pdo_pps_apdo_min_voltage(u32 pdo) 213 + { 214 + return ((pdo >> PDO_PPS_APDO_MIN_VOLT_SHIFT) & 215 + PDO_PPS_APDO_VOLT_MASK) * 100; 216 + } 217 + 218 + static inline unsigned int pdo_pps_apdo_max_voltage(u32 pdo) 219 + { 220 + return ((pdo >> PDO_PPS_APDO_MAX_VOLT_SHIFT) & 221 + PDO_PPS_APDO_VOLT_MASK) * 100; 222 + } 223 + 224 + static inline unsigned int pdo_pps_apdo_max_current(u32 pdo) 225 + { 226 + return ((pdo >> PDO_PPS_APDO_MAX_CURR_SHIFT) & 227 + PDO_PPS_APDO_CURR_MASK) * 50; 327 228 } 328 229 329 230 /* RDO: Request Data Object */ ··· 381 236 #define RDO_BATT(idx, op_mw, max_mw, flags) \ 382 237 (RDO_OBJ(idx) | (flags) | \ 383 238 RDO_BATT_OP_PWR(op_mw) | RDO_BATT_MAX_PWR(max_mw)) 239 + 240 + #define RDO_PROG_VOLT_MASK 0x7ff 241 + #define RDO_PROG_CURR_MASK 0x7f 242 + 243 + #define RDO_PROG_VOLT_SHIFT 9 244 + #define RDO_PROG_CURR_SHIFT 0 245 + 246 + #define RDO_PROG_VOLT_MV_STEP 20 247 + #define RDO_PROG_CURR_MA_STEP 50 248 + 249 + #define PDO_PROG_OUT_VOLT(mv) \ 250 + ((((mv) / RDO_PROG_VOLT_MV_STEP) & RDO_PROG_VOLT_MASK) << RDO_PROG_VOLT_SHIFT) 251 + #define PDO_PROG_OP_CURR(ma) \ 252 + ((((ma) / RDO_PROG_CURR_MA_STEP) & RDO_PROG_CURR_MASK) << RDO_PROG_CURR_SHIFT) 253 + 254 + #define RDO_PROG(idx, out_mv, op_ma, flags) \ 255 + (RDO_OBJ(idx) | (flags) | \ 256 + PDO_PROG_OUT_VOLT(out_mv) | PDO_PROG_OP_CURR(op_ma)) 384 257 385 258 static inline unsigned int rdo_index(u32 rdo) 386 259 {