From c177a5ac1125f4c9a29db6884ac3f4d081cf1bbb Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Fri, 25 Sep 2020 21:42:52 -0500
Subject: ASoC: ec25: New codec driver for the EC25 modem

The EC25 LTE modem has a PCM interface, and supports 16-bit PCM audio at
an 8 kHz or 16 kHz sameple rate.

Suggested-by: Luca Weiss <luca@z3ntu.xyz>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
 sound/soc/codecs/Kconfig  |  3 ++
 sound/soc/codecs/Makefile |  2 +
 sound/soc/codecs/ec25.c   | 94 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+)
 create mode 100644 sound/soc/codecs/ec25.c

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0138cfabbb03..211e77d7d64f 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1147,6 +1147,9 @@ config SND_SOC_HDMI_CODEC
 	select SND_PCM_IEC958
 	select HDMI
 
+config SND_SOC_EC25
+	tristate "EC25 LTE module CODEC"
+
 config SND_SOC_ES7134
 	tristate "Everest Semi ES7134 CODEC"
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index d7ad795603c1..7e12f3ae4f7d 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -122,6 +122,7 @@ snd-soc-da7219-y := da7219.o da7219-aad.o
 snd-soc-da732x-y := da732x.o
 snd-soc-da9055-y := da9055.o
 snd-soc-dmic-y := dmic.o
+snd-soc-ec25-y := ec25.o
 snd-soc-es7134-y := es7134.o
 snd-soc-es7241-y := es7241.o
 snd-soc-es83xx-dsm-common-y := es83xx-dsm-common.o
@@ -539,6 +540,7 @@ obj-$(CONFIG_SND_SOC_DA7219)	+= snd-soc-da7219.o
 obj-$(CONFIG_SND_SOC_DA732X)	+= snd-soc-da732x.o
 obj-$(CONFIG_SND_SOC_DA9055)	+= snd-soc-da9055.o
 obj-$(CONFIG_SND_SOC_DMIC)	+= snd-soc-dmic.o
+obj-$(CONFIG_SND_SOC_EC25)	+= snd-soc-ec25.o
 obj-$(CONFIG_SND_SOC_ES7134)	+= snd-soc-es7134.o
 obj-$(CONFIG_SND_SOC_ES7241)	+= snd-soc-es7241.o
 obj-$(CONFIG_SND_SOC_ES83XX_DSM_COMMON)    += snd-soc-es83xx-dsm-common.o
diff --git a/sound/soc/codecs/ec25.c b/sound/soc/codecs/ec25.c
new file mode 100644
index 000000000000..4f9b6b06cce7
--- /dev/null
+++ b/sound/soc/codecs/ec25.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/module.h>
+#include <sound/soc.h>
+
+static const struct snd_soc_dapm_widget ec25_dapm_widgets[] = {
+	SND_SOC_DAPM_OUTPUT("AOUT"),
+	SND_SOC_DAPM_INPUT("AIN"),
+};
+
+static const struct snd_soc_dapm_route ec25_dapm_routes[] = {
+	{ "AOUT", NULL, "Playback" },
+	{ "AOUT", NULL, "Wideband Playback" },
+	{ "Capture", NULL, "AIN" },
+	{ "Wideband Capture", NULL, "AIN" },
+};
+
+static const struct snd_soc_component_driver ec25_component_driver = {
+	.dapm_widgets		= ec25_dapm_widgets,
+	.num_dapm_widgets	= ARRAY_SIZE(ec25_dapm_widgets),
+	.dapm_routes		= ec25_dapm_routes,
+	.num_dapm_routes	= ARRAY_SIZE(ec25_dapm_routes),
+	.endianness		= 1,
+};
+
+static struct snd_soc_dai_driver ec25_dais[] = {
+	{
+		.name = "ec25",
+		.capture = {
+			.stream_name	= "Capture",
+			.channels_min	= 1,
+			.channels_max	= 1,
+			.rates		= SNDRV_PCM_RATE_8000,
+			.formats	= SNDRV_PCM_FMTBIT_S16_LE,
+		},
+		.playback = {
+			.stream_name	= "Playback",
+			.channels_min	= 1,
+			.channels_max	= 1,
+			.rates		= SNDRV_PCM_RATE_8000,
+			.formats	= SNDRV_PCM_FMTBIT_S16_LE,
+		},
+		.symmetric_rate = 1,
+		.symmetric_channels = 1,
+		.symmetric_sample_bits = 1,
+	},
+	{
+		.name = "ec25-wb",
+		.capture = {
+			.stream_name	= "Wideband Capture",
+			.channels_min	= 1,
+			.channels_max	= 1,
+			.rates		= SNDRV_PCM_RATE_16000,
+			.formats	= SNDRV_PCM_FMTBIT_S16_LE,
+		},
+		.playback = {
+			.stream_name	= "Wideband Playback",
+			.channels_min	= 1,
+			.channels_max	= 1,
+			.rates		= SNDRV_PCM_RATE_16000,
+			.formats	= SNDRV_PCM_FMTBIT_S16_LE,
+		},
+		.symmetric_rate = 1,
+		.symmetric_channels = 1,
+		.symmetric_sample_bits = 1,
+	},
+};
+
+static int ec25_codec_probe(struct platform_device *pdev)
+{
+	return devm_snd_soc_register_component(&pdev->dev, &ec25_component_driver,
+					       ec25_dais, ARRAY_SIZE(ec25_dais));
+}
+
+static const struct of_device_id ec25_codec_of_match[] = {
+	{ .compatible = "quectel,ec25", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, ec25_codec_of_match);
+
+static struct platform_driver ec25_codec_driver = {
+	.driver	= {
+		.name		= "ec25",
+		.of_match_table	= of_match_ptr(ec25_codec_of_match),
+	},
+	.probe	= ec25_codec_probe,
+};
+
+module_platform_driver(ec25_codec_driver);
+
+MODULE_DESCRIPTION("ASoC ec25 driver");
+MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ec25");
-- 
2.35.3

