Lines Matching +full:ramp +full:- +full:down
1 // SPDX-License-Identifier: GPL-2.0-only
3 * wm8350.c -- WM8350 ALSA SoC audio driver
5 * Copyright (C) 2007-12 Wolfson Microelectronics PLC.
48 u16 ramp; member
73 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown.
77 struct wm8350_output *out1 = &wm8350_data->out1; in wm8350_out1_ramp_step()
78 struct wm8350 *wm8350 = wm8350_data->wm8350; in wm8350_out1_ramp_step()
86 if (out1->ramp == WM8350_RAMP_UP) { in wm8350_out1_ramp_step()
87 /* ramp step up */ in wm8350_out1_ramp_step()
88 if (val < out1->left_vol) { in wm8350_out1_ramp_step()
95 } else if (out1->ramp == WM8350_RAMP_DOWN) { in wm8350_out1_ramp_step()
96 /* ramp step down */ in wm8350_out1_ramp_step()
98 val--; in wm8350_out1_ramp_step()
110 if (out1->ramp == WM8350_RAMP_UP) { in wm8350_out1_ramp_step()
111 /* ramp step up */ in wm8350_out1_ramp_step()
112 if (val < out1->right_vol) { in wm8350_out1_ramp_step()
119 } else if (out1->ramp == WM8350_RAMP_DOWN) { in wm8350_out1_ramp_step()
120 /* ramp step down */ in wm8350_out1_ramp_step()
122 val--; in wm8350_out1_ramp_step()
138 * Ramp OUT2 PGA volume to minimise pops at stream startup and shutdown.
142 struct wm8350_output *out2 = &wm8350_data->out2; in wm8350_out2_ramp_step()
143 struct wm8350 *wm8350 = wm8350_data->wm8350; in wm8350_out2_ramp_step()
150 if (out2->ramp == WM8350_RAMP_UP) { in wm8350_out2_ramp_step()
151 /* ramp step up */ in wm8350_out2_ramp_step()
152 if (val < out2->left_vol) { in wm8350_out2_ramp_step()
159 } else if (out2->ramp == WM8350_RAMP_DOWN) { in wm8350_out2_ramp_step()
160 /* ramp step down */ in wm8350_out2_ramp_step()
162 val--; in wm8350_out2_ramp_step()
174 if (out2->ramp == WM8350_RAMP_UP) { in wm8350_out2_ramp_step()
175 /* ramp step up */ in wm8350_out2_ramp_step()
176 if (val < out2->right_vol) { in wm8350_out2_ramp_step()
183 } else if (out2->ramp == WM8350_RAMP_DOWN) { in wm8350_out2_ramp_step()
184 /* ramp step down */ in wm8350_out2_ramp_step()
186 val--; in wm8350_out2_ramp_step()
211 struct wm8350_output *out1 = &wm8350_data->out1, in wm8350_pga_work()
212 *out2 = &wm8350_data->out2; in wm8350_pga_work()
215 /* do we need to ramp at all ? */ in wm8350_pga_work()
216 if (out1->ramp == WM8350_RAMP_NONE && out2->ramp == WM8350_RAMP_NONE) in wm8350_pga_work()
219 /* PGA volumes have 6 bits of resolution to ramp */ in wm8350_pga_work()
223 if (out1->ramp != WM8350_RAMP_NONE) in wm8350_pga_work()
225 if (out2->ramp != WM8350_RAMP_NONE) in wm8350_pga_work()
228 /* ramp finished ? */ in wm8350_pga_work()
232 /* we need to delay longer on the up ramp */ in wm8350_pga_work()
233 if (out1->ramp == WM8350_RAMP_UP || in wm8350_pga_work()
234 out2->ramp == WM8350_RAMP_UP) { in wm8350_pga_work()
246 out1->ramp = WM8350_RAMP_NONE; in wm8350_pga_work()
247 out2->ramp = WM8350_RAMP_NONE; in wm8350_pga_work()
257 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in pga_event()
261 switch (w->shift) { in pga_event()
264 out = &wm8350_data->out1; in pga_event()
268 out = &wm8350_data->out2; in pga_event()
272 WARN(1, "Invalid shift %d\n", w->shift); in pga_event()
273 return -1; in pga_event()
278 out->ramp = WM8350_RAMP_UP; in pga_event()
279 out->active = 1; in pga_event()
281 schedule_delayed_work(&wm8350_data->pga_work, in pga_event()
286 out->ramp = WM8350_RAMP_DOWN; in pga_event()
287 out->active = 0; in pga_event()
289 schedule_delayed_work(&wm8350_data->pga_work, in pga_event()
304 (struct soc_mixer_control *)kcontrol->private_value; in wm8350_put_volsw_2r_vu()
306 unsigned int reg = mc->reg; in wm8350_put_volsw_2r_vu()
314 out = &wm8350_priv->out1; in wm8350_put_volsw_2r_vu()
317 out = &wm8350_priv->out2; in wm8350_put_volsw_2r_vu()
324 out->left_vol = ucontrol->value.integer.value[0]; in wm8350_put_volsw_2r_vu()
325 out->right_vol = ucontrol->value.integer.value[1]; in wm8350_put_volsw_2r_vu()
326 if (!out->active) in wm8350_put_volsw_2r_vu()
345 struct wm8350_output *out1 = &wm8350_priv->out1; in wm8350_get_volsw_2r()
346 struct wm8350_output *out2 = &wm8350_priv->out2; in wm8350_get_volsw_2r()
348 (struct soc_mixer_control *)kcontrol->private_value; in wm8350_get_volsw_2r()
349 unsigned int reg = mc->reg; in wm8350_get_volsw_2r()
354 ucontrol->value.integer.value[0] = out1->left_vol; in wm8350_get_volsw_2r()
355 ucontrol->value.integer.value[1] = out1->right_vol; in wm8350_get_volsw_2r()
359 ucontrol->value.integer.value[0] = out2->left_vol; in wm8350_get_volsw_2r()
360 ucontrol->value.integer.value[1] = out2->right_vol; in wm8350_get_volsw_2r()
389 static DECLARE_TLV_DB_SCALE(pre_amp_tlv, -1200, 3525, 0);
390 static DECLARE_TLV_DB_SCALE(out_pga_tlv, -5700, 600, 0);
391 static DECLARE_TLV_DB_SCALE(dac_pcm_tlv, -7163, 36, 1);
392 static DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -12700, 50, 1);
393 static DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 1);
396 0, 12, TLV_DB_SCALE_ITEM(-3600, 300, 1),
754 struct snd_soc_component *component = codec_dai->component; in wm8350_set_dai_sysclk()
756 struct wm8350 *wm8350 = wm8350_data->wm8350; in wm8350_set_dai_sysclk()
789 struct snd_soc_component *component = codec_dai->component; in wm8350_set_clkdiv()
829 return -EINVAL; in wm8350_set_clkdiv()
837 struct snd_soc_component *component = codec_dai->component; in wm8350_set_dai_fmt()
857 return -EINVAL; in wm8350_set_dai_fmt()
877 return -EINVAL; in wm8350_set_dai_fmt()
894 return -EINVAL; in wm8350_set_dai_fmt()
908 struct snd_soc_component *component = codec_dai->component; in wm8350_pcm_hw_params()
910 struct wm8350 *wm8350 = wm8350_data->wm8350; in wm8350_pcm_hw_params()
934 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in wm8350_pcm_hw_params()
948 struct snd_soc_component *component = dai->component; in wm8350_mute()
980 fll_div->div = 0x4; in fll_factors()
982 fll_div->div = 0x3; in fll_factors()
984 fll_div->div = 0x2; in fll_factors()
986 fll_div->div = 0x1; in fll_factors()
989 return -EINVAL; in fll_factors()
993 fll_div->ratio = 1; in fll_factors()
995 fll_div->ratio = 8; in fll_factors()
997 t1 = output * (1 << (fll_div->div + 1)); in fll_factors()
998 t2 = input * fll_div->ratio; in fll_factors()
1000 fll_div->n = t1 / t2; in fll_factors()
1012 /* Move down to proper range now rounding is done */ in fll_factors()
1014 fll_div->k = K; in fll_factors()
1016 fll_div->k = 0; in fll_factors()
1025 struct snd_soc_component *component = codec_dai->component; in wm8350_set_fll()
1027 struct wm8350 *wm8350 = priv->wm8350; in wm8350_set_fll()
1032 if (freq_in == priv->fll_freq_in && freq_out == priv->fll_freq_out) in wm8350_set_fll()
1035 /* power down FLL - we need to do this for reconfiguration */ in wm8350_set_fll()
1045 dev_dbg(wm8350->dev, in wm8350_set_fll()
1069 priv->fll_freq_out = freq_out; in wm8350_set_fll()
1070 priv->fll_freq_in = freq_in; in wm8350_set_fll()
1079 struct wm8350 *wm8350 = priv->wm8350; in wm8350_set_bias_level()
1081 wm8350->codec.platform_data; in wm8350_set_bias_level()
1091 platform->codec_current_on << 14); in wm8350_set_bias_level()
1103 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), in wm8350_set_bias_level()
1104 priv->supplies); in wm8350_set_bias_level()
1118 platform->dis_out1 | in wm8350_set_bias_level()
1119 (platform->dis_out2 << 2) | in wm8350_set_bias_level()
1120 (platform->dis_out3 << 4) | in wm8350_set_bias_level()
1121 (platform->dis_out4 << 6)); in wm8350_set_bias_level()
1125 (platform-> in wm8350_set_bias_level()
1130 (platform->vmid_s_curve << 8)); in wm8350_set_bias_level()
1132 /* ramp up vmid */ in wm8350_set_bias_level()
1134 (platform-> in wm8350_set_bias_level()
1141 (platform-> in wm8350_set_bias_level()
1148 (platform->codec_current_standby << 14); in wm8350_set_bias_level()
1166 (platform-> in wm8350_set_bias_level()
1183 (platform->vmid_s_curve << 8)); in wm8350_set_bias_level()
1192 (platform-> in wm8350_set_bias_level()
1196 (platform->vmid_s_curve << 8) | in wm8350_set_bias_level()
1197 platform->dis_out1 | in wm8350_set_bias_level()
1198 (platform->dis_out2 << 2) | in wm8350_set_bias_level()
1199 (platform->dis_out3 << 4) | in wm8350_set_bias_level()
1200 (platform->dis_out4 << 6)); in wm8350_set_bias_level()
1210 (platform->drain_msecs)); in wm8350_set_bias_level()
1215 /* disable anti-pop */ in wm8350_set_bias_level()
1231 regulator_bulk_disable(ARRAY_SIZE(priv->supplies), in wm8350_set_bias_level()
1232 priv->supplies); in wm8350_set_bias_level()
1242 struct wm8350 *wm8350 = priv->wm8350; in wm8350_hp_work()
1248 report = jack->report; in wm8350_hp_work()
1252 snd_soc_jack_report(jack->jack, report, jack->report); in wm8350_hp_work()
1261 wm8350_hp_work(priv, &priv->hpl, WM8350_JACK_L_LVL); in wm8350_hpl_work()
1269 wm8350_hp_work(priv, &priv->hpr, WM8350_JACK_R_LVL); in wm8350_hpr_work()
1275 struct wm8350 *wm8350 = priv->wm8350; in wm8350_hpl_jack_handler()
1281 if (device_may_wakeup(wm8350->dev)) in wm8350_hpl_jack_handler()
1282 pm_wakeup_event(wm8350->dev, 250); in wm8350_hpl_jack_handler()
1285 &priv->hpl.work, msecs_to_jiffies(200)); in wm8350_hpl_jack_handler()
1293 struct wm8350 *wm8350 = priv->wm8350; in wm8350_hpr_jack_handler()
1299 if (device_may_wakeup(wm8350->dev)) in wm8350_hpr_jack_handler()
1300 pm_wakeup_event(wm8350->dev, 250); in wm8350_hpr_jack_handler()
1303 &priv->hpr.work, msecs_to_jiffies(200)); in wm8350_hpr_jack_handler()
1309 * wm8350_hp_jack_detect - Enable headphone jack detection.
1323 struct wm8350 *wm8350 = priv->wm8350; in wm8350_hp_jack_detect()
1328 priv->hpl.jack = jack; in wm8350_hp_jack_detect()
1329 priv->hpl.report = report; in wm8350_hp_jack_detect()
1334 priv->hpr.jack = jack; in wm8350_hp_jack_detect()
1335 priv->hpr.report = report; in wm8350_hp_jack_detect()
1340 return -EINVAL; in wm8350_hp_jack_detect()
1367 struct wm8350 *wm8350 = priv->wm8350; in wm8350_mic_handler()
1377 report |= priv->mic.short_report; in wm8350_mic_handler()
1379 report |= priv->mic.report; in wm8350_mic_handler()
1381 snd_soc_jack_report(priv->mic.jack, report, in wm8350_mic_handler()
1382 priv->mic.report | priv->mic.short_report); in wm8350_mic_handler()
1388 * wm8350_mic_jack_detect - Enable microphone jack detection.
1403 struct wm8350 *wm8350 = priv->wm8350; in wm8350_mic_jack_detect()
1405 priv->mic.jack = jack; in wm8350_mic_jack_detect()
1406 priv->mic.report = detect_report; in wm8350_mic_jack_detect()
1407 priv->mic.short_report = short_report; in wm8350_mic_jack_detect()
1439 .name = "wm8350-hifi",
1459 struct wm8350 *wm8350 = dev_get_platdata(component->dev); in wm8350_component_probe()
1465 if (wm8350->codec.platform_data == NULL) { in wm8350_component_probe()
1466 dev_err(component->dev, "No audio platform data supplied\n"); in wm8350_component_probe()
1467 return -EINVAL; in wm8350_component_probe()
1470 priv = devm_kzalloc(component->dev, sizeof(struct wm8350_data), in wm8350_component_probe()
1473 return -ENOMEM; in wm8350_component_probe()
1475 snd_soc_component_init_regmap(component, wm8350->regmap); in wm8350_component_probe()
1478 priv->wm8350 = wm8350; in wm8350_component_probe()
1481 priv->supplies[i].supply = supply_names[i]; in wm8350_component_probe()
1483 ret = devm_regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies), in wm8350_component_probe()
1484 priv->supplies); in wm8350_component_probe()
1491 INIT_DELAYED_WORK(&priv->pga_work, wm8350_pga_work); in wm8350_component_probe()
1492 INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work); in wm8350_component_probe()
1493 INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work); in wm8350_component_probe()
1504 out1 = &priv->out1; in wm8350_component_probe()
1505 out2 = &priv->out2; in wm8350_component_probe()
1506 out1->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME) & in wm8350_component_probe()
1508 out1->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME) & in wm8350_component_probe()
1510 out2->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME) & in wm8350_component_probe()
1512 out2->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME) & in wm8350_component_probe()
1577 struct wm8350 *wm8350 = dev_get_platdata(component->dev); in wm8350_component_remove()
1588 priv->hpl.jack = NULL; in wm8350_component_remove()
1589 priv->hpr.jack = NULL; in wm8350_component_remove()
1590 priv->mic.jack = NULL; in wm8350_component_remove()
1592 cancel_delayed_work_sync(&priv->hpl.work); in wm8350_component_remove()
1593 cancel_delayed_work_sync(&priv->hpr.work); in wm8350_component_remove()
1597 flush_delayed_work(&priv->pga_work); in wm8350_component_remove()
1620 return devm_snd_soc_register_component(&pdev->dev, in wm8350_probe()
1627 .name = "wm8350-codec",
1637 MODULE_ALIAS("platform:wm8350-codec");