aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/usb
diff options
context:
space:
mode:
authorHeikki Krogerus <heikki.krogerus@linux.intel.com>2018-06-27 11:19:50 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-07-02 11:42:36 -0400
commit8a37d87d72f0c69f837229c04d2fcd7117ea57e7 (patch)
tree43cf3111a964678d08fe6638e4459e1c2db50b55 /include/linux/usb
parent4ab8c18d4d67321cc7b660559de17511d4fc0237 (diff)
usb: typec: Bus type for alternate modes
Introducing a simple bus for the alternate modes. Bus allows binding drivers to the discovered alternate modes the partners support. Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Tested-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux/usb')
-rw-r--r--include/linux/usb/typec.h14
-rw-r--r--include/linux/usb/typec_altmode.h160
2 files changed, 163 insertions, 11 deletions
diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h
index 2dcb1683075f..7df4ecabc78a 100644
--- a/include/linux/usb/typec.h
+++ b/include/linux/usb/typec.h
@@ -5,21 +5,18 @@
5 5
6#include <linux/types.h> 6#include <linux/types.h>
7 7
8/* XXX: Once we have a header for USB Power Delivery, this belongs there */
9#define ALTMODE_MAX_MODES 6
10
11/* USB Type-C Specification releases */ 8/* USB Type-C Specification releases */
12#define USB_TYPEC_REV_1_0 0x100 /* 1.0 */ 9#define USB_TYPEC_REV_1_0 0x100 /* 1.0 */
13#define USB_TYPEC_REV_1_1 0x110 /* 1.1 */ 10#define USB_TYPEC_REV_1_1 0x110 /* 1.1 */
14#define USB_TYPEC_REV_1_2 0x120 /* 1.2 */ 11#define USB_TYPEC_REV_1_2 0x120 /* 1.2 */
15 12
16struct typec_altmode;
17struct typec_partner; 13struct typec_partner;
18struct typec_cable; 14struct typec_cable;
19struct typec_plug; 15struct typec_plug;
20struct typec_port; 16struct typec_port;
21 17
22struct fwnode_handle; 18struct fwnode_handle;
19struct device;
23 20
24enum typec_port_type { 21enum typec_port_type {
25 TYPEC_PORT_SRC, 22 TYPEC_PORT_SRC,
@@ -107,7 +104,7 @@ struct typec_altmode_desc {
107 u8 mode; 104 u8 mode;
108 u32 vdo; 105 u32 vdo;
109 /* Only used with ports */ 106 /* Only used with ports */
110 enum typec_port_type roles; 107 enum typec_port_data roles;
111}; 108};
112 109
113struct typec_altmode 110struct typec_altmode
@@ -186,7 +183,6 @@ struct typec_partner_desc {
186 * @dr_set: Set Data Role 183 * @dr_set: Set Data Role
187 * @pr_set: Set Power Role 184 * @pr_set: Set Power Role
188 * @vconn_set: Set VCONN Role 185 * @vconn_set: Set VCONN Role
189 * @activate_mode: Enter/exit given Alternate Mode
190 * @port_type_set: Set port type 186 * @port_type_set: Set port type
191 * 187 *
192 * Static capabilities of a single USB Type-C port. 188 * Static capabilities of a single USB Type-C port.
@@ -212,12 +208,8 @@ struct typec_capability {
212 enum typec_role); 208 enum typec_role);
213 int (*vconn_set)(const struct typec_capability *, 209 int (*vconn_set)(const struct typec_capability *,
214 enum typec_role); 210 enum typec_role);
215
216 int (*activate_mode)(const struct typec_capability *,
217 int mode, int activate);
218 int (*port_type_set)(const struct typec_capability *, 211 int (*port_type_set)(const struct typec_capability *,
219 enum typec_port_type); 212 enum typec_port_type);
220
221}; 213};
222 214
223/* Specific to try_role(). Indicates the user want's to clear the preference. */ 215/* Specific to try_role(). Indicates the user want's to clear the preference. */
diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h
new file mode 100644
index 000000000000..9a88c74a1d0d
--- /dev/null
+++ b/include/linux/usb/typec_altmode.h
@@ -0,0 +1,160 @@
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);
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);
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 */
99enum {
100 TYPEC_MODE_AUDIO = TYPEC_STATE_MODAL, /* Audio Accessory */
101 TYPEC_MODE_DEBUG, /* Debug Accessory */
102};
103
104#define TYPEC_MODAL_STATE(_state_) ((_state_) + TYPEC_STATE_MODAL)
105
106struct typec_altmode *typec_altmode_get_plug(struct typec_altmode *altmode,
107 enum typec_plug_index index);
108void typec_altmode_put_plug(struct typec_altmode *plug);
109
110struct typec_altmode *typec_match_altmode(struct typec_altmode **altmodes,
111 size_t n, u16 svid, u8 mode);
112
113struct typec_altmode *
114typec_altmode_register_notifier(struct device *dev, u16 svid, u8 mode,
115 struct notifier_block *nb);
116
117void typec_altmode_unregister_notifier(struct typec_altmode *adev,
118 struct notifier_block *nb);
119
120/**
121 * typec_altmode_get_orientation - Get cable plug orientation
122 * altmode: Handle to the alternate mode
123 */
124static inline enum typec_orientation
125typec_altmode_get_orientation(struct typec_altmode *altmode)
126{
127 return typec_get_orientation(typec_altmode2port(altmode));
128}
129
130/**
131 * struct typec_altmode_driver - USB Type-C alternate mode device driver
132 * @id_table: Null terminated array of SVIDs
133 * @probe: Callback for device binding
134 * @remove: Callback for device unbinding
135 * @driver: Device driver model driver
136 *
137 * These drivers will be bind to the partner alternate mode devices. They will
138 * handle all SVID specific communication.
139 */
140struct typec_altmode_driver {
141 const struct typec_device_id *id_table;
142 int (*probe)(struct typec_altmode *altmode);
143 void (*remove)(struct typec_altmode *altmode);
144 struct device_driver driver;
145};
146
147#define to_altmode_driver(d) container_of(d, struct typec_altmode_driver, \
148 driver)
149
150#define typec_altmode_register_driver(drv) \
151 __typec_altmode_register_driver(drv, THIS_MODULE)
152int __typec_altmode_register_driver(struct typec_altmode_driver *drv,
153 struct module *module);
154void typec_altmode_unregister_driver(struct typec_altmode_driver *drv);
155
156#define module_typec_altmode_driver(__typec_altmode_driver) \
157 module_driver(__typec_altmode_driver, typec_altmode_register_driver, \
158 typec_altmode_unregister_driver)
159
160#endif /* __USB_TYPEC_ALTMODE_H */