Skip to content

Commit

Permalink
max8997: Implement Accessory Charger Adapter support.
Browse files Browse the repository at this point in the history
Accessory Charger Adapter is a device which allows one to power both
the OTG A- and B-devices. It identifies itself via a particular
pull-down value on the ID pin.

Accessory Charger Adapter is defined in Battery Charging Specification,
section 6.2 (as of rev 1.2).

Change-Id: I64c390d5c8300229df474d5fcf9d50aeb14bb6bc
  • Loading branch information
whitequark authored and Gokhan Moral committed Sep 4, 2012
1 parent ea01b5c commit 26e2362
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 12 deletions.
10 changes: 7 additions & 3 deletions arch/arm/mach-exynos/mach-u1.c
Original file line number Diff line number Diff line change
Expand Up @@ -3117,6 +3117,7 @@ static int max8997_muic_charger_cb(int cable_type)
is_cable_attached = true;
break;
case CABLE_TYPE_MHL_VB:
case CABLE_TYPE_OTG_VB:
value.intval = POWER_SUPPLY_TYPE_MISC;
is_cable_attached = true;
break;
Expand Down Expand Up @@ -3184,7 +3185,7 @@ struct platform_device host_notifier_device = {
};

#include "u1-otg.c"
static void max8997_muic_usb_cb(u8 usb_mode)
static void max8997_muic_usb_cb(u8 usb_mode, bool bus_powered)
{
struct s3c_udc *udc = platform_get_drvdata(&s3c_device_usbgadget);
int ret = 0;
Expand Down Expand Up @@ -3223,16 +3224,19 @@ static void max8997_muic_usb_cb(u8 usb_mode)
#endif

if (udc) {
if (usb_mode == USB_OTGHOST_ATTACHED) {
if (usb_mode == USB_OTGHOST_ATTACHED && !bus_powered) {
usb_otg_accessory_power(1);
max8997_muic_charger_cb(CABLE_TYPE_OTG);
} else if (usb_mode == USB_OTGHOST_ATTACHED) {
pr_info("%s: usb vbus powered host\n", __func__);
usb_otg_accessory_power(0);
}

ret = c210_change_usb_mode(udc, usb_mode);
if (ret < 0)
pr_err("%s: fail to change mode!!!\n", __func__);

if (usb_mode == USB_OTGHOST_DETACHED)
if (usb_mode == USB_OTGHOST_DETACHED && !bus_powered)
usb_otg_accessory_power(0);
} else
pr_info("otg error s3c_udc is null.\n");
Expand Down
69 changes: 61 additions & 8 deletions drivers/misc/max8997-muic.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ enum {
ADC_DOCK_VOL_DN = 0x0a, /* 0x01010 14.46K ohm */
ADC_DOCK_VOL_UP = 0x0b, /* 0x01011 17.26K ohm */
ADC_DOCK_PLAY_PAUSE_KEY = 0x0d,
ADC_ACA_OTG = 0x0f, /* 36K ohm */
ADC_CEA936ATYPE1_CHG = 0x17, /* 0x10111 200K ohm */
ADC_JIG_USB_OFF = 0x18, /* 0x11000 255K ohm */
ADC_JIG_USB_ON = 0x19, /* 0x11001 301K ohm */
Expand Down Expand Up @@ -219,6 +220,8 @@ static ssize_t max8997_muic_show_device(struct device *dev,
return sprintf(buf, "USB\n");
case CABLE_TYPE_OTG:
return sprintf(buf, "OTG\n");
case CABLE_TYPE_OTG_VB:
return sprintf(buf, "OTG/VB\n");
case CABLE_TYPE_TA:
return sprintf(buf, "TA\n");
case CABLE_TYPE_DESKDOCK:
Expand Down Expand Up @@ -575,7 +578,8 @@ static int max8997_muic_set_usb_path(struct max8997_muic_info *info, int path)
gpio_val = 0;
accdet = 1;

if (info->cable_type == CABLE_TYPE_OTG) {
if (info->cable_type == CABLE_TYPE_OTG ||
info->cable_type == CABLE_TYPE_OTG_VB) {
accdet = 0;
/* DN1, DP2 */
cntl1_val = (1 << COMN1SW_SHIFT) | (1 << COMP2SW_SHIFT);
Expand Down Expand Up @@ -839,7 +843,7 @@ static int max8997_muic_attach_usb_type(struct max8997_muic_info *info, int adc)

if ((path == AP_USB_MODE) && (adc == ADC_OPEN)) {
if (mdata->usb_cb && info->is_usb_ready)
mdata->usb_cb(USB_CABLE_ATTACHED);
mdata->usb_cb(USB_CABLE_ATTACHED, 0);
}

return 0;
Expand Down Expand Up @@ -899,7 +903,7 @@ static void max8997_muic_attach_mhl(struct max8997_muic_info *info, u8 chgtyp)

if (info->cable_type == CABLE_TYPE_USB) {
if (mdata->usb_cb && info->is_usb_ready)
mdata->usb_cb(USB_CABLE_DETACHED);
mdata->usb_cb(USB_CABLE_DETACHED, 0);

max8997_muic_set_charging_type(info, true);
}
Expand Down Expand Up @@ -1091,7 +1095,7 @@ static int max8997_muic_handle_attach(struct max8997_muic_info *info,
info->cable_type = CABLE_TYPE_OTG;
max8997_muic_set_usb_path(info, AP_USB_MODE);
if (mdata->usb_cb && info->is_usb_ready)
mdata->usb_cb(USB_OTGHOST_ATTACHED);
mdata->usb_cb(USB_OTGHOST_ATTACHED, 0);
} else if (chgtyp == CHGTYP_USB ||
chgtyp == CHGTYP_DOWNSTREAM_PORT ||
chgtyp == CHGTYP_DEDICATED_CHGR ||
Expand All @@ -1102,6 +1106,43 @@ static int max8997_muic_handle_attach(struct max8997_muic_info *info,
ret = max8997_muic_set_charging_type(info, false);
}
break;

case ADC_ACA_OTG:
if (vbvolt & STATUS2_VBVOLT_MASK) {
if (info->cable_type == CABLE_TYPE_OTG_VB) {
dev_info(info->dev,
"%s: duplicated(OTG/VB)\n",
__func__);
break;
}

dev_info(info->dev, "%s: OTG ACA detected\n",
__func__);

info->cable_type = CABLE_TYPE_OTG_VB;

max8997_muic_set_usb_path(info, AP_USB_MODE);
if (mdata->usb_cb && info->is_usb_ready)
mdata->usb_cb(USB_OTGHOST_ATTACHED, 1);

ret = max8997_muic_set_charging_type(info, false);
} else {
dev_info(info->dev, "%s: unpowered OTG ACA detected\n",
__func__);

if (info->cable_type == CABLE_TYPE_OTG_VB) {
dev_info(info->dev, "%s: OTG ACA power loss\n",
__func__);

if (mdata->usb_cb && info->is_usb_ready)
mdata->usb_cb(USB_OTGHOST_DETACHED, 1);
}

info->cable_type = CABLE_TYPE_NONE;
ret = max8997_muic_set_charging_type(info, false);
}
break;

case ADC_MHL:
#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_TRATS)
/* This is for support old MUIC */
Expand Down Expand Up @@ -1229,7 +1270,16 @@ static int max8997_muic_handle_detach(struct max8997_muic_info *info)
info->cable_type = CABLE_TYPE_NONE;

if (mdata->usb_cb && info->is_usb_ready)
mdata->usb_cb(USB_OTGHOST_DETACHED);
mdata->usb_cb(USB_OTGHOST_DETACHED, 0);
break;
case CABLE_TYPE_OTG_VB:
dev_info(info->dev, "%s: OTG/VB\n", __func__);
info->cable_type = CABLE_TYPE_NONE;

if (mdata->usb_cb && info->is_usb_ready)
mdata->usb_cb(USB_OTGHOST_DETACHED, 1);

max8997_muic_set_charging_type(info, false);
break;
case CABLE_TYPE_USB:
case CABLE_TYPE_JIG_USB_OFF:
Expand All @@ -1249,7 +1299,7 @@ static int max8997_muic_handle_detach(struct max8997_muic_info *info)
return 0;

if (mdata->usb_cb && info->is_usb_ready)
mdata->usb_cb(USB_CABLE_DETACHED);
mdata->usb_cb(USB_CABLE_DETACHED, 0);
break;
case CABLE_TYPE_DESKDOCK:
dev_info(info->dev, "%s: DESKDOCK\n", __func__);
Expand Down Expand Up @@ -1519,10 +1569,13 @@ static void max8997_muic_usb_detect(struct work_struct *work)
case CABLE_TYPE_USB:
case CABLE_TYPE_JIG_USB_OFF:
case CABLE_TYPE_JIG_USB_ON:
mdata->usb_cb(USB_CABLE_ATTACHED);
mdata->usb_cb(USB_CABLE_ATTACHED, 0);
break;
case CABLE_TYPE_OTG:
mdata->usb_cb(USB_OTGHOST_ATTACHED);
mdata->usb_cb(USB_OTGHOST_ATTACHED, 0);
break;
case CABLE_TYPE_OTG_VB:
mdata->usb_cb(USB_OTGHOST_ATTACHED, 1);
break;
default:
break;
Expand Down
3 changes: 2 additions & 1 deletion include/linux/mfd/max8997.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ enum cable_type {
CABLE_TYPE_NONE = 0,
CABLE_TYPE_USB,
CABLE_TYPE_OTG,
CABLE_TYPE_OTG_VB, /* VBUS (sink) enabled */
CABLE_TYPE_TA,
CABLE_TYPE_DESKDOCK,
CABLE_TYPE_CARDOCK,
Expand All @@ -144,7 +145,7 @@ enum cable_type {
};

struct max8997_muic_data {
void (*usb_cb) (u8 attached);
void (*usb_cb) (u8 usb_mode, bool bus_powered);
void (*uart_cb) (u8 attached);
int (*charger_cb) (int cable_type);
void (*deskdock_cb) (bool attached);
Expand Down

0 comments on commit 26e2362

Please sign in to comment.