Merge "power: supply: qcom: use typec mode instead of debounce done"

This commit is contained in:
Linux Build Service Account 2017-05-31 17:58:01 -07:00 committed by Gerrit - the friendly Code Review server
commit aab7f04733
5 changed files with 45 additions and 92 deletions

View file

@ -455,8 +455,7 @@ static int smb2_usb_get_prop(struct power_supply *psy,
if (!val->intval) if (!val->intval)
break; break;
rc = smblib_get_prop_typec_mode(chg, val); if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT ||
if ((val->intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT ||
chg->micro_usb_mode) && chg->micro_usb_mode) &&
chg->real_charger_type == POWER_SUPPLY_TYPE_USB) chg->real_charger_type == POWER_SUPPLY_TYPE_USB)
val->intval = 0; val->intval = 0;
@ -493,7 +492,7 @@ static int smb2_usb_get_prop(struct power_supply *psy,
else if (chip->bad_part) else if (chip->bad_part)
val->intval = POWER_SUPPLY_TYPEC_SOURCE_DEFAULT; val->intval = POWER_SUPPLY_TYPEC_SOURCE_DEFAULT;
else else
rc = smblib_get_prop_typec_mode(chg, val); val->intval = chg->typec_mode;
break; break;
case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE: case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
if (chg->micro_usb_mode) if (chg->micro_usb_mode)
@ -678,8 +677,7 @@ static int smb2_usb_port_get_prop(struct power_supply *psy,
if (!val->intval) if (!val->intval)
break; break;
rc = smblib_get_prop_typec_mode(chg, val); if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT ||
if ((val->intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT ||
chg->micro_usb_mode) && chg->micro_usb_mode) &&
chg->real_charger_type == POWER_SUPPLY_TYPE_USB) chg->real_charger_type == POWER_SUPPLY_TYPE_USB)
val->intval = 1; val->intval = 1;

View file

