Loading sound/soc/codecs/wsa881x.c +73 −2 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ struct wsa881x_priv { bool comp_enable; bool boost_enable; bool visense_enable; u8 pa_gain; struct swr_port port[WSA881X_MAX_SWR_PORTS]; int pd_gpio; struct wsa881x_tz_priv tz_pdata; Loading Loading @@ -132,6 +133,47 @@ static unsigned int devnum; static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, bool enable); static const char * const wsa_pa_gain_text[] = { "G_18_DB", "G_16P5_DB", "G_15_DB", "G_13P5_DB", "G_12_DB", "G_10P5_DB", "G_9_DB", "G_7P5_DB", "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", "G_0_DB" }; static const struct soc_enum wsa_pa_gain_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa_pa_gain_text), wsa_pa_gain_text); static int wsa_pa_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = wsa881x->pa_gain; dev_dbg(codec->dev, "%s: PA gain = 0x%x\n", __func__, wsa881x->pa_gain); return 0; } static int wsa_pa_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); wsa881x->pa_gain = ucontrol->value.integer.value[0]; return 0; } static const struct snd_kcontrol_new wsa_analog_gain_controls[] = { SOC_ENUM_EXT("WSA PA Gain", wsa_pa_gain_enum, wsa_pa_gain_get, wsa_pa_gain_put), }; static int codec_debug_open(struct inode *inode, struct file *file) { file->private_data = inode->i_private; Loading Loading @@ -795,6 +837,7 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, { struct snd_soc_codec *codec = w->codec; struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); int min_gain, max_gain; dev_dbg(codec->dev, "%s: %s %d\n", __func__, w->name, event); switch (event) { Loading @@ -811,16 +854,33 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, swr_slvdev_datapath_control(wsa881x->swr_slave, wsa881x->swr_slave->dev_num, true); /* Set register mode if compander is not enabled */ if (!wsa881x->comp_enable) snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, 0x08, 0x08); else snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, 0x08, 0x00); break; case SND_SOC_DAPM_POST_PMU: if (WSA881X_IS_2_0(wsa881x->version)) { if (!wsa881x->comp_enable) { max_gain = wsa881x->pa_gain; /* * Gain has to set incrementally in 4 steps * as per HW sequence */ if (max_gain > G_4P5DB) min_gain = G_0DB; else min_gain = max_gain + 3; /* * 1ms delay is needed before change in gain * as per HW requirement. */ usleep_range(1000, 1010); wsa881x_ramp_pa_gain(codec, G_13P5DB, G_18DB, wsa881x_ramp_pa_gain(codec, min_gain, max_gain, 1000); } } else { Loading @@ -833,12 +893,21 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, wsa881x_post_pmu_pa, ARRAY_SIZE(wsa881x_post_pmu_pa)); if (!wsa881x->comp_enable) { max_gain = wsa881x->pa_gain; /* * Gain has to set incrementally in 4 steps * as per HW sequence */ if (max_gain > G_4P5DB) min_gain = G_0DB; else min_gain = max_gain + 3; /* * 1ms delay is needed before change in gain * as per HW requirement. */ usleep_range(1000, 1010); wsa881x_ramp_pa_gain(codec, G_12DB, G_13P5DB, wsa881x_ramp_pa_gain(codec, min_gain, max_gain, 1000); } snd_soc_update_bits(codec, WSA881X_ADC_SEL_IBIAS, Loading Loading @@ -1064,6 +1133,8 @@ static int wsa881x_probe(struct snd_soc_codec *codec) wsa881x->tz_pdata.codec = codec; wsa881x->tz_pdata.wsa_temp_reg_read = wsa881x_temp_reg_read; wsa881x_init_thermal(&wsa881x->tz_pdata); snd_soc_add_codec_controls(codec, wsa_analog_gain_controls, ARRAY_SIZE(wsa_analog_gain_controls)); INIT_DELAYED_WORK(&wsa881x->ocp_ctl_work, wsa881x_ocp_ctl_work); return 0; } Loading Loading
sound/soc/codecs/wsa881x.c +73 −2 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ struct wsa881x_priv { bool comp_enable; bool boost_enable; bool visense_enable; u8 pa_gain; struct swr_port port[WSA881X_MAX_SWR_PORTS]; int pd_gpio; struct wsa881x_tz_priv tz_pdata; Loading Loading @@ -132,6 +133,47 @@ static unsigned int devnum; static int32_t wsa881x_resource_acquire(struct snd_soc_codec *codec, bool enable); static const char * const wsa_pa_gain_text[] = { "G_18_DB", "G_16P5_DB", "G_15_DB", "G_13P5_DB", "G_12_DB", "G_10P5_DB", "G_9_DB", "G_7P5_DB", "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB", "G_0_DB" }; static const struct soc_enum wsa_pa_gain_enum = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wsa_pa_gain_text), wsa_pa_gain_text); static int wsa_pa_gain_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); ucontrol->value.integer.value[0] = wsa881x->pa_gain; dev_dbg(codec->dev, "%s: PA gain = 0x%x\n", __func__, wsa881x->pa_gain); return 0; } static int wsa_pa_gain_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n", __func__, ucontrol->value.integer.value[0]); wsa881x->pa_gain = ucontrol->value.integer.value[0]; return 0; } static const struct snd_kcontrol_new wsa_analog_gain_controls[] = { SOC_ENUM_EXT("WSA PA Gain", wsa_pa_gain_enum, wsa_pa_gain_get, wsa_pa_gain_put), }; static int codec_debug_open(struct inode *inode, struct file *file) { file->private_data = inode->i_private; Loading Loading @@ -795,6 +837,7 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, { struct snd_soc_codec *codec = w->codec; struct wsa881x_priv *wsa881x = snd_soc_codec_get_drvdata(codec); int min_gain, max_gain; dev_dbg(codec->dev, "%s: %s %d\n", __func__, w->name, event); switch (event) { Loading @@ -811,16 +854,33 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, swr_slvdev_datapath_control(wsa881x->swr_slave, wsa881x->swr_slave->dev_num, true); /* Set register mode if compander is not enabled */ if (!wsa881x->comp_enable) snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, 0x08, 0x08); else snd_soc_update_bits(codec, WSA881X_SPKR_DRV_GAIN, 0x08, 0x00); break; case SND_SOC_DAPM_POST_PMU: if (WSA881X_IS_2_0(wsa881x->version)) { if (!wsa881x->comp_enable) { max_gain = wsa881x->pa_gain; /* * Gain has to set incrementally in 4 steps * as per HW sequence */ if (max_gain > G_4P5DB) min_gain = G_0DB; else min_gain = max_gain + 3; /* * 1ms delay is needed before change in gain * as per HW requirement. */ usleep_range(1000, 1010); wsa881x_ramp_pa_gain(codec, G_13P5DB, G_18DB, wsa881x_ramp_pa_gain(codec, min_gain, max_gain, 1000); } } else { Loading @@ -833,12 +893,21 @@ static int wsa881x_spkr_pa_event(struct snd_soc_dapm_widget *w, wsa881x_post_pmu_pa, ARRAY_SIZE(wsa881x_post_pmu_pa)); if (!wsa881x->comp_enable) { max_gain = wsa881x->pa_gain; /* * Gain has to set incrementally in 4 steps * as per HW sequence */ if (max_gain > G_4P5DB) min_gain = G_0DB; else min_gain = max_gain + 3; /* * 1ms delay is needed before change in gain * as per HW requirement. */ usleep_range(1000, 1010); wsa881x_ramp_pa_gain(codec, G_12DB, G_13P5DB, wsa881x_ramp_pa_gain(codec, min_gain, max_gain, 1000); } snd_soc_update_bits(codec, WSA881X_ADC_SEL_IBIAS, Loading Loading @@ -1064,6 +1133,8 @@ static int wsa881x_probe(struct snd_soc_codec *codec) wsa881x->tz_pdata.codec = codec; wsa881x->tz_pdata.wsa_temp_reg_read = wsa881x_temp_reg_read; wsa881x_init_thermal(&wsa881x->tz_pdata); snd_soc_add_codec_controls(codec, wsa_analog_gain_controls, ARRAY_SIZE(wsa_analog_gain_controls)); INIT_DELAYED_WORK(&wsa881x->ocp_ctl_work, wsa881x_ocp_ctl_work); return 0; } Loading