drivers/soundwire/alc5682: Support Realtek ALC5682 SoundWire device
The ALC5682 headset codec can be connected over SoundWire and be configured for mainboards to use: - Data Port 0 and Bulk Register Access is supported - Data Ports 1-4 are supported as both source and sink The data port and audio mode 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. For example this device is connected to master link ID 0 and has strap settings configuring it for unique ID 1: chip drivers/soundwire/alc5682 register "desc" = ""Headset Codec"" device generic 0.1 on end end This driver was tested with the volteer reference design by booting and disassembling the runtime SSDT to ensure that the devices have the expected address and properties. Device (SW01) { Name (_ADR, 0x000021025D568200) Name (_DDN, "Headset Codec") Name (_DSD, Package () { ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () { "mipi-sdw-sw-interface-revision", 0x00010000 }, [...] }, ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), Package () { Package () { "mipi-sdw-port-bra-mode-0", "BRA0" }, Package () { "mipi-sdw-dp-0-subproperties", "DP0" }, Package () { "mipi-sdw-port-audio-mode-0", "MOD0" }, Package () { "mipi-sdw-dp-1-source-subproperties", "SRC1" }, Package () { "mipi-sdw-dp-1-sink-subproperties", "SNK1" }, [...] } } Name (BRA0, Package () { ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () { "mipi-sdw-bra-mode-bus-frequency-configs", Package () { 0x000F4240, [...] } }, [...] } } Name (DP0, Package () { ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () { "mipi-sdw-bra-flow-controlled", Zero }, [...] }, ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), Package () { Package () { "mipi-sdw-port-bra-mode-0", "BRA0" } } } Name (MOD0, Package () { ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () { "mipi-sdw-audio-mode-bus-frequency-configs", Package () { 0x000F4240, [...] } }, [...] } } Name (SNK1, Package () { ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () { "mipi-sdw-data-port-type", Zero }, [...] }, ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), Package () { Package () { "mipi-sdw-port-audio-mode-0", "MOD0" } } } Name (SNK1, Package () { ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), Package () { Package () { "mipi-sdw-data-port-type", Zero }, [...] }, ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), Package () { Package () { "mipi-sdw-port-audio-mode-0", "MOD0" } } } } BUG=b:146482091 Signed-off-by: Duncan Laurie <dlaurie@google.com> Change-Id: I488dcd81d2e66a6f2c269ab7fa9f7ceaf2cbf003 Reviewed-on: https://review.coreboot.org/c/coreboot/+/40891 Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
e0563cc16e
commit
73ce9fb18a
|
@ -0,0 +1,2 @@
|
|||
config DRIVERS_SOUNDWIRE_ALC5682
|
||||
bool
|
|
@ -0,0 +1 @@
|
|||
ramstage-$(CONFIG_DRIVERS_SOUNDWIRE_ALC5682) += alc5682.c
|
|
@ -0,0 +1,179 @@
|
|||
/* 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/mipi_ids.h>
|
||||
#include <device/path.h>
|
||||
#include <device/soundwire.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
static struct soundwire_address alc5682_address = {
|
||||
.version = SOUNDWIRE_VERSION_1_1,
|
||||
.manufacturer_id = MIPI_MFG_ID_REALTEK,
|
||||
.part_id = MIPI_DEV_ID_REALTEK_ALC5682,
|
||||
.class = MIPI_CLASS_NONE
|
||||
};
|
||||
|
||||
static struct soundwire_slave alc5682_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(1) | SOUNDWIRE_PORT(2) |
|
||||
SOUNDWIRE_PORT(3) | SOUNDWIRE_PORT(4),
|
||||
.sink_port_list = SOUNDWIRE_PORT(1) | SOUNDWIRE_PORT(2) |
|
||||
SOUNDWIRE_PORT(3) | SOUNDWIRE_PORT(4)
|
||||
};
|
||||
|
||||
static struct soundwire_bra_mode alc5682_dp0_bra_mode = {
|
||||
.bus_frequency_configs_count = 7,
|
||||
.bus_frequency_configs = {
|
||||
1000 * KHz, /* 1 MHz */
|
||||
2400 * KHz, /* 2.4 MHz */
|
||||
3000 * KHz, /* 3 MHz */
|
||||
4000 * KHz, /* 4 MHz */
|
||||
4800 * KHz, /* 4.8 MHz */
|
||||
9600 * KHz, /* 9.6 MHz */
|
||||
12000 * KHz, /* 12 MHz */
|
||||
},
|
||||
.max_data_per_frame = 470,
|
||||
.min_us_between_transactions = 0
|
||||
};
|
||||
|
||||
static struct soundwire_dp0 alc5682_dp0 = {
|
||||
.port_max_wordlength = 64,
|
||||
.port_min_wordlength = 1,
|
||||
.bra_imp_def_response_supported = false,
|
||||
.simplified_channel_prepare_sm = true,
|
||||
.imp_def_dp0_interrupts_supported = 0,
|
||||
.imp_def_bpt_supported = true,
|
||||
.bra_mode_count = 1,
|
||||
.bra_mode_list = { 0 }
|
||||
};
|
||||
|
||||
static struct soundwire_audio_mode alc5682_audio_mode = {
|
||||
.bus_frequency_configs_count = 7,
|
||||
.bus_frequency_configs = {
|
||||
1000 * KHz, /* 1 MHz */
|
||||
2400 * KHz, /* 2.4 MHz */
|
||||
3000 * KHz, /* 3 MHz */
|
||||
4000 * KHz, /* 4 MHz */
|
||||
4800 * KHz, /* 4.8 MHz */
|
||||
9600 * KHz, /* 9.6 MHz */
|
||||
12000 * KHz, /* 12 MHz */
|
||||
},
|
||||
/* Support 8 KHz to 192 KHz sampling frequency */
|
||||
.max_sampling_frequency = 192 * KHz,
|
||||
.min_sampling_frequency = 8 * KHz,
|
||||
.prepare_channel_behavior = CHANNEL_PREPARE_ANY_FREQUENCY
|
||||
};
|
||||
|
||||
static struct soundwire_dpn alc5682_dpn = {
|
||||
.port_wordlength_configs_count = 3,
|
||||
.port_wordlength_configs = { 16, 20, 24 },
|
||||
.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 alc5682_codec = {
|
||||
.slave = &alc5682_slave,
|
||||
.dp0_bra_mode = { &alc5682_dp0_bra_mode },
|
||||
.dp0 = &alc5682_dp0,
|
||||
.audio_mode = { &alc5682_audio_mode },
|
||||
.dpn = {
|
||||
{
|
||||
.port = 1,
|
||||
.source = &alc5682_dpn,
|
||||
.sink = &alc5682_dpn,
|
||||
},
|
||||
{
|
||||
.port = 2,
|
||||
.source = &alc5682_dpn,
|
||||
.sink = &alc5682_dpn,
|
||||
},
|
||||
{
|
||||
.port = 3,
|
||||
.source = &alc5682_dpn,
|
||||
.sink = &alc5682_dpn,
|
||||
},
|
||||
{
|
||||
.port = 4,
|
||||
.source = &alc5682_dpn,
|
||||
.sink = &alc5682_dpn,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void soundwire_alc5682_fill_ssdt(const struct device *dev)
|
||||
{
|
||||
struct drivers_soundwire_alc5682_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. */
|
||||
alc5682_address.link_id = dev->path.generic.id;
|
||||
alc5682_address.unique_id = dev->path.generic.subid;
|
||||
|
||||
acpigen_write_ADR_soundwire_device(&alc5682_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, &alc5682_codec, NULL);
|
||||
acpi_dp_write(dsd);
|
||||
|
||||
acpigen_pop_len(); /* Device */
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
||||
|
||||
static const char *soundwire_alc5682_acpi_name(const struct device *dev)
|
||||
{
|
||||
struct drivers_soundwire_alc5682_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_alc5682_ops = {
|
||||
.read_resources = noop_read_resources,
|
||||
.set_resources = noop_set_resources,
|
||||
.acpi_name = soundwire_alc5682_acpi_name,
|
||||
.acpi_fill_ssdt = soundwire_alc5682_fill_ssdt,
|
||||
};
|
||||
|
||||
static void soundwire_alc5682_enable(struct device *dev)
|
||||
{
|
||||
dev->ops = &soundwire_alc5682_ops;
|
||||
}
|
||||
|
||||
struct chip_operations drivers_soundwire_alc5682_ops = {
|
||||
CHIP_NAME("Realtek ALC5682 SoundWire Codec")
|
||||
.enable_dev = soundwire_alc5682_enable
|
||||
};
|
|
@ -0,0 +1,11 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __DRIVERS_SOUNDWIRE_ALC5682_CHIP_H__
|
||||
#define __DRIVERS_SOUNDWIRE_ALC5682_CHIP_H__
|
||||
|
||||
struct drivers_soundwire_alc5682_config {
|
||||
const char *name;
|
||||
const char *desc;
|
||||
};
|
||||
|
||||
#endif /* __DRIVERS_SOUNDWIRE_ALC5682_CHIP_H__ */
|
|
@ -19,6 +19,9 @@
|
|||
#define MIPI_MFG_ID_TOSHIBA 0x0126
|
||||
|
||||
/* Contributing Members */
|
||||
#define MIPI_MFG_ID_REALTEK 0x025d
|
||||
#define MIPI_DEV_ID_REALTEK_ALC5682 0x5682
|
||||
|
||||
#define MIPI_MFG_ID_MAXIM 0x019f
|
||||
#define MIPI_DEV_ID_MAXIM_MAX98373 0x8373
|
||||
|
||||
|
|
Loading…
Reference in New Issue