@ -841,7 +841,6 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua)
{ {
int rc = 0; int rc = 0;
bool override; bool override;
union power_supply_propval pval;
/* suspend and return if 25mA or less is requested */ /* suspend and return if 25mA or less is requested */
if (icl_ua < USBIN_25MA) if (icl_ua < USBIN_25MA)
@ -851,14 +850,8 @@ int smblib_set_icl_current(struct smb_charger *chg, int icl_ua)
if (icl_ua == INT_MAX) if (icl_ua == INT_MAX)
goto override_suspend_config; goto override_suspend_config;
rc = smblib_get_prop_typec_mode(chg, &pval);
if (rc < 0) {
smblib_err(chg, "Couldn't get typeC mode rc = %d\n", rc);
goto enable_icl_changed_interrupt;
}
/* configure current */ /* configure current */
if (pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT if (chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT
&& (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)) { && (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)) {
rc = set_sdp_current(chg, icl_ua); rc = set_sdp_current(chg, icl_ua);
if (rc < 0) { if (rc < 0) {
@ -880,7 +873,7 @@ override_suspend_config:
if (icl_ua == INT_MAX) { if (icl_ua == INT_MAX) {
/* remove override if no voters - hw defaults is desired */ /* remove override if no voters - hw defaults is desired */
override = false; override = false;
} else if (pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) { } else if (chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) {
if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB) if (chg->real_charger_type == POWER_SUPPLY_TYPE_USB)
/* For std cable with type = SDP never override */ /* For std cable with type = SDP never override */
override = false; override = false;
@ -920,15 +913,8 @@ int smblib_get_icl_current(struct smb_charger *chg, int *icl_ua)
int rc = 0; int rc = 0;
u8 load_cfg; u8 load_cfg;
bool override; bool override;
union power_supply_propval pval;
rc = smblib_get_prop_typec_mode(chg, &pval); if ((chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT
if (rc < 0) {
smblib_err(chg, "Couldn't get typeC mode rc = %d\n", rc);
return rc;
}
if ((pval.intval == POWER_SUPPLY_TYPEC_SOURCE_DEFAULT
|| chg->micro_usb_mode) || chg->micro_usb_mode)
&& (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB)) { && (chg->usb_psy_desc.type == POWER_SUPPLY_TYPE_USB)) {
rc = get_sdp_current(chg, icl_ua); rc = get_sdp_current(chg, icl_ua);
@ -2219,8 +2205,6 @@ static const char * const smblib_typec_mode_name[] = {
static int smblib_get_prop_ufp_mode(struct smb_charger *chg) static int smblib_get_prop_ufp_mode(struct smb_charger *chg)
{ {
switch (chg->typec_status[0]) { switch (chg->typec_status[0]) {
case 0:
return POWER_SUPPLY_TYPEC_NONE;
case UFP_TYPEC_RDSTD_BIT: case UFP_TYPEC_RDSTD_BIT:
return POWER_SUPPLY_TYPEC_SOURCE_DEFAULT; return POWER_SUPPLY_TYPEC_SOURCE_DEFAULT;
case UFP_TYPEC_RD1P5_BIT: case UFP_TYPEC_RD1P5_BIT:
@ -2231,7 +2215,7 @@ static int smblib_get_prop_ufp_mode(struct smb_charger *chg)
break; break;
} }
return POWER_SUPPLY_TYPEC_NON_COMPLIANT; return POWER_SUPPLY_TYPEC_NONE;
} }
static int smblib_get_prop_dfp_mode(struct smb_charger *chg) static int smblib_get_prop_dfp_mode(struct smb_charger *chg)
@ -2245,8 +2229,6 @@ static int smblib_get_prop_dfp_mode(struct smb_charger *chg)
return POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE; return POWER_SUPPLY_TYPEC_SINK_POWERED_CABLE;
case DFP_RD_OPEN_BIT: case DFP_RD_OPEN_BIT:
return POWER_SUPPLY_TYPEC_SINK; return POWER_SUPPLY_TYPEC_SINK;
case DFP_RA_OPEN_BIT:
return POWER_SUPPLY_TYPEC_POWERED_CABLE_ONLY;
default: default:
break; break;
} }
@ -2254,20 +2236,12 @@ static int smblib_get_prop_dfp_mode(struct smb_charger *chg)
return POWER_SUPPLY_TYPEC_NONE; return POWER_SUPPLY_TYPEC_NONE;
} }
int smblib_get_prop_typec_mode(struct smb_charger *chg, static int smblib_get_prop_typec_mode(struct smb_charger *chg)
union power_supply_propval *val)
{ {
if (!(chg->typec_status[3] & TYPEC_DEBOUNCE_DONE_STATUS_BIT)) {
val->intval = POWER_SUPPLY_TYPEC_NONE;
return 0;
}
if (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT) if (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT)
val->intval = smblib_get_prop_dfp_mode(chg); return smblib_get_prop_dfp_mode(chg);
else else
val->intval = smblib_get_prop_ufp_mode(chg); return smblib_get_prop_ufp_mode(chg);
return 0;
} }
int smblib_get_prop_typec_power_role(struct smb_charger *chg, int smblib_get_prop_typec_power_role(struct smb_charger *chg,
@ -2555,24 +2529,12 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
const union power_supply_propval *val) const union power_supply_propval *val)
{ {
int rc; int rc;
bool orientation, cc_debounced, sink_attached, hvdcp; bool orientation, sink_attached, hvdcp;
u8 stat; u8 stat;
if (!get_effective_result(chg->pd_allowed_votable)) if (!get_effective_result(chg->pd_allowed_votable))
return -EINVAL; return -EINVAL;
rc = smblib_read(chg, APSD_STATUS_REG, &stat);
if (rc < 0) {
smblib_err(chg, "Couldn't read APSD status rc=%d\n", rc);
return rc;
}
cc_debounced = (bool)
(chg->typec_status[3] & TYPEC_DEBOUNCE_DONE_STATUS_BIT);
sink_attached = (bool)
(chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT);
hvdcp = stat & QC_CHARGER_BIT;
chg->pd_active = val->intval; chg->pd_active = val->intval;
if (chg->pd_active) { if (chg->pd_active) {
vote(chg->apsd_disable_votable, PD_VOTER, true, 0); vote(chg->apsd_disable_votable, PD_VOTER, true, 0);
@ -2624,6 +2586,14 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
if (rc < 0) if (rc < 0)
smblib_err(chg, "Couldn't unvote USB_PSY rc=%d\n", rc); smblib_err(chg, "Couldn't unvote USB_PSY rc=%d\n", rc);
} else { } else {
rc = smblib_read(chg, APSD_STATUS_REG, &stat);
if (rc < 0) {
smblib_err(chg, "Couldn't read APSD status rc=%d\n",
rc);
return rc;
}
hvdcp = stat & QC_CHARGER_BIT;
vote(chg->apsd_disable_votable, PD_VOTER, false, 0); vote(chg->apsd_disable_votable, PD_VOTER, false, 0);
vote(chg->pd_allowed_votable, PD_VOTER, true, 0); vote(chg->pd_allowed_votable, PD_VOTER, true, 0);
vote(chg->usb_irq_enable_votable, PD_VOTER, true, 0); vote(chg->usb_irq_enable_votable, PD_VOTER, true, 0);
@ -2643,8 +2613,8 @@ int smblib_set_prop_pd_active(struct smb_charger *chg,
* and data could be interrupted. Non-legacy DCP could also draw * and data could be interrupted. Non-legacy DCP could also draw
* more, but it may impact compliance. * more, but it may impact compliance.
*/ */
if (!chg->typec_legacy_valid && cc_debounced && sink_attached = chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT;
!sink_attached && hvdcp) if (!chg->typec_legacy_valid && !sink_attached && hvdcp)
schedule_work(&chg->legacy_detection_work); schedule_work(&chg->legacy_detection_work);
} }
@ -2766,6 +2736,7 @@ static int smblib_cc2_sink_removal_enter(struct smb_charger *chg)
smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc); smblib_err(chg, "Couldn't read TYPE_C_STATUS_4 rc=%d\n", rc);
return rc; return rc;
} }
ccout = (stat & CC_ATTACHED_BIT) ? ccout = (stat & CC_ATTACHED_BIT) ?
(!!(stat & CC_ORIENTATION_BIT) + 1) : 0; (!!(stat & CC_ORIENTATION_BIT) + 1) : 0;
ufp_mode = (stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT) ? ufp_mode = (stat & TYPEC_DEBOUNCE_DONE_STATUS_BIT) ?
@ -3684,8 +3655,7 @@ unlock:
smblib_update_usb_type(chg); smblib_update_usb_type(chg);
} }
static void smblib_handle_typec_insertion(struct smb_charger *chg, static void smblib_handle_typec_insertion(struct smb_charger *chg)
bool sink_attached)
{ {
int rc; int rc;
@ -3697,45 +3667,37 @@ static void smblib_handle_typec_insertion(struct smb_charger *chg,
smblib_err(chg, "Couldn't disable APSD_START_ON_CC rc=%d\n", smblib_err(chg, "Couldn't disable APSD_START_ON_CC rc=%d\n",
rc); rc);
if (sink_attached) if (chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT)
typec_sink_insertion(chg); typec_sink_insertion(chg);
else else
typec_sink_removal(chg); typec_sink_removal(chg);
} }
static void smblib_handle_typec_debounce_done(struct smb_charger *chg, static void smblib_handle_typec_cc_state_change(struct smb_charger *chg)
bool rising, bool sink_attached)
{ {
int rc; if (chg->pr_swap_in_progress)
union power_supply_propval pval = {0, }; return;
if (rising) { chg->typec_mode = smblib_get_prop_typec_mode(chg);
if (!chg->typec_present && !chg->pr_swap_in_progress) { if (!chg->typec_present && chg->typec_mode != POWER_SUPPLY_TYPEC_NONE) {
chg->typec_present = true; chg->typec_present = true;
smblib_dbg(chg, PR_MISC, "TypeC insertion\n"); smblib_dbg(chg, PR_MISC, "TypeC %s insertion\n",
smblib_handle_typec_insertion(chg, sink_attached); smblib_typec_mode_name[chg->typec_mode]);
} smblib_handle_typec_insertion(chg);
} else { } else if (chg->typec_present &&
if (chg->typec_present && !chg->pr_swap_in_progress) { chg->typec_mode == POWER_SUPPLY_TYPEC_NONE) {
chg->typec_present = false; chg->typec_present = false;
smblib_dbg(chg, PR_MISC, "TypeC removal\n"); smblib_dbg(chg, PR_MISC, "TypeC removal\n");
smblib_handle_typec_removal(chg); smblib_handle_typec_removal(chg);
} }
}
rc = smblib_get_prop_typec_mode(chg, &pval); smblib_dbg(chg, PR_INTERRUPT, "IRQ: cc-state-change; Type-C %s detected\n",
if (rc < 0) smblib_typec_mode_name[chg->typec_mode]);
smblib_err(chg, "Couldn't get prop typec mode rc=%d\n", rc);
smblib_dbg(chg, PR_INTERRUPT, "IRQ: debounce-done %s; Type-C %s detected\n",
rising ? "rising" : "falling",
smblib_typec_mode_name[pval.intval]);
} }
static void smblib_usb_typec_change(struct smb_charger *chg) static void smblib_usb_typec_change(struct smb_charger *chg)
{ {
int rc; int rc;
bool debounce_done, sink_attached;
rc = smblib_multibyte_read(chg, TYPE_C_STATUS_1_REG, rc = smblib_multibyte_read(chg, TYPE_C_STATUS_1_REG,
chg->typec_status, 5); chg->typec_status, 5);
@ -3744,12 +3706,7 @@ static void smblib_usb_typec_change(struct smb_charger *chg)
return; return;
} }
debounce_done = smblib_handle_typec_cc_state_change(chg);
(bool)(chg->typec_status[3] & TYPEC_DEBOUNCE_DONE_STATUS_BIT);
sink_attached =
(bool)(chg->typec_status[3] & UFP_DFP_MODE_STATUS_BIT);
smblib_handle_typec_debounce_done(chg, debounce_done, sink_attached);
if (chg->typec_status[3] & TYPEC_VBUS_ERROR_STATUS_BIT) if (chg->typec_status[3] & TYPEC_VBUS_ERROR_STATUS_BIT)
smblib_dbg(chg, PR_INTERRUPT, "IRQ: vbus-error\n"); smblib_dbg(chg, PR_INTERRUPT, "IRQ: vbus-error\n");
@ -4264,8 +4221,7 @@ static void smblib_legacy_detection_work(struct work_struct *work)
chg->typec_legacy_valid = true; chg->typec_legacy_valid = true;
vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, false, 0); vote(chg->usb_icl_votable, LEGACY_UNKNOWN_VOTER, false, 0);
legacy = stat & TYPEC_LEGACY_CABLE_STATUS_BIT; legacy = stat & TYPEC_LEGACY_CABLE_STATUS_BIT;
rp_high = smblib_get_prop_ufp_mode(chg) == rp_high = chg->typec_mode == POWER_SUPPLY_TYPEC_SOURCE_HIGH;
POWER_SUPPLY_TYPEC_SOURCE_HIGH;
if (!legacy || !rp_high) if (!legacy || !rp_high)
vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER, vote(chg->hvdcp_disable_votable_indirect, VBUS_CC_SHORT_VOTER,
false, 0); false, 0);

View file

@ -322,6 +322,7 @@ struct smb_charger {
bool typec_legacy_valid; bool typec_legacy_valid;
int fake_input_current_limited; int fake_input_current_limited;
bool pr_swap_in_progress; bool pr_swap_in_progress;
int typec_mode;
/* workaround flag */ /* workaround flag */
u32 wa_flags; u32 wa_flags;
@ -453,8 +454,6 @@ int smblib_get_prop_usb_current_now(struct smb_charger *chg,
union power_supply_propval *val); union power_supply_propval *val);
int smblib_get_prop_typec_cc_orientation(struct smb_charger *chg, int smblib_get_prop_typec_cc_orientation(struct smb_charger *chg,
union power_supply_propval *val); union power_supply_propval *val);
int smblib_get_prop_typec_mode(struct smb_charger *chg,
union power_supply_propval *val);
int smblib_get_prop_typec_power_role(struct smb_charger *chg, int smblib_get_prop_typec_power_role(struct smb_charger *chg,
union power_supply_propval *val); union power_supply_propval *val);
int smblib_get_prop_pd_allowed(struct smb_charger *chg, int smblib_get_prop_pd_allowed(struct smb_charger *chg,

View file

@ -486,11 +486,11 @@ enum {
#define UFP_TYPEC_OPEN_OPEN_BIT BIT(0) #define UFP_TYPEC_OPEN_OPEN_BIT BIT(0)
#define TYPE_C_STATUS_2_REG (USBIN_BASE + 0x0C) #define TYPE_C_STATUS_2_REG (USBIN_BASE + 0x0C)
#define DFP_TYPEC_MASK 0x8F
#define DFP_RA_OPEN_BIT BIT(7) #define DFP_RA_OPEN_BIT BIT(7)
#define TIMER_STAGE_BIT BIT(6) #define TIMER_STAGE_BIT BIT(6)
#define EXIT_UFP_MODE_BIT BIT(5) #define EXIT_UFP_MODE_BIT BIT(5)
#define EXIT_DFP_MODE_BIT BIT(4) #define EXIT_DFP_MODE_BIT BIT(4)
#define DFP_TYPEC_MASK GENMASK(3, 0)
#define DFP_RD_OPEN_BIT BIT(3) #define DFP_RD_OPEN_BIT BIT(3)
#define DFP_RD_RA_VCONN_BIT BIT(2) #define DFP_RD_RA_VCONN_BIT BIT(2)
#define DFP_RD_RD_BIT BIT(1) #define DFP_RD_RD_BIT BIT(1)

View file

@ -248,7 +248,7 @@ static int smb138x_usb_get_prop(struct power_supply *psy,
val->intval = chg->usb_psy_desc.type; val->intval = chg->usb_psy_desc.type;
break; break;
case POWER_SUPPLY_PROP_TYPEC_MODE: case POWER_SUPPLY_PROP_TYPEC_MODE:
rc = smblib_get_prop_typec_mode(chg, val); val->intval = chg->typec_mode;
break; break;
case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE: case POWER_SUPPLY_PROP_TYPEC_POWER_ROLE:
rc = smblib_get_prop_typec_power_role(chg, val); rc = smblib_get_prop_typec_power_role(chg, val);