aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnil Kumar <anil.kumar.k@intel.com>2020-09-18 15:30:56 -0700
committerPatrick Georgi <pgeorgi@google.com>2021-02-27 09:41:42 +0000
commitd7c31d1dbe89a54db8e244c2b0d746f58a1bd8ad (patch)
tree6a503208d467b5fffcb53d73dd11a923809d9f6a
parent5f5ea02b3d09aefebb078cc3df4fa5a9398c6cc0 (diff)
drivers/soundwire/alc1308 : Add ALC1308 soundwire device
This patch adds new soundwire device ALC1308 The codec properties are filled out as best as possible with the datasheet as a reference. The ACPI address for the codec is calculated with the information in the codec driver combined with the devicetree.cb hierarchy where the link and unique IDs are extracted from the device path. The unique ID is calculated from schematics by referring to ASEL[1:0] strap settings. Datasheet of ALC1308 provides info about the mapping of ASEL strap settings to unique ID For example this device is connected to master link ID 1 and has strap settings configuring it for unique ID 2. chip drivers/soundwire/alc1308 register "desc" = ""Left Speaker"" device generic 1.2 on end end Bug=None Test=Build and boot on TGLRVP.Extract SSDT and confirm that the entries for PCI0.HDAS.SNDW are present for ALC1308 Test speaker out functionality Signed-off-by: Anil Kumar <anil.kumar.k@intel.com> Change-Id: Ibf3f1d5c6881cbd106e96ad1ff17ca216aa272ac Reviewed-on: https://review.coreboot.org/c/coreboot/+/51042 Reviewed-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-by: Sathyanarayana Nujella Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r--src/drivers/soundwire/alc1308/Kconfig2
-rw-r--r--src/drivers/soundwire/alc1308/Makefile.inc1
-rw-r--r--src/drivers/soundwire/alc1308/alc1308.c151
-rw-r--r--src/drivers/soundwire/alc1308/chip.h11
-rw-r--r--src/include/device/mipi_ids.h1
5 files changed, 166 insertions, 0 deletions
diff --git a/src/drivers/soundwire/alc1308/Kconfig b/src/drivers/soundwire/alc1308/Kconfig
new file mode 100644
index 0000000000..c2e97313c1
--- /dev/null
+++ b/src/drivers/soundwire/alc1308/Kconfig
@@ -0,0 +1,2 @@
+config DRIVERS_SOUNDWIRE_ALC1308
+ bool
diff --git a/src/drivers/soundwire/alc1308/Makefile.inc b/src/drivers/soundwire/alc1308/Makefile.inc
new file mode 100644
index 0000000000..6c3458fa0e
--- /dev/null
+++ b/src/drivers/soundwire/alc1308/Makefile.inc
@@ -0,0 +1 @@
+ramstage-$(CONFIG_DRIVERS_SOUNDWIRE_ALC1308) += alc1308.c
diff --git a/src/drivers/soundwire/alc1308/alc1308.c b/src/drivers/soundwire/alc1308/alc1308.c
new file mode 100644
index 0000000000..df60d47bf7
--- /dev/null
+++ b/src/drivers/soundwire/alc1308/alc1308.c
@@ -0,0 +1,151 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <acpi/acpigen.h>
+#include <acpi/acpi_device.h>
+#include <acpi/acpi_soundwire.h>
+#include <device/device.h>
+#include <device/path.h>
+#include <device/mipi_ids.h>
+#include <device/soundwire.h>
+#include <stdio.h>
+
+#include "chip.h"
+
+static struct soundwire_address alc1308_address = {
+ .version = SOUNDWIRE_VERSION_1_1,
+ .manufacturer_id = MIPI_MFG_ID_REALTEK,
+ .part_id = MIPI_DEV_ID_REALTEK_ALC1308,
+ .class = MIPI_CLASS_NONE
+};
+
+static struct soundwire_slave alc1308_slave = {
+ .wake_up_unavailable = false,
+ .test_mode_supported = false,
+ .clock_stop_mode1_supported = true,
+ .simplified_clockstopprepare_sm_supported = true,
+ .clockstopprepare_hard_reset_behavior = false,
+ .highPHY_capable = false,
+ .paging_supported = false,
+ .bank_delay_supported = false,
+ .port15_read_behavior = false,
+ .source_port_list = SOUNDWIRE_PORT(2) | SOUNDWIRE_PORT(4),
+ .sink_port_list = SOUNDWIRE_PORT(1)
+};
+
+static struct soundwire_audio_mode alc1308_audio_mode = {
+ /* Bus frequency must be 1/2/4/8 divider of supported input frequencies. */
+ .bus_frequency_configs_count = 12,
+ .bus_frequency_configs = {
+ 9600 * KHz, 4800 * KHz, 2400 * KHz, 1200 * KHz, /* 9.6 MHz */
+ 12000 * KHz, 6000 * KHz, 3000 * KHz, 1500 * KHz, /* 12 MHz */
+ 12288 * KHz, 6144 * KHz, 3072 * KHz, 1536 * KHz /* 12.288 MHz */
+ },
+ /* Support 16 KHz to 96 KHz sampling frequency */
+ .sampling_frequency_configs_count = 8,
+ .sampling_frequency_configs = {
+ 16 * KHz,
+ 22.05 * KHz,
+ 24 * KHz,
+ 32 * KHz,
+ 44.1 * KHz,
+ 48 * KHz,
+ 88.2 * KHz,
+ 96 * KHz,
+ },
+ .prepare_channel_behavior = CHANNEL_PREPARE_ANY_FREQUENCY
+};
+
+static struct soundwire_dpn alc1308_dp1 = {
+ .port_wordlength_configs_count = 1,
+ .port_wordlength_configs = { 32 },
+ .data_port_type = FULL_DATA_PORT,
+ .max_grouping_supported = BLOCK_GROUP_COUNT_1,
+ .simplified_channelprepare_sm = false,
+ .imp_def_dpn_interrupts_supported = 0,
+ .min_channel_number = 1,
+ .max_channel_number = 2,
+ .modes_supported = MODE_ISOCHRONOUS | MODE_TX_CONTROLLED |
+ MODE_RX_CONTROLLED | MODE_FULL_ASYNCHRONOUS,
+ .block_packing_mode = true,
+ .port_audio_mode_count = 1,
+ .port_audio_mode_list = { 0 }
+};
+
+static const struct soundwire_codec alc1308_codec = {
+ .slave = &alc1308_slave,
+ .audio_mode = { &alc1308_audio_mode },
+ .dpn = {
+ {
+ /* Data Input for Speaker Path */
+ .port = 1,
+ .sink = &alc1308_dp1
+ },
+ {
+ /* Data out for I.V sensing */
+ .port = 2,
+ .source = &alc1308_dp1
+ },
+ {
+ /* Data out for I.V sensing */
+ .port = 4,
+ .source = &alc1308_dp1
+ }
+ }
+
+};
+
+static void soundwire_alc1308_fill_ssdt(const struct device *dev)
+{
+ struct drivers_soundwire_alc1308_config *config = dev->chip_info;
+ const char *scope = acpi_device_scope(dev);
+ struct acpi_dp *dsd;
+
+ if (!dev->enabled || !scope)
+ return;
+
+ acpigen_write_scope(scope);
+ acpigen_write_device(acpi_device_name(dev));
+
+ /* Set codec address IDs. */
+ alc1308_address.link_id = dev->path.generic.id;
+ alc1308_address.unique_id = dev->path.generic.subid;
+
+ acpigen_write_ADR_soundwire_device(&alc1308_address);
+ acpigen_write_name_string("_DDN", config->desc ? : dev->chip_ops->name);
+ acpigen_write_STA(acpi_device_status(dev));
+
+ dsd = acpi_dp_new_table("_DSD");
+ soundwire_gen_codec(dsd, &alc1308_codec, NULL);
+ acpi_dp_write(dsd);
+
+ acpigen_pop_len(); /* Device */
+ acpigen_pop_len(); /* Scope */
+}
+
+static const char *soundwire_alc1308_acpi_name(const struct device *dev)
+{
+ struct drivers_soundwire_alc1308_config *config = dev->chip_info;
+ static char name[5];
+
+ if (config->name)
+ return config->name;
+ snprintf(name, sizeof(name), "SW%1X%1X", dev->path.generic.id, dev->path.generic.subid);
+ return name;
+}
+
+static struct device_operations soundwire_alc1308_ops = {
+ .read_resources = noop_read_resources,
+ .set_resources = noop_set_resources,
+ .acpi_name = soundwire_alc1308_acpi_name,
+ .acpi_fill_ssdt = soundwire_alc1308_fill_ssdt,
+};
+
+static void soundwire_alc1308_enable(struct device *dev)
+{
+ dev->ops = &soundwire_alc1308_ops;
+}
+
+struct chip_operations drivers_soundwire_alc1308_ops = {
+ CHIP_NAME("Realtek ALC1308 SoundWire Codec")
+ .enable_dev = soundwire_alc1308_enable
+};
diff --git a/src/drivers/soundwire/alc1308/chip.h b/src/drivers/soundwire/alc1308/chip.h
new file mode 100644
index 0000000000..ed07cff5c4
--- /dev/null
+++ b/src/drivers/soundwire/alc1308/chip.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __DRIVERS_SOUNDWIRE_ALC1308_CHIP_H__
+#define __DRIVERS_SOUNDWIRE_ALC1308_CHIP_H__
+
+struct drivers_soundwire_alc1308_config {
+ const char *name;
+ const char *desc;
+};
+
+#endif /* __DRIVERS_SOUNDWIRE_ALC1308_CHIP_H__ */
diff --git a/src/include/device/mipi_ids.h b/src/include/device/mipi_ids.h
index 951caaacaa..50faba7806 100644
--- a/src/include/device/mipi_ids.h
+++ b/src/include/device/mipi_ids.h
@@ -21,6 +21,7 @@
#define MIPI_MFG_ID_REALTEK 0x025d
#define MIPI_DEV_ID_REALTEK_ALC5682 0x5682
#define MIPI_DEV_ID_REALTEK_ALC711 0x0711
+#define MIPI_DEV_ID_REALTEK_ALC1308 0x1308
#define MIPI_MFG_ID_MAXIM 0x019f
#define MIPI_DEV_ID_MAXIM_MAX98373 0x8373