Quantcast
Channel: xda-developers - Galaxy S III General
Viewing all articles
Browse latest Browse all 3987

[MOD] USB OTG + Charging on the Galaxy S3

$
0
0
Good news everyone,

SHORT: I got USB Host and charging working at the same time on my Galaxy S3 (will probably work on other Samsung devices though). What you need is a 40.2K ohm resistor across the ID(pin 4) and Ground(pin 5) on your microUSB connector (compared to normal OTG cable where they are shorted) and one of those USB Y cables that ship with some external hard drives that require a second USB port just for power (or make your own by splitting out the +5v and Ground lines, plenty of guides online). That's all :D

LONG: I've been working on a small project of mine to connect my phone to an external device that accepts GPS NMEA messages over a serial interface. At first I was thinking of doing it with a board like the AndroidADK or IOIO which have USB Host controller and several UARTs. In that scenario the board would act as the USB Host and provide power to the phone enabling simultaneous communication with the external device and charging. But this setup was looking too bulky and overly complicated. The boards were too big for my application as I'm very constrained in size and weight for this project. So then I found this great little board:

https://www.sparkfun.com/products/9716

I thought, OK, my phone has USB host capability, this should be solvable with software alone. A couple of weeks later, reading about kernel support and the drivers, I had a working prototype application, no kernel recompiling or module compiling, just a plain old Java written app. With this done, now the only problem left was POWER. As my phone would be running with screen at full brightness, GPS enabled, plus powering the USB to Serial converter through USB OTG, external power was a must. I could use just a normal USB Y cable, but this would only supply power to the converter, which I'm guessing isn't all that much power hungry. What I really needed was for the phone to charge, which doesn't happen out of the box with a standard USB OTG cable.

Again I started digging through the kernel code. At one time I found an article (I think it was for the Galaxy Nexus) that suggested commenting out some code in the kernel that was responsible for switching the battery charger from charging mode to the so called "boost" mode where it was outputting up to 100mA for external devices. However, I could find this code. Maybe because it was for a AOSP ROM kernel, not Samsung kernel, or a device with a different charger circuit. Plus I really didn't want to have to setup a toolchain and recompile the kernel.

Luckily, while going through the kernel code, I came across an interesting enumeration what was listing some integer values with corresponding resistance values in the comments. That's where I saw the 40.2Kohm value. As far as I can understand, when put across the ID and GND pins of the microUSB, it's used to identify a "SMARTDOCK", I'm guessing some premium Samsung accessory that's capable of charging the phone while providing USB host ports (and MHL/HDMI I think).

Following were a couple of hours of painful soldering of SMD (very tiny) resistors, as these where the only ones I could find lying around the house, to get the right resistance value. Note the phone can be a bit picky about the exact value. I did it with 4x10Kohm, which were in abundance on an old HiFi's PCB I had. I added them up to get 40.15Kohm (I guess those were not very precise resistors). This did the trick :D

USB OTG works as usual, plus the phone is charging. Here's a excerpt from the kernel log upon connecting the cable:

Code:

<3>[ 7601.289051] c0 [HOTPLUG IN] check_up 200000>=600000 && 0>200

<3>[ 7601.289439] c0 CPU_UP 1

<4>[ 7601.293467] c1 CPU1: Booted secondary processor

<6>[ 7601.293757] c1 notifier_call_chain : NOTIFY BAD tick_notify

<6>[ 7601.295315] c1 Switched to NOHz mode on CPU #1

<6>[ 7601.951462] c0 cm36651_work_func_light, red = 376 green = 404 blue = 216 white = 388

<3>[ 7602.610492] c0 [HOTPLUG OUT] check_down 700000<=500000 && 300<200

<3>[ 7602.610736] c0 CPU_DOWN 1

<5>[ 7602.615338] c0 CPU1: shutdown

<6>[ 7603.660803] c0 max77693_irq_thread: interrupt source(0x08)

<6>[ 7603.662066] c0 max77693_irq_thread: muic interrupt(0x00, 0x12, 0x00)

