summaryrefslogtreecommitdiffstats
path: root/sound/soc/pxa/mioa701_wm9713.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:49:45 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 18:49:45 +0000
commit2c3c1048746a4622d8c89a29670120dc8fab93c4 (patch)
tree848558de17fb3008cdf4d861b01ac7781903ce39 /sound/soc/pxa/mioa701_wm9713.c
parentInitial commit. (diff)
downloadlinux-2c3c1048746a4622d8c89a29670120dc8fab93c4.tar.xz
linux-2c3c1048746a4622d8c89a29670120dc8fab93c4.zip
Adding upstream version 6.1.76.upstream/6.1.76
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sound/soc/pxa/mioa701_wm9713.c')
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
new file mode 100644
index 000000000..0fa37637e
--- /dev/null
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Handles the Mitac mioa701 SoC system
+ *
+ * Copyright (C) 2008 Robert Jarzmik
+ *
+ * This is a little schema of the sound interconnections :
+ *
+ * Sagem X200 Wolfson WM9713
+ * +--------+ +-------------------+ Rear Speaker
+ * | | | | /-+
+ * | +--->----->---+MONOIN SPKL+--->----+-+ |
+ * | GSM | | | | | |
+ * | +--->----->---+PCBEEP SPKR+--->----+-+ |
+ * | CHIP | | | \-+
+ * | +---<-----<---+MONO |
+ * | | | | Front Speaker
+ * +--------+ | | /-+
+ * | HPL+--->----+-+ |
+ * | | | | |
+ * | OUT3+--->----+-+ |
+ * | | \-+
+ * | |
+ * | | Front Micro
+ * | | +
+ * | MIC1+-----<--+o+
+ * | | +
+ * +-------------------+ ---
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <linux/platform_data/asoc-pxa.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/ac97_codec.h>
+
+#include "../codecs/wm9713.h"
+
+#define AC97_GPIO_PULL 0x58
+
+/* Use GPIO8 for rear speaker amplifier */
+static int rear_amp_power(struct snd_soc_component *component, int power)
+{
+ unsigned short reg;
+
+ if (power) {
+ reg = snd_soc_component_read(component, AC97_GPIO_CFG);
+ snd_soc_component_write(component, AC97_GPIO_CFG, reg | 0x0100);
+ reg = snd_soc_component_read(component, AC97_GPIO_PULL);
+ snd_soc_component_write(component, AC97_GPIO_PULL, reg | (1<<15));
+ } else {
+ reg = snd_soc_component_read(component, AC97_GPIO_CFG);
+ snd_soc_component_write(component, AC97_GPIO_CFG, reg & ~0x0100);
+ reg = snd_soc_component_read(component, AC97_GPIO_PULL);
+ snd_soc_component_write(component, AC97_GPIO_PULL, reg & ~(1<<15));
+ }
+
+ return 0;
+}
+
+static int rear_amp_event(struct snd_soc_dapm_widget *widget,
+ struct snd_kcontrol *kctl, int event)
+{
+ struct snd_soc_card *card = widget->dapm->card;
+ struct snd_soc_pcm_runtime *rtd;
+ struct snd_soc_component *component;
+
+ rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]);
+ component = asoc_rtd_to_codec(rtd, 0)->component;
+ return rear_amp_power(component, SND_SOC_DAPM_EVENT_ON(event));
+}
+
+/* mioa701 machine dapm widgets */
+static const struct snd_soc_dapm_widget mioa701_dapm_widgets[] = {
+ SND_SOC_DAPM_SPK("Front Speaker", NULL),
+ SND_SOC_DAPM_SPK("Rear Speaker", rear_amp_event),
+ SND_SOC_DAPM_MIC("Headset", NULL),
+ SND_SOC_DAPM_LINE("GSM Line Out", NULL),
+ SND_SOC_DAPM_LINE("GSM Line In", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Front Mic", NULL),
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+ /* Call Mic */
+ {"Mic Bias", NULL, "Front Mic"},
+ {"MIC1", NULL, "Mic Bias"},
+
+ /* Headset Mic */
+ {"LINEL", NULL, "Headset Mic"},
+ {"LINER", NULL, "Headset Mic"},
+
+ /* GSM Module */
+ {"MONOIN", NULL, "GSM Line Out"},
+ {"PCBEEP", NULL, "GSM Line Out"},
+ {"GSM Line In", NULL, "MONO"},
+
+ /* headphone connected to HPL, HPR */
+ {"Headset", NULL, "HPL"},
+ {"Headset", NULL, "HPR"},
+
+ /* front speaker connected to HPL, OUT3 */
+ {"Front Speaker", NULL, "HPL"},
+ {"Front Speaker", NULL, "OUT3"},
+
+ /* rear speaker connected to SPKL, SPKR */
+ {"Rear Speaker", NULL, "SPKL"},
+ {"Rear Speaker", NULL, "SPKR"},
+};
+
+static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
+
+ /* Prepare GPIO8 for rear speaker amplifier */
+ snd_soc_component_update_bits(component, AC97_GPIO_CFG, 0x100, 0x100);
+
+ /* Prepare MIC input */
+ snd_soc_component_update_bits(component, AC97_3D_CONTROL, 0xc000, 0xc000);
+
+ return 0;
+}
+
+static struct snd_soc_ops mioa701_ops;
+
+SND_SOC_DAILINK_DEFS(ac97,
+ DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")),
+ DAILINK_COMP_ARRAY(COMP_CODEC("wm9713-codec", "wm9713-hifi")),
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
+
+SND_SOC_DAILINK_DEFS(ac97_aux,
+ DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")),
+ DAILINK_COMP_ARRAY(COMP_CODEC("wm9713-codec", "wm9713-aux")),
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
+
+static struct snd_soc_dai_link mioa701_dai[] = {
+ {
+ .name = "AC97",
+ .stream_name = "AC97 HiFi",
+ .init = mioa701_wm9713_init,
+ .ops = &mioa701_ops,
+ SND_SOC_DAILINK_REG(ac97),
+ },
+ {
+ .name = "AC97 Aux",
+ .stream_name = "AC97 Aux",
+ .ops = &mioa701_ops,
+ SND_SOC_DAILINK_REG(ac97_aux),
+ },
+};
+
+static struct snd_soc_card mioa701 = {
+ .name = "MioA701",
+ .owner = THIS_MODULE,
+ .dai_link = mioa701_dai,
+ .num_links = ARRAY_SIZE(mioa701_dai),
+
+ .dapm_widgets = mioa701_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(mioa701_dapm_widgets),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
+};
+
+static int mioa701_wm9713_probe(struct platform_device *pdev)
+{
+ int rc;
+
+ if (!machine_is_mioa701())
+ return -ENODEV;
+
+ mioa701.dev = &pdev->dev;
+ rc = devm_snd_soc_register_card(&pdev->dev, &mioa701);
+ if (!rc)
+ dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will "
+ "lead to overheating and possible destruction of your device."
+ " Do not use without a good knowledge of mio's board design!\n");
+ return rc;
+}
+
+static struct platform_driver mioa701_wm9713_driver = {
+ .probe = mioa701_wm9713_probe,
+ .driver = {
+ .name = "mioa701-wm9713",
+ .pm = &snd_soc_pm_ops,
+ },
+};
+
+module_platform_driver(mioa701_wm9713_driver);
+
+/* Module information */
+MODULE_AUTHOR("Robert Jarzmik (rjarzmik@free.fr)");
+MODULE_DESCRIPTION("ALSA SoC WM9713 MIO A701");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mioa701-wm9713");