OK, so the USB OTG works just fine, i’ve added the driver for my ‘easycap’ for rearview-camera, and enabled module loading.

Now to dig into how to enable the use of charging while using USB OTG.

In the msm kernel directory, there is a file ./Documentation/usb/msm_otg.txt.

We want ID_A: Configure device to act as host and don’t supply VBUS. The corresponding code is in ./drivers/usb/otg/msm_otg.c

So I plug in a ‘Y’ cable. I plug in a USB device on the ‘OTG’ segment and its detected properly (so far so good).

I plug in power to the other side of the Y, and I get:

msm_otg msm_otg: Failed notifying 1 charger type to PMIC
msm_otg msm_otg: Avail curr from USB = 2
msm_otg msm_otg: current: 500 -> 2 (mA)
msm_hsusb msm_hsusb: CI13XXX_CONTROLLER_SUSPEND_EVENT received
notifying plugin
msm_otg msm_otg: Failed notifying 0 charger type to PMIC
msm_otg msm_otg: Avail curr from USB = 0
msm_hsusb msm_hsusb: CI13XXX_CONTROLLER_DISCONNECT_EVENT received
android_work: android_work: sent uevent USB_STATE=DISCONNECTED
bq27541_battery_callback usb_cable_state = 0
battery_callback cable_wake_lock 5 sec...
elan-ktf3k 3-0010: Update power source to 0
The USB cable status = CHARGER_NONE
msm_otg msm_otg: Failed notifying 0 charger type to PMIC
msm_otg msm_otg: phy_reset: success
bq27541_get_capacity = 67% ret= 69
bq27541_get_psp voltage_now= 3997000 uV
bq27541_get_psp temperature= 260 (0.1¢XC)
bq27541_get_psp status: Not charging ret= 0x0100
msm_otg msm_otg: USB in low power mode
request_suspend_state: wakeup (3->0) at 11409619596093 (2013-08-03 19:32:30.799981455 UTC)
late_resume: call handlers

Hmm. No charge indication, but action occurred.

This comes from msm_otg_notify_charger() which calls msm_otg_notify_chg_type() and gets an error. There’s a big TODO in that latter function 🙂

OK, the chg_type it used was CHARGER_CDP, and the work was done in pm8921_set_usb_power_supply_type(), being passed POWER_SUPPLY_TYPE_USB_CDP as the mode.

Looking in pm8921_set_usb_power_supply_type(), we see:

int pm8921_set_usb_power_supply_type(enum power_supply_type type)
 if (!the_chip) {
 pr_err("called before init\n");
 return -EINVAL;
 return -EINVAL;
 return 0;

Now, ignoring the use of a < in an enum (tsk tsk), that part is not failing (see include/linux/power_supply.h), and presumably the called before init is not the issue, so how could this be an error?

However, its actually using the inline code from include/linux/mfd/pm8xxx/pm8921-charger.h:

static inline int pm8921_set_usb_power_supply_type(enum power_supply_type type)
 return -ENXIO;

Hmm…  CONFIG_PM8921_CHARGER is not set in the config. (see https://android.googlesource.com/kernel/msm.git/+/android-msm-flo-3.4-jb-mr2/arch/arm/configs/flo_defconfig)

And there’s probably a reason. the board-flo.c references it, and SMB345. CONFIG_CHARGER_SMB345 is set. The SMB345 is presumably from Summit Microelectronics (http://www.summitmicro.com/prod_select/products.htm), and presumably very similar to the 346 & 347.

the driver doesn’t get initialised (even w/ CONFIG_PM8921_CHARGER set), so i’m a bit puzzled.