<6>[ 7603.662254] c0 max77693-muic max77693-muic: max77693_muic_irq: irq:445

<6>[ 7603.663205] c0 max77693-muic max77693-muic: func:max77693_muic_detect_dev CONTROL1:3f

<6>[ 7603.664338] c0 max77693-muic max77693-muic: func:max77693_muic_detect_dev irq:445 ret:0

<6>[ 7603.664536] c0 max77693-muic max77693-muic: max77693_muic_detect_dev: STATUS1:0x3f, 2:0x48

<6>[ 7603.664727] c0 max77693-muic max77693-muic: adc:1f adcerr:0 chgtyp:0cable_type:0

<6>[ 7603.664896] c0 max77693-muic max77693-muic: max77693_muic_detect_dev: DETACHED

<6>[ 7603.665072] c0 max77693-muic max77693-muic: func:max77693_muic_handle_detach

<6>[ 7603.669386] c0 max77693-muic max77693-muic: max77693_muic_handle_detach: CNTL2(0x3b)

<6>[ 7603.669568] c0 max77693-muic max77693-muic: max77693_muic_handle_detach: duplicated(NONE)

<6>[ 7603.675052] c0 max77693_irq_thread: interrupt source(0x08)

<6>[ 7603.676364] c0 max77693_irq_thread: muic interrupt(0x01, 0x00, 0x00)

<6>[ 7603.676535] c0 max77693-muic max77693-muic: max77693_muic_irq: irq:437

<6>[ 7603.677472] c0 max77693-muic max77693-muic: func:max77693_muic_detect_dev CONTROL1:3f

<6>[ 7603.678607] c0 max77693-muic max77693-muic: func:max77693_muic_detect_dev irq:437 ret:0

<6>[ 7603.678798] c0 max77693-muic max77693-muic: max77693_muic_detect_dev: STATUS1:0x30, 2:0x48

<6>[ 7603.678990] c0 max77693-muic max77693-muic: func:max77693_muic_handle_dock_vol_key status1:30 adc:10 cable_type:0

<6>[ 7603.679223] c0 max77693-muic max77693-muic: adc:10 adcerr:0 chgtyp:0cable_type:0

<6>[ 7603.679402] c0 max77693-muic max77693-muic: max77693_muic_detect_dev: ATTACHED

<6>[ 7603.679577] c0 max77693-muic max77693-muic: func:max77693_muic_handle_attach st1:30 st2:48 cable_type:0

<6>[ 7603.679793] c0 max77693-muic max77693-muic: func:max77693_muic_handle_attach Attach SmartDock

<6>[ 7603.679996] c0 max77693-muic max77693-muic: func:max77693_muic_set_usb_path path:0

<6>[ 7603.680163] c0 MUIC safeout path=0

<6>[ 7603.680379] c0 regulator regulator.2: func:max77693_reg_is_enabled

<6>[ 7603.680530] c0 regulator regulator.2: func:max77693_get_rid

<6>[ 7603.680667] c0 regulator regulator.2: func:max77693_get_enable_register

<6>[ 7603.681628] c0 regulator regulator.3: func:max77693_reg_is_enabled

<6>[ 7603.681783] c0 regulator regulator.3: func:max77693_get_rid

<6>[ 7603.681917] c0 regulator regulator.3: func:max77693_get_enable_register

<6>[ 7603.682864] c0 max77693-muic max77693-muic: max77693_muic_set_usb_path: AP_USB_MODE

<6>[ 7603.683042] c0 max77693-muic max77693-muic: max77693_muic_set_usb_path: Set manual path

<6>[ 7603.686819] c0 max77693-muic max77693-muic: max77693_muic_set_usb_path: CNTL1(0x3f)

<6>[ 7603.687788] c0 max77693-muic max77693-muic: max77693_muic_set_usb_path: CNTL2(0x3e)

<6>[ 7603.730374] c0 MUIC usb_cb:5

<6>[ 7603.730460] c0 usb: muic: invalid mode5

