wcd939x-usbss: Reset surge CPLDO control register and update pwr mode
1. Reset the CPLDO control register in case a negative surge event has occurred. 2. Cache power mode and update at the time of usecase setup. Change-Id: Ib6060715bd92d743591b62f30da6e4cac5fbcb66 Signed-off-by: Sam Rainey <quic_rainey@quicinc.com> Signed-off-by: Prasad Kumpatla <quic_pkumpatl@quicinc.com>
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||||
*/
|
*/
|
||||||
#ifndef WCD_USBSS_PRIV_H
|
#ifndef WCD_USBSS_PRIV_H
|
||||||
#define WCD_USBSS_PRIV_H
|
#define WCD_USBSS_PRIV_H
|
||||||
@ -41,6 +41,7 @@ struct wcd_usbss_ctxt {
|
|||||||
struct kobject *surge_kobject;
|
struct kobject *surge_kobject;
|
||||||
struct task_struct *surge_thread;
|
struct task_struct *surge_thread;
|
||||||
unsigned int surge_timer_period_ms;
|
unsigned int surge_timer_period_ms;
|
||||||
|
unsigned int cached_audio_pwr_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct regmap *wcd_usbss_regmap_init(struct device *dev,
|
extern struct regmap *wcd_usbss_regmap_init(struct device *dev,
|
||||||
|
@ -81,7 +81,7 @@ static struct kobj_attribute wcd_usbss_surge_period_attribute =
|
|||||||
* 3. Register 0x06 Bit<0> reads 1 after toggling
|
* 3. Register 0x06 Bit<0> reads 1 after toggling
|
||||||
* register WCD_USBSS_PMP_MISC1 Bit<0> from 0 --> 1 --> 0
|
* register WCD_USBSS_PMP_MISC1 Bit<0> from 0 --> 1 --> 0
|
||||||
*
|
*
|
||||||
* Returns true if all checks fails (indicates OVP and reset needed), false otherwise
|
* Returns true if any checks fail (indicates OVP and reset needed), false otherwise
|
||||||
*/
|
*/
|
||||||
static bool wcd_usbss_is_in_reset_state(void)
|
static bool wcd_usbss_is_in_reset_state(void)
|
||||||
{
|
{
|
||||||
@ -90,14 +90,16 @@ static bool wcd_usbss_is_in_reset_state(void)
|
|||||||
|
|
||||||
/* Check 1: Read WCD_USBSS_CPLDO_CTL2 */
|
/* Check 1: Read WCD_USBSS_CPLDO_CTL2 */
|
||||||
regmap_read(wcd_usbss_ctxt_->regmap, WCD_USBSS_CPLDO_CTL2, &read_val);
|
regmap_read(wcd_usbss_ctxt_->regmap, WCD_USBSS_CPLDO_CTL2, &read_val);
|
||||||
if (read_val == 0xFF)
|
if (read_val != 0xFF)
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
/* Check 2: Read WCD_USBSS_RCO_MISC2 */
|
/* Check 2: Read WCD_USBSS_RCO_MISC2 */
|
||||||
for (i = 0; i < NUM_RCO_MISC2_READ; i++) {
|
for (i = 0; i < NUM_RCO_MISC2_READ; i++) {
|
||||||
regmap_read(wcd_usbss_ctxt_->regmap, WCD_USBSS_RCO_MISC2, &read_val);
|
regmap_read(wcd_usbss_ctxt_->regmap, WCD_USBSS_RCO_MISC2, &read_val);
|
||||||
if ((read_val & 0x2) == 0)
|
if ((read_val & 0x2) == 0)
|
||||||
return false;
|
break;
|
||||||
|
if (i == (NUM_RCO_MISC2_READ - 1))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Toggle WCD_USBSS_PMP_MISC1 bit<0>: 0 --> 1 --> 0 */
|
/* Toggle WCD_USBSS_PMP_MISC1 bit<0>: 0 --> 1 --> 0 */
|
||||||
@ -107,11 +109,11 @@ static bool wcd_usbss_is_in_reset_state(void)
|
|||||||
|
|
||||||
/* Check 3: Read WCD_USBSS_PMP_MISC2 */
|
/* Check 3: Read WCD_USBSS_PMP_MISC2 */
|
||||||
regmap_read(wcd_usbss_ctxt_->regmap, WCD_USBSS_PMP_MISC2, &read_val);
|
regmap_read(wcd_usbss_ctxt_->regmap, WCD_USBSS_PMP_MISC2, &read_val);
|
||||||
if (read_val & 0x1)
|
if ((read_val & 0x1) == 0)
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
/* All checks failed, so a reset has occurred, and return true */
|
/* All checks passed, so a reset has not occurred */
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -124,7 +126,11 @@ static int wcd_usbss_reset_routine(void)
|
|||||||
/* Mark the cache as dirty to force a flush */
|
/* Mark the cache as dirty to force a flush */
|
||||||
regcache_mark_dirty(wcd_usbss_ctxt_->regmap);
|
regcache_mark_dirty(wcd_usbss_ctxt_->regmap);
|
||||||
regcache_sync(wcd_usbss_ctxt_->regmap);
|
regcache_sync(wcd_usbss_ctxt_->regmap);
|
||||||
|
/* Write 0xFF to WCD_USBSS_CPLDO_CTL2 */
|
||||||
|
regmap_update_bits(wcd_usbss_ctxt_->regmap, WCD_USBSS_CPLDO_CTL2, 0xFF, 0xFF);
|
||||||
|
/* Set RCO_EN: WCD_USBSS_USB_SS_CNTL Bit<3> --> 0x0 --> 0x1 */
|
||||||
|
regmap_update_bits(wcd_usbss_ctxt_->regmap, WCD_USBSS_USB_SS_CNTL, 0x8, 0x0);
|
||||||
|
regmap_update_bits(wcd_usbss_ctxt_->regmap, WCD_USBSS_USB_SS_CNTL, 0x8, 0x8);
|
||||||
return wcd_usbss_switch_update(wcd_usbss_ctxt_->cable_type, wcd_usbss_ctxt_->cable_status);
|
return wcd_usbss_switch_update(wcd_usbss_ctxt_->cable_type, wcd_usbss_ctxt_->cable_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,6 +383,7 @@ static int wcd_usbss_switch_update_defaults(struct wcd_usbss_ctxt *priv)
|
|||||||
/* Disable Equalizer */
|
/* Disable Equalizer */
|
||||||
regmap_update_bits(priv->regmap, WCD_USBSS_EQUALIZER1,
|
regmap_update_bits(priv->regmap, WCD_USBSS_EQUALIZER1,
|
||||||
WCD_USBSS_EQUALIZER1_EQ_EN_MASK, 0x00);
|
WCD_USBSS_EQUALIZER1_EQ_EN_MASK, 0x00);
|
||||||
|
regmap_update_bits(priv->regmap, WCD_USBSS_USB_SS_CNTL, 0x07, 0x05); /* Mode5: USB*/
|
||||||
/* Once plug-out done, restore to MANUAL mode */
|
/* Once plug-out done, restore to MANUAL mode */
|
||||||
audio_fsm_mode = WCD_USBSS_AUDIO_MANUAL;
|
audio_fsm_mode = WCD_USBSS_AUDIO_MANUAL;
|
||||||
return 0;
|
return 0;
|
||||||
@ -384,8 +391,6 @@ static int wcd_usbss_switch_update_defaults(struct wcd_usbss_ctxt *priv)
|
|||||||
|
|
||||||
static void wcd_usbss_update_reg_init(struct regmap *regmap)
|
static void wcd_usbss_update_reg_init(struct regmap *regmap)
|
||||||
{
|
{
|
||||||
/* update Register Power On Reset values (if any) */
|
|
||||||
regmap_update_bits(regmap, WCD_USBSS_USB_SS_CNTL, 0x07, 0x02); /*Mode2*/
|
|
||||||
if (audio_fsm_mode == WCD_USBSS_AUDIO_FSM)
|
if (audio_fsm_mode == WCD_USBSS_AUDIO_FSM)
|
||||||
regmap_update_bits(regmap, WCD_USBSS_FUNCTION_ENABLE, 0x03,
|
regmap_update_bits(regmap, WCD_USBSS_FUNCTION_ENABLE, 0x03,
|
||||||
0x02); /* AUDIO_FSM mode */
|
0x02); /* AUDIO_FSM mode */
|
||||||
@ -510,9 +515,15 @@ int wcd_usbss_audio_config(bool enable, enum wcd_usbss_config_type config_type,
|
|||||||
|
|
||||||
switch (config_type) {
|
switch (config_type) {
|
||||||
case WCD_USBSS_CONFIG_TYPE_POWER_MODE:
|
case WCD_USBSS_CONFIG_TYPE_POWER_MODE:
|
||||||
/* Configure power mode from RX HPH mixer ctl */
|
|
||||||
regmap_update_bits(wcd_usbss_ctxt_->regmap,
|
/* Configure power mode from RX HPH mixer ctl if AATC cable is connected */
|
||||||
|
if (wcd_usbss_ctxt_->cable_status == WCD_USBSS_CABLE_CONNECT &&
|
||||||
|
(wcd_usbss_ctxt_->cable_type == WCD_USBSS_AATC ||
|
||||||
|
wcd_usbss_ctxt_->cable_type == WCD_USBSS_GND_MIC_SWAP_AATC ||
|
||||||
|
wcd_usbss_ctxt_->cable_type == WCD_USBSS_HSJ_CONNECT))
|
||||||
|
regmap_update_bits(wcd_usbss_ctxt_->regmap,
|
||||||
WCD_USBSS_USB_SS_CNTL, 0x07, power_mode);
|
WCD_USBSS_USB_SS_CNTL, 0x07, power_mode);
|
||||||
|
wcd_usbss_ctxt_->cached_audio_pwr_mode = power_mode;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("%s Invalid config type %d\n", __func__, config_type);
|
pr_err("%s Invalid config type %d\n", __func__, config_type);
|
||||||
@ -555,6 +566,10 @@ int wcd_usbss_switch_update(enum wcd_usbss_cable_types ctype,
|
|||||||
wcd_usbss_dpdm_switch_update(true, true);
|
wcd_usbss_dpdm_switch_update(true, true);
|
||||||
break;
|
break;
|
||||||
case WCD_USBSS_AATC:
|
case WCD_USBSS_AATC:
|
||||||
|
/* Update power mode as per wcd mixer ctls */
|
||||||
|
regmap_update_bits(wcd_usbss_ctxt_->regmap,
|
||||||
|
WCD_USBSS_USB_SS_CNTL, 0x07,
|
||||||
|
wcd_usbss_ctxt_->cached_audio_pwr_mode);
|
||||||
/* for AATC plug-in, change mode to FSM */
|
/* for AATC plug-in, change mode to FSM */
|
||||||
audio_fsm_mode = WCD_USBSS_AUDIO_FSM;
|
audio_fsm_mode = WCD_USBSS_AUDIO_FSM;
|
||||||
/* Disable all switches */
|
/* Disable all switches */
|
||||||
@ -602,6 +617,9 @@ int wcd_usbss_switch_update(enum wcd_usbss_cable_types ctype,
|
|||||||
case WCD_USBSS_GND_MIC_SWAP_AATC:
|
case WCD_USBSS_GND_MIC_SWAP_AATC:
|
||||||
dev_info(wcd_usbss_ctxt_->dev,
|
dev_info(wcd_usbss_ctxt_->dev,
|
||||||
"%s: GND MIC Swap register updates..\n", __func__);
|
"%s: GND MIC Swap register updates..\n", __func__);
|
||||||
|
regmap_update_bits(wcd_usbss_ctxt_->regmap,
|
||||||
|
WCD_USBSS_USB_SS_CNTL, 0x07,
|
||||||
|
wcd_usbss_ctxt_->cached_audio_pwr_mode);
|
||||||
/* for GND MIC Swap, change mode to FSM */
|
/* for GND MIC Swap, change mode to FSM */
|
||||||
audio_fsm_mode = WCD_USBSS_AUDIO_FSM;
|
audio_fsm_mode = WCD_USBSS_AUDIO_FSM;
|
||||||
/* Disable all switches */
|
/* Disable all switches */
|
||||||
@ -629,6 +647,9 @@ int wcd_usbss_switch_update(enum wcd_usbss_cable_types ctype,
|
|||||||
WCD_USBSS_AUDIO_FSM_START, 0x01, 0x01, NULL, false, true);
|
WCD_USBSS_AUDIO_FSM_START, 0x01, 0x01, NULL, false, true);
|
||||||
break;
|
break;
|
||||||
case WCD_USBSS_HSJ_CONNECT:
|
case WCD_USBSS_HSJ_CONNECT:
|
||||||
|
regmap_update_bits(wcd_usbss_ctxt_->regmap,
|
||||||
|
WCD_USBSS_USB_SS_CNTL, 0x07,
|
||||||
|
wcd_usbss_ctxt_->cached_audio_pwr_mode);
|
||||||
/* Select MG2, GSBU1 */
|
/* Select MG2, GSBU1 */
|
||||||
regmap_update_bits(wcd_usbss_ctxt_->regmap,
|
regmap_update_bits(wcd_usbss_ctxt_->regmap,
|
||||||
WCD_USBSS_SWITCH_SELECT0, 0x03, 0x1);
|
WCD_USBSS_SWITCH_SELECT0, 0x03, 0x1);
|
||||||
|
Reference in New Issue
Block a user