117 lines
3.4 KiB
Diff
117 lines
3.4 KiB
Diff
diff --git a/sound/soc/codecs/ec25.c b/sound/soc/codecs/ec25.c
|
|
index 7c96aa7a79d0..20687ec386ef 100644
|
|
--- a/sound/soc/codecs/ec25.c
|
|
+++ b/sound/soc/codecs/ec25.c
|
|
@@ -3,6 +3,50 @@
|
|
#include <linux/module.h>
|
|
#include <sound/soc.h>
|
|
|
|
+u32 curr_sample_rate;
|
|
+
|
|
+static const char *const avail_sample_rates[] = {"8000", "16000", "48000"};
|
|
+static const struct soc_enum ec25_enum[] = {
|
|
+ SOC_ENUM_SINGLE_EXT(3, avail_sample_rates),
|
|
+};
|
|
+
|
|
+static int ec25_sample_rate_get(struct snd_kcontrol *kcontrol,
|
|
+ struct snd_ctl_elem_value *ucontrol)
|
|
+{
|
|
+ pr_info("%s: Forced sample rate = %i\n",
|
|
+ __func__, curr_sample_rate);
|
|
+ ucontrol->value.integer.value[0] = curr_sample_rate;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int ec25_sample_rate_set(struct snd_kcontrol *kcontrol,
|
|
+ struct snd_ctl_elem_value *ucontrol)
|
|
+{
|
|
+ switch (ucontrol->value.integer.value[0]) {
|
|
+ case 0:
|
|
+ curr_sample_rate = 8000;
|
|
+ break;
|
|
+ case 1:
|
|
+ curr_sample_rate = 16000;
|
|
+ break;
|
|
+ case 2:
|
|
+ curr_sample_rate = 48000;
|
|
+ break;
|
|
+ default:
|
|
+ curr_sample_rate = 8000;
|
|
+ break;
|
|
+ }
|
|
+ pr_info("%s: Forced sample rate = %i\n",
|
|
+ __func__, curr_sample_rate);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static const struct snd_kcontrol_new ec25_controls[] = {
|
|
+ SOC_ENUM_EXT("EC25 Sample Rate", ec25_enum[0],
|
|
+ ec25_sample_rate_get,
|
|
+ ec25_sample_rate_set),
|
|
+};
|
|
+
|
|
static const struct snd_soc_dapm_widget ec25_dapm_widgets[] = {
|
|
SND_SOC_DAPM_OUTPUT("AOUT"),
|
|
SND_SOC_DAPM_INPUT("AIN"),
|
|
@@ -22,23 +66,50 @@ static const struct snd_soc_component_driver ec25_component_driver = {
|
|
.num_dapm_routes = ARRAY_SIZE(ec25_dapm_routes),
|
|
.endianness = 1,
|
|
.non_legacy_dai_naming = 1,
|
|
+ .controls = ec25_controls,
|
|
+ .num_controls = ARRAY_SIZE(ec25_controls),
|
|
+};
|
|
+
|
|
+static int ec25_startup(struct snd_pcm_substream *substream,
|
|
+ struct snd_soc_dai *dai)
|
|
+{
|
|
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
|
|
+ /* HACK: This is a const pointer, but we know the underlying data is not const. */
|
|
+ struct snd_soc_pcm_stream *params = (struct snd_soc_pcm_stream *)rtd->dai_link->params;
|
|
+ struct snd_soc_pcm_stream *stream = snd_soc_dai_get_pcm_stream(dai, substream->stream);
|
|
+
|
|
+ if (stream->rates & snd_pcm_rate_to_rate_bit(curr_sample_rate)) {
|
|
+ dev_info(dai->dev, "Setting sample rate to %u\n", curr_sample_rate);
|
|
+ params->rate_min = curr_sample_rate;
|
|
+ params->rate_max = curr_sample_rate;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+static const struct snd_soc_dai_ops ec25_dai_ops = {
|
|
+ .startup = ec25_startup,
|
|
};
|
|
|
|
static struct snd_soc_dai_driver ec25_dais[] = {
|
|
{
|
|
.name = "ec25",
|
|
+ .ops = &ec25_dai_ops,
|
|
.capture = {
|
|
.stream_name = "Capture",
|
|
.channels_min = 1,
|
|
.channels_max = 1,
|
|
- .rates = SNDRV_PCM_RATE_8000,
|
|
+ .rates = SNDRV_PCM_RATE_8000 |
|
|
+ SNDRV_PCM_RATE_16000 |
|
|
+ SNDRV_PCM_RATE_48000,
|
|
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
|
},
|
|
.playback = {
|
|
.stream_name = "Playback",
|
|
.channels_min = 1,
|
|
.channels_max = 1,
|
|
- .rates = SNDRV_PCM_RATE_8000,
|
|
+ .rates = SNDRV_PCM_RATE_8000 |
|
|
+ SNDRV_PCM_RATE_16000 |
|
|
+ SNDRV_PCM_RATE_48000,
|
|
.formats = SNDRV_PCM_FMTBIT_S16_LE,
|
|
},
|
|
.symmetric_rates = 1,
|
|
@@ -69,6 +140,7 @@ static struct snd_soc_dai_driver ec25_dais[] = {
|
|
|
|
static int ec25_codec_probe(struct platform_device *pdev)
|
|
{
|
|
+ curr_sample_rate = 8000;
|
|
return devm_snd_soc_register_component(&pdev->dev, &ec25_component_driver,
|
|
ec25_dais, ARRAY_SIZE(ec25_dais));
|
|
}
|