File Index
Files and directories
Sign in
FILE

typec_altmode.h

File preview with syntax highlighting.

linux-6.19.14/include/linux/usb/typec_altmode.h C
  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 * @cable_ops: Cable operations vector from the driver.
 24 */
 25struct typec_altmode {
 26	struct device			dev;
 27	u16				svid;
 28	int				mode;
 29	u32				vdo;
 30	unsigned int			active:1;
 31
 32	char				*desc;
 33	const struct typec_altmode_ops	*ops;
 34	const struct typec_cable_ops	*cable_ops;
 35};
 36
 37#define to_typec_altmode(d) container_of(d, struct typec_altmode, dev)
 38
 39static inline void typec_altmode_set_drvdata(struct typec_altmode *altmode,
 40					     void *data)
 41{
 42	dev_set_drvdata(&altmode->dev, data);
 43}
 44
 45static inline void *typec_altmode_get_drvdata(struct typec_altmode *altmode)
 46{
 47	return dev_get_drvdata(&altmode->dev);
 48}
 49
 50/**
 51 * struct typec_altmode_ops - Alternate mode specific operations vector
 52 * @enter: Operations to be executed with Enter Mode Command
 53 * @exit: Operations to be executed with Exit Mode Command
 54 * @attention: Callback for Attention Command
 55 * @vdm: Callback for SVID specific commands
 56 * @notify: Communication channel for platform and the alternate mode
 57 * @activate: User callback for Enter/Exit Mode
 58 */
 59struct typec_altmode_ops {
 60	int (*enter)(struct typec_altmode *altmode, u32 *vdo);
 61	int (*exit)(struct typec_altmode *altmode);
 62	void (*attention)(struct typec_altmode *altmode, u32 vdo);
 63	int (*vdm)(struct typec_altmode *altmode, const u32 hdr,
 64		   const u32 *vdo, int cnt);
 65	int (*notify)(struct typec_altmode *altmode, unsigned long conf,
 66		      void *data);
 67	int (*activate)(struct typec_altmode *altmode, int activate);
 68};
 69
 70int typec_altmode_enter(struct typec_altmode *altmode, u32 *vdo);
 71int typec_altmode_exit(struct typec_altmode *altmode);
 72int typec_altmode_attention(struct typec_altmode *altmode, u32 vdo);
 73int typec_altmode_vdm(struct typec_altmode *altmode,
 74		      const u32 header, const u32 *vdo, int count);
 75int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf,
 76			 void *data);
 77const struct typec_altmode *
 78typec_altmode_get_partner(struct typec_altmode *altmode);
 79
 80/**
 81 * struct typec_cable_ops - Cable alternate mode operations vector
 82 * @enter: Operations to be executed with Enter Mode Command
 83 * @exit: Operations to be executed with Exit Mode Command
 84 * @vdm: Callback for SVID specific commands
 85 */
 86struct typec_cable_ops {
 87	int (*enter)(struct typec_altmode *altmode, enum typec_plug_index sop, u32 *vdo);
 88	int (*exit)(struct typec_altmode *altmode, enum typec_plug_index sop);
 89	int (*vdm)(struct typec_altmode *altmode, enum typec_plug_index sop,
 90		   const u32 hdr, const u32 *vdo, int cnt);
 91};
 92
 93int typec_cable_altmode_enter(struct typec_altmode *altmode, enum typec_plug_index sop, u32 *vdo);
 94int typec_cable_altmode_exit(struct typec_altmode *altmode, enum typec_plug_index sop);
 95int typec_cable_altmode_vdm(struct typec_altmode *altmode, enum typec_plug_index sop,
 96			    const u32 header, const u32 *vdo, int count);
 97
 98/**
 99 * typec_altmode_get_cable_svdm_version - Get negotiated SVDM version for cable plug
100 * @altmode: Handle to the alternate mode
101 */
102static inline int
103typec_altmode_get_cable_svdm_version(struct typec_altmode *altmode)
104{
105	return typec_get_cable_svdm_version(typec_altmode2port(altmode));
106}
107
108/*
109 * These are the connector states (USB, Safe and Alt Mode) defined in USB Type-C
110 * Specification. SVID specific connector states are expected to follow and
111 * start from the value TYPEC_STATE_MODAL.
112 */
113enum {
114	TYPEC_STATE_SAFE,	/* USB Safe State */
115	TYPEC_STATE_USB,	/* USB Operation */
116	TYPEC_STATE_MODAL,	/* Alternate Modes */
117};
118
119/*
120 * For the muxes there is no difference between Accessory Modes and Alternate
121 * Modes, so the Accessory Modes are supplied with specific modal state values
122 * here. Unlike with Alternate Modes, where the mux will be linked with the
123 * alternate mode device, the mux for Accessory Modes will be linked with the
124 * port device instead.
125 *
126 * Port drivers can use TYPEC_MODE_AUDIO and TYPEC_MODE_DEBUG as the mode
127 * value for typec_set_mode() when accessory modes are supported.
128 *
129 * USB4 also requires that the pins on the connector are repurposed, just like
130 * Alternate Modes. USB4 mode is however not entered with the Enter Mode Command
131 * like the Alternate Modes are, but instead with a special Enter_USB Message.
132 * The Enter_USB Message can also be used for setting to connector to operate in
133 * USB 3.2 or in USB 2.0 mode instead of USB4.
134 *
135 * The Enter_USB specific "USB Modes" are also supplied here as special modal
136 * state values, just like the Accessory Modes.
137 */
138enum {
139	TYPEC_MODE_USB2 = TYPEC_STATE_MODAL,	/* USB 2.0 mode */
140	TYPEC_MODE_USB3,			/* USB 3.2 mode */
141	TYPEC_MODE_USB4,			/* USB4 mode */
142	TYPEC_MODE_AUDIO,			/* Audio Accessory */
143	TYPEC_MODE_DEBUG,			/* Debug Accessory */
144};
145
146#define TYPEC_MODAL_STATE(_state_)	((_state_) + TYPEC_STATE_MODAL)
147
148struct typec_altmode *typec_altmode_get_plug(struct typec_altmode *altmode,
149					     enum typec_plug_index index);
150void typec_altmode_put_plug(struct typec_altmode *plug);
151
152struct typec_altmode *typec_match_altmode(struct typec_altmode **altmodes,
153					  size_t n, u16 svid, u8 mode);
154
155/**
156 * typec_altmode_get_orientation - Get cable plug orientation
157 * @altmode: Handle to the alternate mode
158 */
159static inline enum typec_orientation
160typec_altmode_get_orientation(struct typec_altmode *altmode)
161{
162	return typec_get_orientation(typec_altmode2port(altmode));
163}
164
165/**
166 * typec_altmode_get_svdm_version - Get negotiated SVDM version
167 * @altmode: Handle to the alternate mode
168 */
169static inline int
170typec_altmode_get_svdm_version(struct typec_altmode *altmode)
171{
172	return typec_get_negotiated_svdm_version(typec_altmode2port(altmode));
173}
174
175/**
176 * typec_altmode_get_data_role - Get port data role
177 * @altmode: Handle to the alternate mode
178 *
179 * Alt Mode drivers should only issue Enter Mode through the port if they are
180 * the DFP.
181 */
182static inline enum typec_data_role
183typec_altmode_get_data_role(struct typec_altmode *altmode)
184{
185	return typec_get_data_role(typec_altmode2port(altmode));
186}
187
188/**
189 * struct typec_altmode_driver - USB Type-C alternate mode device driver
190 * @id_table: Null terminated array of SVIDs
191 * @probe: Callback for device binding
192 * @remove: Callback for device unbinding
193 * @driver: Device driver model driver
194 *
195 * These drivers will be bind to the partner alternate mode devices. They will
196 * handle all SVID specific communication.
197 */
198struct typec_altmode_driver {
199	const struct typec_device_id *id_table;
200	int (*probe)(struct typec_altmode *altmode);
201	void (*remove)(struct typec_altmode *altmode);
202	struct device_driver driver;
203};
204
205#define to_altmode_driver(d) container_of(d, struct typec_altmode_driver, \
206					  driver)
207
208/**
209 * typec_altmode_register_driver - registers a USB Type-C alternate mode
210 * 				   device driver
211 * @drv: pointer to struct typec_altmode_driver
212 *
213 * These drivers will be bind to the partner alternate mode devices. They will
214 * handle all SVID specific communication.
215 */
216#define typec_altmode_register_driver(drv) \
217		__typec_altmode_register_driver(drv, THIS_MODULE)
218int __typec_altmode_register_driver(struct typec_altmode_driver *drv,
219				    struct module *module);
220/**
221 * typec_altmode_unregister_driver - unregisters a USB Type-C alternate mode
222 * 				     device driver
223 * @drv: pointer to struct typec_altmode_driver
224 *
225 * These drivers will be bind to the partner alternate mode devices. They will
226 * handle all SVID specific communication.
227 */
228void typec_altmode_unregister_driver(struct typec_altmode_driver *drv);
229
230#define module_typec_altmode_driver(__typec_altmode_driver) \
231	module_driver(__typec_altmode_driver, typec_altmode_register_driver, \
232		      typec_altmode_unregister_driver)
233
234#endif /* __USB_TYPEC_ALTMODE_H */
~/ Read-only file preview.