LINUX.ORG.RU

Работает ли USB-OTG в режиме device на актуальном U-Boot?

 , ,


0

1

Мне нужно проинициализировать OTG-контроллер в режиме Device. Подскажите, возможно ли это в принципе? Если да, то как я могу это сделать и проверить работоспособность?

  • Работаю с платой BPI M2 Berry (процессор Allwinner A40i-H)
  • Версия U-Boot 6.8.0-90-generic

Из того, что уже сделано

Модифицированы dts-файлы

usb_otg: usb@1c13000 {
	compatible = "allwinner,sun8i-h3-musb";
	reg = <0x01c13000 0x400>;
	clocks = <&ccu CLK_BUS_OTG>;
	resets = <&ccu RST_BUS_OTG>;
	interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
	interrupt-names = "mc";
	phys = <&usbphy 0>;
	phy-names = "usb";
	extcon = <&usbphy 0>;
	dr_mode = "otg";
	status = "disabled";
};

---

&usb_otg {
	dr_mode = "peripheral";
	status = "okay";
};

&usbphy {
	usb0_id_det = "disabled";
	usb1_vbus-supply = <&reg_vcc5v0>;
	status = "okay";
};

В menuconfig включены такие настройки (в блоке USB Support):

  • Enable driver model for USB Gadget
  • MUSB host mode support (без этого поля даже не начинается инициализация otg-контроллера)
  • MUSB gadget mode support
  • Enable sunxi OTG/DRC USB controller
  • Hardcode MUSB CONFIGDATA register (без этого поля тоже возникает больше проблем)
  • USB Gadget support
  • USB Gadget support in SPL (Указал то, что показалось значимым. Мог что-то упустить)

При вызове usb start получаю следующий вывод:

=> usb start
starting USB...
Bus usb@1c13000: Port not available.

Актуальный u-boot имеет версию 2026.01, и allwinner’ов в нём со включенным CONFIG_USB_MUSB_GADGET=y пара дюжин. Сетью на cdc-ecm я тоже время от времени там пользовался, так что да, на актуальном u-boot работает. Что происходит в вендорском, я в душе не чаю.

beefdeadbeef
()
Ответ на: комментарий от beefdeadbeef

Я обновился до версии 2026.04 Конфиг под мою плату из USB включает только HCD. И даже не описан узел otg в dts-файле.

Как же оно тогда работает? Или мне надо снова всё вручную настраивать?

maxBbb
() автор топика
Ответ на: комментарий от maxBbb

«работает» очевидно относилось к тем платкам из числа пары дюжин, да и «вообще». Ну т.е. «вообще» достаточно добавить в соответствующий config одну строчку CONFIG_USB_MUSB_GADGET=y. Что до конкретно этой платки, то да, для неё в mainline в dts узел usb@1c13000 вообще не описан, так что я могу только гадать, что в железе (r40/v40 и как они там ещё называются) он всё-таки существует и не отличается от такого же в, скажем, h3. Соответственно, можно было бы списать usb_otg: из sunxi-h3-h5.dtsi (с поправкой на адрес/прерывание он выглядит так же, как и ваш).

Вторая часть выглядит обычно так (опять же, с поправкой на id pin и vbus-supply):

&usb_otg {                                                                                                                                                                    
        status = "okay";                                                                                                                                                      
        dr_mode = "otg";                                                                                                                                                      
};                                                                                                                                                                            
                                                                                                                                                                              
&usbphy {                                                                                                                                                                     
        usb0_id_det-gpios = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */                                                                                                          
        usb0_vbus-supply = <&reg_usb0_vbus>;                                                                                                                                  
        status = "okay";                                                                                                                                                      
};

Продолжая гадать, предложил бы попробовать в другую сторону – в dr_mode = «host» оно работает ?

beefdeadbeef
()
Ответ на: комментарий от beefdeadbeef

Соответственно, можно было бы списать usb_otg: из sunxi-h3-h5.dtsi

Описание узла otg для A40 уже совпадает с h3-h5, с поправкой на мои адреса. Точно такой же узел помог мне завести otg под линуксом на этой же плате.

Вторая часть выглядит обычно так

Если я указываю id-det-gpios, то получаю такой вывод:

