drivers/soundwire/cs42l43: Support Cirrus Logic CS42L43 codec
CS42L43 is a PC Codec with headphone and class D speaker drivers.
The driver was written based on the datasheet for CS42L43 part and
generates the audio SSDT information.
CS42L43 supports DisCo Version v2.1, but coreboot currently only
supports DisCo v1.0, so ACPI is only generated based on DisCo v1.0.
CS42L43 also supports the SDCA v1.0 Specification (from DisCo v2.1)
is also not currently supported by coreboot, therefore SDCA ACPI
properties are also not generated.
This is currently only tested using QEMU using example configuration:
chip drivers/soundwire/cs42l43
# SoundWire Link 0 ID 1
register "desc" = ""CODEC""
register "sub" = ""1337""
device generic 0.1 on end
end
Which produces the ACPI:
Device (SW01)
{
Name (_ADR, 0x00003101FA424301) // _ADR: Address
Name (_DDN, "CODEC") // _DDN: DOS Device Name
Name (_SUB, "1337") // _SUB: Subsystem ID
Method (_STA, 0, NotSerialized) // _STA: Status
{
Return (0x0F)
}
Name (_DSD, Package (0x04) // _DSD: Device-Specific Data
{
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */,
Package (0x0F)
{
Package (0x02)
{
"mipi-sdw-sw-interface-revision",
0x00010000
},
Package (0x02)
{
"mipi-sdw-wake-up-unavailable",
Zero
},
Package (0x02)
{
"mipi-sdw-test-mode-supported",
Zero
},
Package (0x02)
{
"mipi-sdw-clock-stop-mode1-supported",
Zero
},
Package (0x02)
{
"mipi-sdw-simplified-clockstopprepare-sm-supported",
Zero
},
Package (0x02)
{
"mipi-sdw-clockstopprepare-timeout",
Zero
},
Package (0x02)
{
"mipi-sdw-clockstopprepare-hard-reset-behavior",
Zero
},
Package (0x02)
{
"mipi-sdw-slave-channelprepare-timeout",
Zero
},
Package (0x02)
{
"mipi-sdw-highPHY-capable",
Zero
},
Package (0x02)
{
"mipi-sdw-paging-supported",
One
},
Package (0x02)
{
"mipi-sdw-bank-delay-supported",
Zero
},
Package (0x02)
{
"mipi-sdw-port15-read-behavior",
Zero
},
Package (0x02)
{
"mipi-sdw-master-count",
Zero
},
Package (0x02)
{
"mipi-sdw-source-port-list",
0x06
},
Package (0x02)
{
"mipi-sdw-sink-port-list",
0x60
}
},
ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b") /* Hierarchical Data Extension */,
Package (0x06)
{
Package (0x02)
{
"mipi-sdw-port-bra-mode-0",
"BRA0"
},
Package (0x02)
{
"mipi-sdw-dp-0-subproperties",
"DP0"
},
Package (0x02)
{
"mipi-sdw-dp-2-source-subproperties",
"SRC2"
},
Package (0x02)
{
"mipi-sdw-dp-5-sink-subproperties",
"SNK5"
},
Package (0x02)
{
"mipi-sdw-dp-1-sink-subproperties",
"SNK1"
},
Package (0x02)
{
"mipi-sdw-dp-6-source-subproperties",
"SRC6"
}
}
})
Name (BRA0, Package (0x02)
{
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */,
Package (0x04)
{
Package (0x02)
{
"mipi-sdw-bra-mode-min-bus-frequency",
Zero
},
Package (0x02)
{
"mipi-sdw-bra-mode-max-bus-frequency",
Zero
},
Package (0x02)
{
"mipi-sdw-bra-mode-max-data-per-frame",
0x01D6
},
Package (0x02)
{
"mipi-sdw-bra-mode-min-us-between-transactions",
Zero
}
}
})
Name (DP0, Package (0x04)
{
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */,
Package (0x07)
{
Package (0x02)
{
"mipi-sdw-port-wordlength-configs",
Package (0x03)
{
0x08,
0x10,
0x18
}
},
Package (0x02)
{
"mipi-sdw-bra-flow-controlled",
One
},
Package (0x02)
{
"mipi-sdw-bra-imp-def-response-supported",
One
},
Package (0x02)
{
"mipi-sdw-bra-role-supported",
One
},
Package (0x02)
{
"mipi-sdw-simplified-channel-prepare-sm",
Zero
},
Package (0x02)
{
"mipi-sdw-imp-def-dp0-interrupts-supported",
Zero
},
Package (0x02)
{
"mipi-sdw-imp-def-bpt-supported",
Zero
}
},
ToUUID ("dbb8e3e6-5886-4ba6-8795-1319f52a966b") /* Hierarchical Data Extension */,
Package (0x01)
{
Package (0x02)
{
"mipi-sdw-port-bra-mode-0",
"BRA0"
}
}
})
Name (SRC2, Package (0x02)
{
ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */,
Package (0x0C)
{
Package (0x02)
{
"mipi-sdw-data-port-type",
Zero
},
Package (0x02)
{
"mipi-sdw-max-grouping-supported",
Zero
},
Package (0x02)
{
"mipi-sdw-imp-def-dpn-interrupts-supported",
Zero
},
Package (0x02)
{
"mipi-sdw-modes-supported",
One
},
Package (0x02)
{
"mipi-sdw-max-async-buffer",
Zero
},
Package (0x02)
{
"mipi-sdw-block-packing-mode",
One
},
Package (0x02)
{
"mipi-sdw-port-encoding-type",
One
},
Package (0x02)
{
"mipi-sdw-port-wordlength-configs",
Package (0x03)
{
0x08,
0x10,
0x18
}
},
Package (0x02)
{
"mipi-sdw-simplified-channelprepare-sm",
Zero
},
Package (0x02)
{
"mipi-sdw-port-channelprepare-timeout",
Zero
},
Package (0x02)
{
"mipi-sdw-channel-number-list",
Package (0x02)
{
Zero,
One
}
},
Package (0x02)
{
"mipi-sdw-channel-combination-list",
Package (0x03)
{
0x03,
0x02,
One
}
}
}
})
Name (SNK5, Package (0x02)
{
[... Same as SRC2 ...]
})
Name (SNK1, Package (0x02)
{
[... Same as SRC2 except:]
Package (0x02)
{
"mipi-sdw-channel-number-list",
Package (0x04)
{
Zero,
One,
0x02,
0x03
}
},
Package (0x02)
{
"mipi-sdw-channel-combination-list",
Package (0x04)
{
One,
0x03,
0x07,
0x0F
}
}
[ Same as SRC2 ...]
}
})
Name (SRC6, Package (0x02)
{
[... Same as SRC2 ...]
})
}
Change-Id: I38f40d29945b22f9c308ea4b7ed6157ccadb3c7c
Signed-off-by: Maciej Strozek <mstrozek@opensource.cirrus.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/89230
Reviewed-by: Paul Menzel <paulepanter@mailbox.org>
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Kapil Porwal <kapilporwal@google.com>
This commit is contained in:
parent
35970abcdf
commit
f1c973bbff
5 changed files with 195 additions and 0 deletions
8
src/drivers/soundwire/cs42l43/Kconfig
Normal file
8
src/drivers/soundwire/cs42l43/Kconfig
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
## SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
config DRIVERS_SOUNDWIRE_CS42L43
|
||||
bool
|
||||
depends on HAVE_ACPI_TABLES
|
||||
default n
|
||||
help
|
||||
SoundWire CS42L43 CODEC SSDT generator.
|
||||
3
src/drivers/soundwire/cs42l43/Makefile.mk
Normal file
3
src/drivers/soundwire/cs42l43/Makefile.mk
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
## SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
ramstage-$(CONFIG_DRIVERS_SOUNDWIRE_CS42L43) += cs42l43.c
|
||||
17
src/drivers/soundwire/cs42l43/chip.h
Normal file
17
src/drivers/soundwire/cs42l43/chip.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef __DRIVERS_SOUNDWIRE_CS42L43_CHIP_H__
|
||||
#define __DRIVERS_SOUNDWIRE_CS42L43_CHIP_H__
|
||||
|
||||
#include <acpi/acpi.h>
|
||||
#include <acpi/acpi_device.h>
|
||||
#include <mipi/ids.h>
|
||||
|
||||
struct drivers_soundwire_cs42l43_config {
|
||||
char acpi_name[ACPI_NAME_BUFFER_SIZE]; /* Set by the acpi_name ops */
|
||||
const char *desc;
|
||||
|
||||
const char *sub; /* SUB ID to uniquely identify system */
|
||||
};
|
||||
|
||||
#endif /* __DRIVERS_SOUNDWIRE_CS42L43_CHIP_H__ */
|
||||
166
src/drivers/soundwire/cs42l43/cs42l43.c
Normal file
166
src/drivers/soundwire/cs42l43/cs42l43.c
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/* 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 cs42l43_address = {
|
||||
.version = SOUNDWIRE_VERSION_1_2,
|
||||
.manufacturer_id = MIPI_MFG_ID_CIRRUS,
|
||||
.part_id = MIPI_DEV_ID_CIRRUS_CS42L43,
|
||||
.class = MIPI_CLASS_SDCA
|
||||
};
|
||||
|
||||
static struct soundwire_slave cs42l43_slave = {
|
||||
.wake_up_unavailable = false,
|
||||
.test_mode_supported = false,
|
||||
.clock_stop_mode1_supported = false,
|
||||
.simplified_clockstopprepare_sm_supported = false,
|
||||
.paging_supported = true,
|
||||
.source_port_list = SOUNDWIRE_PORT(1) | SOUNDWIRE_PORT(2),
|
||||
.sink_port_list = SOUNDWIRE_PORT(5) | SOUNDWIRE_PORT(6)
|
||||
};
|
||||
|
||||
static struct soundwire_dp0 cs42l43_dp0 = {
|
||||
.port_wordlength_configs_count = 3,
|
||||
.port_wordlength_configs = {8, 16, 24},
|
||||
.bra_flow_controlled = true,
|
||||
.bra_imp_def_response_supported = true,
|
||||
.bra_role_supported = true,
|
||||
.imp_def_dp0_interrupts_supported = 0,
|
||||
.imp_def_bpt_supported = false,
|
||||
.bra_mode_count = 1,
|
||||
.bra_mode_list = { 0 },
|
||||
.simplified_channel_prepare_sm = false
|
||||
};
|
||||
|
||||
static struct soundwire_bra_mode cs42l43_dp0_bra_mode = {
|
||||
.max_data_per_frame = 470,
|
||||
.block_alignment = 4
|
||||
};
|
||||
|
||||
static struct soundwire_dpn cs42l43_dp1 = {
|
||||
.data_port_type = FULL_DATA_PORT,
|
||||
.max_grouping_supported = BLOCK_GROUP_COUNT_1,
|
||||
.modes_supported = MODE_ISOCHRONOUS,
|
||||
.max_async_buffer = 0,
|
||||
.block_packing_mode = true,
|
||||
.port_encoding_type = ENCODE_TWOS_COMPLEMENT,
|
||||
.port_wordlength_configs_count = 3,
|
||||
.port_wordlength_configs = {8, 16, 24},
|
||||
.simplified_channelprepare_sm = false,
|
||||
.channel_number_list_count = 4,
|
||||
.channel_number_list = {0, 1, 2, 3},
|
||||
.channel_combination_list_count = 4,
|
||||
.channel_combination_list = {0x1, 0x3, 0x7, 0xF},
|
||||
.port_audio_mode_count = 0
|
||||
};
|
||||
|
||||
static struct soundwire_dpn cs42l43_dpn = {
|
||||
.data_port_type = FULL_DATA_PORT,
|
||||
.max_grouping_supported = BLOCK_GROUP_COUNT_1,
|
||||
.modes_supported = MODE_ISOCHRONOUS,
|
||||
.max_async_buffer = 0,
|
||||
.block_packing_mode = true,
|
||||
.port_encoding_type = ENCODE_TWOS_COMPLEMENT,
|
||||
.port_wordlength_configs_count = 3,
|
||||
.port_wordlength_configs = {8, 16, 24},
|
||||
.simplified_channelprepare_sm = false,
|
||||
.channel_number_list_count = 2,
|
||||
.channel_number_list = {0, 1},
|
||||
.channel_combination_list_count = 3,
|
||||
.channel_combination_list = {0x3, 0x2, 0x1},
|
||||
.port_audio_mode_count = 0
|
||||
};
|
||||
|
||||
static const struct soundwire_codec cs42l43_codec = {
|
||||
.slave = &cs42l43_slave,
|
||||
.dp0 = &cs42l43_dp0,
|
||||
.dp0_bra_mode = { &cs42l43_dp0_bra_mode },
|
||||
.dpn = {
|
||||
{
|
||||
/* UAJ_MIC */
|
||||
.port = 2,
|
||||
.source = &cs42l43_dpn
|
||||
},
|
||||
{
|
||||
/* UAJ_SPK */
|
||||
.port = 5,
|
||||
.sink = &cs42l43_dpn
|
||||
},
|
||||
{
|
||||
/* MIC */
|
||||
.port = 1,
|
||||
.sink = &cs42l43_dp1
|
||||
},
|
||||
{
|
||||
/* SPK */
|
||||
.port = 6,
|
||||
.source = &cs42l43_dpn
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static void soundwire_cs42l43_fill_ssdt(const struct device *dev)
|
||||
{
|
||||
struct drivers_soundwire_cs42l43_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. */
|
||||
cs42l43_address.link_id = dev->path.generic.id;
|
||||
cs42l43_address.unique_id = dev->path.generic.subid;
|
||||
|
||||
acpigen_write_ADR_soundwire_device(&cs42l43_address);
|
||||
acpigen_write_name_string("_DDN", config->desc ? : dev->chip_ops->name);
|
||||
acpigen_write_name_string("_SUB", config->sub);
|
||||
acpigen_write_STA(acpi_device_status(dev));
|
||||
|
||||
dsd = acpi_dp_new_table("_DSD");
|
||||
|
||||
soundwire_gen_codec(dsd, &cs42l43_codec, NULL);
|
||||
|
||||
acpi_dp_write(dsd);
|
||||
|
||||
acpigen_pop_len(); /* Device */
|
||||
acpigen_pop_len(); /* Scope */
|
||||
}
|
||||
|
||||
static const char *soundwire_cs42l43_acpi_name(const struct device *dev)
|
||||
{
|
||||
struct drivers_soundwire_cs42l43_config *config = dev->chip_info;
|
||||
if (config->acpi_name[0] != 0)
|
||||
return config->acpi_name;
|
||||
snprintf(config->acpi_name, sizeof(config->acpi_name), "SW%1X%1X",
|
||||
dev->path.generic.id, dev->path.generic.subid);
|
||||
return config->acpi_name;
|
||||
}
|
||||
|
||||
static struct device_operations soundwire_cs42l43_ops = {
|
||||
.read_resources = noop_read_resources,
|
||||
.set_resources = noop_set_resources,
|
||||
.acpi_name = soundwire_cs42l43_acpi_name,
|
||||
.acpi_fill_ssdt = soundwire_cs42l43_fill_ssdt,
|
||||
};
|
||||
|
||||
static void soundwire_cs42l43_enable(struct device *dev)
|
||||
{
|
||||
dev->ops = &soundwire_cs42l43_ops;
|
||||
}
|
||||
|
||||
struct chip_operations drivers_soundwire_cs42l43_ops = {
|
||||
.name = "Cirrus CS42L43 SoundWire Codec",
|
||||
.enable_dev = soundwire_cs42l43_enable
|
||||
};
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#define MIPI_MFG_ID_CIRRUS 0x01fa
|
||||
#define MIPI_DEV_ID_CIRRUS_CS42L42 0x4242
|
||||
#define MIPI_DEV_ID_CIRRUS_CS42L43 0x4243
|
||||
#define MIPI_DEV_ID_CIRRUS_CS35L56 0x3556
|
||||
#define MIPI_DEV_ID_CIRRUS_CS35L57 0x3557
|
||||
#define MIPI_DEV_ID_CIRRUS_CS35L63 0x3563
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue