usb: pd: Add support to notify plug orientation via extcon
Policy engine needs to provide the plug orientation upon type-c cable plug in. qmp phy driver needs to program phy lane based upon this information. Change-Id: Idd236136c9f0a9163b4ae7a8405c412f1d69ca9e Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
This commit is contained in:
parent
20b1701b73
commit
77f6fd8044
1 changed files with 49 additions and 1 deletions
|
@ -118,6 +118,12 @@ enum usbpd_data_msg_type {
|
||||||
MSG_VDM = 0xF,
|
MSG_VDM = 0xF,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum plug_orientation {
|
||||||
|
ORIENTATION_NONE,
|
||||||
|
ORIENTATION_CC1,
|
||||||
|
ORIENTATION_CC2,
|
||||||
|
};
|
||||||
|
|
||||||
/* Timeouts (in ms) */
|
/* Timeouts (in ms) */
|
||||||
#define ERROR_RECOVERY_TIME 25
|
#define ERROR_RECOVERY_TIME 25
|
||||||
#define SENDER_RESPONSE_TIME 30
|
#define SENDER_RESPONSE_TIME 30
|
||||||
|
@ -239,10 +245,41 @@ static LIST_HEAD(_usbpd); /* useful for debugging */
|
||||||
static const unsigned int usbpd_extcon_cable[] = {
|
static const unsigned int usbpd_extcon_cable[] = {
|
||||||
EXTCON_USB,
|
EXTCON_USB,
|
||||||
EXTCON_USB_HOST,
|
EXTCON_USB_HOST,
|
||||||
|
EXTCON_USB_CC,
|
||||||
EXTCON_NONE,
|
EXTCON_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const u32 usbpd_extcon_exclusive[] = {0xffffffff, 0};
|
/* EXTCON_USB and EXTCON_USB_HOST are mutually exclusive */
|
||||||
|
static const u32 usbpd_extcon_exclusive[] = {0x3, 0};
|
||||||
|
|
||||||
|
static enum plug_orientation usbpd_get_plug_orientation(struct usbpd *pd)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
union power_supply_propval val;
|
||||||
|
|
||||||
|
ret = power_supply_get_property(pd->usb_psy,
|
||||||
|
POWER_SUPPLY_PROP_TYPEC_CC_ORIENTATION, &val);
|
||||||
|
if (ret)
|
||||||
|
return ORIENTATION_NONE;
|
||||||
|
|
||||||
|
return val.intval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_cable_flipped(struct usbpd *pd)
|
||||||
|
{
|
||||||
|
enum plug_orientation cc;
|
||||||
|
|
||||||
|
cc = usbpd_get_plug_orientation(pd);
|
||||||
|
if (cc == ORIENTATION_CC2)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ORIENTATION_CC1 or ORIENTATION_NONE.
|
||||||
|
* Return value for ORIENTATION_NONE is
|
||||||
|
* "dont care" as disconnect handles it.
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int set_power_role(struct usbpd *pd, enum power_role pr)
|
static int set_power_role(struct usbpd *pd, enum power_role pr)
|
||||||
{
|
{
|
||||||
|
@ -611,6 +648,9 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
|
||||||
|
|
||||||
if (pd->psy_type == POWER_SUPPLY_TYPE_USB ||
|
if (pd->psy_type == POWER_SUPPLY_TYPE_USB ||
|
||||||
pd->psy_type == POWER_SUPPLY_TYPE_USB_CDP)
|
pd->psy_type == POWER_SUPPLY_TYPE_USB_CDP)
|
||||||
|
extcon_set_cable_state_(pd->extcon,
|
||||||
|
EXTCON_USB_CC,
|
||||||
|
is_cable_flipped(pd));
|
||||||
extcon_set_cable_state_(pd->extcon,
|
extcon_set_cable_state_(pd->extcon,
|
||||||
EXTCON_USB, 1);
|
EXTCON_USB, 1);
|
||||||
}
|
}
|
||||||
|
@ -705,6 +745,8 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
|
||||||
extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0);
|
extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0);
|
||||||
|
|
||||||
pd->current_dr = DR_UFP;
|
pd->current_dr = DR_UFP;
|
||||||
|
extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC,
|
||||||
|
is_cable_flipped(pd));
|
||||||
extcon_set_cable_state_(pd->extcon, EXTCON_USB, 1);
|
extcon_set_cable_state_(pd->extcon, EXTCON_USB, 1);
|
||||||
pd_phy_update_roles(pd->current_dr, pd->current_pr);
|
pd_phy_update_roles(pd->current_dr, pd->current_pr);
|
||||||
}
|
}
|
||||||
|
@ -739,10 +781,14 @@ static void dr_swap(struct usbpd *pd)
|
||||||
{
|
{
|
||||||
if (pd->current_dr == DR_DFP) {
|
if (pd->current_dr == DR_DFP) {
|
||||||
extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0);
|
extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 0);
|
||||||
|
extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC,
|
||||||
|
is_cable_flipped(pd));
|
||||||
extcon_set_cable_state_(pd->extcon, EXTCON_USB, 1);
|
extcon_set_cable_state_(pd->extcon, EXTCON_USB, 1);
|
||||||
pd->current_dr = DR_UFP;
|
pd->current_dr = DR_UFP;
|
||||||
} else if (pd->current_dr == DR_UFP) {
|
} else if (pd->current_dr == DR_UFP) {
|
||||||
extcon_set_cable_state_(pd->extcon, EXTCON_USB, 0);
|
extcon_set_cable_state_(pd->extcon, EXTCON_USB, 0);
|
||||||
|
extcon_set_cable_state_(pd->extcon, EXTCON_USB_CC,
|
||||||
|
is_cable_flipped(pd));
|
||||||
extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 1);
|
extcon_set_cable_state_(pd->extcon, EXTCON_USB_HOST, 1);
|
||||||
pd->current_dr = DR_DFP;
|
pd->current_dr = DR_DFP;
|
||||||
}
|
}
|
||||||
|
@ -864,6 +910,8 @@ static void usbpd_sm(struct work_struct *w)
|
||||||
|
|
||||||
if (pd->caps_count == 5 && pd->current_dr == DR_DFP) {
|
if (pd->caps_count == 5 && pd->current_dr == DR_DFP) {
|
||||||
/* Likely not PD-capable, start host now */
|
/* Likely not PD-capable, start host now */
|
||||||
|
extcon_set_cable_state_(pd->extcon,
|
||||||
|
EXTCON_USB_CC, is_cable_flipped(pd));
|
||||||
extcon_set_cable_state_(pd->extcon,
|
extcon_set_cable_state_(pd->extcon,
|
||||||
EXTCON_USB_HOST, 1);
|
EXTCON_USB_HOST, 1);
|
||||||
} else if (pd->caps_count >= PD_CAPS_COUNT) {
|
} else if (pd->caps_count >= PD_CAPS_COUNT) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue