Anil Kumar K has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/81920?usp=email )
Change subject: drivers/soundwire: Support Realtek ALC722 codec ......................................................................
drivers/soundwire: Support Realtek ALC722 codec
This patch adds soundwire driver to support ALC722 audio codec.
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.
For example this device is connected to master link ID 0 and has strap settings configuring it for unique ID 1:
chip drivers/soundwire/alc722 register "desc" = ""Headset Codec"" device generic 0.1 on end end
TEST=This driver was tested on Intel RVP with on board ALC722 codec by booting and disassembling the runtime SSDT to ensure that the devices have the expected address and properties. Test soundcard binding works and devices are detected and check for audio playback.
Signed-off-by: Anil Kumar anil.kumar.k@intel.com Change-Id: Ieb16a1c6f3a79321fdc35987468daa8be33b6e49 --- A src/drivers/soundwire/alc722/Kconfig A src/drivers/soundwire/alc722/Makefile.mk A src/drivers/soundwire/alc722/alc722.c A src/drivers/soundwire/alc722/chip.h M src/include/mipi/ids.h 5 files changed, 174 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/20/81920/1
diff --git a/src/drivers/soundwire/alc722/Kconfig b/src/drivers/soundwire/alc722/Kconfig new file mode 100644 index 0000000..8d7d6df --- /dev/null +++ b/src/drivers/soundwire/alc722/Kconfig @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +config DRIVERS_SOUNDWIRE_ALC722 + bool diff --git a/src/drivers/soundwire/alc722/Makefile.mk b/src/drivers/soundwire/alc722/Makefile.mk new file mode 100644 index 0000000..ca59033 --- /dev/null +++ b/src/drivers/soundwire/alc722/Makefile.mk @@ -0,0 +1,3 @@ +## SPDX-License-Identifier: GPL-2.0-only + +ramstage-$(CONFIG_DRIVERS_SOUNDWIRE_ALC722) += alc722.c diff --git a/src/drivers/soundwire/alc722/alc722.c b/src/drivers/soundwire/alc722/alc722.c new file mode 100644 index 0000000..5e15bd0 --- /dev/null +++ b/src/drivers/soundwire/alc722/alc722.c @@ -0,0 +1,155 @@ +/* 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/soundwire.h> +#include <mipi/ids.h> +#include <stdio.h> + +#include "chip.h" + +static struct soundwire_address alc722_address = { + .version = SOUNDWIRE_VERSION_1_2, + .manufacturer_id = MIPI_MFG_ID_REALTEK, + .part_id = MIPI_DEV_ID_REALTEK_ALC722, + .class = MIPI_CLASS_SDCA +}; + +static struct soundwire_slave alc722_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), + .sink_port_list = SOUNDWIRE_PORT(1), +}; + +static struct soundwire_audio_mode alc722_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, + 12000 * KHz, + 6000 * KHz, + 3000 * KHz, + 1500 * KHz, + 12288 * KHz, + 6144 * KHz, + 3072 * KHz, + 1536 * KHz + }, + /* Support 16 KHz to 192 KHz sampling frequency */ + .sampling_frequency_configs_count = 9, + .sampling_frequency_configs = { + 16 * KHz, + 22.05 * KHz, + 24 * KHz, + 32 * KHz, + 44.1 * KHz, + 48 * KHz, + 88.2 * KHz, + 96 * KHz, + 192 * KHz + }, + .prepare_channel_behavior = CHANNEL_PREPARE_ANY_FREQUENCY +}; + +static struct soundwire_dpn alc722_dp = { + .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 alc722_codec = { + .slave = &alc722_slave, + .audio_mode = { &alc722_audio_mode }, + .dpn = { + { + /* Data Input for Speaker Path */ + .port = 1, + .sink = &alc722_dp + }, + { + /* Data Output for DSP Path */ + .port = 2, + .source = &alc722_dp + } + } + +}; + +static void soundwire_alc722_fill_ssdt(const struct device *dev) +{ + struct drivers_soundwire_alc722_config *config = dev->chip_info; + const char *scope = acpi_device_scope(dev); + struct acpi_dp *dsd; + + if (!scope) + return; + + acpigen_write_scope(scope); + acpigen_write_device(acpi_device_name(dev)); + + /* Set codec address IDs. */ + alc722_address.link_id = dev->path.generic.id; + alc722_address.unique_id = dev->path.generic.subid; + + acpigen_write_ADR_soundwire_device(&alc722_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, &alc722_codec, NULL); + acpi_dp_write(dsd); + + acpigen_pop_len(); /* Device */ + acpigen_pop_len(); /* Scope */ +} + +static const char *soundwire_alc722_acpi_name(const struct device *dev) +{ + struct drivers_soundwire_alc722_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_alc722_ops = { + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, + .acpi_name = soundwire_alc722_acpi_name, + .acpi_fill_ssdt = soundwire_alc722_fill_ssdt, +}; + +static void soundwire_alc722_enable(struct device *dev) +{ + dev->ops = &soundwire_alc722_ops; +} + +struct chip_operations drivers_soundwire_alc722_ops = { + .name = "Realtek ALC722 SoundWire Codec", + .enable_dev = soundwire_alc722_enable +}; diff --git a/src/drivers/soundwire/alc722/chip.h b/src/drivers/soundwire/alc722/chip.h new file mode 100644 index 0000000..87d8b98 --- /dev/null +++ b/src/drivers/soundwire/alc722/chip.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __DRIVERS_SOUNDWIRE_ALC722_CHIP_H__ +#define __DRIVERS_SOUNDWIRE_ALC722_CHIP_H__ + +struct drivers_soundwire_alc722_config { + const char *name; + const char *desc; +}; + +#endif /* __DRIVERS_SOUNDWIRE_ALC722_CHIP_H__ */ diff --git a/src/include/mipi/ids.h b/src/include/mipi/ids.h index 5aa5a67..4e54b62 100644 --- a/src/include/mipi/ids.h +++ b/src/include/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_ALC722 0x0722 #define MIPI_DEV_ID_REALTEK_ALC1308 0x1308
#define MIPI_MFG_ID_MAXIM 0x019f