Lines Matching +full:codec +full:- +full:analog +full:- +full:controls

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>
26 /* In slave mode at single speed, the codec is documented as accepting 5
50 * ES8316 controls
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),
136 /* Analog Input Mux */
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"
212 SND_SOC_DAPM_SUPPLY("Analog power", ES8316_SYS_PDN, 4, 1, NULL, 0),
295 {"MIC1", NULL, "Analog power"},
296 {"MIC2", NULL, "Analog power"},
298 {"Differential Mux", "lin1-rin1", "MIC1"},
299 {"Differential Mux", "lin2-rin2", "MIC2"},
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"},
359 {"Headphone Out", NULL, "Analog power"},
367 struct snd_soc_component *component = codec_dai->component;
372 es8316->sysclk = freq;
373 es8316->sysclk_constraints.list = NULL;
374 es8316->sysclk_constraints.count = 0;
379 ret = clk_set_rate(es8316->mclk, freq);
384 * by the codec running in slave mode.
390 es8316->allowed_rates[count++] = freq / ratio;
393 * since the codec supports halving the MCLK.
396 es8316->allowed_rates[count++] = freq / ratio / 2;
400 es8316->sysclk_constraints.list = es8316->allowed_rates;
401 es8316->sysclk_constraints.count = count;
410 struct snd_soc_component *component = codec_dai->component;
420 dev_err(component->dev, "Codec driver only supports I2S format\n");
421 return -EINVAL;
439 return -EINVAL;
459 struct snd_soc_component *component = dai->component;
462 if (es8316->sysclk_constraints.list)
463 snd_pcm_hw_constraint_list(substream->runtime, 0,
465 &es8316->sysclk_constraints);
474 struct snd_soc_component *component = dai->component;
480 unsigned int clk = es8316->sysclk / 2;
485 * the CODEC with a too high frequency. We have an SKU where
501 if (clk == es8316->sysclk)
502 return -EINVAL;
503 clk = es8316->sysclk;
509 if (clk != es8316->sysclk) {
536 return -EINVAL;
553 snd_soc_component_update_bits(dai->component, ES8316_DAC_SET1, 0x20,
597 snd_soc_dapm_force_enable_pin_unlocked(dapm, "Analog power");
612 snd_soc_dapm_disable_pin_unlocked(dapm, "Analog power");
621 struct snd_soc_component *comp = es8316->component;
624 mutex_lock(&es8316->lock);
626 regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
628 goto out; /* Powered-down / reset */
631 if (!es8316->jack)
634 if (es8316->jd_inverted)
637 dev_dbg(comp->dev, "gpio flags %#04x\n", flags);
640 if (es8316->jack->status & SND_JACK_MICROPHONE)
643 if (es8316->jack->status & SND_JACK_HEADPHONE) {
644 snd_soc_jack_report(es8316->jack, 0,
646 dev_dbg(comp->dev, "jack unplugged\n");
648 } else if (!(es8316->jack->status & SND_JACK_HEADPHONE)) {
651 regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags);
652 if (es8316->jd_inverted)
654 dev_dbg(comp->dev, "gpio flags %#04x\n", flags);
660 snd_soc_jack_report(es8316->jack,
663 /* Keep mic-gnd-short detection on for button press */
666 snd_soc_jack_report(es8316->jack,
669 /* No longer need mic-gnd-short detection */
672 } else if (es8316->jack->status & SND_JACK_MICROPHONE) {
676 snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0);
679 snd_soc_jack_report(es8316->jack,
686 mutex_unlock(&es8316->lock);
696 * Init es8316->jd_inverted here and not in the probe, as we cannot
697 * guarantee that the bytchr-es8316 driver, which might set this
700 es8316->jd_inverted = device_property_read_bool(component->dev,
701 "everest,jack-detect-inverted");
703 mutex_lock(&es8316->lock);
705 es8316->jack = jack;
707 if (es8316->jack->status & SND_JACK_MICROPHONE)
714 mutex_unlock(&es8316->lock);
717 enable_irq(es8316->irq);
718 es8316_irq(es8316->irq, es8316);
725 if (!es8316->jack)
728 disable_irq(es8316->irq);
730 mutex_lock(&es8316->lock);
735 if (es8316->jack->status & SND_JACK_MICROPHONE) {
737 snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0);
740 es8316->jack = NULL;
742 mutex_unlock(&es8316->lock);
761 es8316->component = component;
763 es8316->mclk = devm_clk_get_optional(component->dev, "mclk");
764 if (IS_ERR(es8316->mclk)) {
765 dev_err(component->dev, "unable to get mclk\n");
766 return PTR_ERR(es8316->mclk);
768 if (!es8316->mclk)
769 dev_warn(component->dev, "assuming static mclk\n");
771 ret = clk_prepare_enable(es8316->mclk);
773 dev_err(component->dev, "unable to enable mclk\n");
777 /* Reset codec and enable current state machine */
791 * but here is a vendor-provided value that improves volume
803 clk_disable_unprepare(es8316->mclk);
810 regcache_cache_only(es8316->regmap, false);
811 regcache_sync(es8316->regmap);
820 regcache_cache_only(es8316->regmap, true);
821 regcache_mark_dirty(es8316->regmap);
832 .controls = es8316_snd_controls,
864 struct device *dev = &i2c_client->dev;
868 es8316 = devm_kzalloc(&i2c_client->dev, sizeof(struct es8316_priv),
871 return -ENOMEM;
875 es8316->regmap = devm_regmap_init_i2c(i2c_client, &es8316_regmap);
876 if (IS_ERR(es8316->regmap))
877 return PTR_ERR(es8316->regmap);
879 es8316->irq = i2c_client->irq;
880 mutex_init(&es8316->lock);
882 if (es8316->irq > 0) {
883 ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq,
887 dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret);
888 es8316->irq = -ENXIO;
892 return devm_snd_soc_register_component(&i2c_client->dev,
931 MODULE_DESCRIPTION("Everest Semi ES8316 ALSA SoC Codec Driver");
932 MODULE_AUTHOR("David Yang <yangxiaohua@everest-semi.com>");