Allwinner A40i полностью рабочий USB-OTG
Добрый день!
Возможно ли предусмотреть работу usb0 в режиме OTG на Allwinner-A40i?
Судя по информации из интернета это возможно: https://lore.kernel.org/linux-arm-kernel/daf5c543-a1d1-04d2-6486-6cc9cd72d8e5@sholland.org/T/#md5e9ce01feb201041467c136f09e80628f414557
В моем случае пин ID USB OTG - PI11. Настроил следующим образом файл дерева устройств:
/ {
#include "sun8i-r40.dtsi" /* <--- в этом файле ничего не менял */
...
/* ohci0 and ehci0 need to be included to work with USB OTG */
ohci0: usb@1c14400 {
compatible = "allwinner,sun8i-r40-ohci", "generic-ohci";
reg = <0x01c14400 0x100>;
interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>,
<&ccu CLK_USB_OHCI0>;
resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
status = "okay";
};
ehci0: usb@1c14000 {
compatible = "allwinner,sun8i-r40-ehci", "generic-ehci";
reg = <0x01c14000 0x100>;
interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>;
resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>;
status = "okay";
};
...
}
...
&usb_otg {
/* в dtsi определено dr_mode = "peripheral"; */
status = "okay";
};
&usbphy {
dr_mode = "otg";
usb0_id_det-gpios = <PIN_PI 11 GPIO_ACTIVE_HIGH>;
usb0_vbus-supply = <®_vcc5v0>;
status = "okay";
};
USB-OTG работает, но проблема в том, что своё состояние host или client он определяет единственный раз при старте по пину ID.
Для меня все выглядит так, как будто драйвер настраивается на работу через прерывание по пину GPIO PI11, c отладочными принтами в подсистеме прерываний есть регистрация EINT23 в драйвере pinctrl:
[ 11.578919] sun4i-pinctrl 1c20800.pinctrl: 1c20800.pinctrl: request IRQ for GPIO 267, return 23
[ 11.587657] devm_request_irq data->id_det_irq: 74, ret: 0
74: 0 0 0 0 sunxi_pio_edge 23 Edge usb0-id-det
Все прерывания:
# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
26: 0 0 0 0 GICv2 54 Level timer@1c20c00
27: 0 0 0 0 GICv2 29 Level arch_timer
28: 198416 45783 21540 10341 GICv2 30 Level arch_timer
31: 0 0 0 0 GICv2 152 Level arm-pmu
32: 0 0 0 0 GICv2 153 Level arm-pmu
33: 0 0 0 0 GICv2 154 Level arm-pmu
34: 0 0 0 0 GICv2 155 Level arm-pmu
35: 0 0 0 0 GICv2 59 Level 1c02000.dma-controller
37: 0 0 0 0 GICv2 102 Level gpmmu
38: 0 0 0 0 GICv2 104 Level ppmmu0
39: 0 0 0 0 GICv2 107 Level ppmmu1
40: 175 0 0 0 GICv2 101 Level gp
41: 128 0 0 0 GICv2 103 Level pp0
42: 128 0 0 0 GICv2 106 Level pp1
43: 0 0 0 0 GICv2 71 Level ehci_hcd:usb1
44: 0 0 0 0 GICv2 72 Level ohci_hcd:usb2
45: 1289 0 0 0 GICv2 61 Level sun4i-ts
46: 0 0 0 0 GICv2 56 Level 1c20400.rtc
47: 0 0 0 0 GICv2 125 Level 1400000.deinterlace
48: 0 0 0 0 GICv2 126 Level sun8i-ce-ns
49: 0 0 0 0 GICv2 85 Level 1c0e000.video-codec
74: 0 0 0 0 sunxi_pio_edge 23 Edge usb0-id-det
83: 28 0 0 0 GICv2 33 Level ttyS0
84: 0 0 0 0 GICv2 44 Level sun6i-spi
85: 80306 0 0 0 GICv2 39 Level mv64xxx_i2c
86: 0 0 0 0 sunxi-nmi 0 Level axp22x_irq_chip
109: 0 0 0 0 axp22x_irq_chip 22 Edge axp20x-pek-dbr
110: 0 0 0 0 axp22x_irq_chip 23 Edge axp20x-pek-dbf
113: 0 0 0 0 GICv2 40 Level mv64xxx_i2c
114: 0 0 0 0 GICv2 41 Level mv64xxx_i2c
115: 0 0 0 0 GICv2 120 Level mv64xxx_i2c
116: 0 0 0 0 GICv2 121 Level mv64xxx_i2c
117: 0 0 0 0 GICv2 129 Level tvd0
118: 0 0 0 0 GICv2 130 Level tvd1
119: 0 0 0 0 GICv2 131 Level tvd2
120: 0 0 0 0 GICv2 132 Level tvd3
121: 10281 0 0 0 GICv2 68 Level ths
122: 245 0 0 0 GICv2 66 Level sunxi-mmc
123: 5690 0 0 0 GICv2 64 Level sunxi-mmc
129: 0 0 0 0 GICv2 88 Level ahci-sunxi[1c18000.sata]
130: 168336 0 0 0 GICv2 87 Level eth0
131: 81204 0 0 0 GICv2 117 Level eth1
132: 401 0 0 0 GICv2 70 Level musb-hdrc.2.auto
133: 0 0 0 0 GICv2 96 Level ohci_hcd:usb3
134: 0 0 0 0 GICv2 97 Level ohci_hcd:usb4
135: 9114 0 0 0 GICv2 76 Level 1c71000.lcd-controller
136: 13939 0 0 0 GICv2 83 Level 1c73000.lcd-controller
137: 515 0 0 0 GICv2 90 Level 1ee0000.hdmi
138: 0 0 0 0 GICv2 110 Level ehci_hcd:usb5
139: 0 0 0 0 GICv2 108 Level ehci_hcd:usb6
IPI0: 0 0 0 0 CPU wakeup interrupts
IPI1: 0 0 0 0 Timer broadcast interrupts
IPI2: 71 81 134 106 Rescheduling interrupts
IPI3: 5850 17893 6323 6836 Function call interrupts
IPI4: 0 0 0 0 CPU stop interrupts
IPI5: 16353 2205 1054 417 IRQ work interrupts
IPI6: 0 0 0 0 completion interrupts
Err: 0
Но по какой-то причине запуска обработчика прерывания не происходит.
Реально проверил - пин ID меняет свое состояние в зависимости от подключения разъема OTG. Внешнее прерывание на пине возможно - PI11/SPI0_CLK/UART5_RX/EINT23.
Привожу ссылку на архив с syslog и полный dts: https://disk.yandex.ru/d/0H5tnCl1qQIE2g
Прошу по возможности помочь с диагностикой и посоветовать ресурсы/направления диагностики, буду очень благодарен, если требуется какая-либо дополнительная информация - пожалуйста сообщите.