<6>[ 7603.730573] c0 max77693_powered_otg_control: enable(1)

<6>[ 7603.731882] c0 otg_accessory_powered_booster: otg accessory power = 1

<6>[ 7603.732038] c0 host_notifier: start usbhostd notify

<6>[ 7603.732162] c0 host_notify: ndev name=usb_otg: from state=2 -> to state=1

<7>[ 7603.734407] c3 mif: set_hsic_lpa_states: 215: called(s5p_usb_phy_resume+0x514/0x534):

<6>[ 7603.734597] c3 mif: set hsic lpa wake: pda active (1)

<6>[ 7603.755687] c0 MUIC attached:1

<6>[ 7603.755809] c0 MHL Attached !!

<6>[ 7603.755916] c0 sii9234_wake_lock()

<6>[ 7603.756034] c0 sii9234: mhl_onoff_ex(on)

<6>[ 7603.756151] c0 sii9234_power_onoff(1)

<6>[ 7603.756282] c0 sii9234_reset()

<6>[ 7603.775375] c0 sii9234: detection started d3

<6>[ 7603.775501] c0 mhl_hpd_handler() state is aready off

<6>[ 7603.953645] c0 sii9234 : go_to d3 mode!!!

<6>[ 7603.953706] c0 goto_d3() : enable_irq(1)

<6>[ 7603.953746] c0 max77693-muic max77693-muic: func:max77693_muic_set_charging_type force_disable:0

<6>[ 7603.953818] c0 max77693_muic_charger_cb: 13

<6>[ 7603.953852] c0 max77693_set_muic_cb_type: muic cable type(13)

<5>[ 7603.953907] c0 melfas-ts 3-0048: melfas_ta_cb

<5>[ 7603.953941] c0 melfas-ts 3-0048: TA connect!!!

<3>[ 7603.985700] c0 [ERROR] sii9234 : mhl_tx_read_reg(0x71)

<3>[ 7603.985729] c0 [ERROR] sii9234_irq_thread():3121 read MHL_TX_INTR1_REG failed !

<6>[ 7603.985765] c0 sii9234_irq_thread(): i2c error exit

<6>[ 7603.985790] c0 sii9234: wake_up

<6>[ 7604.454668] c0 max77693_get_cable_type: CDR(0x1)

<3>[ 7604.454716] c0 max77693_get_cable_type: chgtyp detect err, retry 1, CHGIN(0x3). MU_ST2(0x48), CDR(0x1), VB(0x1), CHGTYP(0x0)

<6>[ 7604.560636] c3 max77693_irq_thread: interrupt source(0x08)

<6>[ 7604.561801] c3 max77693_irq_thread: muic interrupt(0x00, 0x07, 0x00)

<6>[ 7604.561925] c3 max77693-muic max77693-muic: max77693_muic_irq: irq:441

<6>[ 7604.562785] c3 max77693-muic max77693-muic: func:max77693_muic_detect_dev CONTROL1:9

<6>[ 7604.563819] c3 max77693-muic max77693-muic: func:max77693_muic_detect_dev irq:441 ret:0

<6>[ 7604.563958] c3 max77693-muic max77693-muic: max77693_muic_detect_dev: STATUS1:0x30, 2:0x41

<6>[ 7604.564102] c3 max77693-muic max77693-muic: adc:10 adcerr:0 chgtyp:1cable_type:d

<6>[ 7604.564223] c3 max77693-muic max77693-muic: max77693_muic_detect_dev: ATTACHED

<6>[ 7604.564350] c3 max77693-muic max77693-muic: func:max77693_muic_handle_attach st1:30 st2:41 cable_type:13

<6>[ 7604.564495] c3 max77693-muic max77693-muic: max77693_muic_handle_attach: duplicated(SMARTDOCK)

<3>[ 7604.656888] c0 max77693_get_cable_type: CHGIN(0x3). MU_ST2(0x41), CDR(0x0), VB(0x1), CHGTYP(0x1)

