linux/include/linux/usb/typec_altmode.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2
   3#ifndef __USB_TYPEC_ALTMODE_H
   4#define __USB_TYPEC_ALTMODE_H
   5
   6#include <linux/mod_devicetable.h>
   7#include <linux/usb/typec.h>
   8#include <linux/device.h>
   9
  10#define MODE_DISCOVERY_MAX      6
  11
  12struct typec_altmode_ops;
  13
  14/**
  15 * struct typec_altmode - USB Type-C alternate mode device
  16 * @dev: Driver model's view of this device
  17 * @svid: Standard or Vendor ID (SVID) of the alternate mode
  18 * @mode: Index of the Mode
  19 * @vdo: VDO returned by Discover Modes USB PD command
  20 * @active: Tells has the mode been entered or not
  21 * @desc: Optional human readable description of the mode
  22 * @ops: Operations vector from the driver
  23 */
  24struct typec_altmode {
  25        struct device                   dev;
  26        u16                             svid;
  27        int                             mode;
  28        u32                             vdo;
  29        unsigned int                    active:1;
  30
  31        char                            *desc;
  32        const struct typec_altmode_ops  *ops;
  33};
  34
  35#define to_typec_altmode(d) container_of(d, struct typec_altmode, dev)
  36
  37static inline void typec_altmode_set_drvdata(struct typec_altmode *altmode,
  38                                             void *data)
  39{
  40        dev_set_drvdata(&altmode->dev, data);
  41}
  42
  43static inline void *typec_altmode_get_drvdata(struct typec_altmode *altmode)
  44{
  45        return dev_get_drvdata(&altmode->dev);
  46}
  47
  48/**
  49 * struct typec_altmode_ops - Alternate mode specific operations vector
  50 * @enter: Operations to be executed with Enter Mode Command
  51 * @exit: Operations to be executed with Exit Mode Command
  52 * @attention: Callback for Attention Command
  53 * @vdm: Callback for SVID specific commands
  54 * @notify: Communication channel for platform and the alternate mode
  55 * @activate: User callback for Enter/Exit Mode
  56 */
  57struct typec_altmode_ops {
  58        int (*enter)(struct typec_altmode *altmode, u32 *vdo);
  59        int (*exit)(struct typec_altmode *altmode);
  60        void (*attention)(struct typec_altmode *altmode, u32 vdo);
  61        int (*vdm)(struct typec_altmode *altmode, const u32 hdr,
  62                   const u32 *vdo, int cnt);
  63        int (*notify)(struct typec_altmode *altmode, unsigned long conf,
  64                      void *data);
  65        int (*activate)(struct typec_altmode *altmode, int activate);
  66};
  67
  68int typec_altmode_enter(struct typec_altmode *altmode, u32 *vdo);
  69int typec_altmode_exit(struct typec_altmode *altmode);
  70void typec_altmode_attention(struct typec_altmode *altmode, u32 vdo);
  71int typec_altmode_vdm(struct typec_altmode *altmode,
  72                      const u32 header, const u32 *vdo, int count);
  73int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf,
  74                         void *data);
  75const struct typec_altmode *
  76typec_altmode_get_partner(struct typec_altmode *altmode);
  77
  78/*
  79 * These are the connector states (USB, Safe and Alt Mode) defined in USB Type-C
  80 * Specification. SVID specific connector states are expected to follow and
  81 * start from the value TYPEC_STATE_MODAL.
  82 */
  83enum {
  84        TYPEC_STATE_SAFE,       /* USB Safe State */
  85        TYPEC_STATE_USB,        /* USB Operation */
  86        TYPEC_STATE_MODAL,      /* Alternate Modes */
  87};
  88
  89/*
  90 * For the muxes there is no difference between Accessory Modes and Alternate
  91 * Modes, so the Accessory Modes are supplied with specific modal state values
  92 * here. Unlike with Alternate Modes, where the mux will be linked with the
  93 * alternate mode device, the mux for Accessory Modes will be linked with the
  94 * port device instead.
  95 *
  96 * Port drivers can use TYPEC_MODE_AUDIO and TYPEC_MODE_DEBUG as the mode
  97 * value for typec_set_mode() when accessory modes are supported.
  98 *
  99 * USB4 also requires that the pins on the connector are repurposed, just like
 100 * Alternate Modes. USB4 mode is however not entered with the Enter Mode Command
 101 * like the Alternate Modes are, but instead with a special Enter_USB Message.
 102 * The Enter_USB Message can also be used for setting to connector to operate in
 103 * USB 3.2 or in USB 2.0 mode instead of USB4.
 104 *
 105 * The Enter_USB specific "USB Modes" are also supplied here as special modal
 106 * state values, just like the Accessory Modes.
 107 */
 108enum {
 109        TYPEC_MODE_USB2 = TYPEC_STATE_MODAL,    /* USB 2.0 mode */
 110        TYPEC_MODE_USB3,                        /* USB 3.2 mode */
 111        TYPEC_MODE_USB4,                        /* USB4 mode */
 112        TYPEC_MODE_AUDIO,                       /* Audio Accessory */
 113        TYPEC_MODE_DEBUG,                       /* Debug Accessory */
 114};
 115
 116#define TYPEC_MODAL_STATE(_state_)      ((_state_) + TYPEC_STATE_MODAL)
 117
 118struct typec_altmode *typec_altmode_get_plug(struct typec_altmode *altmode,
 119                                             enum typec_plug_index index);
 120void typec_altmode_put_plug(struct typec_altmode *plug);
 121
 122struct typec_altmode *typec_match_altmode(struct typec_altmode **altmodes,
 123                                          size_t n, u16 svid, u8 mode);
 124
 125/**
 126 * typec_altmode_get_orientation - Get cable plug orientation
 127 * altmode: Handle to the alternate mode
 128 */
 129static inline enum typec_orientation
 130typec_altmode_get_orientation(struct typec_altmode *altmode)
 131{
 132        return typec_get_orientation(typec_altmode2port(altmode));
 133}
 134
 135/**
 136 * typec_altmode_get_svdm_version - Get negotiated SVDM version
 137 * @altmode: Handle to the alternate mode
 138 */
 139static inline int
 140typec_altmode_get_svdm_version(struct typec_altmode *altmode)
 141{
 142        return typec_get_negotiated_svdm_version(typec_altmode2port(altmode));
 143}
 144
 145/**
 146 * struct typec_altmode_driver - USB Type-C alternate mode device driver
 147 * @id_table: Null terminated array of SVIDs
 148 * @probe: Callback for device binding
 149 * @remove: Callback for device unbinding
 150 * @driver: Device driver model driver
 151 *
 152 * These drivers will be bind to the partner alternate mode devices. They will
 153 * handle all SVID specific communication.
 154 */
 155struct typec_altmode_driver {
 156        const struct typec_device_id *id_table;
 157        int (*probe)(struct typec_altmode *altmode);
 158        void (*remove)(struct typec_altmode *altmode);
 159        struct device_driver driver;
 160};
 161
 162#define to_altmode_driver(d) container_of(d, struct typec_altmode_driver, \
 163                                          driver)
 164
 165/**
 166 * typec_altmode_register_driver - registers a USB Type-C alternate mode
 167 *                                 device driver
 168 * @drv: pointer to struct typec_altmode_driver
 169 *
 170 * These drivers will be bind to the partner alternate mode devices. They will
 171 * handle all SVID specific communication.
 172 */
 173#define typec_altmode_register_driver(drv) \
 174                __typec_altmode_register_driver(drv, THIS_MODULE)
 175int __typec_altmode_register_driver(struct typec_altmode_driver *drv,
 176                                    struct module *module);
 177/**
 178 * typec_altmode_unregister_driver - unregisters a USB Type-C alternate mode
 179 *                                   device driver
 180 * @drv: pointer to struct typec_altmode_driver
 181 *
 182 * These drivers will be bind to the partner alternate mode devices. They will
 183 * handle all SVID specific communication.
 184 */
 185void typec_altmode_unregister_driver(struct typec_altmode_driver *drv);
 186
 187#define module_typec_altmode_driver(__typec_altmode_driver) \
 188        module_driver(__typec_altmode_driver, typec_altmode_register_driver, \
 189                      typec_altmode_unregister_driver)
 190
 191#endif /* __USB_TYPEC_ALTMODE_H */
 192