Lines Matching +full:out +full:- +full:volume +full:- +full:limit
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>
51 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv, -9600, 50, 1);
52 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9600, 50, 1);
53 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_max_gain_tlv, -650, 150, 0);
54 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_min_gain_tlv, -1200, 150, 0);
55 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(alc_target_tlv, -1650, 150, 0);
57 0, 4, TLV_DB_SCALE_ITEM(-1200, 150, 0),
58 8, 11, TLV_DB_SCALE_ITEM(-450, 150, 0),
62 0, 0, TLV_DB_SCALE_ITEM(-350, 0, 0),
71 0, 0, TLV_DB_SCALE_ITEM(-4800, 0, 0),
72 1, 3, TLV_DB_SCALE_ITEM(-2400, 1200, 0),
89 SOC_DOUBLE_TLV("Headphone Playback Volume", ES8316_CPHP_ICAL_VOL,
91 SOC_DOUBLE_TLV("Headphone Mixer Volume", ES8316_HPMIX_VOL,
95 SOC_DOUBLE_R_TLV("DAC Playback Volume", ES8316_DAC_VOLL,
106 SOC_SINGLE_TLV("ADC Capture Volume", ES8316_ADC_VOLUME,
108 SOC_SINGLE_TLV("ADC PGA Gain Volume", ES8316_ADC_PGAGAIN,
114 SOC_SINGLE_TLV("ALC Capture Max Volume", ES8316_ADC_ALC1, 0, 28, 0,
116 SOC_SINGLE_TLV("ALC Capture Min Volume", ES8316_ADC_ALC2, 0, 28, 0,
118 SOC_SINGLE_TLV("ALC Capture Target Volume", ES8316_ADC_ALC3, 4, 10, 0,
132 "lin1-rin1",
133 "lin2-rin2",
134 "lin1-rin1 with 20db Boost",
135 "lin2-rin2 with 20db Boost"
162 "lin1-rin1",
163 "lin2-rin2",
164 "lin-rin with Boost",
165 "lin-rin with Boost and PGA"
227 SND_SOC_DAPM_AIF_OUT("I2S OUT", "I2S1 Capture", 1,
251 SND_SOC_DAPM_PGA("Left Headphone Mixer Out", ES8316_HPMIX_PDN,
253 SND_SOC_DAPM_PGA("Right Headphone Mixer Out", ES8316_HPMIX_PDN,
269 SND_SOC_DAPM_SUPPLY("Headphone Out", ES8316_CPHP_PDN1, 2, 1, NULL, 0),
292 {"Differential Mux", "lin1-rin1", "MIC1"},
293 {"Differential Mux", "lin2-rin2", "MIC2"},
308 {"I2S OUT", NULL, "Digital Mic Mux"},
322 {"Left Headphone Mux", "lin-rin with Boost and PGA", "Line input PGA"},
323 {"Right Headphone Mux", "lin-rin with Boost and PGA", "Line input PGA"},
331 {"Left Headphone Mixer Out", NULL, "Left Headphone Mixer"},
332 {"Right Headphone Mixer Out", NULL, "Right Headphone Mixer"},
334 {"Left Headphone Charge Pump", NULL, "Left Headphone Mixer Out"},
335 {"Right Headphone Charge Pump", NULL, "Right Headphone Mixer Out"},
352 {"Headphone Out", NULL, "Bias"},
353 {"Headphone Out", NULL, "Analog power"},
354 {"HPOL", NULL, "Headphone Out"},
355 {"HPOR", NULL, "Headphone Out"},
361 struct snd_soc_component *component = codec_dai->component; in es8316_set_dai_sysclk()
366 es8316->sysclk = freq; in es8316_set_dai_sysclk()
369 es8316->sysclk_constraints.list = NULL; in es8316_set_dai_sysclk()
370 es8316->sysclk_constraints.count = 0; in es8316_set_dai_sysclk()
375 ret = clk_set_rate(es8316->mclk, freq); in es8316_set_dai_sysclk()
379 /* Limit supported sample rates to ones that can be autodetected in es8316_set_dai_sysclk()
386 es8316->allowed_rates[count++] = freq / ratio; in es8316_set_dai_sysclk()
389 es8316->sysclk_constraints.list = es8316->allowed_rates; in es8316_set_dai_sysclk()
390 es8316->sysclk_constraints.count = count; in es8316_set_dai_sysclk()
398 struct snd_soc_component *component = codec_dai->component; in es8316_set_dai_fmt()
405 dev_err(component->dev, "Codec driver only supports slave mode\n"); in es8316_set_dai_fmt()
406 return -EINVAL; in es8316_set_dai_fmt()
410 dev_err(component->dev, "Codec driver only supports I2S format\n"); in es8316_set_dai_fmt()
411 return -EINVAL; in es8316_set_dai_fmt()
429 return -EINVAL; in es8316_set_dai_fmt()
449 struct snd_soc_component *component = dai->component; in es8316_pcm_startup()
452 if (es8316->sysclk_constraints.list) in es8316_pcm_startup()
453 snd_pcm_hw_constraint_list(substream->runtime, 0, in es8316_pcm_startup()
455 &es8316->sysclk_constraints); in es8316_pcm_startup()
464 struct snd_soc_component *component = dai->component; in es8316_pcm_hw_params()
473 if (es8316->sysclk % ratio != 0) in es8316_pcm_hw_params()
475 if (es8316->sysclk / ratio == params_rate(params)) in es8316_pcm_hw_params()
479 return -EINVAL; in es8316_pcm_hw_params()
495 return -EINVAL; in es8316_pcm_hw_params()
507 snd_soc_component_update_bits(dai->component, ES8316_DAC_SET1, 0x20, in es8316_mute()
575 struct snd_soc_component *comp = es8316->component; in es8316_irq()
578 mutex_lock(&es8316->lock); in es8316_irq()
580 regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags); in es8316_irq()
582 goto out; /* Powered-down / reset */ in es8316_irq()
585 if (!es8316->jack) in es8316_irq()
586 goto out; in es8316_irq()
588 if (es8316->jd_inverted) in es8316_irq()
591 dev_dbg(comp->dev, "gpio flags %#04x\n", flags); in es8316_irq()
594 if (es8316->jack->status & SND_JACK_MICROPHONE) in es8316_irq()
597 if (es8316->jack->status & SND_JACK_HEADPHONE) { in es8316_irq()
598 snd_soc_jack_report(es8316->jack, 0, in es8316_irq()
600 dev_dbg(comp->dev, "jack unplugged\n"); in es8316_irq()
602 } else if (!(es8316->jack->status & SND_JACK_HEADPHONE)) { in es8316_irq()
605 regmap_read(es8316->regmap, ES8316_GPIO_FLAG, &flags); in es8316_irq()
606 if (es8316->jd_inverted) in es8316_irq()
608 dev_dbg(comp->dev, "gpio flags %#04x\n", flags); in es8316_irq()
614 snd_soc_jack_report(es8316->jack, in es8316_irq()
617 /* Keep mic-gnd-short detection on for button press */ in es8316_irq()
620 snd_soc_jack_report(es8316->jack, in es8316_irq()
623 /* No longer need mic-gnd-short detection */ in es8316_irq()
626 } else if (es8316->jack->status & SND_JACK_MICROPHONE) { in es8316_irq()
630 snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0); in es8316_irq()
633 snd_soc_jack_report(es8316->jack, in es8316_irq()
639 out: in es8316_irq()
640 mutex_unlock(&es8316->lock); in es8316_irq()
650 * Init es8316->jd_inverted here and not in the probe, as we cannot in es8316_enable_jack_detect()
651 * guarantee that the bytchr-es8316 driver, which might set this in es8316_enable_jack_detect()
654 es8316->jd_inverted = device_property_read_bool(component->dev, in es8316_enable_jack_detect()
655 "everest,jack-detect-inverted"); in es8316_enable_jack_detect()
657 mutex_lock(&es8316->lock); in es8316_enable_jack_detect()
659 es8316->jack = jack; in es8316_enable_jack_detect()
661 if (es8316->jack->status & SND_JACK_MICROPHONE) in es8316_enable_jack_detect()
668 mutex_unlock(&es8316->lock); in es8316_enable_jack_detect()
671 enable_irq(es8316->irq); in es8316_enable_jack_detect()
672 es8316_irq(es8316->irq, es8316); in es8316_enable_jack_detect()
679 disable_irq(es8316->irq); in es8316_disable_jack_detect()
681 mutex_lock(&es8316->lock); in es8316_disable_jack_detect()
686 if (es8316->jack->status & SND_JACK_MICROPHONE) { in es8316_disable_jack_detect()
688 snd_soc_jack_report(es8316->jack, 0, SND_JACK_BTN_0); in es8316_disable_jack_detect()
691 es8316->jack = NULL; in es8316_disable_jack_detect()
693 mutex_unlock(&es8316->lock); in es8316_disable_jack_detect()
712 es8316->component = component; in es8316_probe()
714 es8316->mclk = devm_clk_get_optional(component->dev, "mclk"); in es8316_probe()
715 if (IS_ERR(es8316->mclk)) { in es8316_probe()
716 dev_err(component->dev, "unable to get mclk\n"); in es8316_probe()
717 return PTR_ERR(es8316->mclk); in es8316_probe()
719 if (!es8316->mclk) in es8316_probe()
720 dev_warn(component->dev, "assuming static mclk\n"); in es8316_probe()
722 ret = clk_prepare_enable(es8316->mclk); in es8316_probe()
724 dev_err(component->dev, "unable to enable mclk\n"); in es8316_probe()
742 * but here is a vendor-provided value that improves volume in es8316_probe()
754 clk_disable_unprepare(es8316->mclk); in es8316_remove()
792 struct device *dev = &i2c_client->dev; in es8316_i2c_probe()
796 es8316 = devm_kzalloc(&i2c_client->dev, sizeof(struct es8316_priv), in es8316_i2c_probe()
799 return -ENOMEM; in es8316_i2c_probe()
803 es8316->regmap = devm_regmap_init_i2c(i2c_client, &es8316_regmap); in es8316_i2c_probe()
804 if (IS_ERR(es8316->regmap)) in es8316_i2c_probe()
805 return PTR_ERR(es8316->regmap); in es8316_i2c_probe()
807 es8316->irq = i2c_client->irq; in es8316_i2c_probe()
808 mutex_init(&es8316->lock); in es8316_i2c_probe()
810 ret = devm_request_threaded_irq(dev, es8316->irq, NULL, es8316_irq, in es8316_i2c_probe()
814 /* Gets re-enabled by es8316_set_jack() */ in es8316_i2c_probe()
815 disable_irq(es8316->irq); in es8316_i2c_probe()
817 dev_warn(dev, "Failed to get IRQ %d: %d\n", es8316->irq, ret); in es8316_i2c_probe()
818 es8316->irq = -ENXIO; in es8316_i2c_probe()
821 return devm_snd_soc_register_component(&i2c_client->dev, in es8316_i2c_probe()
858 MODULE_AUTHOR("David Yang <yangxiaohua@everest-semi.com>");