static void madera_extcon_hp_clamp(struct madera_extcon *info, bool clamp)
{
struct madera *madera = info->madera;
- unsigned int mask = 0, val = 0;
- unsigned int edre_reg = 0, edre_val = 0;
- unsigned int ep_sel = 0;
+ unsigned int mask = 0, ep_mask = 0, val = 0;
int ret;
snd_soc_dapm_mutex_lock(madera->dapm);
switch (madera->type) {
case CS47L15:
case CS47L35:
- case CS47L92:
- case CS47L93:
- /*
- * check whether audio is routed to EPOUT, do not disable OUT1
- * in that case
- */
- regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel);
- ep_sel &= MADERA_EP_SEL_MASK;
- break;
- default:
- break;
- };
-
- switch (madera->type) {
- case CS47L35:
+ ep_mask = MADERA_EP_SEL_MASK;
break;
case CS47L85:
case WM1840:
- edre_reg = MADERA_EDRE_MANUAL;
- mask = MADERA_HP1L_SHRTO | MADERA_HP1L_FLWR | MADERA_HP1L_SHRTI;
- if (clamp) {
- val = MADERA_HP1L_SHRTO;
- edre_val = MADERA_EDRE_OUT1L_MANUAL |
- MADERA_EDRE_OUT1R_MANUAL;
- } else {
- val = MADERA_HP1L_FLWR | MADERA_HP1L_SHRTI;
- edre_val = 0;
- }
break;
default:
mask = MADERA_HPD_OVD_ENA_SEL_MASK;
- if (clamp)
+ if (!clamp)
val = MADERA_HPD_OVD_ENA_SEL_MASK;
else
val = 0;
madera->out_clamp[0] = clamp;
- /* Keep the HP output stages disabled while doing the clamp */
- if (clamp && !ep_sel) {
+ /* Keep the HP output stages disabled while disabling the clamp */
+ if (!clamp) {
ret = regmap_update_bits(madera->regmap,
MADERA_OUTPUT_ENABLES_1,
- (MADERA_OUT1L_ENA |
+ ep_mask |
+ ((MADERA_OUT1L_ENA |
MADERA_OUT1R_ENA) <<
- (2 * (info->pdata->output - 1)),
+ (2 * (info->pdata->output - 1))),
0);
if (ret)
dev_warn(info->dev,
ret);
}
- if (edre_reg && !ep_sel) {
- ret = regmap_update_bits(madera->regmap, edre_reg,
- MADERA_EDRE_OUT1L_MANUAL_MASK |
- MADERA_EDRE_OUT1R_MANUAL_MASK,
- edre_val);
- if (ret)
- dev_warn(info->dev,
- "Failed to set EDRE Manual: %d\n", ret);
- }
-
- dev_warn(info->dev, "%s clamp mask=0x%x val=0x%x\n",
+ dev_dbg(info->dev, "%s clamp mask=0x%x val=0x%x\n",
clamp ? "Setting" : "Clearing", mask, val);
switch (madera->type) {
case CS47L35:
- break;
case CS47L85:
case WM1840:
- ret = regmap_update_bits(madera->regmap,
- MADERA_HP_CTRL_1L, mask, val);
- if (ret)
- dev_warn(info->dev, "Failed to do clamp: %d\n", ret);
-
- ret = regmap_update_bits(madera->regmap,
- MADERA_HP_CTRL_1R, mask, val);
- if (ret)
- dev_warn(info->dev, "Failed to do clamp: %d\n", ret);
break;
default:
ret = regmap_update_bits(madera->regmap,
break;
}
- /* Restore the desired state while not doing the clamp */
- if (!clamp) {
+ /* Restore the desired state when restoring the clamp */
+ if (clamp) {
+ if (ep_mask) {
+ ret = regmap_update_bits(madera->regmap,
+ MADERA_OUTPUT_ENABLES_1,
+ ep_mask, madera->ep_sel);
+ if (ret)
+ dev_warn(info->dev,
+ "Failed to restore output demux: %d\n",
+ ret);
+ }
+
madera->out_shorted[0] = (madera->hp_impedance_x100[0] <=
info->hpdet_short_x100);
- if (!madera->out_shorted[0] && !ep_sel) {
+ if (!madera->out_shorted[0]) {
ret = regmap_update_bits(madera->regmap,
MADERA_OUTPUT_ENABLES_1,
(MADERA_OUT1L_ENA |
case CS47L35:
case CS47L85:
case WM1840:
- madera_extcon_hp_clamp(info, true);
+ madera_extcon_hp_clamp(info, false);
ret = regmap_update_bits(madera->regmap,
MADERA_ACCESSORY_DETECT_MODE_1,
MADERA_ACCDET_MODE_MASK,
"Failed to set HPDET sense: %d\n", ret);
goto err;
}
- madera_extcon_hp_clamp(info, true);
+ madera_extcon_hp_clamp(info, false);
madera_hpdet_start_micd(info);
break;
}
return 0;
err:
- madera_extcon_hp_clamp(info, false);
+ madera_extcon_hp_clamp(info, true);
pm_runtime_put_autosuspend(info->dev);
break;
}
- madera_extcon_hp_clamp(info, false);
+ madera_extcon_hp_clamp(info, true);
pm_runtime_mark_last_busy(info->dev);
pm_runtime_put_autosuspend(info->dev);
madera_extcon_set_micd_clamp_mode(info);
+ /*Since Invert the calmp was set, the calmp need to set true as init in case EPOUT will be mute */
+ madera->out_clamp[0]=true;
+
if ((info->num_micd_modes > 2) && !info->micd_pol_gpio)
dev_warn(info->dev, "Have >1 mic_configs but no pol_gpio\n");
snd_soc_dapm_kcontrol_dapm(kcontrol);
struct madera *madera = dev_get_drvdata(codec->dev->parent);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
- unsigned int ep_sel, mux, change;
- int ret, demux_change_ret;
+ unsigned int mux, change;
+ int ret, demux_change_ret = 0;
bool out_mono, restore_out = true;
if (ucontrol->value.enumerated.item[0] > e->items - 1)
return -EINVAL;
mux = ucontrol->value.enumerated.item[0];
- ep_sel = mux << MADERA_EP_SEL_SHIFT;
snd_soc_dapm_mutex_lock(dapm);
+ madera->ep_sel = mux << MADERA_EP_SEL_SHIFT;
+
change = snd_soc_test_bits(codec, MADERA_OUTPUT_ENABLES_1,
- MADERA_EP_SEL_MASK, ep_sel);
+ MADERA_EP_SEL_MASK, madera->ep_sel);
if (!change)
goto end;
usleep_range(2000, 3000); /* wait for wseq to complete */
/*
- * if HP detection clamp is applied while switching to HPOUT
- * OUT1 should remain disabled and EDRE should be set to manual
+ * if HPDET has disabled the clamp while switching to HPOUT
+ * OUT1 should remain disabled
*/
- if (!ep_sel &&
- (madera->out_clamp[0] || madera->out_shorted[0]))
+ if (!madera->ep_sel &&
+ (!madera->out_clamp[0] || madera->out_shorted[0]))
restore_out = false;
/* change demux setting */
- demux_change_ret = regmap_update_bits(madera->regmap,
- MADERA_OUTPUT_ENABLES_1,
- MADERA_EP_SEL_MASK, ep_sel);
+ if (madera->out_clamp[0])
+ demux_change_ret = regmap_update_bits(madera->regmap,
+ MADERA_OUTPUT_ENABLES_1,
+ MADERA_EP_SEL_MASK,
+ madera->ep_sel);
if (demux_change_ret) {
dev_err(madera->dev, "Failed to set OUT1 demux: %d\n",
demux_change_ret);
} else {
/* apply correct setting for mono mode */
- if (!ep_sel && !madera->pdata.codec.out_mono[0])
+ if (!madera->ep_sel && !madera->pdata.codec.out_mono[0])
out_mono = false; /* stereo HP */
else
out_mono = true; /* EP or mono HP */
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
- unsigned int val;
- val = snd_soc_read(codec, MADERA_OUTPUT_ENABLES_1);
- val &= MADERA_EP_SEL_MASK;
- val >>= MADERA_EP_SEL_SHIFT;
- ucontrol->value.enumerated.item[0] = val;
+ struct snd_soc_dapm_context *dapm =
+ snd_soc_dapm_kcontrol_dapm(kcontrol);
+ struct madera *madera = dev_get_drvdata(codec->dev->parent);
+
+ snd_soc_dapm_mutex_lock(dapm);
+ ucontrol->value.enumerated.item[0] = madera->ep_sel >> MADERA_EP_SEL_SHIFT;
+ snd_soc_dapm_mutex_unlock(dapm);
+
return 0;
}
EXPORT_SYMBOL_GPL(madera_out1_demux_get);
regmap_read(madera->regmap, MADERA_OUTPUT_ENABLES_1, &ep_sel);
ep_sel &= MADERA_EP_SEL_MASK;
- /* Force off if HPDET clamp is active for this output */
+ /* Force off if HPDET disabled the clamp for this output */
if (!ep_sel &&
- (madera->out_clamp[out_num] || madera->out_shorted[out_num]))
+ (!madera->out_clamp[out_num] || madera->out_shorted[out_num]))
val = 0;
regmap_update_bits(madera->regmap, MADERA_OUTPUT_ENABLES_1, mask, val);