summaryrefslogtreecommitdiff
path: root/sound/soc/intel/boards/sof_sdw_rt1308.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel/boards/sof_sdw_rt1308.c')
-rw-r--r--sound/soc/intel/boards/sof_sdw_rt1308.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/sound/soc/intel/boards/sof_sdw_rt1308.c b/sound/soc/intel/boards/sof_sdw_rt1308.c
index f078fb1aad02..a19b055b9c6f 100644
--- a/sound/soc/intel/boards/sof_sdw_rt1308.c
+++ b/sound/soc/intel/boards/sof_sdw_rt1308.c
@@ -11,9 +11,86 @@
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include <sound/soc-dapm.h>
+#include <linux/soundwire/sdw.h>
+#include <linux/soundwire/sdw_type.h>
+#include <linux/dmi.h>
#include "sof_sdw_common.h"
+#include "sof_sdw_amp_coeff_tables.h"
#include "../../codecs/rt1308.h"
+struct rt1308_platform_data {
+ const unsigned char *bq_params;
+ const unsigned int bq_params_cnt;
+};
+
+static const struct rt1308_platform_data dell_0a5d_platform_data = {
+ .bq_params = dell_0a5d_bq_params,
+ .bq_params_cnt = ARRAY_SIZE(dell_0a5d_bq_params),
+};
+
+static const struct dmi_system_id dmi_platform_data[] = {
+ /* CometLake devices */
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0990")
+ },
+ .driver_data = (void *)&dell_0a5d_platform_data,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "098F")
+ },
+ .driver_data = (void *)&dell_0a5d_platform_data,
+ },
+ /* TigerLake devices */
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5D")
+ },
+ .driver_data = (void *)&dell_0a5d_platform_data,
+ },
+ {
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0A5E")
+ },
+ .driver_data = (void *)&dell_0a5d_platform_data,
+ },
+};
+
+static int rt1308_add_device_props(struct device *sdw_dev)
+{
+ struct property_entry props[3] = {};
+ struct fwnode_handle *fwnode;
+ const struct dmi_system_id *dmi_data;
+ const struct rt1308_platform_data *pdata;
+ unsigned char params[RT1308_MAX_BQ_REG];
+ int ret;
+
+ dmi_data = dmi_first_match(dmi_platform_data);
+ if (!dmi_data)
+ return 0;
+
+ pdata = dmi_data->driver_data;
+ memcpy(&params, pdata->bq_params, sizeof(unsigned char) * pdata->bq_params_cnt);
+
+ props[0] = PROPERTY_ENTRY_U8_ARRAY("realtek,bq-params", params);
+ props[1] = PROPERTY_ENTRY_U32("realtek,bq-params-cnt", pdata->bq_params_cnt);
+
+ fwnode = fwnode_create_software_node(props, NULL);
+ if (IS_ERR(fwnode))
+ return PTR_ERR(fwnode);
+
+ ret = device_add_software_node(sdw_dev, to_software_node(fwnode));
+
+ fwnode_handle_put(fwnode);
+
+ return ret;
+}
+
static const struct snd_soc_dapm_widget rt1308_widgets[] = {
SND_SOC_DAPM_SPK("Speaker", NULL),
};
@@ -127,12 +204,33 @@ struct snd_soc_ops sof_sdw_rt1308_i2s_ops = {
.hw_params = rt1308_i2s_hw_params,
};
+int sof_sdw_rt1308_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
+{
+ struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+
+ if (ctx->amp_dev1) {
+ device_remove_software_node(ctx->amp_dev1);
+ put_device(ctx->amp_dev1);
+ }
+
+ if (ctx->amp_dev2) {
+ device_remove_software_node(ctx->amp_dev2);
+ put_device(ctx->amp_dev2);
+ }
+
+ return 0;
+}
+
int sof_sdw_rt1308_init(struct snd_soc_card *card,
const struct snd_soc_acpi_link_adr *link,
struct snd_soc_dai_link *dai_links,
struct sof_sdw_codec_info *info,
bool playback)
{
+ struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct device *sdw_dev1, *sdw_dev2;
+ int ret;
+
/* Count amp number and do init on playback link only. */
if (!playback)
return 0;
@@ -142,6 +240,28 @@ int sof_sdw_rt1308_init(struct snd_soc_card *card,
dai_links->init = first_spk_init;
if (info->amp_num == 2) {
+ sdw_dev1 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name);
+ if (!sdw_dev1)
+ return -EPROBE_DEFER;
+
+ ret = rt1308_add_device_props(sdw_dev1);
+ if (ret < 0) {
+ put_device(sdw_dev1);
+ return ret;
+ }
+ ctx->amp_dev1 = sdw_dev1;
+
+ sdw_dev2 = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[1].name);
+ if (!sdw_dev2)
+ return -EPROBE_DEFER;
+
+ ret = rt1308_add_device_props(sdw_dev2);
+ if (ret < 0) {
+ put_device(sdw_dev2);
+ return ret;
+ }
+ ctx->amp_dev2 = sdw_dev2;
+
/*
* if two 1308s are in one dai link, the init function
* in this dai link will be first set for the first speaker,