<3>[ 7604.657055] c0 max77693_get_cable_type: chgtyp detect ok, CHGIN(0x3). MU_ST2(0x41), CDR(0x0), VB(0x1), CHGTYP(0x1)

<3>[ 7604.657231] c0 max77693_get_cable_type: cable type(3)

<6>[ 7604.677259] c0 battery_update_info: state(1), type(3), health(1), present(1), cable(3), curr(466), soc(96), raw(9548), vol(4245000), ocv(4264000), tmp(291)

<3>[ 7604.677486] c0 battery_monitor_work: Updated Cable State(3)

<3>[ 7604.883067] c0 battery_charge_control: charge enabled, current as 466/460mA @52286

<6>[ 7604.884009] c0 battery_interval_calulation: v diff(19000), weight(120)

<6>[ 7604.884138] c0 battery_interval_calulation: weight(120)

<6>[ 7604.884258] c0 battery_monitor_interval: apply weight(120), 30 -> 36

<6>[ 7604.884439] c0 [997] bat: s(96, 0), v(4245, -19), b(1), t(29.1), h(1), cs(1, 1), cb(3), cr(466, 460), a(0), f(0), r(0), t(52286)

<7>[ 7605.126794] c0 Motor:tspdrv: ImmVibeSPI_ForceOut_AmpEnable (1)

<7>[ 7605.213586] c0 Motor:tspdrv: ImmVibeSPI_ForceOut_AmpDisable (0)

<3>[ 7607.105308] c0 [HOTPLUG IN] check_up 200000>=600000 && 0>200

<3>[ 7607.105368] c0 CPU_UP 1

<4>[ 7607.107141] c1 CPU1: Booted secondary processor

<6>[ 7607.107246] c1 notifier_call_chain : NOTIFY BAD tick_notify

<6>[ 7607.110239] c1 Switched to NOHz mode on CPU #1

<3>[ 7608.150538] c0 [HOTPLUG OUT] check_down 500000<=500000 && 391<200

<3>[ 7608.150745] c0 CPU_DOWN 1

<6>[ 7608.151774] c0 cm36651_work_func_light, red = 376 green = 405 blue = 216 white = 388

<5>[ 7608.157231] c0 CPU1: shutdown

If you look at the log carefully, you'll notice there are a couple of lines going about MHL failing to enable. I'm guess this SMARTDOCK I'm emulating also has a HDMI port for video out and uses some of the additional pins on the Galaxy's connector. The S3 has a non standard 11-pin microUSB connector exactly for this purpose (USB OTG + Power + Video out + maybe audio). Nevertheless, this setup works for me and there are no visible side effects.

NOTES:
1. Connect power before connecting the cable to the phone. The driver switches charging on only if power is present on the VBUS upon connecting the cable and it doesn't monitor the VBUS state actively. So if you plug in the power supply after connecting the cable to the phone, it won't start charging. You have to disconnect and reconnect it.
2. Requires a Sammy kernel. Not 100% sure, haven't tested with CM9/10, but since the code is about a Samsung accessory and is in the driver for the switching circuit used in S3 (\drivers\misc\max77693-muic.c) this is a high probability.
3. Charge is done at 460 mA. At least that's what the log states at one point. Then again at another place it reads "TA connect!!!" which I think means that a wall adapter is connected. Measuring the actual current is on my todo list.
4. MHL failed to enable - this should be a big issue. I think it's from the fact that I emulate a SMARTDOCK being connected, that (possibly) has HDMI out.
5. I haven't tried using a 124Kohm resistor with is the standard for enabling USB OTG + charging called "Accessory Charger Adapter". I have a hunch that maybe this won't work as a found a datasheet for the switching circuit used in older Samsung devices and in there is a table that lists all the resistance values that can be used on the ID pin. There's one at around 120Kohm that's pretty close to the 124Kohm value and it has nothing to do with USB OTG or charging. For comparison the 40.2K value is listed as being for additional accessories (vendor specific), which is what Samsung use it for.

Viewing all articles
Browse latest Browse all 3987

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>