linux/drivers/usb/typec/ucsi/ucsi.h
<<
>>
Prefs
   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
  10/* -------------------------------------------------------------------------- */
  11
  12/* Command Status and Connector Change Indication (CCI) data structure */
  13struct ucsi_cci {
  14        u8:1; /* reserved */
  15        u8 connector_change:7;
  16        u8 data_length;
  17        u16:9; /* reserved */
  18        u16 not_supported:1;
  19        u16 cancel_complete:1;
  20        u16 reset_complete:1;
  21        u16 busy:1;
  22        u16 ack_complete:1;
  23        u16 error:1;
  24        u16 cmd_complete:1;
  25} __packed;
  26
  27/* Default fields in CONTROL data structure */
  28struct ucsi_command {
  29        u8 cmd;
  30        u8 length;
  31        u64 data:48;
  32} __packed;
  33
  34/* ACK Command structure */
  35struct ucsi_ack_cmd {
  36        u8 cmd;
  37        u8 length;
  38        u8 cci_ack:1;
  39        u8 cmd_ack:1;
  40        u8:6; /* reserved */
  41} __packed;
  42
  43/* Connector Reset Command structure */
  44struct ucsi_con_rst {
  45        u8 cmd;
  46        u8 length;
  47        u8 con_num:7;
  48        u8 hard_reset:1;
  49} __packed;
  50
  51/* Set USB Operation Mode Command structure */
  52struct ucsi_uor_cmd {
  53        u8 cmd;
  54        u8 length;
  55        u16 con_num:7;
  56        u16 role:3;
  57#define UCSI_UOR_ROLE_DFP                       BIT(0)
  58#define UCSI_UOR_ROLE_UFP                       BIT(1)
  59#define UCSI_UOR_ROLE_DRP                       BIT(2)
  60        u16:6; /* reserved */
  61} __packed;
  62
  63struct ucsi_control {
  64        union {
  65                u64 raw_cmd;
  66                struct ucsi_command cmd;
  67                struct ucsi_uor_cmd uor;
  68                struct ucsi_ack_cmd ack;
  69                struct ucsi_con_rst con_rst;
  70        };
  71};
  72
  73#define __UCSI_CMD(_ctrl_, _cmd_)                                       \
  74{                                                                       \
  75        (_ctrl_).raw_cmd = 0;                                           \
  76        (_ctrl_).cmd.cmd = _cmd_;                                       \
  77}
  78
  79/* Helper for preparing ucsi_control for CONNECTOR_RESET command. */
  80#define UCSI_CMD_CONNECTOR_RESET(_ctrl_, _con_, _hard_)                 \
  81{                                                                       \
  82        __UCSI_CMD(_ctrl_, UCSI_CONNECTOR_RESET)                        \
  83        (_ctrl_).con_rst.con_num = (_con_)->num;                        \
  84        (_ctrl_).con_rst.hard_reset = _hard_;                           \
  85}
  86
  87/* Helper for preparing ucsi_control for ACK_CC_CI command. */
  88#define UCSI_CMD_ACK(_ctrl_, _ack_)                                     \
  89{                                                                       \
  90        __UCSI_CMD(_ctrl_, UCSI_ACK_CC_CI)                              \
  91        (_ctrl_).ack.cci_ack = ((_ack_) == UCSI_ACK_EVENT);             \
  92        (_ctrl_).ack.cmd_ack = ((_ack_) == UCSI_ACK_CMD);               \
  93}
  94
  95/* Helper for preparing ucsi_control for SET_NOTIFY_ENABLE command. */
  96#define UCSI_CMD_SET_NTFY_ENABLE(_ctrl_, _ntfys_)                       \
  97{                                                                       \
  98        __UCSI_CMD(_ctrl_, UCSI_SET_NOTIFICATION_ENABLE)                \
  99        (_ctrl_).cmd.data = _ntfys_;                                    \
 100}
 101
 102/* Helper for preparing ucsi_control for GET_CAPABILITY command. */
 103#define UCSI_CMD_GET_CAPABILITY(_ctrl_)                                 \
 104{                                                                       \
 105        __UCSI_CMD(_ctrl_, UCSI_GET_CAPABILITY)                         \
 106}
 107
 108/* Helper for preparing ucsi_control for GET_CONNECTOR_CAPABILITY command. */
 109#define UCSI_CMD_GET_CONNECTOR_CAPABILITY(_ctrl_, _con_)                \
 110{                                                                       \
 111        __UCSI_CMD(_ctrl_, UCSI_GET_CONNECTOR_CAPABILITY)               \
 112        (_ctrl_).cmd.data = _con_;                                      \
 113}
 114
 115/* Helper for preparing ucsi_control for GET_CONNECTOR_STATUS command. */
 116#define UCSI_CMD_GET_CONNECTOR_STATUS(_ctrl_, _con_)                    \
 117{                                                                       \
 118        __UCSI_CMD(_ctrl_, UCSI_GET_CONNECTOR_STATUS)                   \
 119        (_ctrl_).cmd.data = _con_;                                      \
 120}
 121
 122#define __UCSI_ROLE(_ctrl_, _cmd_, _con_num_)                           \
 123{                                                                       \
 124        __UCSI_CMD(_ctrl_, _cmd_)                                       \
 125        (_ctrl_).uor.con_num = _con_num_;                               \
 126        (_ctrl_).uor.role = UCSI_UOR_ROLE_DRP;                          \
 127}
 128
 129/* Helper for preparing ucsi_control for SET_UOR command. */
 130#define UCSI_CMD_SET_UOR(_ctrl_, _con_, _role_)                         \
 131{                                                                       \
 132        __UCSI_ROLE(_ctrl_, UCSI_SET_UOR, (_con_)->num)         \
 133        (_ctrl_).uor.role |= (_role_) == TYPEC_HOST ? UCSI_UOR_ROLE_DFP : \
 134                          UCSI_UOR_ROLE_UFP;                            \
 135}
 136
 137/* Helper for preparing ucsi_control for SET_PDR command. */
 138#define UCSI_CMD_SET_PDR(_ctrl_, _con_, _role_)                 \
 139{                                                                       \
 140        __UCSI_ROLE(_ctrl_, UCSI_SET_PDR, (_con_)->num)         \
 141        (_ctrl_).uor.role |= (_role_) == TYPEC_SOURCE ? UCSI_UOR_ROLE_DFP : \
 142                        UCSI_UOR_ROLE_UFP;                              \
 143}
 144
 145/* Commands */
 146#define UCSI_PPM_RESET                  0x01
 147#define UCSI_CANCEL                     0x02
 148#define UCSI_CONNECTOR_RESET            0x03
 149#define UCSI_ACK_CC_CI                  0x04
 150#define UCSI_SET_NOTIFICATION_ENABLE    0x05
 151#define UCSI_GET_CAPABILITY             0x06
 152#define UCSI_GET_CONNECTOR_CAPABILITY   0x07
 153#define UCSI_SET_UOM                    0x08
 154#define UCSI_SET_UOR                    0x09
 155#define UCSI_SET_PDM                    0x0a
 156#define UCSI_SET_PDR                    0x0b
 157#define UCSI_GET_ALTERNATE_MODES        0x0c
 158#define UCSI_GET_CAM_SUPPORTED          0x0d
 159#define UCSI_GET_CURRENT_CAM            0x0e
 160#define UCSI_SET_NEW_CAM                0x0f
 161#define UCSI_GET_PDOS                   0x10
 162#define UCSI_GET_CABLE_PROPERTY         0x11
 163#define UCSI_GET_CONNECTOR_STATUS       0x12
 164#define UCSI_GET_ERROR_STATUS           0x13
 165
 166/* ACK_CC_CI commands */
 167#define UCSI_ACK_EVENT                  1
 168#define UCSI_ACK_CMD                    2
 169
 170/* Bits for SET_NOTIFICATION_ENABLE command */
 171#define UCSI_ENABLE_NTFY_CMD_COMPLETE           BIT(0)
 172#define UCSI_ENABLE_NTFY_EXT_PWR_SRC_CHANGE     BIT(1)
 173#define UCSI_ENABLE_NTFY_PWR_OPMODE_CHANGE      BIT(2)
 174#define UCSI_ENABLE_NTFY_CAP_CHANGE             BIT(5)
 175#define UCSI_ENABLE_NTFY_PWR_LEVEL_CHANGE       BIT(6)
 176#define UCSI_ENABLE_NTFY_PD_RESET_COMPLETE      BIT(7)
 177#define UCSI_ENABLE_NTFY_CAM_CHANGE             BIT(8)
 178#define UCSI_ENABLE_NTFY_BAT_STATUS_CHANGE      BIT(9)
 179#define UCSI_ENABLE_NTFY_PARTNER_CHANGE         BIT(11)
 180#define UCSI_ENABLE_NTFY_PWR_DIR_CHANGE         BIT(12)
 181#define UCSI_ENABLE_NTFY_CONNECTOR_CHANGE       BIT(14)
 182#define UCSI_ENABLE_NTFY_ERROR                  BIT(15)
 183#define UCSI_ENABLE_NTFY_ALL                    0xdbe7
 184
 185/* Error information returned by PPM in response to GET_ERROR_STATUS command. */
 186#define UCSI_ERROR_UNREGONIZED_CMD              BIT(0)
 187#define UCSI_ERROR_INVALID_CON_NUM              BIT(1)
 188#define UCSI_ERROR_INVALID_CMD_ARGUMENT         BIT(2)
 189#define UCSI_ERROR_INCOMPATIBLE_PARTNER         BIT(3)
 190#define UCSI_ERROR_CC_COMMUNICATION_ERR         BIT(4)
 191#define UCSI_ERROR_DEAD_BATTERY                 BIT(5)
 192#define UCSI_ERROR_CONTRACT_NEGOTIATION_FAIL    BIT(6)
 193
 194/* Data structure filled by PPM in response to GET_CAPABILITY command. */
 195struct ucsi_capability {
 196        u32 attributes;
 197#define UCSI_CAP_ATTR_DISABLE_STATE             BIT(0)
 198#define UCSI_CAP_ATTR_BATTERY_CHARGING          BIT(1)
 199#define UCSI_CAP_ATTR_USB_PD                    BIT(2)
 200#define UCSI_CAP_ATTR_TYPEC_CURRENT             BIT(6)
 201#define UCSI_CAP_ATTR_POWER_AC_SUPPLY           BIT(8)
 202#define UCSI_CAP_ATTR_POWER_OTHER               BIT(10)
 203#define UCSI_CAP_ATTR_POWER_VBUS                BIT(14)
 204        u32 num_connectors:8;
 205        u32 features:24;
 206#define UCSI_CAP_SET_UOM                        BIT(0)
 207#define UCSI_CAP_SET_PDM                        BIT(1)
 208#define UCSI_CAP_ALT_MODE_DETAILS               BIT(2)
 209#define UCSI_CAP_ALT_MODE_OVERRIDE              BIT(3)
 210#define UCSI_CAP_PDO_DETAILS                    BIT(4)
 211#define UCSI_CAP_CABLE_DETAILS                  BIT(5)
 212#define UCSI_CAP_EXT_SUPPLY_NOTIFICATIONS       BIT(6)
 213#define UCSI_CAP_PD_RESET                       BIT(7)
 214        u8 num_alt_modes;
 215        u8 reserved;
 216        u16 bc_version;
 217        u16 pd_version;
 218        u16 typec_version;
 219} __packed;
 220
 221/* Data structure filled by PPM in response to GET_CONNECTOR_CAPABILITY cmd. */
 222struct ucsi_connector_capability {
 223        u8 op_mode;
 224#define UCSI_CONCAP_OPMODE_DFP                  BIT(0)
 225#define UCSI_CONCAP_OPMODE_UFP                  BIT(1)
 226#define UCSI_CONCAP_OPMODE_DRP                  BIT(2)
 227#define UCSI_CONCAP_OPMODE_AUDIO_ACCESSORY      BIT(3)
 228#define UCSI_CONCAP_OPMODE_DEBUG_ACCESSORY      BIT(4)
 229#define UCSI_CONCAP_OPMODE_USB2                 BIT(5)
 230#define UCSI_CONCAP_OPMODE_USB3                 BIT(6)
 231#define UCSI_CONCAP_OPMODE_ALT_MODE             BIT(7)
 232        u8 provider:1;
 233        u8 consumer:1;
 234        u8:6; /* reserved */
 235} __packed;
 236
 237struct ucsi_altmode {
 238        u16 svid;
 239        u32 mid;
 240} __packed;
 241
 242/* Data structure filled by PPM in response to GET_CABLE_PROPERTY command. */
 243struct ucsi_cable_property {
 244        u16 speed_supported;
 245        u8 current_capability;
 246        u8 vbus_in_cable:1;
 247        u8 active_cable:1;
 248        u8 directionality:1;
 249        u8 plug_type:2;
 250#define UCSI_CABLE_PROPERTY_PLUG_TYPE_A         0
 251#define UCSI_CABLE_PROPERTY_PLUG_TYPE_B         1
 252#define UCSI_CABLE_PROPERTY_PLUG_TYPE_C         2
 253#define UCSI_CABLE_PROPERTY_PLUG_OTHER          3
 254        u8 mode_support:1;
 255        u8:2; /* reserved */
 256        u8 latency:4;
 257        u8:4; /* reserved */
 258} __packed;
 259
 260/* Data structure filled by PPM in response to GET_CONNECTOR_STATUS command. */
 261struct ucsi_connector_status {
 262        u16 change;
 263#define UCSI_CONSTAT_EXT_SUPPLY_CHANGE          BIT(1)
 264#define UCSI_CONSTAT_POWER_OPMODE_CHANGE        BIT(2)
 265#define UCSI_CONSTAT_PDOS_CHANGE                BIT(5)
 266#define UCSI_CONSTAT_POWER_LEVEL_CHANGE         BIT(6)
 267#define UCSI_CONSTAT_PD_RESET_COMPLETE          BIT(7)
 268#define UCSI_CONSTAT_CAM_CHANGE                 BIT(8)
 269#define UCSI_CONSTAT_BC_CHANGE                  BIT(9)
 270#define UCSI_CONSTAT_PARTNER_CHANGE             BIT(11)
 271#define UCSI_CONSTAT_POWER_DIR_CHANGE           BIT(12)
 272#define UCSI_CONSTAT_CONNECT_CHANGE             BIT(14)
 273#define UCSI_CONSTAT_ERROR                      BIT(15)
 274        u16 pwr_op_mode:3;
 275#define UCSI_CONSTAT_PWR_OPMODE_NONE            0
 276#define UCSI_CONSTAT_PWR_OPMODE_DEFAULT         1
 277#define UCSI_CONSTAT_PWR_OPMODE_BC              2
 278#define UCSI_CONSTAT_PWR_OPMODE_PD              3
 279#define UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5        4
 280#define UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0        5
 281        u16 connected:1;
 282        u16 pwr_dir:1;
 283        u16 partner_flags:8;
 284#define UCSI_CONSTAT_PARTNER_FLAG_USB           BIT(0)
 285#define UCSI_CONSTAT_PARTNER_FLAG_ALT_MODE      BIT(1)
 286        u16 partner_type:3;
 287#define UCSI_CONSTAT_PARTNER_TYPE_DFP           1
 288#define UCSI_CONSTAT_PARTNER_TYPE_UFP           2
 289#define UCSI_CONSTAT_PARTNER_TYPE_CABLE         3 /* Powered Cable */
 290#define UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP 4 /* Powered Cable */
 291#define UCSI_CONSTAT_PARTNER_TYPE_DEBUG         5
 292#define UCSI_CONSTAT_PARTNER_TYPE_AUDIO         6
 293        u32 request_data_obj;
 294        u8 bc_status:2;
 295#define UCSI_CONSTAT_BC_NOT_CHARGING            0
 296#define UCSI_CONSTAT_BC_NOMINAL_CHARGING        1
 297#define UCSI_CONSTAT_BC_SLOW_CHARGING           2
 298#define UCSI_CONSTAT_BC_TRICKLE_CHARGING        3
 299        u8 provider_cap_limit_reason:4;
 300#define UCSI_CONSTAT_CAP_PWR_LOWERED            0
 301#define UCSI_CONSTAT_CAP_PWR_BUDGET_LIMIT       1
 302        u8:2; /* reserved */
 303} __packed;
 304
 305/* -------------------------------------------------------------------------- */
 306
 307struct ucsi;
 308
 309struct ucsi_data {
 310        u16 version;
 311        u16 reserved;
 312        union {
 313                u32 raw_cci;
 314                struct ucsi_cci cci;
 315        };
 316        struct ucsi_control ctrl;
 317        u32 message_in[4];
 318        u32 message_out[4];
 319} __packed;
 320
 321/*
 322 * struct ucsi_ppm - Interface to UCSI Platform Policy Manager
 323 * @data: memory location to the UCSI data structures
 324 * @cmd: UCSI command execution routine
 325 * @sync: Refresh UCSI mailbox (the data structures)
 326 */
 327struct ucsi_ppm {
 328        struct ucsi_data *data;
 329        int (*cmd)(struct ucsi_ppm *, struct ucsi_control *);
 330        int (*sync)(struct ucsi_ppm *);
 331};
 332
 333struct ucsi *ucsi_register_ppm(struct device *dev, struct ucsi_ppm *ppm);
 334void ucsi_unregister_ppm(struct ucsi *ucsi);
 335void ucsi_notify(struct ucsi *ucsi);
 336
 337#endif /* __DRIVER_USB_TYPEC_UCSI_H */
 338