root/drivers/usb/typec/ucsi/ucsi.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. ucsi_register_displayport
  2. ucsi_displayport_remove_partner

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 
   3 #ifndef __DRIVER_USB_TYPEC_UCSI_H
   4 #define __DRIVER_USB_TYPEC_UCSI_H
   5 
   6 #include <linux/bitops.h>
   7 #include <linux/device.h>
   8 #include <linux/types.h>
   9 #include <linux/usb/typec.h>
  10 
  11 /* -------------------------------------------------------------------------- */
  12 
  13 /* Command Status and Connector Change Indication (CCI) data structure */
  14 struct ucsi_cci {
  15         u8:1; /* reserved */
  16         u8 connector_change:7;
  17         u8 data_length;
  18         u16:9; /* reserved */
  19         u16 not_supported:1;
  20         u16 cancel_complete:1;
  21         u16 reset_complete:1;
  22         u16 busy:1;
  23         u16 ack_complete:1;
  24         u16 error:1;
  25         u16 cmd_complete:1;
  26 } __packed;
  27 
  28 /* Default fields in CONTROL data structure */
  29 struct ucsi_command {
  30         u8 cmd;
  31         u8 length;
  32         u64 data:48;
  33 } __packed;
  34 
  35 /* ACK Command structure */
  36 struct ucsi_ack_cmd {
  37         u8 cmd;
  38         u8 length;
  39         u8 cci_ack:1;
  40         u8 cmd_ack:1;
  41         u8:6; /* reserved */
  42 } __packed;
  43 
  44 /* Connector Reset Command structure */
  45 struct ucsi_con_rst {
  46         u8 cmd;
  47         u8 length;
  48         u8 con_num:7;
  49         u8 hard_reset:1;
  50 } __packed;
  51 
  52 /* Set USB Operation Mode Command structure */
  53 struct ucsi_uor_cmd {
  54         u8 cmd;
  55         u8 length;
  56         u16 con_num:7;
  57         u16 role:3;
  58 #define UCSI_UOR_ROLE_DFP                       BIT(0)
  59 #define UCSI_UOR_ROLE_UFP                       BIT(1)
  60 #define UCSI_UOR_ROLE_DRP                       BIT(2)
  61         u16:6; /* reserved */
  62 } __packed;
  63 
  64 /* Get Alternate Modes Command structure */
  65 struct ucsi_altmode_cmd {
  66         u8 cmd;
  67         u8 length;
  68         u8 recipient;
  69 #define UCSI_RECIPIENT_CON                      0
  70 #define UCSI_RECIPIENT_SOP                      1
  71 #define UCSI_RECIPIENT_SOP_P                    2
  72 #define UCSI_RECIPIENT_SOP_PP                   3
  73         u8 con_num;
  74         u8 offset;
  75         u8 num_altmodes;
  76 } __packed;
  77 
  78 struct ucsi_control {
  79         union {
  80                 u64 raw_cmd;
  81                 struct ucsi_command cmd;
  82                 struct ucsi_uor_cmd uor;
  83                 struct ucsi_ack_cmd ack;
  84                 struct ucsi_con_rst con_rst;
  85                 struct ucsi_altmode_cmd alt;
  86         };
  87 };
  88 
  89 #define __UCSI_CMD(_ctrl_, _cmd_)                                       \
  90 {                                                                       \
  91         (_ctrl_).raw_cmd = 0;                                           \
  92         (_ctrl_).cmd.cmd = _cmd_;                                       \
  93 }
  94 
  95 /* Helper for preparing ucsi_control for CONNECTOR_RESET command. */
  96 #define UCSI_CMD_CONNECTOR_RESET(_ctrl_, _con_, _hard_)                 \
  97 {                                                                       \
  98         __UCSI_CMD(_ctrl_, UCSI_CONNECTOR_RESET)                        \
  99         (_ctrl_).con_rst.con_num = (_con_)->num;                        \
 100         (_ctrl_).con_rst.hard_reset = _hard_;                           \
 101 }
 102 
 103 /* Helper for preparing ucsi_control for ACK_CC_CI command. */
 104 #define UCSI_CMD_ACK(_ctrl_, _ack_)                                     \
 105 {                                                                       \
 106         __UCSI_CMD(_ctrl_, UCSI_ACK_CC_CI)                              \
 107         (_ctrl_).ack.cci_ack = ((_ack_) == UCSI_ACK_EVENT);             \
 108         (_ctrl_).ack.cmd_ack = ((_ack_) == UCSI_ACK_CMD);               \
 109 }
 110 
 111 /* Helper for preparing ucsi_control for SET_NOTIFY_ENABLE command. */
 112 #define UCSI_CMD_SET_NTFY_ENABLE(_ctrl_, _ntfys_)                       \
 113 {                                                                       \
 114         __UCSI_CMD(_ctrl_, UCSI_SET_NOTIFICATION_ENABLE)                \
 115         (_ctrl_).cmd.data = _ntfys_;                                    \
 116 }
 117 
 118 /* Helper for preparing ucsi_control for GET_CAPABILITY command. */
 119 #define UCSI_CMD_GET_CAPABILITY(_ctrl_)                                 \
 120 {                                                                       \
 121         __UCSI_CMD(_ctrl_, UCSI_GET_CAPABILITY)                         \
 122 }
 123 
 124 /* Helper for preparing ucsi_control for GET_CONNECTOR_CAPABILITY command. */
 125 #define UCSI_CMD_GET_CONNECTOR_CAPABILITY(_ctrl_, _con_)                \
 126 {                                                                       \
 127         __UCSI_CMD(_ctrl_, UCSI_GET_CONNECTOR_CAPABILITY)               \
 128         (_ctrl_).cmd.data = _con_;                                      \
 129 }
 130 
 131 /* Helper for preparing ucsi_control for GET_ALTERNATE_MODES command. */
 132 #define UCSI_CMD_GET_ALTERNATE_MODES(_ctrl_, _r_, _con_num_, _o_, _num_)\
 133 {                                                                       \
 134         __UCSI_CMD((_ctrl_), UCSI_GET_ALTERNATE_MODES)                  \
 135         _ctrl_.alt.recipient = (_r_);                                   \
 136         _ctrl_.alt.con_num = (_con_num_);                               \
 137         _ctrl_.alt.offset = (_o_);                                      \
 138         _ctrl_.alt.num_altmodes = (_num_) - 1;                          \
 139 }
 140 
 141 /* Helper for preparing ucsi_control for GET_CAM_SUPPORTED command. */
 142 #define UCSI_CMD_GET_CAM_SUPPORTED(_ctrl_, _con_)                       \
 143 {                                                                       \
 144         __UCSI_CMD((_ctrl_), UCSI_GET_CAM_SUPPORTED)                    \
 145         _ctrl_.cmd.data = (_con_);                                      \
 146 }
 147 
 148 /* Helper for preparing ucsi_control for GET_CAM_SUPPORTED command. */
 149 #define UCSI_CMD_GET_CURRENT_CAM(_ctrl_, _con_)                 \
 150 {                                                                       \
 151         __UCSI_CMD((_ctrl_), UCSI_GET_CURRENT_CAM)                      \
 152         _ctrl_.cmd.data = (_con_);                                      \
 153 }
 154 
 155 /* Helper for preparing ucsi_control for GET_CONNECTOR_STATUS command. */
 156 #define UCSI_CMD_GET_CONNECTOR_STATUS(_ctrl_, _con_)                    \
 157 {                                                                       \
 158         __UCSI_CMD(_ctrl_, UCSI_GET_CONNECTOR_STATUS)                   \
 159         (_ctrl_).cmd.data = _con_;                                      \
 160 }
 161 
 162 #define __UCSI_ROLE(_ctrl_, _cmd_, _con_num_)                           \
 163 {                                                                       \
 164         __UCSI_CMD(_ctrl_, _cmd_)                                       \
 165         (_ctrl_).uor.con_num = _con_num_;                               \
 166         (_ctrl_).uor.role = UCSI_UOR_ROLE_DRP;                          \
 167 }
 168 
 169 /* Helper for preparing ucsi_control for SET_UOR command. */
 170 #define UCSI_CMD_SET_UOR(_ctrl_, _con_, _role_)                         \
 171 {                                                                       \
 172         __UCSI_ROLE(_ctrl_, UCSI_SET_UOR, (_con_)->num)         \
 173         (_ctrl_).uor.role |= (_role_) == TYPEC_HOST ? UCSI_UOR_ROLE_DFP : \
 174                           UCSI_UOR_ROLE_UFP;                            \
 175 }
 176 
 177 /* Helper for preparing ucsi_control for SET_PDR command. */
 178 #define UCSI_CMD_SET_PDR(_ctrl_, _con_, _role_)                 \
 179 {                                                                       \
 180         __UCSI_ROLE(_ctrl_, UCSI_SET_PDR, (_con_)->num)         \
 181         (_ctrl_).uor.role |= (_role_) == TYPEC_SOURCE ? UCSI_UOR_ROLE_DFP : \
 182                         UCSI_UOR_ROLE_UFP;                              \
 183 }
 184 
 185 /* Commands */
 186 #define UCSI_PPM_RESET                  0x01
 187 #define UCSI_CANCEL                     0x02
 188 #define UCSI_CONNECTOR_RESET            0x03
 189 #define UCSI_ACK_CC_CI                  0x04
 190 #define UCSI_SET_NOTIFICATION_ENABLE    0x05
 191 #define UCSI_GET_CAPABILITY             0x06
 192 #define UCSI_GET_CONNECTOR_CAPABILITY   0x07
 193 #define UCSI_SET_UOM                    0x08
 194 #define UCSI_SET_UOR                    0x09
 195 #define UCSI_SET_PDM                    0x0a
 196 #define UCSI_SET_PDR                    0x0b
 197 #define UCSI_GET_ALTERNATE_MODES        0x0c
 198 #define UCSI_GET_CAM_SUPPORTED          0x0d
 199 #define UCSI_GET_CURRENT_CAM            0x0e
 200 #define UCSI_SET_NEW_CAM                0x0f
 201 #define UCSI_GET_PDOS                   0x10
 202 #define UCSI_GET_CABLE_PROPERTY         0x11
 203 #define UCSI_GET_CONNECTOR_STATUS       0x12
 204 #define UCSI_GET_ERROR_STATUS           0x13
 205 
 206 /* ACK_CC_CI commands */
 207 #define UCSI_ACK_EVENT                  1
 208 #define UCSI_ACK_CMD                    2
 209 
 210 /* Bits for SET_NOTIFICATION_ENABLE command */
 211 #define UCSI_ENABLE_NTFY_CMD_COMPLETE           BIT(0)
 212 #define UCSI_ENABLE_NTFY_EXT_PWR_SRC_CHANGE     BIT(1)
 213 #define UCSI_ENABLE_NTFY_PWR_OPMODE_CHANGE      BIT(2)
 214 #define UCSI_ENABLE_NTFY_CAP_CHANGE             BIT(5)
 215 #define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE       BIT(6)
 216 #define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE      BIT(7)
 217 #define UCSI_ENABLE_NTFY_CAM_CHANGE             BIT(8)
 218 #define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE      BIT(9)
 219 #define UCSI_ENABLE_NTFY_PARTNER_CHANGE         BIT(11)
 220 #define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE         BIT(12)
 221 #define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE       BIT(14)
 222 #define UCSI_ENABLE_NTFY_ERROR                  BIT(15)
 223 #define UCSI_ENABLE_NTFY_ALL                    0xdbe7
 224 
 225 /* Error information returned by PPM in response to GET_ERROR_STATUS command. */
 226 #define UCSI_ERROR_UNREGONIZED_CMD              BIT(0)
 227 #define UCSI_ERROR_INVALID_CON_NUM              BIT(1)
 228 #define UCSI_ERROR_INVALID_CMD_ARGUMENT         BIT(2)
 229 #define UCSI_ERROR_INCOMPATIBLE_PARTNER         BIT(3)
 230 #define UCSI_ERROR_CC_COMMUNICATION_ERR         BIT(4)
 231 #define UCSI_ERROR_DEAD_BATTERY                 BIT(5)
 232 #define UCSI_ERROR_CONTRACT_NEGOTIATION_FAIL    BIT(6)
 233 
 234 /* Data structure filled by PPM in response to GET_CAPABILITY command. */
 235 struct ucsi_capability {
 236         u32 attributes;
 237 #define UCSI_CAP_ATTR_DISABLE_STATE             BIT(0)
 238 #define UCSI_CAP_ATTR_BATTERY_CHARGING          BIT(1)
 239 #define UCSI_CAP_ATTR_USB_PD                    BIT(2)
 240 #define UCSI_CAP_ATTR_TYPEC_CURRENT             BIT(6)
 241 #define UCSI_CAP_ATTR_POWER_AC_SUPPLY           BIT(8)
 242 #define UCSI_CAP_ATTR_POWER_OTHER               BIT(10)
 243 #define UCSI_CAP_ATTR_POWER_VBUS                BIT(14)
 244         u32 num_connectors:8;
 245         u32 features:24;
 246 #define UCSI_CAP_SET_UOM                        BIT(0)
 247 #define UCSI_CAP_SET_PDM                        BIT(1)
 248 #define UCSI_CAP_ALT_MODE_DETAILS               BIT(2)
 249 #define UCSI_CAP_ALT_MODE_OVERRIDE              BIT(3)
 250 #define UCSI_CAP_PDO_DETAILS                    BIT(4)
 251 #define UCSI_CAP_CABLE_DETAILS                  BIT(5)
 252 #define UCSI_CAP_EXT_SUPPLY_NOTIFICATIONS       BIT(6)
 253 #define UCSI_CAP_PD_RESET                       BIT(7)
 254         u8 num_alt_modes;
 255         u8 reserved;
 256         u16 bc_version;
 257         u16 pd_version;
 258         u16 typec_version;
 259 } __packed;
 260 
 261 /* Data structure filled by PPM in response to GET_CONNECTOR_CAPABILITY cmd. */
 262 struct ucsi_connector_capability {
 263         u8 op_mode;
 264 #define UCSI_CONCAP_OPMODE_DFP                  BIT(0)
 265 #define UCSI_CONCAP_OPMODE_UFP                  BIT(1)
 266 #define UCSI_CONCAP_OPMODE_DRP                  BIT(2)
 267 #define UCSI_CONCAP_OPMODE_AUDIO_ACCESSORY      BIT(3)
 268 #define UCSI_CONCAP_OPMODE_DEBUG_ACCESSORY      BIT(4)
 269 #define UCSI_CONCAP_OPMODE_USB2                 BIT(5)
 270 #define UCSI_CONCAP_OPMODE_USB3                 BIT(6)
 271 #define UCSI_CONCAP_OPMODE_ALT_MODE             BIT(7)
 272         u8 provider:1;
 273         u8 consumer:1;
 274         u8:6; /* reserved */
 275 } __packed;
 276 
 277 struct ucsi_altmode {
 278         u16 svid;
 279         u32 mid;
 280 } __packed;
 281 
 282 /* Data structure filled by PPM in response to GET_CABLE_PROPERTY command. */
 283 struct ucsi_cable_property {
 284         u16 speed_supported;
 285         u8 current_capability;
 286         u8 vbus_in_cable:1;
 287         u8 active_cable:1;
 288         u8 directionality:1;
 289         u8 plug_type:2;
 290 #define UCSI_CABLE_PROPERTY_PLUG_TYPE_A         0
 291 #define UCSI_CABLE_PROPERTY_PLUG_TYPE_B         1
 292 #define UCSI_CABLE_PROPERTY_PLUG_TYPE_C         2
 293 #define UCSI_CABLE_PROPERTY_PLUG_OTHER          3
 294         u8 mode_support:1;
 295         u8:2; /* reserved */
 296         u8 latency:4;
 297         u8:4; /* reserved */
 298 } __packed;
 299 
 300 /* Data structure filled by PPM in response to GET_CONNECTOR_STATUS command. */
 301 struct ucsi_connector_status {
 302         u16 change;
 303 #define UCSI_CONSTAT_EXT_SUPPLY_CHANGE          BIT(1)
 304 #define UCSI_CONSTAT_POWER_OPMODE_CHANGE        BIT(2)
 305 #define UCSI_CONSTAT_PDOS_CHANGE                BIT(5)
 306 #define UCSI_CONSTAT_POWER_LEVEL_CHANGE         BIT(6)
 307 #define UCSI_CONSTAT_PD_RESET_COMPLETE          BIT(7)
 308 #define UCSI_CONSTAT_CAM_CHANGE                 BIT(8)
 309 #define UCSI_CONSTAT_BC_CHANGE                  BIT(9)
 310 #define UCSI_CONSTAT_PARTNER_CHANGE             BIT(11)
 311 #define UCSI_CONSTAT_POWER_DIR_CHANGE           BIT(12)
 312 #define UCSI_CONSTAT_CONNECT_CHANGE             BIT(14)
 313 #define UCSI_CONSTAT_ERROR                      BIT(15)
 314         u16 pwr_op_mode:3;
 315 #define UCSI_CONSTAT_PWR_OPMODE_NONE            0
 316 #define UCSI_CONSTAT_PWR_OPMODE_DEFAULT         1
 317 #define UCSI_CONSTAT_PWR_OPMODE_BC              2
 318 #define UCSI_CONSTAT_PWR_OPMODE_PD              3
 319 #define UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5        4
 320 #define UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0        5
 321         u16 connected:1;
 322         u16 pwr_dir:1;
 323         u16 partner_flags:8;
 324 #define UCSI_CONSTAT_PARTNER_FLAG_USB           BIT(0)
 325 #define UCSI_CONSTAT_PARTNER_FLAG_ALT_MODE      BIT(1)
 326         u16 partner_type:3;
 327 #define UCSI_CONSTAT_PARTNER_TYPE_DFP           1
 328 #define UCSI_CONSTAT_PARTNER_TYPE_UFP           2
 329 #define UCSI_CONSTAT_PARTNER_TYPE_CABLE         3 /* Powered Cable */
 330 #define UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP 4 /* Powered Cable */
 331 #define UCSI_CONSTAT_PARTNER_TYPE_DEBUG         5
 332 #define UCSI_CONSTAT_PARTNER_TYPE_AUDIO         6
 333         u32 request_data_obj;
 334         u8 bc_status:2;
 335 #define UCSI_CONSTAT_BC_NOT_CHARGING            0
 336 #define UCSI_CONSTAT_BC_NOMINAL_CHARGING        1
 337 #define UCSI_CONSTAT_BC_SLOW_CHARGING           2
 338 #define UCSI_CONSTAT_BC_TRICKLE_CHARGING        3
 339         u8 provider_cap_limit_reason:4;
 340 #define UCSI_CONSTAT_CAP_PWR_LOWERED            0
 341 #define UCSI_CONSTAT_CAP_PWR_BUDGET_LIMIT       1
 342         u8:2; /* reserved */
 343 } __packed;
 344 
 345 /* -------------------------------------------------------------------------- */
 346 
 347 struct ucsi;
 348 
 349 struct ucsi_data {
 350         u16 version;
 351         u16 reserved;
 352         union {
 353                 u32 raw_cci;
 354                 struct ucsi_cci cci;
 355         };
 356         struct ucsi_control ctrl;
 357         u32 message_in[4];
 358         u32 message_out[4];
 359 } __packed;
 360 
 361 /*
 362  * struct ucsi_ppm - Interface to UCSI Platform Policy Manager
 363  * @data: memory location to the UCSI data structures
 364  * @cmd: UCSI command execution routine
 365  * @sync: Refresh UCSI mailbox (the data structures)
 366  */
 367 struct ucsi_ppm {
 368         struct ucsi_data *data;
 369         int (*cmd)(struct ucsi_ppm *, struct ucsi_control *);
 370         int (*sync)(struct ucsi_ppm *);
 371 };
 372 
 373 struct ucsi *ucsi_register_ppm(struct device *dev, struct ucsi_ppm *ppm);
 374 void ucsi_unregister_ppm(struct ucsi *ucsi);
 375 void ucsi_notify(struct ucsi *ucsi);
 376 
 377 /* -------------------------------------------------------------------------- */
 378 
 379 enum ucsi_status {
 380         UCSI_IDLE = 0,
 381         UCSI_BUSY,
 382         UCSI_ERROR,
 383 };
 384 
 385 struct ucsi {
 386         struct device *dev;
 387         struct ucsi_ppm *ppm;
 388 
 389         enum ucsi_status status;
 390         struct completion complete;
 391         struct ucsi_capability cap;
 392         struct ucsi_connector *connector;
 393 
 394         struct work_struct work;
 395 
 396         /* PPM Communication lock */
 397         struct mutex ppm_lock;
 398 
 399         /* PPM communication flags */
 400         unsigned long flags;
 401 #define EVENT_PENDING   0
 402 #define COMMAND_PENDING 1
 403 #define ACK_PENDING     2
 404 };
 405 
 406 #define UCSI_MAX_SVID           5
 407 #define UCSI_MAX_ALTMODES       (UCSI_MAX_SVID * 6)
 408 
 409 struct ucsi_connector {
 410         int num;
 411 
 412         struct ucsi *ucsi;
 413         struct mutex lock; /* port lock */
 414         struct work_struct work;
 415         struct completion complete;
 416 
 417         struct typec_port *port;
 418         struct typec_partner *partner;
 419 
 420         struct typec_altmode *port_altmode[UCSI_MAX_ALTMODES];
 421         struct typec_altmode *partner_altmode[UCSI_MAX_ALTMODES];
 422 
 423         struct typec_capability typec_cap;
 424 
 425         struct ucsi_connector_status status;
 426         struct ucsi_connector_capability cap;
 427 };
 428 
 429 int ucsi_send_command(struct ucsi *ucsi, struct ucsi_control *ctrl,
 430                       void *retval, size_t size);
 431 
 432 void ucsi_altmode_update_active(struct ucsi_connector *con);
 433 int ucsi_resume(struct ucsi *ucsi);
 434 
 435 #if IS_ENABLED(CONFIG_TYPEC_DP_ALTMODE)
 436 struct typec_altmode *
 437 ucsi_register_displayport(struct ucsi_connector *con,
 438                           bool override, int offset,
 439                           struct typec_altmode_desc *desc);
 440 
 441 void ucsi_displayport_remove_partner(struct typec_altmode *adev);
 442 
 443 #else
 444 static inline struct typec_altmode *
 445 ucsi_register_displayport(struct ucsi_connector *con,
 446                           bool override, int offset,
 447                           struct typec_altmode_desc *desc)
 448 {
 449         return NULL;
 450 }
 451 
 452 static inline void
 453 ucsi_displayport_remove_partner(struct typec_altmode *adev) { }
 454 #endif /* CONFIG_TYPEC_DP_ALTMODE */
 455 
 456 #endif /* __DRIVER_USB_TYPEC_UCSI_H */

/* [<][>][^][v][top][bottom][index][help] */