[PATCH 1/6] sound: ti: Add sound support for am625 board in Uboot
Scaria Kochidanadu
s-kochidanadu at ti.com
Mon Jul 8 09:52:02 CEST 2024
Add a UCLASS_SOUND driver for Texas Instruments SoCs which ties together
the tlv320aic3106 audio codec and MCASP I2S controller. Enable audio
playback functionality by taking a data pointer and data size as the
sound data. The uboot sound play command takes time and frequency as
input and creates the data for a beep sound with the given parameters,
which is then passed to the sound play function.
The code is based on the samsung sound driver[1] in uboot.
Link: https://gitlab.com/u-boot/u-boot/-/blob/master/drivers/sound/samsung_sound.c [1]
Signed-off-by: Scaria Kochidanadu <s-kochidanadu at ti.com>
---
MAINTAINERS | 1 +
drivers/sound/Kconfig | 10 ++++
drivers/sound/Makefile | 1 +
drivers/sound/ti_sound.c | 119 +++++++++++++++++++++++++++++++++++++++
4 files changed, 131 insertions(+)
create mode 100644 drivers/sound/ti_sound.c
diff --git a/MAINTAINERS b/MAINTAINERS
index f8afd7d51e..785afff1a7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -738,6 +738,7 @@ F: drivers/reset/reset-ti-sci.c
F: drivers/rtc/davinci.c
F: drivers/serial/serial_omap.c
F: drivers/soc/ti/
+F: drivers/sound/ti_sound.c
F: drivers/sysreset/sysreset-ti-sci.c
F: drivers/thermal/ti-bandgap.c
F: drivers/timer/omap-timer.c
diff --git a/drivers/sound/Kconfig b/drivers/sound/Kconfig
index 0948d8caab..be9f18b6c7 100644
--- a/drivers/sound/Kconfig
+++ b/drivers/sound/Kconfig
@@ -148,4 +148,14 @@ config SOUND_WM8994
audio data and I2C for codec control. At present it only works
with the Samsung I2S driver.
+config I2S_TI
+ bool "Enable I2S support for AM62x SoCs"
+ depends on I2S
+ help
+ TI AM62x SoCs support an I2S interface for sending audio
+ data to an audio codec. This option enables support for this,
+ using one of the available audio codec drivers. Enabling this
+ option provides an implementation for sound_init() and
+ sound_play().
+
endmenu
diff --git a/drivers/sound/Makefile b/drivers/sound/Makefile
index 9b40c8012f..95aaa8521c 100644
--- a/drivers/sound/Makefile
+++ b/drivers/sound/Makefile
@@ -23,3 +23,4 @@ obj-$(CONFIG_SOUND_I8254) += i8254_beep.o
obj-$(CONFIG_SOUND_RT5677) += rt5677.o
obj-$(CONFIG_INTEL_BROADWELL) += broadwell_i2s.o broadwell_sound.o
obj-$(CONFIG_SOUND_IVYBRIDGE) += ivybridge_sound.o
+obj-$(CONFIG_I2S_TI) += ti_sound.o
diff --git a/drivers/sound/ti_sound.c b/drivers/sound/ti_sound.c
new file mode 100644
index 0000000000..a424a99b72
--- /dev/null
+++ b/drivers/sound/ti_sound.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2024 Texas Instruments Incorporated - https://www.ti.com/
+ * Scaria M Kochidanadu, s-kochidanadu at ti.com
+ *
+ * based on the uboot samsung sound driver, which is
+ *
+ * Copyright 2018 Google, LLC
+ * Written by Simon Glass <sjg at chromium.org>
+ */
+
+#include <asm/u-boot.h> /* boot information for Linux kernel */
+/* Pull in stuff for the build system */
+#ifdef DO_DEPS_ONLY
+#include <env_internal.h>
+#endif
+#include <audio_codec.h>
+#include <dm.h>
+#include <i2s.h>
+#include <log.h>
+#include <sound.h>
+#include <asm/gpio.h>
+
+static int ti_sound_setup(struct udevice *dev)
+{
+ struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct i2s_uc_priv *i2s_priv = dev_get_uclass_priv(uc_priv->i2s);
+ int ret;
+
+ if (uc_priv->setup_done)
+ return -EALREADY;
+
+ ret = audio_codec_set_params(uc_priv->codec, i2s_priv->id,
+ i2s_priv->samplingrate,
+ i2s_priv->samplingrate * i2s_priv->rfs,
+ i2s_priv->bitspersample,
+ i2s_priv->channels);
+
+ if (ret) {
+ return ret;
+ printf("failed in set_params\n");
+ }
+ uc_priv->setup_done = true;
+
+ return 0;
+}
+
+static int ti_sound_play(struct udevice *dev, void *data, uint data_size)
+{
+ struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev);
+
+ return i2s_tx_data(uc_priv->i2s, data, data_size);
+}
+
+static int ti_sound_stop_play(struct udevice *dev)
+{
+ /* This function is necassary to satisfy the function calls
+ * in the Uboot command: sound play
+ */
+ return 0;
+}
+
+static int ti_sound_probe(struct udevice *dev)
+{
+ struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev);
+ struct ofnode_phandle_args args;
+ ofnode node;
+ int ret;
+
+ ret = uclass_get_device_by_phandle(UCLASS_AUDIO_CODEC, dev,
+ "ti,codec",
+ &uc_priv->codec);
+ if (ret) {
+ debug("Failed to probe audio codec\n");
+ return ret;
+ }
+
+ node = ofnode_find_subnode(dev_ofnode(dev), "simple-audio-card,cpu");
+ if (!ofnode_valid(node)) {
+ debug("Failed to find /cpu subnode\n");
+ return -EINVAL;
+ }
+
+ ret = ofnode_parse_phandle_with_args(node, "sound-dai",
+ "#sound-dai-cells", 0, 0, &args);
+ if (ret) {
+ debug("Cannot find phandle: %d\n", ret);
+ return ret;
+ }
+
+ ret = uclass_get_device_by_ofnode(UCLASS_I2S, args.node, &uc_priv->i2s);
+ if (ret) {
+ debug("Cannot find i2s: %d\n", ret);
+ return ret;
+ }
+ debug("Probed sound '%s' with codec '%s' and i2s '%s'\n", dev->name,
+ uc_priv->codec->name, uc_priv->i2s->name);
+
+ return 0;
+}
+
+static const struct sound_ops ti_sound_ops = {
+ .setup = ti_sound_setup,
+ .play = ti_sound_play,
+ .stop_play = ti_sound_stop_play,
+};
+
+static const struct udevice_id ti_sound_ids[] = {
+ { .compatible = "simple-audio-card" },
+ { }
+};
+
+U_BOOT_DRIVER(ti_sound) = {
+ .name = "ti_sound",
+ .id = UCLASS_SOUND,
+ .of_match = ti_sound_ids,
+ .probe = ti_sound_probe,
+ .ops = &ti_sound_ops,
+};
--
2.34.1
More information about the U-Boot
mailing list