]>
Commit | Line | Data |
---|---|---|
13e71d09 JP |
1 | From ecf210d50915efb265d93f8b84cfd53a492ffefc Mon Sep 17 00:00:00 2001 |
2 | From: Ondřej Jirman | |
3 | Date: Sun, 7 Nov 2021 19:24:40 +0100 | |
4 | Subject: usb: typec: typec-extcon: Add typec -> extcon bridge driver | |
8c9054af | 5 | |
13e71d09 JP |
6 | This bridge connects standard Type C port interfaces for controling |
7 | muxes, switches and usb roles to muxes, switches and usb role | |
8 | drivers controlled via extcon interface. | |
9 | ||
10 | Signed-off-by: Ondrej Jirman <megi@xff.cz> | |
8c9054af | 11 | --- |
13e71d09 JP |
12 | drivers/usb/typec/Kconfig | 7 + |
13 | drivers/usb/typec/Makefile | 1 + | |
14 | drivers/usb/typec/typec-extcon.c | 332 +++++++++++++++++++++++++++++++++++++++ | |
15 | 3 files changed, 340 insertions(+) | |
16 | create mode 100644 drivers/usb/typec/typec-extcon.c | |
8c9054af | 17 | |
03acaa9b | 18 | diff --git a/drivers/usb/typec/Kconfig b/drivers/usb/typec/Kconfig |
13e71d09 | 19 | index 2f80c2792dbd..40a2934691d6 100644 |
03acaa9b JP |
20 | --- a/drivers/usb/typec/Kconfig |
21 | +++ b/drivers/usb/typec/Kconfig | |
13e71d09 | 22 | @@ -110,6 +110,13 @@ config TYPEC_WUSB3801 |
74b60f45 JP |
23 | If you choose to build this driver as a dynamically linked module, the |
24 | module will be called wusb3801.ko. | |
03acaa9b JP |
25 | |
26 | +config TYPEC_EXTCON | |
27 | + tristate "Type-C switch/mux -> extcon interface bridge driver" | |
28 | + depends on USB_ROLE_SWITCH | |
29 | + help | |
30 | + Say Y or M here if your system needs bridging between typec class | |
31 | + and extcon interfaces. | |
8c9054af | 32 | + |
03acaa9b JP |
33 | source "drivers/usb/typec/mux/Kconfig" |
34 | ||
35 | source "drivers/usb/typec/altmodes/Kconfig" | |
36 | diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile | |
13e71d09 | 37 | index 7a368fea61bc..fe4bf3b8ff60 100644 |
03acaa9b JP |
38 | --- a/drivers/usb/typec/Makefile |
39 | +++ b/drivers/usb/typec/Makefile | |
13e71d09 | 40 | @@ -11,4 +11,5 @@ obj-$(CONFIG_TYPEC_HD3SS3220) += hd3ss3220.o |
03acaa9b | 41 | obj-$(CONFIG_TYPEC_STUSB160X) += stusb160x.o |
74b60f45 JP |
42 | obj-$(CONFIG_TYPEC_RT1719) += rt1719.o |
43 | obj-$(CONFIG_TYPEC_WUSB3801) += wusb3801.o | |
03acaa9b JP |
44 | +obj-$(CONFIG_TYPEC_EXTCON) += typec-extcon.o |
45 | obj-$(CONFIG_TYPEC) += mux/ | |
03acaa9b JP |
46 | diff --git a/drivers/usb/typec/typec-extcon.c b/drivers/usb/typec/typec-extcon.c |
47 | new file mode 100644 | |
13e71d09 | 48 | index 000000000000..e460f35c8390 |
03acaa9b JP |
49 | --- /dev/null |
50 | +++ b/drivers/usb/typec/typec-extcon.c | |
13e71d09 | 51 | @@ -0,0 +1,332 @@ |
03acaa9b JP |
52 | +/* |
53 | + * typec -> extcon bridge | |
54 | + * Copyright (c) 2021 Ondřej Jirman <megi@xff.cz> | |
55 | + * | |
56 | + * This driver bridges standard type-c interfaces to drivers that | |
57 | + * expect extcon interface. | |
58 | + */ | |
59 | + | |
60 | +#include <linux/delay.h> | |
61 | +#include <linux/kernel.h> | |
62 | +#include <linux/module.h> | |
63 | +#include <linux/power_supply.h> | |
64 | +#include <linux/platform_device.h> | |
65 | +#include <linux/usb/pd.h> | |
66 | +#include <linux/usb/role.h> | |
67 | +#include <linux/usb/typec.h> | |
68 | +#include <linux/usb/typec_dp.h> | |
69 | +#include <linux/usb/typec_mux.h> | |
70 | +#include <linux/extcon-provider.h> | |
71 | + | |
72 | +struct typec_extcon { | |
73 | + struct device *dev; | |
74 | + | |
75 | + /* consumers */ | |
76 | + struct usb_role_switch *role_sw; | |
0592a12c JP |
77 | + struct typec_switch_dev *sw; |
78 | + struct typec_mux_dev *mux; | |
03acaa9b JP |
79 | + |
80 | + /* providers */ | |
81 | + struct extcon_dev *extcon; | |
82 | + struct notifier_block extcon_nb; | |
83 | + | |
84 | + /* cached state from typec controller */ | |
85 | + enum usb_role role; | |
86 | + enum typec_orientation orientation; | |
87 | + struct typec_altmode alt; | |
88 | + unsigned long mode; | |
89 | + bool has_alt; | |
90 | + struct mutex lock; | |
91 | +}; | |
92 | + | |
93 | +static const unsigned int typec_extcon_cable[] = { | |
94 | + EXTCON_DISP_DP, | |
95 | + | |
96 | + EXTCON_USB, | |
97 | + EXTCON_USB_HOST, | |
98 | + | |
99 | + EXTCON_CHG_USB_SDP, | |
100 | + EXTCON_CHG_USB_CDP, | |
101 | + EXTCON_CHG_USB_DCP, | |
102 | + EXTCON_CHG_USB_ACA, | |
103 | + | |
104 | + EXTCON_NONE, | |
105 | +}; | |
106 | + | |
107 | +static void typec_extcon_set_cable(struct typec_extcon *tce, int id, bool on, | |
108 | + union extcon_property_value prop_ss, | |
109 | + union extcon_property_value prop_or) | |
8c9054af | 110 | +{ |
03acaa9b JP |
111 | + union extcon_property_value cur_ss, cur_or; |
112 | + bool prop_diff = false; | |
113 | + int ret; | |
114 | + | |
115 | + ret = extcon_get_property(tce->extcon, id, | |
116 | + EXTCON_PROP_USB_SS, &cur_ss); | |
117 | + if (ret || cur_ss.intval != prop_ss.intval) | |
118 | + prop_diff = true; | |
119 | + | |
120 | + ret = extcon_get_property(tce->extcon, id, | |
121 | + EXTCON_PROP_USB_TYPEC_POLARITY, &cur_or); | |
122 | + if (ret || cur_or.intval != prop_or.intval) | |
123 | + prop_diff = true; | |
124 | + | |
125 | + if (!on && extcon_get_state(tce->extcon, id)) { | |
126 | + extcon_set_state_sync(tce->extcon, id, false); | |
127 | + } else if (on && (!extcon_get_state(tce->extcon, id) || prop_diff)) { | |
128 | + extcon_set_state(tce->extcon, id, true); | |
129 | + extcon_set_property(tce->extcon, id, | |
130 | + EXTCON_PROP_USB_SS, prop_ss); | |
131 | + extcon_set_property(tce->extcon, id, | |
132 | + EXTCON_PROP_USB_TYPEC_POLARITY, prop_or); | |
133 | + extcon_sync(tce->extcon, id); | |
8c9054af JP |
134 | + } |
135 | +} | |
136 | + | |
03acaa9b | 137 | +static int typec_extcon_sync_extcon(struct typec_extcon *tce) |
8c9054af | 138 | +{ |
03acaa9b JP |
139 | + union extcon_property_value prop_ss, prop_or; |
140 | + bool has_dp = false; | |
8c9054af | 141 | + |
03acaa9b JP |
142 | + mutex_lock(&tce->lock); |
143 | + | |
144 | + /* connector is disconnected */ | |
145 | + if (tce->orientation == TYPEC_ORIENTATION_NONE) { | |
146 | + typec_extcon_set_cable(tce, EXTCON_USB, false, prop_ss, prop_or); | |
147 | + typec_extcon_set_cable(tce, EXTCON_USB_HOST, false, prop_ss, prop_or); | |
148 | + typec_extcon_set_cable(tce, EXTCON_DISP_DP, false, prop_ss, prop_or); | |
149 | + | |
03acaa9b | 150 | + goto out_unlock; |
8c9054af | 151 | + } |
03acaa9b JP |
152 | + |
153 | + prop_or.intval = tce->orientation == TYPEC_ORIENTATION_NORMAL ? 0 : 1; | |
154 | + prop_ss.intval = 0; | |
155 | + | |
156 | + if (tce->has_alt && tce->alt.svid == USB_TYPEC_DP_SID) { | |
157 | + switch (tce->mode) { | |
158 | + case TYPEC_STATE_SAFE: | |
159 | + break; | |
160 | + case TYPEC_DP_STATE_C: | |
161 | + case TYPEC_DP_STATE_E: | |
162 | + has_dp = true; | |
163 | + break; | |
164 | + case TYPEC_DP_STATE_D: | |
165 | + has_dp = true; | |
166 | + fallthrough; | |
167 | + case TYPEC_STATE_USB: | |
168 | + prop_ss.intval = 1; | |
169 | + break; | |
170 | + default: | |
171 | + dev_err(tce->dev, "unhandled mux mode=%lu\n", tce->mode); | |
172 | + break; | |
173 | + } | |
8c9054af | 174 | + } |
8c9054af | 175 | + |
03acaa9b JP |
176 | + typec_extcon_set_cable(tce, EXTCON_USB, |
177 | + tce->role == USB_ROLE_DEVICE, prop_ss, prop_or); | |
178 | + typec_extcon_set_cable(tce, EXTCON_USB_HOST, | |
179 | + tce->role == USB_ROLE_HOST, prop_ss, prop_or); | |
8c9054af | 180 | + |
03acaa9b JP |
181 | + typec_extcon_set_cable(tce, EXTCON_DISP_DP, has_dp, prop_ss, prop_or); |
182 | + | |
183 | +out_unlock: | |
184 | + mutex_unlock(&tce->lock); | |
185 | + return 0; | |
186 | +} | |
187 | + | |
0592a12c | 188 | +static int typec_extcon_sw_set(struct typec_switch_dev *sw, |
03acaa9b | 189 | + enum typec_orientation orientation) |
8c9054af | 190 | +{ |
03acaa9b JP |
191 | + struct typec_extcon *tce = typec_switch_get_drvdata(sw); |
192 | + | |
193 | + dev_dbg(tce->dev, "SW SET: orientation=%d\n", orientation); | |
194 | + | |
195 | + mutex_lock(&tce->lock); | |
196 | + tce->orientation = orientation; | |
197 | + mutex_unlock(&tce->lock); | |
198 | + | |
199 | + typec_extcon_sync_extcon(tce); | |
200 | + | |
201 | + return 0; | |
8c9054af JP |
202 | +} |
203 | + | |
0592a12c | 204 | +static int typec_extcon_mux_set(struct typec_mux_dev *mux, |
03acaa9b | 205 | + struct typec_mux_state *state) |
8c9054af | 206 | +{ |
03acaa9b JP |
207 | + struct typec_extcon *tce = typec_mux_get_drvdata(mux); |
208 | + struct typec_altmode *alt = state->alt; | |
8c9054af | 209 | + |
03acaa9b JP |
210 | + dev_dbg(tce->dev, "MUX SET: state->mode=%lu\n", state->mode); |
211 | + if (alt) | |
212 | + dev_dbg(tce->dev, " ...alt: svid=%04hx mode=%d vdo=%08x active=%u\n", | |
213 | + alt->svid, alt->mode, alt->vdo, alt->active); | |
214 | + | |
215 | + mutex_lock(&tce->lock); | |
216 | + tce->mode = state->mode; | |
217 | + tce->has_alt = alt != NULL; | |
218 | + if (alt) | |
219 | + tce->alt = *alt; | |
220 | + mutex_unlock(&tce->lock); | |
221 | + | |
222 | + typec_extcon_sync_extcon(tce); | |
223 | + | |
224 | + return 0; | |
8c9054af JP |
225 | +} |
226 | + | |
03acaa9b JP |
227 | +static int typec_extcon_usb_set_role(struct usb_role_switch *sw, |
228 | + enum usb_role role) | |
229 | +{ | |
230 | + struct typec_extcon *tce = usb_role_switch_get_drvdata(sw); | |
231 | + | |
232 | + dev_dbg(tce->dev, "ROLE SET: role=%d\n", role); | |
233 | + | |
234 | + mutex_lock(&tce->lock); | |
235 | + tce->role = role; | |
236 | + mutex_unlock(&tce->lock); | |
237 | + | |
238 | + typec_extcon_sync_extcon(tce); | |
239 | + | |
240 | + return 0; | |
8c9054af JP |
241 | +} |
242 | + | |
03acaa9b JP |
243 | +static int typec_extcon_notifier(struct notifier_block *nb, |
244 | + unsigned long action, void *data) | |
245 | +{ | |
246 | + struct typec_extcon *tce = container_of(nb, struct typec_extcon, extcon_nb); | |
8c9054af | 247 | + |
03acaa9b JP |
248 | + bool sdp = extcon_get_state(tce->extcon, EXTCON_CHG_USB_SDP); |
249 | + bool cdp = extcon_get_state(tce->extcon, EXTCON_CHG_USB_CDP); | |
250 | + bool dcp = extcon_get_state(tce->extcon, EXTCON_CHG_USB_DCP); | |
251 | + bool usb = extcon_get_state(tce->extcon, EXTCON_USB); | |
252 | + bool usb_host = extcon_get_state(tce->extcon, EXTCON_USB_HOST); | |
253 | + bool dp = extcon_get_state(tce->extcon, EXTCON_DISP_DP); | |
8c9054af | 254 | + |
03acaa9b JP |
255 | + dev_info(tce->dev, "extcon changed sdp=%d cdp=%d dcp=%d usb=%d usb_host=%d dp=%d\n", |
256 | + sdp, cdp, dcp, usb, usb_host, dp); | |
8c9054af | 257 | + |
03acaa9b JP |
258 | + return NOTIFY_OK; |
259 | +} | |
8c9054af | 260 | + |
03acaa9b | 261 | +static int typec_extcon_probe(struct platform_device *pdev) |
8c9054af | 262 | +{ |
03acaa9b JP |
263 | + struct typec_switch_desc sw_desc = { }; |
264 | + struct typec_mux_desc mux_desc = { }; | |
265 | + struct usb_role_switch_desc role_desc = { }; | |
266 | + struct device *dev = &pdev->dev; | |
267 | + struct typec_extcon *tce; | |
268 | + int ret = 0; | |
8c9054af | 269 | + |
03acaa9b JP |
270 | + tce = devm_kzalloc(dev, sizeof(*tce), GFP_KERNEL); |
271 | + if (!tce) | |
272 | + return -ENOMEM; | |
8c9054af | 273 | + |
03acaa9b JP |
274 | + tce->dev = &pdev->dev; |
275 | + mutex_init(&tce->lock); | |
276 | + tce->mode = TYPEC_STATE_SAFE; | |
8c9054af | 277 | + |
03acaa9b JP |
278 | + sw_desc.drvdata = tce; |
279 | + sw_desc.fwnode = dev->fwnode; | |
280 | + sw_desc.set = typec_extcon_sw_set; | |
8c9054af | 281 | + |
03acaa9b JP |
282 | + tce->sw = typec_switch_register(dev, &sw_desc); |
283 | + if (IS_ERR(tce->sw)) | |
284 | + return dev_err_probe(dev, PTR_ERR(tce->sw), | |
285 | + "Error registering typec switch\n"); | |
8c9054af | 286 | + |
03acaa9b JP |
287 | + mux_desc.drvdata = tce; |
288 | + mux_desc.fwnode = dev->fwnode; | |
289 | + mux_desc.set = typec_extcon_mux_set; | |
290 | + | |
291 | + tce->mux = typec_mux_register(dev, &mux_desc); | |
292 | + if (IS_ERR(tce->mux)) { | |
293 | + ret = dev_err_probe(dev, PTR_ERR(tce->mux), | |
294 | + "Error registering typec mux\n"); | |
295 | + goto err_sw; | |
8c9054af | 296 | + } |
8c9054af | 297 | + |
03acaa9b JP |
298 | + role_desc.driver_data = tce; |
299 | + role_desc.fwnode = dev->fwnode; | |
300 | + role_desc.name = fwnode_get_name(dev->fwnode); | |
301 | + role_desc.set = typec_extcon_usb_set_role; | |
302 | + | |
303 | + tce->role_sw = usb_role_switch_register(dev, &role_desc); | |
304 | + if (IS_ERR(tce->role_sw)) { | |
305 | + ret = dev_err_probe(dev, PTR_ERR(tce->role_sw), | |
306 | + "Error registering USB role switch\n"); | |
307 | + goto err_mux; | |
8c9054af | 308 | + } |
03acaa9b JP |
309 | + |
310 | + tce->extcon = devm_extcon_dev_allocate(dev, typec_extcon_cable); | |
311 | + if (IS_ERR(tce->extcon)) { | |
312 | + ret = PTR_ERR(tce->extcon); | |
313 | + goto err_role; | |
8c9054af | 314 | + } |
03acaa9b JP |
315 | + |
316 | + ret = devm_extcon_dev_register(dev, tce->extcon); | |
317 | + if (ret) { | |
318 | + ret = dev_err_probe(dev, ret, "failed to register extcon device\n"); | |
319 | + goto err_role; | |
8c9054af | 320 | + } |
03acaa9b JP |
321 | + |
322 | + extcon_set_property_capability(tce->extcon, EXTCON_USB, | |
323 | + EXTCON_PROP_USB_SS); | |
324 | + extcon_set_property_capability(tce->extcon, EXTCON_USB, | |
325 | + EXTCON_PROP_USB_TYPEC_POLARITY); | |
326 | + extcon_set_property_capability(tce->extcon, EXTCON_USB_HOST, | |
327 | + EXTCON_PROP_USB_SS); | |
328 | + extcon_set_property_capability(tce->extcon, EXTCON_USB_HOST, | |
329 | + EXTCON_PROP_USB_TYPEC_POLARITY); | |
330 | + extcon_set_property_capability(tce->extcon, EXTCON_DISP_DP, | |
331 | + EXTCON_PROP_USB_SS); | |
332 | + extcon_set_property_capability(tce->extcon, EXTCON_DISP_DP, | |
333 | + EXTCON_PROP_USB_TYPEC_POLARITY); | |
334 | + | |
335 | + tce->extcon_nb.notifier_call = typec_extcon_notifier; | |
336 | + ret = devm_extcon_register_notifier_all(dev, tce->extcon, &tce->extcon_nb); | |
337 | + if (ret) { | |
338 | + dev_err_probe(dev, ret, "Failed to register extcon notifier\n"); | |
339 | + goto err_role; | |
8c9054af JP |
340 | + } |
341 | + | |
03acaa9b JP |
342 | + return 0; |
343 | + | |
344 | +err_role: | |
345 | + usb_role_switch_unregister(tce->role_sw); | |
346 | +err_mux: | |
347 | + typec_mux_unregister(tce->mux); | |
348 | +err_sw: | |
349 | + typec_switch_unregister(tce->sw); | |
350 | + return ret; | |
351 | +} | |
352 | + | |
353 | +static int typec_extcon_remove(struct platform_device *pdev) | |
354 | +{ | |
355 | + struct typec_extcon *tce = platform_get_drvdata(pdev); | |
356 | + | |
357 | + usb_role_switch_unregister(tce->role_sw); | |
358 | + typec_mux_unregister(tce->mux); | |
359 | + typec_switch_unregister(tce->sw); | |
360 | + | |
361 | + return 0; | |
362 | +} | |
363 | + | |
364 | +static struct of_device_id typec_extcon_of_match_table[] = { | |
365 | + { .compatible = "linux,typec-extcon-bridge" }, | |
366 | + { }, | |
367 | +}; | |
368 | +MODULE_DEVICE_TABLE(of, typec_extcon_of_match_table); | |
369 | + | |
370 | +static struct platform_driver typec_extcon_driver = { | |
371 | + .driver = { | |
372 | + .name = "typec-extcon", | |
373 | + .of_match_table = typec_extcon_of_match_table, | |
374 | + }, | |
375 | + .probe = typec_extcon_probe, | |
376 | + .remove = typec_extcon_remove, | |
377 | +}; | |
378 | + | |
379 | +module_platform_driver(typec_extcon_driver); | |
380 | + | |
381 | +MODULE_LICENSE("GPL"); | |
13e71d09 | 382 | +MODULE_AUTHOR("Ondrej Jirman <megi@xff.cz>"); |
03acaa9b | 383 | +MODULE_DESCRIPTION("typec -> extcon bridge driver"); |
8c9054af | 384 | -- |
13e71d09 JP |
385 | cgit v1.2.3 |
386 | ||
387 | From 509e948e64f676d1347dbcbd077f1c4ce34f0f25 Mon Sep 17 00:00:00 2001 | |
388 | From: Ondrej Jirman | |
389 | Date: Thu, 9 Feb 2023 20:33:50 +0100 | |
390 | Subject: usb: typec: typec-extcon: Allow to force reset on each mux change | |
8c9054af | 391 | |
13e71d09 | 392 | This may help with some Alt-DP USB adapters. |
8c9054af | 393 | |
13e71d09 | 394 | Signed-off-by: Ondrej Jirman <megi@xff.cz> |
8c9054af | 395 | --- |
13e71d09 JP |
396 | drivers/usb/typec/typec-extcon.c | 15 +++++++++++++++ |
397 | 1 file changed, 15 insertions(+) | |
398 | ||
399 | diff --git a/drivers/usb/typec/typec-extcon.c b/drivers/usb/typec/typec-extcon.c | |
400 | index 12be8f203f76..d5a7f40f0921 100644 | |
401 | --- a/drivers/usb/typec/typec-extcon.c | |
402 | +++ b/drivers/usb/typec/typec-extcon.c | |
403 | @@ -19,6 +19,10 @@ | |
404 | #include <linux/usb/typec_mux.h> | |
405 | #include <linux/extcon-provider.h> | |
406 | ||
407 | +static bool reset_on_mux; | |
408 | +module_param(reset_on_mux, bool, S_IRUGO | S_IWUSR); | |
409 | +MODULE_PARM_DESC(reset_on_mux, "Set DP=0 on each type-c mux change"); | |
410 | + | |
411 | struct typec_extcon { | |
412 | struct device *dev; | |
413 | ||
414 | @@ -162,6 +166,17 @@ static int typec_extcon_mux_set(struct typec_mux_dev *mux, | |
415 | dev_dbg(tce->dev, " ...alt: svid=%04hx mode=%d vdo=%08x active=%u\n", | |
416 | alt->svid, alt->mode, alt->vdo, alt->active); | |
417 | ||
418 | + mutex_lock(&tce->lock); | |
419 | + if (reset_on_mux && alt != NULL && tce->has_alt) { | |
420 | + tce->mode = state->mode; | |
421 | + tce->has_alt = false; | |
422 | + mutex_unlock(&tce->lock); | |
423 | + | |
424 | + typec_extcon_sync_extcon(tce); | |
425 | + } else { | |
426 | + mutex_unlock(&tce->lock); | |
427 | + } | |
428 | + | |
429 | mutex_lock(&tce->lock); | |
430 | tce->mode = state->mode; | |
431 | tce->has_alt = alt != NULL; | |
432 | -- | |
433 | cgit v1.2.3 | |
434 | ||
435 | From c132654f50ab4726cdf0e116236c33c6038da08a Mon Sep 17 00:00:00 2001 | |
436 | From: Ondřej Jirman | |
437 | Date: Wed, 2 Dec 2020 12:09:45 +0100 | |
438 | Subject: arm64: dts: rk3399-pinebook-pro: Improve Type-C support on Pinebook | |
439 | Pro | |
440 | ||
441 | This is using the same extcon bridge developed by me for Pinephone Pro. | |
442 | ||
443 | Signed-off-by: Ondrej Jirman <megi@xff.cz> | |
444 | --- | |
445 | .../boot/dts/rockchip/rk3399-pinebook-pro.dts | 57 +++++++++++++++++++--- | |
446 | 1 file changed, 50 insertions(+), 7 deletions(-) | |
8c9054af | 447 | |
03acaa9b | 448 | diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts |
13e71d09 | 449 | index 15e90f836745..0d0310c4a82f 100644 |
03acaa9b JP |
450 | --- a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts |
451 | +++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts | |
13e71d09 JP |
452 | @@ -335,7 +335,7 @@ |
453 | ||
454 | /* Regulators supplied by vcc5v0_usb */ | |
455 | /* Type C port power supply regulator */ | |
456 | - vbus_5vout: vbus_typec: vbus-5vout { | |
457 | + vbus_5vout: vbus-5vout { | |
458 | compatible = "regulator-fixed"; | |
459 | enable-active-high; | |
460 | gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>; | |
461 | @@ -374,6 +374,14 @@ | |
03acaa9b JP |
462 | pinctrl-names = "default"; |
463 | pinctrl-0 = <&dc_det_pin>; | |
464 | }; | |
13e71d09 JP |
465 | + |
466 | + typec_extcon_bridge: typec-extcon { | |
03acaa9b JP |
467 | + compatible = "linux,typec-extcon-bridge"; |
468 | + usb-role-switch; | |
469 | + orientation-switch; | |
470 | + mode-switch; | |
471 | + svid = /bits/ 16 <0xff01>; | |
472 | + }; | |
13e71d09 JP |
473 | }; |
474 | ||
475 | &cpu_b0 { | |
476 | @@ -400,6 +408,12 @@ | |
477 | cpu-supply = <&vdd_cpu_l>; | |
478 | }; | |
479 | ||
03acaa9b JP |
480 | +&cdn_dp { |
481 | + status = "okay"; | |
482 | + extcon = <&typec_extcon_bridge>; | |
483 | + phys = <&tcphy0_dp>; | |
13e71d09 JP |
484 | +}; |
485 | + | |
486 | &edp { | |
487 | force-hpd; | |
488 | pinctrl-names = "default"; | |
489 | @@ -691,7 +705,9 @@ | |
490 | interrupts = <RK_PA2 IRQ_TYPE_LEVEL_LOW>; | |
03acaa9b JP |
491 | pinctrl-names = "default"; |
492 | pinctrl-0 = <&fusb0_int_pin>; | |
13e71d09 JP |
493 | - vbus-supply = <&vbus_typec>; |
494 | + vbus-supply = <&vbus_5vout>; | |
03acaa9b | 495 | + usb-role-switch = <&typec_extcon_bridge>; |
13e71d09 | 496 | + extcon = <&typec_extcon_bridge>; |
03acaa9b JP |
497 | |
498 | connector { | |
499 | compatible = "usb-c-connector"; | |
13e71d09 | 500 | @@ -700,10 +716,19 @@ |
03acaa9b JP |
501 | op-sink-microwatt = <1000000>; |
502 | power-role = "dual"; | |
503 | sink-pdos = | |
504 | - <PDO_FIXED(5000, 2500, PDO_FIXED_USB_COMM)>; | |
505 | + <PDO_FIXED(5000, 2500, PDO_FIXED_USB_COMM | PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP)>; | |
506 | source-pdos = | |
507 | - <PDO_FIXED(5000, 1400, PDO_FIXED_USB_COMM)>; | |
508 | + <PDO_FIXED(5000, 1400, PDO_FIXED_USB_COMM | PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP)>; | |
509 | try-power-role = "sink"; | |
03acaa9b JP |
510 | + mode-switch = <&typec_extcon_bridge>; |
511 | + orientation-switch = <&typec_extcon_bridge>; | |
512 | + | |
513 | + altmodes { | |
514 | + dp { | |
515 | + svid = <0xff01>; | |
13e71d09 | 516 | + vdo = <0x0c46>; |
03acaa9b JP |
517 | + }; |
518 | + }; | |
519 | ||
520 | ports { | |
521 | #address-cells = <1>; | |
13e71d09 | 522 | @@ -971,6 +996,7 @@ |
03acaa9b JP |
523 | }; |
524 | ||
525 | &tcphy0 { | |
526 | + extcon = <&typec_extcon_bridge>; | |
527 | status = "okay"; | |
528 | }; | |
8c9054af | 529 | |
13e71d09 JP |
530 | @@ -1004,13 +1030,21 @@ |
531 | ||
532 | &u2phy0 { | |
533 | status = "okay"; | |
534 | + extcon = <&typec_extcon_bridge>; | |
535 | + extcon,ignore-usb; | |
536 | ||
537 | u2phy0_otg: otg-port { | |
538 | + /* | |
539 | + * Type-C port on the left side of the chasis. | |
540 | + */ | |
541 | status = "okay"; | |
542 | }; | |
543 | ||
544 | u2phy0_host: host-port { | |
545 | - phy-supply = <&vcc5v0_otg>; | |
546 | + /* | |
547 | + * USB 2.0 host port for the keyboard (internally connected). | |
548 | + */ | |
549 | + phy-supply = <&vcc5v0_usb>; | |
550 | status = "okay"; | |
551 | }; | |
552 | ||
553 | @@ -1025,11 +1059,18 @@ | |
554 | status = "okay"; | |
555 | ||
556 | u2phy1_otg: otg-port { | |
557 | + /* | |
558 | + * USB 3.0 A port on the left side of the chasis. | |
559 | + */ | |
560 | status = "okay"; | |
561 | }; | |
562 | ||
563 | u2phy1_host: host-port { | |
564 | - phy-supply = <&vcc5v0_otg>; | |
565 | + /* | |
566 | + * To the HUB that has USB camera and USB 2.0 port on the right | |
567 | + * side of the chasis. | |
568 | + */ | |
569 | + phy-supply = <&vcc5v0_usb>; | |
570 | status = "okay"; | |
571 | }; | |
572 | }; | |
573 | @@ -1080,7 +1121,9 @@ | |
574 | }; | |
575 | ||
576 | &usbdrd_dwc3_0 { | |
577 | - dr_mode = "host"; | |
578 | + dr_mode = "otg"; | |
579 | + extcon = <&typec_extcon_bridge>; | |
580 | + snps,usb3-phy-reset-quirk; | |
581 | status = "okay"; | |
582 | }; | |
583 | ||
8c9054af | 584 | -- |
13e71d09 | 585 | cgit v1.2.3 |
8c9054af | 586 |