USB OTG power, take 2

bq27541, smb345, pm8921 (all in drivers/powr) and ektf3k (drivers/input/touchscreen) seem to know when power state changes. The latter relates to slimport hdmi and receiving power through it.

drivers/usb/otg/msm_otg is the other spot the work happens

The BQ27541 is a 'fuel-gauge' and the data sheet shows it is not involved in decisions about charging. There is a callback there for cable-state change tho, bq27541_battery_callback(). This in turn calls power_supply_changed(). Not part of the charging, but notifies the system (to e.g. change scheduler etc).

CONFIG_PM8921_CHARGER is not set in kernel config. And i suspect there is a reason.

One can see the registers of the smb345 in real time through the sysfs:

cd /sys/bus/i2c/drivers/smb345/0-006a; cat reg_status

and there is no register difference between power in or power out when OTG cable is inserted.

I note that CONFIG_USB_MSM_ACA is not set. Will try setting it.

if I look @ the ACA (accessory charger adapter) in /sys/kernel/debug/msm_otg/aca, it is 'disabled'. If i echo 'enabled' there, it doesn't have any affect.

I would think that something like this would work (it does not):

diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 54603bb..bf2d872 100755
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -38,7 +38,12 @@
 #include <linux/usb/msm_hsusb.h>
 #include <linux/usb/msm_hsusb_hw.h>
 #include <linux/regulator/consumer.h>
+#ifdef CONFIG_CHARGER_SMB345
+#include <linux/smb345-charger.h>
+#else
 #include <linux/mfd/pm8xxx/pm8921-charger.h>
+#endif
+
 #include <linux/mfd/pm8xxx/misc.h>
 #include <linux/power_supply.h>
 #include <linux/mhl_8334.h>
@@ -97,6 +102,7 @@ static int global_id_pin_suspend_status;
 #define APQ_AP_ACOK 23
 #define APQ_OTG_ID_PIN 77

+#ifndef CONFIG_CHARGER_SMB345
 enum msm_otg_smb345_chg_type {
 CHARGER_NONE = 0,
 CHARGER_CDP,
@@ -106,6 +112,7 @@ enum msm_otg_smb345_chg_type {
 CHARGER_ACA,
 CHARGER_TBD,
 };
+#endif

 extern int usb_cable_type_detect(unsigned int chgr_type);
 extern void smb345_otg_status(bool on);
@@ -135,10 +142,12 @@ static void asus_chg_set_chg_mode(enum usb_chg_type chg_src)
 {
 int chg_type = chg_src;

+#if 0 /* DAB */
 if (old_chg_type == chg_type) {
 printk(KERN_INFO "The USB charging type is same : return\n");
 return;
 }
+#endif

 switch (chg_type) {
 case USB_INVALID_CHARGER:
@@ -1154,11 +1163,12 @@ psy_not_supported:

 static int msm_otg_notify_chg_type(struct msm_otg *motg)
 {
- int charger_type;
+ int charger_type, ret;
 /*
 * TODO
 * Unify OTG driver charger types and power supply charger types
 */
+ printk("DAB: [usb_otg] chg_type %d\r\n", motg->chg_type);

 if (motg->chg_type == USB_SDP_CHARGER)
 charger_type = POWER_SUPPLY_TYPE_USB;
@@ -1175,7 +1185,15 @@ static int msm_otg_notify_chg_type(struct msm_otg *motg)
 else
 charger_type = POWER_SUPPLY_TYPE_BATTERY;

- return pm8921_set_usb_power_supply_type(charger_type);
+#ifdef CONFIG_CHARGER_SMB345
+ printk("DAB: call smb345_charger_enable(%d)", motg->chg_type == USB_INVALID_CHARGER ? false : true);
+ ret = smb345_charger_enable(motg->chg_type == USB_INVALID_CHARGER ? false : true);
+ printk("DAB: smb345_charger_enable() returned %d", ret);
+#else
+ ret = pm8921_set_usb_power_supply_type(charger_type);
+ printk("DAB: pm8921_set_usb_power_supply_type(%d) returned %d\r\n", charger_type, ret);
+#endif
+ return ret;
 }

 static int msm_otg_notify_power_supply(struct msm_otg *motg, unsigned mA)
@@ -1231,7 +1249,11 @@ static void msm_otg_notify_charger(struct msm_otg *motg, unsigned mA)

 dev_info(motg->phy.dev, "Avail curr from USB = %u\n", mA);

+#ifdef CONFIG_CHARGER_SMB345
+ printk("DAB: not setting smb345 vbus_draw...");
+#else
 pm8921_charger_vbus_draw(mA);
+#endif
 msm_otg_notify_power_supply(motg, mA);

 motg->cur_power = mA;

Would seem to be correct, but its not.

Leave a Reply

Your email address will not be published. Required fields are marked *

*