ASoC: Intel: sof_realtek_common: support 4xALC1011 amplifier
Add support for boards with four ALC1011 amplifiers. Configuration is copied from cml_rt1011_rt5682 machine driver for backward compatibility with existing cml devices. Reviewed-by: Chao Song <chao.song@linux.intel.com> Signed-off-by: Brent Lu <brent.lu@intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20240411220347.131267-10-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
fe18a4be97
commit
551fb5593c
@ -15,10 +15,40 @@
|
||||
#include "../../codecs/rt1011.h"
|
||||
#include "../../codecs/rt1015.h"
|
||||
#include "../../codecs/rt1308.h"
|
||||
#include "../common/soc-intel-quirks.h"
|
||||
#include "sof_realtek_common.h"
|
||||
|
||||
/*
|
||||
* Current only 2-amp configuration is supported for rt1011
|
||||
* Common structures and functions
|
||||
*/
|
||||
static const struct snd_kcontrol_new realtek_4spk_kcontrols[] = {
|
||||
SOC_DAPM_PIN_SWITCH("WL Ext Spk"),
|
||||
SOC_DAPM_PIN_SWITCH("WR Ext Spk"),
|
||||
SOC_DAPM_PIN_SWITCH("TL Ext Spk"),
|
||||
SOC_DAPM_PIN_SWITCH("TR Ext Spk"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget realtek_4spk_widgets[] = {
|
||||
SND_SOC_DAPM_SPK("WL Ext Spk", NULL),
|
||||
SND_SOC_DAPM_SPK("WR Ext Spk", NULL),
|
||||
SND_SOC_DAPM_SPK("TL Ext Spk", NULL),
|
||||
SND_SOC_DAPM_SPK("TR Ext Spk", NULL),
|
||||
};
|
||||
|
||||
/* helper function to get the number of specific codec */
|
||||
static unsigned int get_num_codecs(const char *hid)
|
||||
{
|
||||
struct acpi_device *adev;
|
||||
unsigned int dev_num = 0;
|
||||
|
||||
for_each_acpi_dev_match(adev, hid, NULL, -1)
|
||||
dev_num++;
|
||||
|
||||
return dev_num;
|
||||
}
|
||||
|
||||
/*
|
||||
* Realtek ALC1011
|
||||
*/
|
||||
static const struct snd_soc_dapm_route speaker_map_lr[] = {
|
||||
/* speaker */
|
||||
@ -26,16 +56,14 @@ static const struct snd_soc_dapm_route speaker_map_lr[] = {
|
||||
{ "Right Spk", NULL, "Right SPO" },
|
||||
};
|
||||
|
||||
/*
|
||||
* Make sure device's Unique ID follows this configuration:
|
||||
*
|
||||
* Two speakers:
|
||||
* 0: left, 1: right
|
||||
* Four speakers:
|
||||
* 0: Woofer left, 1: Woofer right
|
||||
* 2: Tweeter left, 3: Tweeter right
|
||||
*/
|
||||
static struct snd_soc_codec_conf rt1011_codec_confs[] = {
|
||||
static const struct snd_soc_dapm_route rt1011_4spk_routes[] = {
|
||||
{"WL Ext Spk", NULL, "WL SPO" },
|
||||
{"WR Ext Spk", NULL, "WR SPO" },
|
||||
{"TL Ext Spk", NULL, "TL SPO" },
|
||||
{"TR Ext Spk", NULL, "TR SPO" },
|
||||
};
|
||||
|
||||
static struct snd_soc_codec_conf rt1011_2spk_codec_confs[] = {
|
||||
{
|
||||
.dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME),
|
||||
.name_prefix = "Left",
|
||||
@ -46,6 +74,25 @@ static struct snd_soc_codec_conf rt1011_codec_confs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_codec_conf rt1011_4spk_codec_confs[] = {
|
||||
{
|
||||
.dlc = COMP_CODEC_CONF(RT1011_DEV0_NAME),
|
||||
.name_prefix = "WL",
|
||||
},
|
||||
{
|
||||
.dlc = COMP_CODEC_CONF(RT1011_DEV1_NAME),
|
||||
.name_prefix = "WR",
|
||||
},
|
||||
{
|
||||
.dlc = COMP_CODEC_CONF(RT1011_DEV2_NAME),
|
||||
.name_prefix = "TL",
|
||||
},
|
||||
{
|
||||
.dlc = COMP_CODEC_CONF(RT1011_DEV3_NAME),
|
||||
.name_prefix = "TR",
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_link_component rt1011_dai_link_components[] = {
|
||||
{
|
||||
.name = RT1011_DEV0_NAME,
|
||||
@ -55,6 +102,14 @@ static struct snd_soc_dai_link_component rt1011_dai_link_components[] = {
|
||||
.name = RT1011_DEV1_NAME,
|
||||
.dai_name = RT1011_CODEC_DAI,
|
||||
},
|
||||
{
|
||||
.name = RT1011_DEV2_NAME,
|
||||
.dai_name = RT1011_CODEC_DAI,
|
||||
},
|
||||
{
|
||||
.name = RT1011_DEV3_NAME,
|
||||
.dai_name = RT1011_CODEC_DAI,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct {
|
||||
@ -63,6 +118,8 @@ static const struct {
|
||||
} rt1011_tdm_mask[] = {
|
||||
{.tx = 0x4, .rx = 0x1},
|
||||
{.tx = 0x8, .rx = 0x2},
|
||||
{.tx = 0x1, .rx = 0x1},
|
||||
{.tx = 0x2, .rx = 0x2},
|
||||
};
|
||||
|
||||
static int rt1011_hw_params(struct snd_pcm_substream *substream,
|
||||
@ -118,28 +175,109 @@ static const struct snd_soc_ops rt1011_ops = {
|
||||
static int rt1011_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID);
|
||||
int ret;
|
||||
|
||||
ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map_lr,
|
||||
ARRAY_SIZE(speaker_map_lr));
|
||||
if (ret)
|
||||
dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret);
|
||||
switch (num_codecs) {
|
||||
case 2:
|
||||
if (!soc_intel_is_cml()) {
|
||||
ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map_lr,
|
||||
ARRAY_SIZE(speaker_map_lr));
|
||||
if (ret) {
|
||||
dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* register speaker widgets "WL Ext Spk" and "WR Ext Spk" to
|
||||
* keep backward compatible with cml devices
|
||||
*/
|
||||
fallthrough;
|
||||
case 4:
|
||||
ret = snd_soc_dapm_new_controls(&card->dapm, realtek_4spk_widgets,
|
||||
num_codecs);
|
||||
if (ret) {
|
||||
dev_err(rtd->dev, "fail to add rt1011 widgets, ret %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_add_card_controls(card, realtek_4spk_kcontrols,
|
||||
num_codecs);
|
||||
if (ret) {
|
||||
dev_err(rtd->dev, "fail to add rt1011 controls, ret %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dapm_add_routes(&card->dapm, rt1011_4spk_routes,
|
||||
num_codecs);
|
||||
if (ret) {
|
||||
dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dev_err(rtd->dev, "rt1011: invalid num_codecs %d\n", num_codecs);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void sof_rt1011_dai_link(struct snd_soc_dai_link *link)
|
||||
void sof_rt1011_dai_link(struct device *dev, struct snd_soc_dai_link *link)
|
||||
{
|
||||
unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID);
|
||||
|
||||
link->codecs = rt1011_dai_link_components;
|
||||
link->num_codecs = ARRAY_SIZE(rt1011_dai_link_components);
|
||||
|
||||
switch (num_codecs) {
|
||||
case 2:
|
||||
case 4:
|
||||
link->num_codecs = num_codecs;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "rt1011: invalid num_codecs %d\n", num_codecs);
|
||||
break;
|
||||
}
|
||||
|
||||
link->init = rt1011_init;
|
||||
link->ops = &rt1011_ops;
|
||||
}
|
||||
EXPORT_SYMBOL_NS(sof_rt1011_dai_link, SND_SOC_INTEL_SOF_REALTEK_COMMON);
|
||||
|
||||
void sof_rt1011_codec_conf(struct snd_soc_card *card)
|
||||
void sof_rt1011_codec_conf(struct device *dev, struct snd_soc_card *card)
|
||||
{
|
||||
card->codec_conf = rt1011_codec_confs;
|
||||
card->num_configs = ARRAY_SIZE(rt1011_codec_confs);
|
||||
unsigned int num_codecs = get_num_codecs(RT1011_ACPI_HID);
|
||||
|
||||
switch (num_codecs) {
|
||||
case 2:
|
||||
if (soc_intel_is_cml()) {
|
||||
/*
|
||||
* use name prefix 'WL' and 'WR' for speaker widgets to
|
||||
* keep backward compatible with cml devices
|
||||
*/
|
||||
card->codec_conf = rt1011_4spk_codec_confs;
|
||||
} else {
|
||||
card->codec_conf = rt1011_2spk_codec_confs;
|
||||
}
|
||||
|
||||
card->num_configs = num_codecs;
|
||||
break;
|
||||
case 4:
|
||||
card->codec_conf = rt1011_4spk_codec_confs;
|
||||
card->num_configs = ARRAY_SIZE(rt1011_4spk_codec_confs);
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "rt1011: invalid num_codecs %d\n", num_codecs);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
EXPORT_SYMBOL_NS(sof_rt1011_codec_conf, SND_SOC_INTEL_SOF_REALTEK_COMMON);
|
||||
|
||||
|
@ -23,8 +23,8 @@
|
||||
#define RT1011_DEV2_NAME "i2c-" RT1011_ACPI_HID ":02"
|
||||
#define RT1011_DEV3_NAME "i2c-" RT1011_ACPI_HID ":03"
|
||||
|
||||
void sof_rt1011_dai_link(struct snd_soc_dai_link *link);
|
||||
void sof_rt1011_codec_conf(struct snd_soc_card *card);
|
||||
void sof_rt1011_dai_link(struct device *dev, struct snd_soc_dai_link *link);
|
||||
void sof_rt1011_codec_conf(struct device *dev, struct snd_soc_card *card);
|
||||
|
||||
/*
|
||||
* Realtek ALC1015 (AUTO)
|
||||
|
@ -576,7 +576,7 @@ sof_card_dai_links_create(struct device *dev, struct snd_soc_card *card,
|
||||
max_98390_dai_link(dev, ctx->amp_link);
|
||||
break;
|
||||
case CODEC_RT1011:
|
||||
sof_rt1011_dai_link(ctx->amp_link);
|
||||
sof_rt1011_dai_link(dev, ctx->amp_link);
|
||||
break;
|
||||
case CODEC_RT1015:
|
||||
sof_rt1015_dai_link(ctx->amp_link);
|
||||
@ -683,7 +683,7 @@ static int sof_audio_probe(struct platform_device *pdev)
|
||||
max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682);
|
||||
break;
|
||||
case CODEC_RT1011:
|
||||
sof_rt1011_codec_conf(&sof_audio_card_rt5682);
|
||||
sof_rt1011_codec_conf(&pdev->dev, &sof_audio_card_rt5682);
|
||||
break;
|
||||
case CODEC_RT1015:
|
||||
sof_rt1015_codec_conf(&sof_audio_card_rt5682);
|
||||
|
Loading…
x
Reference in New Issue
Block a user