No host cable detected: Bus usb@1c13000: Port not available.

По-моему, выглядит, будто u-boot пытается инициализировать otg как хост, невзирая на dr-mode, который я ему указываю. Что, опять же странно, потому что линукс на этой плате проблем не имеет (если таки допилить dts-файлы).

Продолжая гадать, предложил бы попробовать в другую сторону – в dr_mode = «host» оно работает ?

Дополнил dts включение ehci:

&ehci0 {
	status = "okay";
};

Получаю такой вывод:

No host cable detected: Bus usb@1c13000: Port not available.
USB EHCI 1.00
Bus usb@1c14000: 1 USB Device(s) found
maxBbb
() автор топика
Ответ на: комментарий от maxBbb

Было предположение, что, судя по неуверенному описанию железа на сайте производителя, в разъёме вообще ничего, кроме питания, не распаяно. Но коль в линуксе работает … А что мы увидим, если почитаем по адресам 1c13000 и какой там у usbphy с помощью md ? Уж не сплошные ли нули ?

beefdeadbeef
()
Ответ на: комментарий от beefdeadbeef

У usbphy адрес - 1c13400. 1c13000 - это USB OTG

Если прочитать через md, то там есть данные:

=> md 0x01c13400
01c13400: 4203b000 00000000 00000000 00000000  ...B............
01c13410: 00002b80 00000000 023438e4 00000000  .+.......84.....
01c13420: 00000001 00000001 00000000 00000000  ................
01c13430: 00000000 00000000 00000000 00000000  ................
01c13440: 00000000 00000000 00000000 00000000  ................
--- и далее нули ---

(это если инициализировать otg как хост)

У меня ещё организован лог чтения/записи по адресам 1c13000 и 1c13400. Может он будет в чём-то полезен

В поле addr стоят флаги (старшие 4 бита):

  • B/C/E - запись 1/2/4 байт
  • 1/2/4 - чтение 1/2/4 байт
