forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/usb/typec/bus.c
....@@ -1,5 +1,5 @@
11 // SPDX-License-Identifier: GPL-2.0
2
-/**
2
+/*
33 * Bus for USB Type-C Alternate Modes
44 *
55 * Copyright (C) 2018 Intel Corporation
....@@ -10,26 +10,30 @@
1010
1111 #include "bus.h"
1212
13
-static inline int typec_altmode_set_mux(struct altmode *alt, u8 state)
13
+static inline int
14
+typec_altmode_set_mux(struct altmode *alt, unsigned long conf, void *data)
1415 {
15
- return alt->mux ? alt->mux->set(alt->mux, state) : 0;
16
+ struct typec_mux_state state;
17
+
18
+ if (!alt->mux)
19
+ return 0;
20
+
21
+ state.alt = &alt->adev;
22
+ state.mode = conf;
23
+ state.data = data;
24
+
25
+ return alt->mux->set(alt->mux, &state);
1626 }
1727
18
-static int typec_altmode_set_state(struct typec_altmode *adev, int state)
28
+static int typec_altmode_set_state(struct typec_altmode *adev,
29
+ unsigned long conf, void *data)
1930 {
2031 bool is_port = is_typec_port(adev->dev.parent);
2132 struct altmode *port_altmode;
22
- int ret;
2333
2434 port_altmode = is_port ? to_altmode(adev) : to_altmode(adev)->partner;
2535
26
- ret = typec_altmode_set_mux(port_altmode, state);
27
- if (ret)
28
- return ret;
29
-
30
- blocking_notifier_call_chain(&port_altmode->nh, state, NULL);
31
-
32
- return 0;
36
+ return typec_altmode_set_mux(port_altmode, conf, data);
3337 }
3438
3539 /* -------------------------------------------------------------------------- */
....@@ -67,12 +71,9 @@
6771 is_port = is_typec_port(adev->dev.parent);
6872 partner = altmode->partner;
6973
70
- ret = typec_altmode_set_mux(is_port ? altmode : partner, (u8)conf);
74
+ ret = typec_altmode_set_mux(is_port ? altmode : partner, conf, data);
7175 if (ret)
7276 return ret;
73
-
74
- blocking_notifier_call_chain(is_port ? &altmode->nh : &partner->nh,
75
- conf, data);
7677
7778 if (partner->adev.ops && partner->adev.ops->notify)
7879 return partner->adev.ops->notify(&partner->adev, conf, data);
....@@ -84,12 +85,14 @@
8485 /**
8586 * typec_altmode_enter - Enter Mode
8687 * @adev: The alternate mode
88
+ * @vdo: VDO for the Enter Mode command
8789 *
8890 * The alternate mode drivers use this function to enter mode. The port drivers
8991 * use this to inform the alternate mode drivers that the partner has initiated
90
- * Enter Mode command.
92
+ * Enter Mode command. If the alternate mode does not require VDO, @vdo must be
93
+ * NULL.
9194 */
92
-int typec_altmode_enter(struct typec_altmode *adev)
95
+int typec_altmode_enter(struct typec_altmode *adev, u32 *vdo)
9396 {
9497 struct altmode *partner = to_altmode(adev)->partner;
9598 struct typec_altmode *pdev = &partner->adev;
....@@ -101,13 +104,16 @@
101104 if (!pdev->ops || !pdev->ops->enter)
102105 return -EOPNOTSUPP;
103106
107
+ if (is_typec_port(pdev->dev.parent) && !pdev->active)
108
+ return -EPERM;
109
+
104110 /* Moving to USB Safe State */
105
- ret = typec_altmode_set_state(adev, TYPEC_STATE_SAFE);
111
+ ret = typec_altmode_set_state(adev, TYPEC_STATE_SAFE, NULL);
106112 if (ret)
107113 return ret;
108114
109115 /* Enter Mode */
110
- return pdev->ops->enter(pdev);
116
+ return pdev->ops->enter(pdev, vdo);
111117 }
112118 EXPORT_SYMBOL_GPL(typec_altmode_enter);
113119
....@@ -126,11 +132,11 @@
126132 if (!adev || !adev->active)
127133 return 0;
128134
129
- if (!pdev->ops || !pdev->ops->enter)
135
+ if (!pdev->ops || !pdev->ops->exit)
130136 return -EOPNOTSUPP;
131137
132138 /* Moving to USB Safe State */
133
- ret = typec_altmode_set_state(adev, TYPEC_STATE_SAFE);
139
+ ret = typec_altmode_set_state(adev, TYPEC_STATE_SAFE, NULL);
134140 if (ret)
135141 return ret;
136142
....@@ -146,12 +152,20 @@
146152 *
147153 * Notifies the partner of @adev about Attention command.
148154 */
149
-void typec_altmode_attention(struct typec_altmode *adev, u32 vdo)
155
+int typec_altmode_attention(struct typec_altmode *adev, u32 vdo)
150156 {
151
- struct typec_altmode *pdev = &to_altmode(adev)->partner->adev;
157
+ struct altmode *partner = to_altmode(adev)->partner;
158
+ struct typec_altmode *pdev;
159
+
160
+ if (!partner)
161
+ return -ENODEV;
162
+
163
+ pdev = &partner->adev;
152164
153165 if (pdev->ops && pdev->ops->attention)
154166 pdev->ops->attention(pdev, vdo);
167
+
168
+ return 0;
155169 }
156170 EXPORT_SYMBOL_GPL(typec_altmode_attention);
157171
....@@ -386,7 +400,7 @@
386400 drv->remove(to_typec_altmode(dev));
387401
388402 if (adev->active) {
389
- WARN_ON(typec_altmode_set_state(adev, TYPEC_STATE_SAFE));
403
+ WARN_ON(typec_altmode_set_state(adev, TYPEC_STATE_SAFE, NULL));
390404 typec_altmode_update_active(adev, false);
391405 }
392406