ASoC: WCD9335: important changes on tasha codec
Following commit ID's are propagated with this gerrit. I3e3980e48ce19955b4230876887adfde5b44e8ea I48b24d81e2047d4d4c299ca60cdbd299e172393e Iae361cabf7b5194e12f5ddc8e32d60cf94bf28c3 I8b3271ee9af91b9e921957998e0fb074ffdebe86 I562f17363d7d38caece358a50d1e3f654d87491f Change-Id: I1b8610f8333b91be5e2bf9ecacf916d4b25d3f54 Signed-off-by: Santosh Mardi <gsantosh@codeaurora.org>
This commit is contained in:
parent
2a015e8412
commit
6c21d6ca04
|
@ -113,7 +113,7 @@
|
|||
/* Convert from vout ctl to micbias voltage in mV */
|
||||
#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
|
||||
|
||||
#define TASHA_ZDET_NUM_MEASUREMENTS 60
|
||||
#define TASHA_ZDET_NUM_MEASUREMENTS 150
|
||||
#define TASHA_MBHC_GET_C1(c) ((c & 0xC000) >> 14)
|
||||
#define TASHA_MBHC_GET_X1(x) (x & 0x3FFF)
|
||||
/* z value compared in milliOhm */
|
||||
|
@ -142,6 +142,12 @@ MODULE_PARM_DESC(tasha_cpe_debug_mode, "tasha boot cpe in debug mode");
|
|||
|
||||
#define TASHA_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000)
|
||||
|
||||
#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64
|
||||
|
||||
static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = {
|
||||
"cdc-vdd-mic-bias",
|
||||
};
|
||||
|
||||
enum {
|
||||
POWER_COLLAPSE,
|
||||
POWER_RESUME,
|
||||
|
@ -346,6 +352,7 @@ enum {
|
|||
AIF2_CAP,
|
||||
AIF3_PB,
|
||||
AIF3_CAP,
|
||||
AIF4_PB,
|
||||
AIF_MIX1_PB,
|
||||
AIF4_MAD_TX,
|
||||
AIF4_VIFEED,
|
||||
|
@ -463,6 +470,7 @@ static const u32 vport_slim_check_table[NUM_CODEC_DAIS] = {
|
|||
BIT(AIF1_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX), /* AIF2_CAP */
|
||||
0, /* AIF3_PB */
|
||||
BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF4_MAD_TX), /* AIF3_CAP */
|
||||
0, /* AIF4_PB */
|
||||
0, /* AIF_MIX1_PB */
|
||||
BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF3_CAP), /* AIF4_MAD_TX */
|
||||
};
|
||||
|
@ -762,6 +770,8 @@ struct tasha_priv {
|
|||
int power_active_ref;
|
||||
int (*zdet_gpio_cb)(struct snd_soc_codec *codec, bool high);
|
||||
|
||||
struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX];
|
||||
|
||||
int (*machine_codec_event_cb)(struct snd_soc_codec *codec,
|
||||
enum wcd9335_codec_event);
|
||||
struct snd_info_entry *entry;
|
||||
|
@ -1275,6 +1285,53 @@ static void tasha_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec,
|
|||
0xC0, 0x40);
|
||||
}
|
||||
|
||||
static int tasha_enable_ext_mb_source(struct snd_soc_codec *codec,
|
||||
bool turn_on)
|
||||
{
|
||||
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
|
||||
int ret = 0;
|
||||
struct on_demand_supply *supply;
|
||||
|
||||
if (!tasha)
|
||||
return -EINVAL;
|
||||
|
||||
supply = &tasha->on_demand_list[ON_DEMAND_MICBIAS];
|
||||
if (!supply->supply) {
|
||||
dev_dbg(codec->dev, "%s: warning supply not present ond for %s\n",
|
||||
__func__, "onDemand Micbias");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on,
|
||||
supply->ondemand_supply_count);
|
||||
|
||||
if (turn_on) {
|
||||
if (!(supply->ondemand_supply_count)) {
|
||||
ret = snd_soc_dapm_force_enable_pin(&codec->dapm,
|
||||
"MICBIAS_REGULATOR");
|
||||
snd_soc_dapm_sync(&codec->dapm);
|
||||
}
|
||||
supply->ondemand_supply_count++;
|
||||
} else {
|
||||
if (supply->ondemand_supply_count > 0)
|
||||
supply->ondemand_supply_count--;
|
||||
if (!(supply->ondemand_supply_count)) {
|
||||
ret = snd_soc_dapm_disable_pin(&codec->dapm,
|
||||
"MICBIAS_REGULATOR");
|
||||
snd_soc_dapm_sync(&codec->dapm);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
dev_err(codec->dev, "%s: Failed to %s external micbias source\n",
|
||||
__func__, turn_on ? "enable" : "disabled");
|
||||
else
|
||||
dev_dbg(codec->dev, "%s: %s external micbias source\n",
|
||||
__func__, turn_on ? "Enabled" : "Disabled");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tasha_micbias_control(struct snd_soc_codec *codec,
|
||||
int micb_num,
|
||||
int req, bool is_dapm)
|
||||
|
@ -1548,11 +1605,15 @@ static inline void tasha_mbhc_get_result_params(struct wcd9xxx *wcd9xxx,
|
|||
WCD9335_ANA_MBHC_ZDET, 0x20, 0x00);
|
||||
x1 = TASHA_MBHC_GET_X1(val);
|
||||
c1 = TASHA_MBHC_GET_C1(val);
|
||||
/* If ramp is not complete, give additional 5ms */
|
||||
if ((c1 < 2) && x1)
|
||||
usleep_range(5000, 5050);
|
||||
|
||||
if (!c1 || !x1) {
|
||||
dev_dbg(wcd9xxx->dev,
|
||||
"%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
|
||||
__func__, c1, x1);
|
||||
return;
|
||||
goto ramp_down;
|
||||
}
|
||||
d1 = d1_a[c1];
|
||||
denom = (x1 * d1) - (1 << (14 - noff));
|
||||
|
@ -1563,6 +1624,7 @@ static inline void tasha_mbhc_get_result_params(struct wcd9xxx *wcd9xxx,
|
|||
|
||||
dev_dbg(wcd9xxx->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n",
|
||||
__func__, d1, c1, x1, *zdet);
|
||||
ramp_down:
|
||||
i = 0;
|
||||
while (x1) {
|
||||
wcd9xxx_bulk_read(&wcd9xxx->core_res,
|
||||
|
@ -1677,7 +1739,7 @@ static void tasha_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
|
|||
bool is_change = false;
|
||||
struct tasha_mbhc_zdet_param zdet_param[] = {
|
||||
{4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
|
||||
{1, 0, 2, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
|
||||
{2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
|
||||
{1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
|
||||
{1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
|
||||
};
|
||||
|
@ -1896,6 +1958,7 @@ static const struct wcd_mbhc_cb mbhc_cb = {
|
|||
.free_irq = tasha_mbhc_free_irq,
|
||||
.clk_setup = tasha_mbhc_clk_setup,
|
||||
.map_btn_code_to_num = tasha_mbhc_btn_to_num,
|
||||
.enable_mb_source = tasha_enable_ext_mb_source,
|
||||
.mbhc_bias = tasha_mbhc_mbhc_bias_control,
|
||||
.set_btn_thr = tasha_mbhc_program_btn_thr,
|
||||
.lock_sleep = tasha_mbhc_lock_sleep,
|
||||
|
@ -2266,7 +2329,7 @@ static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
|
|||
}
|
||||
|
||||
static const char *const slim_rx_mux_text[] = {
|
||||
"ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF_MIX1_PB"
|
||||
"ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB", "AIF_MIX1_PB"
|
||||
};
|
||||
|
||||
static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
|
||||
|
@ -2335,6 +2398,17 @@ static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
|
|||
&tasha_p->dai[AIF3_PB].wcd9xxx_ch_list);
|
||||
break;
|
||||
case 4:
|
||||
if (wcd9xxx_rx_vport_validation(port_id +
|
||||
TASHA_RX_PORT_START_NUMBER,
|
||||
&tasha_p->dai[AIF4_PB].wcd9xxx_ch_list)) {
|
||||
dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
|
||||
__func__, port_id);
|
||||
goto rtn;
|
||||
}
|
||||
list_add_tail(&core->rx_chs[port_id].list,
|
||||
&tasha_p->dai[AIF4_PB].wcd9xxx_ch_list);
|
||||
break;
|
||||
case 5:
|
||||
if (wcd9xxx_rx_vport_validation(port_id +
|
||||
TASHA_RX_PORT_START_NUMBER,
|
||||
&tasha_p->dai[AIF_MIX1_PB].wcd9xxx_ch_list)) {
|
||||
|
@ -4847,6 +4921,57 @@ static int tasha_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tasha_codec_enable_on_demand_supply(
|
||||
struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
int ret = 0;
|
||||
struct snd_soc_codec *codec = w->codec;
|
||||
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
|
||||
struct on_demand_supply *supply;
|
||||
|
||||
if (w->shift >= ON_DEMAND_SUPPLIES_MAX) {
|
||||
dev_err(codec->dev, "%s: error index > MAX Demand supplies",
|
||||
__func__);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev_dbg(codec->dev, "%s: supply: %s event: %d\n",
|
||||
__func__, on_demand_supply_name[w->shift], event);
|
||||
|
||||
supply = &tasha->on_demand_list[w->shift];
|
||||
WARN_ONCE(!supply->supply, "%s isn't defined\n",
|
||||
on_demand_supply_name[w->shift]);
|
||||
if (!supply->supply) {
|
||||
dev_err(codec->dev, "%s: err supply not present ond for %d",
|
||||
__func__, w->shift);
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
ret = regulator_enable(supply->supply);
|
||||
if (ret)
|
||||
dev_err(codec->dev, "%s: Failed to enable %s\n",
|
||||
__func__,
|
||||
on_demand_supply_name[w->shift]);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
ret = regulator_disable(supply->supply);
|
||||
if (ret)
|
||||
dev_err(codec->dev, "%s: Failed to disable %s\n",
|
||||
__func__,
|
||||
on_demand_supply_name[w->shift]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tasha_codec_find_amic_input(struct snd_soc_codec *codec,
|
||||
int adc_mux_n)
|
||||
{
|
||||
|
@ -6243,6 +6368,15 @@ static const struct snd_soc_dapm_route audio_map[] = {
|
|||
{"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
|
||||
{"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
|
||||
{"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
|
||||
/* SLIM_MUX("AIF4_PB", "AIF4 PB"),*/
|
||||
{"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"},
|
||||
{"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"},
|
||||
{"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"},
|
||||
{"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"},
|
||||
{"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"},
|
||||
{"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"},
|
||||
{"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"},
|
||||
{"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"},
|
||||
|
||||
/* SLIM_MUX("AIF_MIX1_PB", "AIF MIX1 PB"),*/
|
||||
{"SLIM RX0 MUX", "AIF_MIX1_PB", "AIF MIX1 PB"},
|
||||
|
@ -8089,6 +8223,14 @@ static const struct snd_kcontrol_new tasha_analog_gain_controls[] = {
|
|||
line_gain),
|
||||
SOC_SINGLE_TLV("HPHR Volume", WCD9335_HPH_R_EN, 0, 20, 1,
|
||||
line_gain),
|
||||
SOC_SINGLE_TLV("LINEOUT1 Volume", WCD9335_DIFF_LO_LO1_COMPANDER,
|
||||
3, 16, 1, line_gain),
|
||||
SOC_SINGLE_TLV("LINEOUT2 Volume", WCD9335_DIFF_LO_LO2_COMPANDER,
|
||||
3, 16, 1, line_gain),
|
||||
SOC_SINGLE_TLV("LINEOUT3 Volume", WCD9335_SE_LO_LO3_GAIN, 0, 20, 1,
|
||||
line_gain),
|
||||
SOC_SINGLE_TLV("LINEOUT4 Volume", WCD9335_SE_LO_LO4_GAIN, 0, 20, 1,
|
||||
line_gain),
|
||||
|
||||
SOC_SINGLE_TLV("ADC1 Volume", WCD9335_ANA_AMIC1, 0, 20, 0,
|
||||
analog_gain),
|
||||
|
@ -9296,6 +9438,9 @@ static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
|
||||
AIF3_PB, 0, tasha_codec_enable_slimrx,
|
||||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM,
|
||||
AIF4_PB, 0, tasha_codec_enable_slimrx,
|
||||
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_AIF_IN_E("AIF MIX1 PB", "AIF Mix Playback", 0,
|
||||
SND_SOC_NOPM, AIF_MIX1_PB, 0,
|
||||
tasha_codec_enable_slimrx,
|
||||
|
@ -9966,6 +10111,10 @@ static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_OUTPUT("LINEOUT4"),
|
||||
SND_SOC_DAPM_OUTPUT("ANC LINEOUT1"),
|
||||
SND_SOC_DAPM_OUTPUT("ANC LINEOUT2"),
|
||||
SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM,
|
||||
ON_DEMAND_MICBIAS, 0,
|
||||
tasha_codec_enable_on_demand_supply,
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
|
||||
|
||||
SND_SOC_DAPM_SWITCH("ADC US MUX0", WCD9335_CDC_TX0_TX_PATH_192_CTL, 0,
|
||||
0, &adc_us_mux0_switch),
|
||||
|
@ -10025,6 +10174,7 @@ static int tasha_get_channel_map(struct snd_soc_dai *dai,
|
|||
case AIF1_PB:
|
||||
case AIF2_PB:
|
||||
case AIF3_PB:
|
||||
case AIF4_PB:
|
||||
case AIF_MIX1_PB:
|
||||
if (!rx_slot || !rx_num) {
|
||||
pr_err("%s: Invalid rx_slot %p or rx_num %p\n",
|
||||
|
@ -10575,6 +10725,20 @@ static struct snd_soc_dai_driver tasha_dai[] = {
|
|||
},
|
||||
.ops = &tasha_dai_ops,
|
||||
},
|
||||
{
|
||||
.name = "tasha_rx4",
|
||||
.id = AIF4_PB,
|
||||
.playback = {
|
||||
.stream_name = "AIF4 Playback",
|
||||
.rates = WCD9335_RATES_MASK | WCD9335_FRAC_RATES_MASK,
|
||||
.formats = TASHA_FORMATS_S16_S24_LE,
|
||||
.rate_min = 8000,
|
||||
.rate_max = 192000,
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
},
|
||||
.ops = &tasha_dai_ops,
|
||||
},
|
||||
{
|
||||
.name = "tasha_mix_rx1",
|
||||
.id = AIF_MIX1_PB,
|
||||
|
@ -11998,6 +12162,26 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct regulator *tasha_codec_find_ondemand_regulator(
|
||||
struct snd_soc_codec *codec, const char *name)
|
||||
{
|
||||
int i;
|
||||
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
|
||||
struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
|
||||
struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
|
||||
|
||||
for (i = 0; i < wcd9xxx->num_of_supplies; ++i) {
|
||||
if (pdata->regulator[i].ondemand &&
|
||||
wcd9xxx->supplies[i].supply &&
|
||||
!strcmp(wcd9xxx->supplies[i].supply, name))
|
||||
return wcd9xxx->supplies[i].consumer;
|
||||
}
|
||||
|
||||
dev_dbg(tasha->dev, "Warning: regulator not found:%s\n",
|
||||
name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int tasha_codec_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct wcd9xxx *control;
|
||||
|
@ -12007,6 +12191,7 @@ static int tasha_codec_probe(struct snd_soc_codec *codec)
|
|||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
int i, ret;
|
||||
void *ptr = NULL;
|
||||
struct regulator *supply;
|
||||
|
||||
control = dev_get_drvdata(codec->dev->parent);
|
||||
codec->control_data = control->regmap;
|
||||
|
@ -12060,6 +12245,14 @@ static int tasha_codec_probe(struct snd_soc_codec *codec)
|
|||
goto err;
|
||||
}
|
||||
|
||||
supply = tasha_codec_find_ondemand_regulator(codec,
|
||||
on_demand_supply_name[ON_DEMAND_MICBIAS]);
|
||||
if (supply) {
|
||||
tasha->on_demand_list[ON_DEMAND_MICBIAS].supply = supply;
|
||||
tasha->on_demand_list[ON_DEMAND_MICBIAS].ondemand_supply_count =
|
||||
0;
|
||||
}
|
||||
|
||||
tasha->fw_data = devm_kzalloc(codec->dev,
|
||||
sizeof(*(tasha->fw_data)), GFP_KERNEL);
|
||||
if (!tasha->fw_data) {
|
||||
|
|
Loading…
Reference in New Issue