RW LIST:
0 addr E1C13410  val 00000000
1 addr 41C13410  val 00000000
2 addr E1C13410  val 00000c00
3 addr 11C13410  val 00000000
4 addr B1C13410  val 00000080
5 addr 11C13410  val 00000080
6 addr B1C13410  val 00000081
7 addr 11C13410  val 00000081
8 addr B1C13410  val 00000080
9 addr E1C13410  val 00000000
10 addr 41C13410  val 00000000
11 addr E1C13410  val 00002000
12 addr 11C13410  val 00000000
13 addr B1C13410  val 00000000
14 addr 11C13410  val 00000000
15 addr B1C13410  val 00000001
16 addr 11C13410  val 00000001
17 addr B1C13410  val 00000000
18 addr 41C13410  val 00002000
19 addr E1C13410  val 00002100
20 addr 11C13410  val 00000000
21 addr B1C13410  val 00000000
22 addr 11C13410  val 00000000
23 addr B1C13410  val 00000001
24 addr 11C13410  val 00000001
25 addr B1C13410  val 00000000
26 addr 41C13410  val 00002100
27 addr E1C13410  val 00002200
28 addr 11C13410  val 00000000
29 addr B1C13410  val 00000080
30 addr 11C13410  val 00000080
31 addr B1C13410  val 00000081
32 addr 11C13410  val 00000081
33 addr B1C13410  val 00000080
34 addr 41C13410  val 00002280
35 addr E1C13410  val 00002380
36 addr 11C13410  val 00000080
37 addr B1C13410  val 00000000
38 addr 11C13410  val 00000000
39 addr B1C13410  val 00000001
40 addr 11C13410  val 00000001
41 addr B1C13410  val 00000000
42 addr 41C13410  val 00002300
43 addr E1C13410  val 00002400
44 addr 11C13410  val 00000000
45 addr B1C13410  val 00000080
46 addr 11C13410  val 00000080
47 addr B1C13410  val 00000081
48 addr 11C13410  val 00000081
49 addr B1C13410  val 00000080
50 addr E1C13410  val 00000000
51 addr 41C13410  val 00000000
52 addr E1C13410  val 00002a00
53 addr 11C13410  val 00000000
54 addr B1C13410  val 00000080
55 addr 11C13410  val 00000080
56 addr B1C13410  val 00000081
57 addr 11C13410  val 00000081
58 addr B1C13410  val 00000080
59 addr 41C13410  val 00002a80
60 addr E1C13410  val 00002b80
61 addr 11C13410  val 00000080
62 addr B1C13410  val 00000080
63 addr 11C13410  val 00000080
64 addr B1C13410  val 00000081
65 addr 11C13410  val 00000081
66 addr B1C13410  val 00000080
67 addr 41C13420  val 00000001
68 addr E1C13420  val 00000001
69 addr 41C13400  val 40000000
70 addr E1C13400  val 40010000
71 addr 41C13400  val 40010000
72 addr E1C13400  val 40030000
73 addr 41C13400  val 40030000
74 addr E1C13400  val 40038000
75 addr 41C13400  val 40038000
76 addr E1C13400  val 4003b000
77 addr B1C13050  val 00000000
78 addr C1C13048  val 00000000
79 addr C1C1304A  val 00000000
80 addr B1C13041  val 00000000
81 addr 11C1304C  val 00000000
82 addr 21C13044  val 00000000
83 addr 21C13046  val 00000000
84 addr B1C13042  val 00000000
85 addr B1C13090  val 00000003
86 addr C1C13092  val 00000000
87 addr B1C13094  val 00000003
88 addr C1C13096  val 00000000
89 addr B1C13042  val 00000001
90 addr B1C13090  val 00000006
91 addr C1C13092  val 00000008
92 addr B1C13042  val 00000001
93 addr B1C13094  val 00000006
94 addr C1C13096  val 00000048
95 addr B1C13042  val 00000002
96 addr B1C13090  val 00000006
97 addr C1C13092  val 00000088
98 addr B1C13042  val 00000002
99 addr B1C13094  val 00000006
100 addr C1C13096  val 000000c8
101 addr B1C13042  val 00000003
102 addr B1C13090  val 00000006
103 addr C1C13092  val 00000108
104 addr B1C13042  val 00000003
105 addr B1C13094  val 00000006
106 addr C1C13096  val 00000148
107 addr B1C13042  val 00000004
108 addr B1C13090  val 00000006
109 addr C1C13092  val 00000188
110 addr B1C13042  val 00000004
111 addr B1C13094  val 00000006
112 addr C1C13096  val 000001c8
113 addr 11C13041  val 00000080
114 addr C1C13048  val 0000001f
115 addr C1C1304A  val 0000001e
116 addr B1C13050  val 000000f7
117 addr B1C1307C  val 00000000
118 addr B1C13040  val 000000a0
119 addr 11C13041  val 00000080
120 addr B1C13042  val 00000000
121 addr B1C13098  val 00000000
122 addr B1C13043  val 00000000
maxBbb
() автор топика

Я, конечно, могу ошибаться, но как по-вашему, U-Boot понимает, что в к устройству подключили хост? Обычно для этого ставят отдельную микросхему, вроде FUSB302, которая определяет направление и генерирует прерывание, которое уже ловит система. Мне кажется так. Возможно, что в твоей конфигурации не хватает как раз описания такой микросхемы и драйвера для неё (если она вообще есть на плате). Посмотри в DT для Линукса и в menuconfig U-Boot, возможно там что-то есть. Обычно такие микросхемы управляются по I2C.

stabilitron
()
Ответ на: комментарий от stabilitron

Тут https://linux-sunxi.org/USB_OTG_Controller_Register_Guide написано, что есть встроенный USB Port Controller, который ТС, как-то, описал в dts. И в этом контроллере есть регистры, показывающие состояние ID-контакта и прочее. ИМХО, в случае Allwinner/sunxi дополнительной микросхемы не надо.

mky ★★★★★
()
Ответ на: комментарий от stabilitron

mky уже верно написал.

На плате отдельной микросхемы, о которой вы говорите, нет. К тому же, Линукс на этом же устройстве вполне удачно работает в режиме device. Но, к сожалению, линуксовые настройки в dts в моём случае не помогают. U-Boot не хочет работать ни в режиме device, ни в режиме host.

maxBbb
() автор топика
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.