drivers/sof: Add new driver to generate ACPI _DSD table

Add a new chip driver for boards which use SOF (Sound Open Firmware)
OS drivers, which will be attached to the HDAS device and generate
entries in an ACPI _DSD table for the OS driver to use. This will allow
the OS drivers to easily determine the correct topology for the speaker
and jack amplifiers and correct microphone configuration.

TEST=tested with rest of patch train

Change-Id: Ie0431b2002287f35245cbf959828e931d7f375b2
Signed-off-by: Matt DeVillier <matt.devillier@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/74813
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: CoolStar <coolstarorganization@gmail.com>
Reviewed-by: Martin Roth <martin.roth@amd.corp-partner.google.com>
diff --git a/src/drivers/sof/Kconfig b/src/drivers/sof/Kconfig
new file mode 100644
index 0000000..3d8bdd3
--- /dev/null
+++ b/src/drivers/sof/Kconfig
@@ -0,0 +1,3 @@
+config DRIVERS_AUDIO_SOF
+	bool
+	depends on HAVE_ACPI_TABLES
diff --git a/src/drivers/sof/Makefile.inc b/src/drivers/sof/Makefile.inc
new file mode 100644
index 0000000..6faabe4
--- /dev/null
+++ b/src/drivers/sof/Makefile.inc
@@ -0,0 +1 @@
+ramstage-$(CONFIG_DRIVERS_AUDIO_SOF) += sof.c
diff --git a/src/drivers/sof/chip.h b/src/drivers/sof/chip.h
new file mode 100644
index 0000000..134c0de
--- /dev/null
+++ b/src/drivers/sof/chip.h
@@ -0,0 +1,43 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __DRIVERS_AUDIO_SOF_H__
+#define __DRIVERS_AUDIO_SOF_H__
+
+#include <acpi/acpi_device.h>
+#include <stdint.h>
+
+/* Speaker topology */
+enum _spkr_tplg {
+	max98373 = 1,
+	max98360a,
+	max98357a,
+	max98390,
+	rt1011,
+	rt1015,
+};
+
+/* Jack topology */
+enum _jack_tplg {
+	cs42l42 = 1,
+	da7219,
+	nau8825,
+	rt5682,
+};
+
+/* Mic topology */
+enum _mic_tplg {
+	_1ch = 1,
+	_2ch_pdm0,
+	_2ch_pdm1,
+	_4ch,
+};
+
+
+
+struct drivers_sof_config {
+	unsigned int spkr_tplg;
+	unsigned int jack_tplg;
+	unsigned int mic_tplg;
+};
+
+#endif /* __DRIVERS_AUDIO_SOF_H__ */
diff --git a/src/drivers/sof/sof.c b/src/drivers/sof/sof.c
new file mode 100644
index 0000000..d11f730
--- /dev/null
+++ b/src/drivers/sof/sof.c
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <acpi/acpi_device.h>
+#include <acpi/acpigen.h>
+#include <device/device.h>
+#include <device/path.h>
+#include <string.h>
+
+#include "chip.h"
+
+static const char *get_spkr_tplg_str(unsigned int index)
+{
+	switch (index) {
+		case 1: return "max98373";
+		case 2: return "max98360a";
+		case 3: return "max98357a";
+		case 4: return "max98390";
+		case 5: return "rt1011";
+		case 6: return "rt1015";
+		default: return "default";
+	}
+}
+
+static const char *get_jack_tplg_str(unsigned int index)
+{
+	switch (index) {
+		case 1: return "cs42l42";
+		case 2: return "da7219";
+		case 3: return "nau8825";
+		case 4: return "rt5682";
+		default: return "default";
+	}
+}
+
+static const char *get_mic_tplg_str(unsigned int index)
+{
+	switch (index) {
+		case 1: return "1ch";
+		case 2: return "2ch-pdm0";
+		case 3: return "2ch-pdm1";
+		case 4: return "4ch";
+		default: return "default";
+	}
+}
+
+static void sof_fill_ssdt_generator(const struct device *dev)
+{
+	struct drivers_sof_config *config = dev->chip_info;
+	const char *scope = acpi_device_scope(dev);
+	struct acpi_dp *dsd;
+
+	if (!dev->enabled || !config || !scope)
+		return;
+
+	/* Device */
+	acpigen_write_scope(scope);
+
+	/* DSD */
+	dsd = acpi_dp_new_table("_DSD");
+	acpi_dp_add_string(dsd, "speaker-tplg",
+				get_spkr_tplg_str(config->spkr_tplg));
+	acpi_dp_add_string(dsd, "hp-tplg",
+				get_jack_tplg_str(config->jack_tplg));
+	acpi_dp_add_string(dsd, "mic-tplg",
+				get_mic_tplg_str(config->mic_tplg));
+	acpi_dp_write(dsd);
+	acpigen_pop_len(); /* Scope */
+}
+
+
+static struct device_operations sof_ops = {
+	.read_resources		= noop_read_resources,
+	.set_resources		= noop_set_resources,
+	.acpi_fill_ssdt		= sof_fill_ssdt_generator,
+};
+
+static void sof_enable(struct device *dev)
+{
+	dev->ops = &sof_ops;
+}
+
+struct chip_operations drivers_sof_ops = {
+	CHIP_NAME("SOF")
+	.enable_dev = sof_enable
+};