Lines Matching +full:adc +full:- +full:freq
1 // SPDX-License-Identifier: GPL-2.0-only
3 * es8316.c -- es8316 ALSA SoC audio driver
6 * Authors: David Yang <yangxiaohua@everest-semi.com>,
21 #include <sound/soc-dapm.h>
52 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv, -9600, 50, 1);
53 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9600, 50, 1);
54 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_max_gain_tlv, -650, 150, 0);
55 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_min_gain_tlv, -1200, 150, 0);
58 0, 10, TLV_DB_SCALE_ITEM(-1650, 150, 0),
59 11, 11, TLV_DB_SCALE_ITEM(-150, 0, 0),
63 0, 4, TLV_DB_SCALE_ITEM(-1200, 150, 0),
64 8, 11, TLV_DB_SCALE_ITEM(-450, 150, 0),
68 0, 0, TLV_DB_SCALE_ITEM(-350, 0, 0),
77 0, 0, TLV_DB_SCALE_ITEM(-4800, 0, 0),
78 1, 3, TLV_DB_SCALE_ITEM(-2400, 1200, 0),
82 { "Constant PGA Gain", "Mute ADC Output" };
112 SOC_SINGLE_TLV("ADC Capture Volume", ES8316_ADC_VOLUME,
114 SOC_SINGLE_TLV("ADC PGA Gain Volume", ES8316_ADC_PGAGAIN,
116 SOC_SINGLE("ADC Soft Ramp Switch", ES8316_ADC_MUTE, 4, 1, 0),
117 SOC_SINGLE("ADC Double Fs Switch", ES8316_ADC_DMIC, 4, 1, 0),
138 "lin1-rin1",
139 "lin2-rin2",
140 "lin1-rin1 with 20db Boost",
141 "lin2-rin2 with 20db Boost"
168 "lin1-rin1",
169 "lin2-rin2",
170 "lin-rin with Boost",
171 "lin-rin with Boost and PGA"
223 SND_SOC_DAPM_SUPPLY("ADC Vref", ES8316_SYS_PDN, 1, 1, NULL, 0),
224 SND_SOC_DAPM_SUPPLY("ADC bias", ES8316_SYS_PDN, 2, 1, NULL, 0),
225 SND_SOC_DAPM_SUPPLY("ADC Clock", ES8316_CLKMGR_CLKSW, 3, 0, NULL, 0),
228 SND_SOC_DAPM_ADC("Mono ADC", NULL, ES8316_ADC_PDN_LINSEL, 6, 1),
298 {"Differential Mux", "lin1-rin1", "MIC1"},
299 {"Differential Mux", "lin2-rin2", "MIC2"},
302 {"Mono ADC", NULL, "ADC Clock"},
303 {"Mono ADC", NULL, "ADC Vref"},
304 {"Mono ADC", NULL, "ADC bias"},
305 {"Mono ADC", NULL, "Line input PGA"},
308 * the DAC clock must be running for the ADC to work.
310 {"Mono ADC", NULL, "DAC Clock"},
312 {"Digital Mic Mux", "dmic disable", "Mono ADC"},
328 {"Left Headphone Mux", "lin-rin with Boost and PGA", "Line input PGA"},
329 {"Right Headphone Mux", "lin-rin with Boost and PGA", "Line input PGA"},
365 int clk_id, unsigned int freq, int dir) in es8316_set_dai_sysclk() argument
367 struct snd_soc_component *component = codec_dai->component; in es8316_set_dai_sysclk()
372 es8316->sysclk = freq; in es8316_set_dai_sysclk()
373 es8316->sysclk_constraints.list = NULL; in es8316_set_dai_sysclk()
374 es8316->sysclk_constraints.count = 0; in es8316_set_dai_sysclk()
376 if (freq == 0) in es8316_set_dai_sysclk()
379 ret = clk_set_rate(es8316->mclk, freq); in es8316_set_dai_sysclk()
389 if (freq % ratio == 0) in es8316_set_dai_sysclk()
390 es8316->allowed_rates[count++] = freq / ratio; in es8316_set_dai_sysclk()
395 if ((freq / ratio) % 2 == 0) in es8316_set_dai_sysclk()
396 es8316->allowed_rates[count++] = freq / ratio / 2; in es8316_set_dai_sysclk()
400 es8316->sysclk_constraints.list = es8316->allowed_rates; in es8316_set_dai_sysclk()
401 es8316->sysclk_constraints.count = count; in es8316_set_dai_sysclk()
410 struct snd_soc_component *component = codec_dai->component; in es8316_set_dai_fmt()
420 dev_err(component->dev, "Codec driver only supports I2S format\n"); in es8316_set_dai_fmt()
421 return -EINVAL; in es8316_set_dai_fmt()
439 return -EINVAL; in es8316_set_dai_fmt()
459 struct snd_soc_component *component = dai->component; in es8316_pcm_startup()
462 if (es8316->sysclk_constraints.list) in es8316_pcm_startup()
463 snd_pcm_hw_constraint_list(substream->runtime, 0, in es8316_pcm_startup()
465 &es8316->sysclk_constraints); in es8316_pcm_startup()
474 struct snd_soc_component *component = dai->component; in es8316_pcm_hw_params()
480 unsigned int clk = es8316->sysclk / 2; in es8316_pcm_hw_params()
501 if (clk == es8316->sysclk) in es8316_pcm_hw_params()
502 return -EINVAL; in es8316_pcm_hw_params()
503 clk = es8316->sysclk; in es8316_pcm_hw_params()
509 if (clk != es8316->sysclk) { in es8316_pcm_hw_params()
536 return -EINVAL; in es8316_pcm_hw_params()
553 snd_soc_component_update_bits(dai->component, ES8316_DAC_SET1, 0x20, in es8316_mute()
621 struct snd_soc_component *comp = es8316->component; in es8316_irq()
624 mutex_lock(&es8316->lock); in es8316_irq()
626 regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags); in es8316_irq()
628 goto out; /* Powered-down / reset */ in es8316_irq()
631 if (!es8316->jack) in es8316_irq()
634 if (es8316->jd_inverted) in es8316_irq()
637 dev_dbg(comp->dev, "gpio flags %#04x\n", flags); in es8316_irq()
640 if (es8316->jack->status & SND_JACK_MICROPHONE) in es8316_irq()
643 if (es8316->jack->status & SND_JACK_HEADPHONE) { in es8316_irq()
644 snd_soc_jack_report(es8316->jack, 0, in es8316_irq()
646 dev_dbg(comp->dev, "jack unplugged\n"); in es8316_irq()
648 } else if (!(es8316->jack->status & SND_JACK_HEADPHONE)) { in es8316_irq()
651 regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags); in es8316_irq()
652 if (es8316->jd_inverted) in es8316_irq()
654 dev_dbg(comp->dev, "gpio flags %#04x\n", flags); in es8316_irq()
660 snd_soc_jack_report(es8316->jack, in es8316_irq()
663 /* Keep mic-gnd-short detection on for button press */ in es8316_irq()
666 snd_soc_jack_report(es8316->jack, in es8316_irq()
669 /* No longer need mic-gnd-short detection */ in es8316_irq()
672 } else if (es8316->jack->status & SND_JACK_MICROPHONE) { in es8316_irq()
676 snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0); in es8316_irq()
679 snd_soc_jack_report(es8316->jack, in es8316_irq()
686 mutex_unlock(&es8316->lock); in es8316_irq()
696 * Init es8316->jd_inverted here and not in the probe, as we cannot in es8316_enable_jack_detect()
697 * guarantee that the bytchr-es8316 driver, which might set this in es8316_enable_jack_detect()
700 es8316->jd_inverted = device_property_read_bool(component->dev, in es8316_enable_jack_detect()
701 "everest,jack-detect-inverted"); in es8316_enable_jack_detect()
703 mutex_lock(&es8316->lock); in es8316_enable_jack_detect()
705 es8316->jack = jack; in es8316_enable_jack_detect()
707 if (es8316->jack->status & SND_JACK_MICROPHONE) in es8316_enable_jack_detect()
714 mutex_unlock(&es8316->lock); in es8316_enable_jack_detect()
717 enable_irq(es8316->irq); in es8316_enable_jack_detect()
718 es8316_irq(es8316->irq, es8316); in es8316_enable_jack_detect()
725 if (!es8316->jack) in es8316_disable_jack_detect()
728 disable_irq(es8316->irq); in es8316_disable_jack_detect()
730 mutex_lock(&es8316->lock); in es8316_disable_jack_detect()
735 if (es8316->jack->status & SND_JACK_MICROPHONE) { in es8316_disable_jack_detect()
737 snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0); in es8316_disable_jack_detect()
740 es8316->jack = NULL; in es8316_disable_jack_detect()
742 mutex_unlock(&es8316->lock); in es8316_disable_jack_detect()
761 es8316->component = component; in es8316_probe()
763 es8316->mclk = devm_clk_get_optional(component->dev, "mclk"); in es8316_probe()
764 if (IS_ERR(es8316->mclk)) { in es8316_probe()
765 dev_err(component->dev, "unable to get mclk\n"); in es8316_probe()
766 return PTR_ERR(es8316->mclk); in es8316_probe()
768 if (!es8316->mclk) in es8316_probe()
769 dev_warn(component->dev, "assuming static mclk\n"); in es8316_probe()
771 ret = clk_prepare_enable(es8316->mclk); in es8316_probe()
773 dev_err(component->dev, "unable to enable mclk\n"); in es8316_probe()
791 * but here is a vendor-provided value that improves volume in es8316_probe()
803 clk_disable_unprepare(es8316->mclk); in es8316_remove()
810 regcache_cache_only(es8316->regmap, false); in es8316_resume()
811 regcache_sync(es8316->regmap); in es8316_resume()
820 regcache_cache_only(es8316->regmap, true); in es8316_suspend()
821 regcache_mark_dirty(es8316->regmap); in es8316_suspend()
864 struct device *dev = &i2c_client->dev; in es8316_i2c_probe()
868 es8316 = devm_kzalloc(&i2c_client->dev, sizeof(struct es8316_priv), in es8316_i2c_probe()
871 return -ENOMEM; in es8316_i2c_probe()
875 es8316->regmap = devm_regmap_init_i2c(i2c_client, &es8316_regmap); in es8316_i2c_probe()
876 if (IS_ERR(es8316->regmap)) in es8316_i2c_probe()
877 return PTR_ERR(es8316->regmap); in es8316_i2c_probe()
879 es8316->irq = i2c_client->irq; in es8316_i2c_probe()
880 mutex_init(&es8316->lock); in es8316_i2c_probe()
882 if (es8316->irq > 0) { in es8316_i2c_probe()
883 ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq, in es8316_i2c_probe()
887 dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret); in es8316_i2c_probe()
888 es8316->irq = -ENXIO; in es8316_i2c_probe()
892 return devm_snd_soc_register_component(&i2c_client->dev, in es8316_i2c_probe()
932 MODULE_AUTHOR("David Yang <yangxiaohua@everest-semi.com>");