pinephone-linux/ec25.patch

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));
}