Project

General

Profile

Actions

Issue #2202

open

midas: Make usb host work

Added by Denis 'GNUtoo' Carikli almost 4 years ago. Updated 8 months ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
Linux
Start date:
12/26/2020
Due date:
% Done:

0%

Estimated time:
Upstream patch status:
Work not started
Grant:
Type of work:
C programming
Actions #1

Updated by Denis 'GNUtoo' Carikli almost 4 years ago

  • Target version changed from Replicant 6.0 to Any Replicant version with an upstream kernel
Actions #2

Updated by Denis 'GNUtoo' Carikli almost 4 years ago

  • Project changed from Replicant to Upstreaming patches
  • Target version deleted (Any Replicant version with an upstream kernel)
  • Upstream patch status set to Work not started
  • Device deleted (Unknown)
Actions #3

Updated by Denis 'GNUtoo' Carikli almost 4 years ago

TODO:
  • Cleanup the logs below
  • Find where we got the advise about the connector driver and document it It's in the logs below
19:52 <@Putti> GNUtoo, I read today some kernel code and I think we need to add support for the USB OTG pin (GND <-> ID) detection and if that is detected we enable the ESAFEOUT1
19:52 <@Putti> there is just so many max77693-* drivers I don't know which one to add it to or if we need a new one
19:53 <@GNUtoo> First we probably need to add support for the host
19:53 <@GNUtoo> somehow even forcing that doesn't make it switch
19:54 <@Putti> well, working on the usb driver doesn't stop working on the max77693 driver
19:54 <@GNUtoo> indeed
19:54 <@GNUtoo> Though I wonder how to test
19:54 <@Putti> I have usb cable where led turns on if there is power
19:54 <@GNUtoo> like if we need all the pieces or not to test it
19:54 <@Putti> :D
19:55 <@GNUtoo> I'll look at the dwc2 code
19:55 <@GNUtoo> but assuming that I make the switch to host,
19:55 <@GNUtoo> I hope that nothing will get in my way in testing that
19:56 <@GNUtoo> like there is the connector stuff as well
19:57 <@Putti> well, I couldn't get extcon-max77693.c driver to notify in dmesg that the connector was attached when I added otg cable
19:57 <@Putti> so probably some issue there indeed
19:58 <@GNUtoo> USB is routed fine at least as the i9300 was in peripheral mode when forced to be in host mode
19:59 <@GNUtoo> ohhh dwc2 has a debugfs interface
19:59 <@GNUtoo> I don't know what theses test modes are though
20:01 <@GNUtoo>  * dwc2_force_mode() - Force the mode of the controller.
20:01 <@GNUtoo>  * 1) If the dr_mode is set to either HOST or PERIPHERAL we force the
20:01 <@GNUtoo>  * controller to stay in a particular mode regardless of ID pin
20:01 <@GNUtoo>  * changes. We do this once during probe.
20:02 <@GNUtoo> Also we need to understand how the stack works in software and hardware as there are many components usually
20:02 <@GNUtoo> for instance dwc2 seem to be an USB controller, I need to check what's the PHY etc
20:02 <@GNUtoo> At least we have host and device mode in dwc2
20:03 <@GNUtoo> There are probably exynos specific parts too
20:03 <@GNUtoo> that's usually where you have to add stuff
20:05 <@GNUtoo> &exynos_usbphy { vbus-supply = <&esafeout1_reg>;
20:06 <@GNUtoo> ah we already have the vbus in the dts
20:06 <@GNUtoo> &exynos_usbphy { compatible = "samsung,exynos4x12-usb2-phy";
20:09 <@GNUtoo> ok, we seem to have 1 otg constroller and a bunch of host-only controllers, so we're interested in the "hsotg: hsotg@12480000" 
20:10 <@GNUtoo> ???? <-> exynos_usbphy (samsung,exynos4210-usb2-phy) <-> hsotg (samsung,s3c6400-hsotg)
20:11 <@GNUtoo> samsung,s3c6400-hsotg is the dwc2 part specific to s3c/exynos socs in params.c
20:19 <@GNUtoo> I don't know the UTMI / ULPI etc for the phy but if "p->phy_utmi_width = 8;" isn't an issue, that part should probably work
20:19 <@GNUtoo> I'll doulbe check though
20:19 <@Putti> GNUtoo, have you tried just adding the 5V on the rail and see if it works?
20:20 <@GNUtoo> the rationale is that I recall that it worked on another board the "libretech" s805x (that requires nonfree software to boot)
20:20 <@GNUtoo> and we have:
20:20 <@GNUtoo>         { .compatible = "amlogic,meson-g12a-usb",
20:20 <@GNUtoo>           .data = dwc2_set_amlogic_g12a_params },
20:20 <@Putti> I started working on max77694_otg.c that detects the GND-ID pin and enables the ESAFEOUT1 regulator
20:20 <@GNUtoo> so that's in the same file with slightly different params
20:21 <@GNUtoo> Putti: yes but I tired with a hub in between
20:21 <@GNUtoo> and the 5V produced prints
20:21 <@GNUtoo> not the hub
20:21 <@Putti> ok
20:22 <@GNUtoo> dwc2 12480000.hsotg: new device is full-speed
20:22 <@GNUtoo> That's the print it produced
20:23 <@GNUtoo> So maybe it declared the usb controller ready or something and it appeared on lsusb (as an usb controller in peripheral mode)
20:23 <@Putti> ok, and did you change from kernel config the dwc2 to host mode?
20:23 <@GNUtoo> yes
20:24 <@GNUtoo> dr_mode = "host";
20:24 <@Putti> not from dts
20:24 <@Putti> there is kernel config also
20:24 <@GNUtoo> or whatever was the value to switch to host mode
20:24 <@GNUtoo> ah no
20:24 <@GNUtoo> I kept it as dual role
20:25 <@Putti> it would be interesting to see if you change it via the config to host mode then what happens
20:25 <@GNUtoo> Example of lsusb on a beagleboard with the USB controller in peripheral mode: Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
20:25 <@GNUtoo> *beaglebone green
20:25 <@GNUtoo> uh oops
20:25 <@GNUtoo> that's a host
20:25 <@GNUtoo> so forget what I told
20:25 <@GNUtoo> the print is strange then
20:25 <@GNUtoo> this also has a host port
20:25 <@GNUtoo> so we don't see the device controller in lsusb
20:25 <@GNUtoo> strange strange
20:26  * GNUtoo had bad memory on that one
20:26 <@GNUtoo> So I force host mode through dts, It produces ~0V on the vbus, I add 5V externally, and we have some prints
20:27 <@GNUtoo> but it still doesn't find the hub
20:27  * GNUtoo will try your suggestion
20:27 <@GNUtoo> Though I'll also want to try forcing the esafeout1
20:28 <@GNUtoo> to avoid interferences with components thining they are in device mode if no voltage is there or if a voltage is not produced the right way
20:30  * GNUtoo tries forcing ESAFEOUT1 first
20:30 <@GNUtoo> regulator-always-on;
20:30 <@Putti> I couldn't get it work like that
20:32 <@GNUtoo> How do you know it didn't work?
20:32 <@GNUtoo> Because you got no voltage?
20:32 <@Putti> yup
20:34 <@Putti> GNUtoo, well kernel reported it was on but clearly it was not
20:35 <@Putti> like I wonder if it needs special setup routine
20:35 <@GNUtoo> Someone told us that host wasn't implemented if I recall well
20:35 <@GNUtoo> does that person told what was missing?
20:36 <@GNUtoo> *did
20:37 <@Putti> <Viciouss> for the OTG, I wrote with Marek Szyprowski while I was doing the changes for the p4note dts, he mentioned that ehci is used for the otg port in host mode but this is not yet supported in mainline.
20:37 <@GNUtoo> cat /sys/class/udc/12480000.hsotg/is_selfpowered
20:37 <@GNUtoo> 0
20:37 <@Putti> this was from yesterday
20:37 <@GNUtoo> hmmm
20:37 <@GNUtoo> ok, so it was Viciouss that had the info, thanks
20:39 <@GNUtoo> Viciouss: hi, do you know what part is not implemented in the OTG stack to make it switch to host, did Marek Szyprowski told you more details than just that it wasn't supported yet in mainline?
21:04  * GNUtoo made a better setup: I managed to power the hub separately
21:05 <@GNUtoo> now the prints don't appear anymore when plugging the hub
21:05 < Viciouss> GNUtoo: he mentioned that the otg port is routed to dwc2 for the usb device support and that there is need for a switch depending on what is connected to route the usb signal correctly
21:05 <@GNUtoo> because the hub power supply doesn't leak to the device
21:05 < Viciouss> so my guess is that the extcon integration is missing?
21:05 <@GNUtoo> oh ok
21:05  * GNUtoo is trying to force host by recompilation now
21:05 <@GNUtoo> Viciouss: thanks a lot
21:06 <@Putti> extcon missing would confirm why the plugging in of the otg cable is not detected
21:10 <@GNUtoo> hmmm nothing more when forcing with CONFIG_USB_DWC2_HOST=y
21:10 <@GNUtoo> current config: CONFIG_USB_DWC2_HOST=y, dr_mode = "host";, regulator-always-on;
21:10 <@Putti> and you have 5v?
21:11 <@GNUtoo> on the hub, yet, on the smartphone connector, no
21:11 <@Putti> ok
21:11 <@GNUtoo> 0.38v instead
21:12 <@sensiblemn> fyi, Marek Szyprowski is mszyprow in #linux-exynos on freenode if you have any questions. also krzk likely would be a helpful resource as well. yesterday he pointed me to https://exynos.wiki.kernel.org/todo_tasks
21:13 <@GNUtoo> oh nice
21:13 <@GNUtoo> thanks a lot
21:14 <@sensiblemn> also, Putti had just merged this patch by wolfgang that seems to try to integrate the extcon driver https://github.com/ReplicantOS-midas/android_device_midas_common/commits/replicant-9
19:13 <@Putti> belgin, we need to somehow get the ESAFEOUT{1,2} regulators enabled, even if you forced it with the dts it didn't work so maybe it requires that something else is disabled first, like battery charging
19:13 <@Putti> belgin, kernel shows the regulator enabled but no output from the power pin
19:13 < belgin> ok
19:15 <@Putti> belgin, another issue after you get the power is then with the usb controller driver probably: GNUtoo used externally powered usb hub and the plugged in devices still would not show up in kernel logs.
19:17 < belgin> i have an external hub let me try
19:19 <@Putti> and be sure to have otg or host mode in the dts for n5110 if you try, it is also possible to select the perhipheral vs. host mode in the dwc2 kconfig so make sure that is also what you expect
19:21 < belgin> ok
19:24 < belgin> Putti: now it says [ 3490.099739] dwc2 12480000.hsotg: new device is full-speed
19:24 < belgin> but that's it
19:24 < belgin> still doesn't work
19:24 <@Putti> ok, same result as GNUtoo got, so probably some work needed in the driver
19:25 < belgin> ok thank you for your help
19:31 <@GNUtoo> I also got some strange things
19:32 <@GNUtoo> injecting 5V to the device USB port resulted in new prints
19:32 <@GNUtoo> so that looks consistent with the info we got that we needed to add support upstream (in the connector driver if I recall well)
19:33 <@GNUtoo> There is maybe some logic related to vbus stuff and the connector driver
19:33 <@GNUtoo> though Putti and me didn't manage to see the effect of enabling the VBUS through ESAFEOUT(1?)
Actions #4

Updated by Denis 'GNUtoo' Carikli almost 4 years ago

Some more interesting discussion:

<@sensiblemn> GNUtoo: someone at postmarketOS, Timon Baetz, just upstreamed charging related patches for the i9100 within the last 
                    couple of days. two of the patches, v6 7/8 and 8/8 seem to include some ESAFEOUT2 related changes and i think use 
                    extcon drivers. i figure that maybe looking at what they did it might help us conceptualize similar patches with the 
                    i9300, so here's the link: https://patchwork.kernel.org/project/linux-samsung-soc/list/?
<@sensiblemn> bmitter=195745&state=*
<@sensiblemn> *8/8, seem
<@GNUtoo> Nice
<@GNUtoo> indeed, it's probably relevant to USB host on the GT-I9300
<@GNUtoo> Thanks

Actions #5

Updated by _I3^ RELATIVISM over 3 years ago

  • Type of work C programming added
Actions #6

Updated by Victor Shilin over 3 years ago

I was investigating how the OTG support is done in the smdk4412 3.0.101 kernel.
3.0.101 indeed has some codepaths activating safeout1 regulator, but it turned out the crucial part for the VBUS to work was setting up the OTG_EN gpio.

I wrote a sysfs interface to activate the OTG mode on the smdk4412 kernel (I'm using 3.18 kernel which has the hardware-specific drivers from 3.0.101 as the base):
https://github.com/Midas-Mainline/android_kernel_samsung_smdk4412/blob/139b15002baed3bbbeadf95308627512f85ee02b/arch/arm/mach-exynos/sec-switch.c#L368

Roughly, enabling USB HOST mode on smdk4412 3.0.101 kernel consists of the following parts (as far as could figure out and unless I'm missing something else):

(1)
VBUS support

Enabling OTG_EN gpio (otg_accessory_power(1) call does this on smdk4412 kernel).
This will enable VBUS. Forcing ESAFEOUT1 regulator wasn't required, even though smdk4412 ensures it's enabled (probably the regulator is enabled from the kernel bootup).

The otg_accessory_power does the following:

static void otg_accessory_power(int enable) {
u8 on = (u8)!!enable;

/* max77693 otg power control */
otg_control(enable);

gpio_request(GPIO_OTG_EN, "USB_OTG_EN");
gpio_direction_output(GPIO_OTG_EN, on);
gpio_free(GPIO_OTG_EN);
pr_info("%s: otg accessory power = %d\n", func, on);
}

otg_control control function sets up MUIC registers for the USB HOST mode (2).

(2)
MUIC (extcon) registers

otg_control is provided by drivers/misc/max77693-muic.c on smdk4412 kernel, which in turn calls max77693_otg_control function.
I found the following patch in the Tizen 3.10 kernel that ports this function to the mainline kernel:
"max77693: Add support for OTG host power supply" (https://github.com/Midas-Mainline/android_kernel_samsung_smdk4412/commit/be74b5c51dc606ae1fb5c1f82739c35d39cf205a)

Whilst I can't verify whether the backported patch still works in 5.12 (but does compile without any errors), I assume this is absolutely required for the OTG HOST mode as it presents in both smdk4412 and Tizen kernels.

muic_set_usb_path(AP_USB_MODE) sets up MAX77693_MUIC_REG_CTRL1 and MAX77693_MUIC_REG_CTRL2 registers:
https://github.com/Midas-Mainline/android_kernel_samsung_smdk4412/blob/otg-3.18/drivers/misc/max77693-muic.c#L1133

Mainline already has max77693_muic_set_path function which seemingly supposed to do the same thing, but I didn't verify if the way I called this function changes registers in the same way as it happens in smdk4412 kernel:
https://github.com/Midas-Mainline/android_kernel_samsung_smdk4412/commit/8ca7e8551d78fdbe88b08f9fca33ae485e9db087#diff-8df8d0afc665f94d56924c86617ff13cff2d55b5904e2ea38b2f527eb4f70db4R749

(3)
USB Gadget support.

The hardest part to get working.

smdk4412 kernel uses s3c_udc_otg (drivers/usb/gadget/s3c_udc_otg.c), whereas the mainline use the DWC2 driver.
The crucial part to notify the USB gadget from the platform code is done by the call max77693_muic_usb_cb(USB_OTGHOST_ATTACHED):

https://github.com/Midas-Mainline/android_kernel_samsung_smdk4412/blob/139b15002baed3bbbeadf95308627512f85ee02b/arch/arm/mach-exynos/sec-switch.c#L378

max77693_muic_usb_cb calls usb_gadget_vbus_connect(gadget):
https://github.com/Midas-Mainline/android_kernel_samsung_smdk4412/blob/139b15002baed3bbbeadf95308627512f85ee02b/arch/arm/mach-exynos/sec-switch.c#L308

This calls s3c_vbus_enable in drivers/usb/gadget/s3c_udc_otg.c:
https://github.com/Midas-Mainline/android_kernel_samsung_smdk4412/blob/otg-3.18/drivers/usb/gadget/s3c_udc_otg.c#L321

which I have no idea what the corresponding part for the mainline kernel would be, as we don't use s3c_udc_otg in the mainline anymore.

Some other references:
https://github.com/Sekilsgs2/i9100_kernel_mainline_port

Sekilsgs2's 4.20 kernel ported to i9100 that includes OTG support. I would probably not figured out that activating OTG_EN gpio was required instead of just forcing the ESAFEOUT1 regulator be ON, if I didn't check out this repository first.
The repository doesn't have much notes on how exactly the work was derived, but I figured the closest to this repo revision in the mainline linux kernel was https://github.com/torvalds/linux/tree/903b77c63167
This repository also has some changes to the DWC2 USB driver which should most probably be useful for the OTG support on i9300.

The current work on OTG support for i9300 can be tracked here:
https://github.com/Midas-Mainline/android_kernel_samsung_smdk4412/commits/otg-5.12

The branch "otg-3.18" contains some experiments on the smdk4412 kernel:
https://github.com/Midas-Mainline/android_kernel_samsung_smdk4412/commits/otg-3.18

USB HOST mode can only be activated via sysfs parameter (tested on the mouse only, the mouse must be connected before activating the sysfs):

root@localhost:/home/acroreiser# cd /sys/module/sec_switch/parameters/
root@localhost:/sys/module/sec_switch/parameters# ls
enable_otg_control enable_otg_powered_control enable_usbhost_control
root@localhost:/sys/module/sec_switch/parameters# echo 1 > enable_usbhost_control

Note, that the commits I made commented out some of the code (some of the code that smdk4412 kernel uses is not relevant to the OTG HOST support) and I also commented out some callbacks (usb notifiers) in the place where they should be, in order to be able that the sysfs node works.

5.12 kernel for now only provides VBUS support that can be activated via sysfs.

Actions #7

Updated by Victor Shilin over 3 years ago

OTG now works on i9300 in Linux kernel 4.20:

https://github.com/Midas-Mainline/android_kernel_samsung_smdk4412/commits/otg-4.20

The activation of the USB HOST mode still has to be done via the sysfs node /sys/devices/platform/otg_hack/votg_power
(but it's just a matter of the technique to make this work via the extcon, as the driver already supports cable detection).

Credit goes to Sekilsgs2, this wouldn't have been possible without his work for i9100.
The patch for DWC2 USB driver is taken from his kernel as is, I didn't yet look much into that (anyways, all the code needs to be cleaned up, there are a lot of hacks).

The kernel log from Ubuntu 16.04:

[ 74.846714] max77693-muic max77693-muic: external connector is detached(chg_type:0x0, prev_chg_type:0x0)
[ 95.382898] otg_gpiohack otg_hack: new state: 1
[ 95.442767] max77693-muic max77693-muic: CONTROL1 : 0x09, CONTROL2 : 0x04, state : attached
[ 95.442790] dwc2_force_mode: Forcing mode to host
[ 95.542862] dwc2 12480000.hsotg: ++Connector ID Status Change Interrupt++ (Host)
[ 95.542957] dwc2 12480000.hsotg: connId B
[ 95.542985] dwc2 12480000.hsotg: Waiting for Peripheral Mode, Mode=Host
[ 95.580657] dwc2 12480000.hsotg: connId A
[ 96.080660] usb 1-1: new low-speed USB device number 2 using dwc2
[ 96.334699] usb 1-1: New USB device found, idVendor=275d, idProduct=0ba6, bcdDevice= 1.00
[ 96.334748] usb 1-1: New USB device strings: Mfr=0, Product=1, SerialNumber=0
[ 96.334780] usb 1-1: Product: USB OPTICAL MOUSE
[ 96.347314] input: USB OPTICAL MOUSE as /devices/platform/soc/12480000.hsotg/usb1/1-1/1-1:1.0/0003:275D:0BA6.0001/input/input4
[ 96.348203] hid-generic 0003:275D:0BA6.0001: input: USB HID v1.11 Mouse [USB OPTICAL MOUSE ] on usb-12480000.hsotg-1/input0

Actions #8

Updated by Kurtis Hanna over 3 years ago

the pmOS repo that includes upstream kernel support for midas devices and the i9100, linux-postmarketos-exynos4, added a patch set a month ago called "add kernel patches to fix charging" which might be worth investigating: https://gitlab.com/postmarketOS/pmaports/-/commit/1d562fc44be15026a180b975adc55cd5acc66ea1

Actions #9

Updated by Kurtis Hanna over 3 years ago

I made a post at #2022-10 that might be relevant to this issue, but it is just a hypothesis.

Actions #10

Updated by Denis 'GNUtoo' Carikli about 3 years ago

  • Category set to Linux
Actions #11

Updated by Kurtis Hanna about 3 years ago

I'm unsure if it is relevant to this issue, but a max77693 patch was applied upstream today: https://lore.kernel.org/linux-devicetree/YVLl4n9O8xXuDeWo@google.com/T/

Actions #12

Updated by Denis 'GNUtoo' Carikli 8 months ago

  • Target version set to Replicant 11.0
Actions

Also available in: Atom PDF