ASoC: Intel: bxt-da7219-max98357a: support MAX98390 speaker amp
Support MAX98390 speaker amplifier on cometlake platform. Driver now detects amplifier type in the probe function and installs corresponding controls and DAPM widgets/routes in the late_probe function. Signed-off-by: Brent Lu <brent.lu@intel.com> Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/1593596211-28344-1-git-send-email-brent.lu@intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
a2b782d59c
commit
e1435a1feb
3 changed files with 127 additions and 8 deletions
|
@ -288,6 +288,7 @@ config SND_SOC_INTEL_DA7219_MAX98357A_GENERIC
|
||||||
tristate
|
tristate
|
||||||
select SND_SOC_DA7219
|
select SND_SOC_DA7219
|
||||||
select SND_SOC_MAX98357A
|
select SND_SOC_MAX98357A
|
||||||
|
select SND_SOC_MAX98390
|
||||||
select SND_SOC_DMIC
|
select SND_SOC_DMIC
|
||||||
select SND_SOC_HDAC_HDMI
|
select SND_SOC_HDAC_HDMI
|
||||||
|
|
||||||
|
@ -298,14 +299,14 @@ config SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON
|
||||||
if SND_SOC_INTEL_APL
|
if SND_SOC_INTEL_APL
|
||||||
|
|
||||||
config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH
|
config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH
|
||||||
tristate "Broxton with DA7219 and MAX98357A in I2S Mode"
|
tristate "Broxton with DA7219 and MAX98357A/MAX98390 in I2S Mode"
|
||||||
depends on I2C && ACPI && GPIOLIB
|
depends on I2C && ACPI && GPIOLIB
|
||||||
depends on MFD_INTEL_LPSS || COMPILE_TEST
|
depends on MFD_INTEL_LPSS || COMPILE_TEST
|
||||||
depends on SND_HDA_CODEC_HDMI
|
depends on SND_HDA_CODEC_HDMI
|
||||||
select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON
|
select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON
|
||||||
help
|
help
|
||||||
This adds support for ASoC machine driver for Broxton-P platforms
|
This adds support for ASoC machine driver for Broxton-P platforms
|
||||||
with DA7219 + MAX98357A I2S audio codec.
|
with DA7219 + MAX98357A/MAX98390 I2S audio codec.
|
||||||
Say Y or m if you have such a device. This is a recommended option.
|
Say Y or m if you have such a device. This is a recommended option.
|
||||||
If unsure select "N".
|
If unsure select "N".
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,14 @@
|
||||||
|
|
||||||
#define BXT_DIALOG_CODEC_DAI "da7219-hifi"
|
#define BXT_DIALOG_CODEC_DAI "da7219-hifi"
|
||||||
#define BXT_MAXIM_CODEC_DAI "HiFi"
|
#define BXT_MAXIM_CODEC_DAI "HiFi"
|
||||||
|
#define MAX98390_DEV0_NAME "i2c-MX98390:00"
|
||||||
|
#define MAX98390_DEV1_NAME "i2c-MX98390:01"
|
||||||
#define DUAL_CHANNEL 2
|
#define DUAL_CHANNEL 2
|
||||||
#define QUAD_CHANNEL 4
|
#define QUAD_CHANNEL 4
|
||||||
|
|
||||||
|
#define SPKAMP_MAX98357A 1
|
||||||
|
#define SPKAMP_MAX98390 2
|
||||||
|
|
||||||
static struct snd_soc_jack broxton_headset;
|
static struct snd_soc_jack broxton_headset;
|
||||||
static struct snd_soc_jack broxton_hdmi[3];
|
static struct snd_soc_jack broxton_hdmi[3];
|
||||||
|
|
||||||
|
@ -40,6 +45,7 @@ struct bxt_hdmi_pcm {
|
||||||
struct bxt_card_private {
|
struct bxt_card_private {
|
||||||
struct list_head hdmi_pcm_list;
|
struct list_head hdmi_pcm_list;
|
||||||
bool common_hdmi_codec_drv;
|
bool common_hdmi_codec_drv;
|
||||||
|
int spkamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -85,13 +91,20 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w,
|
||||||
static const struct snd_kcontrol_new broxton_controls[] = {
|
static const struct snd_kcontrol_new broxton_controls[] = {
|
||||||
SOC_DAPM_PIN_SWITCH("Headphone Jack"),
|
SOC_DAPM_PIN_SWITCH("Headphone Jack"),
|
||||||
SOC_DAPM_PIN_SWITCH("Headset Mic"),
|
SOC_DAPM_PIN_SWITCH("Headset Mic"),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snd_kcontrol_new max98357a_controls[] = {
|
||||||
SOC_DAPM_PIN_SWITCH("Spk"),
|
SOC_DAPM_PIN_SWITCH("Spk"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct snd_kcontrol_new max98390_controls[] = {
|
||||||
|
SOC_DAPM_PIN_SWITCH("Left Spk"),
|
||||||
|
SOC_DAPM_PIN_SWITCH("Right Spk"),
|
||||||
|
};
|
||||||
|
|
||||||
static const struct snd_soc_dapm_widget broxton_widgets[] = {
|
static const struct snd_soc_dapm_widget broxton_widgets[] = {
|
||||||
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
SND_SOC_DAPM_HP("Headphone Jack", NULL),
|
||||||
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
SND_SOC_DAPM_MIC("Headset Mic", NULL),
|
||||||
SND_SOC_DAPM_SPK("Spk", NULL),
|
|
||||||
SND_SOC_DAPM_MIC("SoC DMIC", NULL),
|
SND_SOC_DAPM_MIC("SoC DMIC", NULL),
|
||||||
SND_SOC_DAPM_SPK("HDMI1", NULL),
|
SND_SOC_DAPM_SPK("HDMI1", NULL),
|
||||||
SND_SOC_DAPM_SPK("HDMI2", NULL),
|
SND_SOC_DAPM_SPK("HDMI2", NULL),
|
||||||
|
@ -100,14 +113,20 @@ static const struct snd_soc_dapm_widget broxton_widgets[] = {
|
||||||
platform_clock_control, SND_SOC_DAPM_POST_PMD|SND_SOC_DAPM_PRE_PMU),
|
platform_clock_control, SND_SOC_DAPM_POST_PMD|SND_SOC_DAPM_PRE_PMU),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_dapm_widget max98357a_widgets[] = {
|
||||||
|
SND_SOC_DAPM_SPK("Spk", NULL),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_dapm_widget max98390_widgets[] = {
|
||||||
|
SND_SOC_DAPM_SPK("Left Spk", NULL),
|
||||||
|
SND_SOC_DAPM_SPK("Right Spk", NULL),
|
||||||
|
};
|
||||||
|
|
||||||
static const struct snd_soc_dapm_route audio_map[] = {
|
static const struct snd_soc_dapm_route audio_map[] = {
|
||||||
/* HP jack connectors - unknown if we have jack detection */
|
/* HP jack connectors - unknown if we have jack detection */
|
||||||
{"Headphone Jack", NULL, "HPL"},
|
{"Headphone Jack", NULL, "HPL"},
|
||||||
{"Headphone Jack", NULL, "HPR"},
|
{"Headphone Jack", NULL, "HPR"},
|
||||||
|
|
||||||
/* speaker */
|
|
||||||
{"Spk", NULL, "Speaker"},
|
|
||||||
|
|
||||||
/* other jacks */
|
/* other jacks */
|
||||||
{"MIC", NULL, "Headset Mic"},
|
{"MIC", NULL, "Headset Mic"},
|
||||||
|
|
||||||
|
@ -134,6 +153,17 @@ static const struct snd_soc_dapm_route audio_map[] = {
|
||||||
{ "Headset Mic", NULL, "Platform Clock" },
|
{ "Headset Mic", NULL, "Platform Clock" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_dapm_route max98357a_routes[] = {
|
||||||
|
/* speaker */
|
||||||
|
{"Spk", NULL, "Speaker"},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct snd_soc_dapm_route max98390_routes[] = {
|
||||||
|
/* Speaker */
|
||||||
|
{"Left Spk", NULL, "Left BE_OUT"},
|
||||||
|
{"Right Spk", NULL, "Right BE_OUT"},
|
||||||
|
};
|
||||||
|
|
||||||
static const struct snd_soc_dapm_route broxton_map[] = {
|
static const struct snd_soc_dapm_route broxton_map[] = {
|
||||||
{"HiFi Playback", NULL, "ssp5 Tx"},
|
{"HiFi Playback", NULL, "ssp5 Tx"},
|
||||||
{"ssp5 Tx", NULL, "codec0_out"},
|
{"ssp5 Tx", NULL, "codec0_out"},
|
||||||
|
@ -404,6 +434,10 @@ SND_SOC_DAILINK_DEF(ssp5_pin,
|
||||||
SND_SOC_DAILINK_DEF(ssp5_codec,
|
SND_SOC_DAILINK_DEF(ssp5_codec,
|
||||||
DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00",
|
DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00",
|
||||||
BXT_MAXIM_CODEC_DAI)));
|
BXT_MAXIM_CODEC_DAI)));
|
||||||
|
SND_SOC_DAILINK_DEF(max98390_codec,
|
||||||
|
DAILINK_COMP_ARRAY(
|
||||||
|
/* Left */ COMP_CODEC(MAX98390_DEV0_NAME, "max98390-aif1"),
|
||||||
|
/* Right */ COMP_CODEC(MAX98390_DEV1_NAME, "max98390-aif1")));
|
||||||
|
|
||||||
SND_SOC_DAILINK_DEF(ssp1_pin,
|
SND_SOC_DAILINK_DEF(ssp1_pin,
|
||||||
DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin")));
|
DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin")));
|
||||||
|
@ -601,15 +635,69 @@ static struct snd_soc_dai_link broxton_dais[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct snd_soc_codec_conf max98390_codec_confs[] = {
|
||||||
|
{
|
||||||
|
.dlc = COMP_CODEC_CONF(MAX98390_DEV0_NAME),
|
||||||
|
.name_prefix = "Left",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.dlc = COMP_CODEC_CONF(MAX98390_DEV1_NAME),
|
||||||
|
.name_prefix = "Right",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
#define NAME_SIZE 32
|
#define NAME_SIZE 32
|
||||||
static int bxt_card_late_probe(struct snd_soc_card *card)
|
static int bxt_card_late_probe(struct snd_soc_card *card)
|
||||||
{
|
{
|
||||||
struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
|
struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
|
||||||
struct bxt_hdmi_pcm *pcm;
|
struct bxt_hdmi_pcm *pcm;
|
||||||
struct snd_soc_component *component = NULL;
|
struct snd_soc_component *component = NULL;
|
||||||
int err, i = 0;
|
const struct snd_kcontrol_new *controls;
|
||||||
|
const struct snd_soc_dapm_widget *widgets;
|
||||||
|
const struct snd_soc_dapm_route *routes;
|
||||||
|
int num_controls, num_widgets, num_routes, err, i = 0;
|
||||||
char jack_name[NAME_SIZE];
|
char jack_name[NAME_SIZE];
|
||||||
|
|
||||||
|
switch (ctx->spkamp) {
|
||||||
|
case SPKAMP_MAX98357A:
|
||||||
|
controls = max98357a_controls;
|
||||||
|
num_controls = ARRAY_SIZE(max98357a_controls);
|
||||||
|
widgets = max98357a_widgets;
|
||||||
|
num_widgets = ARRAY_SIZE(max98357a_widgets);
|
||||||
|
routes = max98357a_routes;
|
||||||
|
num_routes = ARRAY_SIZE(max98357a_routes);
|
||||||
|
break;
|
||||||
|
case SPKAMP_MAX98390:
|
||||||
|
controls = max98390_controls;
|
||||||
|
num_controls = ARRAY_SIZE(max98390_controls);
|
||||||
|
widgets = max98390_widgets;
|
||||||
|
num_widgets = ARRAY_SIZE(max98390_widgets);
|
||||||
|
routes = max98390_routes;
|
||||||
|
num_routes = ARRAY_SIZE(max98390_routes);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_err(card->dev, "Invalid speaker amplifier %d\n", ctx->spkamp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = snd_soc_dapm_new_controls(&card->dapm, widgets, num_widgets);
|
||||||
|
if (err) {
|
||||||
|
dev_err(card->dev, "Fail to new widgets\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = snd_soc_add_card_controls(card, controls, num_controls);
|
||||||
|
if (err) {
|
||||||
|
dev_err(card->dev, "Fail to add controls\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = snd_soc_dapm_add_routes(&card->dapm, routes, num_routes);
|
||||||
|
if (err) {
|
||||||
|
dev_err(card->dev, "Fail to add routes\n");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
if (soc_intel_is_glk())
|
if (soc_intel_is_glk())
|
||||||
snd_soc_dapm_add_routes(&card->dapm, gemini_map,
|
snd_soc_dapm_add_routes(&card->dapm, gemini_map,
|
||||||
ARRAY_SIZE(gemini_map));
|
ARRAY_SIZE(gemini_map));
|
||||||
|
@ -678,6 +766,11 @@ static int broxton_audio_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
|
INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
|
||||||
|
|
||||||
|
if (acpi_dev_present("MX98390", NULL, -1))
|
||||||
|
ctx->spkamp = SPKAMP_MAX98390;
|
||||||
|
else
|
||||||
|
ctx->spkamp = SPKAMP_MAX98357A;
|
||||||
|
|
||||||
broxton_audio_card.dev = &pdev->dev;
|
broxton_audio_card.dev = &pdev->dev;
|
||||||
snd_soc_card_set_drvdata(&broxton_audio_card, ctx);
|
snd_soc_card_set_drvdata(&broxton_audio_card, ctx);
|
||||||
if (soc_intel_is_glk()) {
|
if (soc_intel_is_glk()) {
|
||||||
|
@ -702,7 +795,13 @@ static int broxton_audio_probe(struct platform_device *pdev)
|
||||||
} else if (soc_intel_is_cml()) {
|
} else if (soc_intel_is_cml()) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
broxton_audio_card.name = "cmlda7219max";
|
if (ctx->spkamp == SPKAMP_MAX98390) {
|
||||||
|
broxton_audio_card.name = "cml_max98390_da7219";
|
||||||
|
|
||||||
|
broxton_audio_card.codec_conf = max98390_codec_confs;
|
||||||
|
broxton_audio_card.num_configs = ARRAY_SIZE(max98390_codec_confs);
|
||||||
|
} else
|
||||||
|
broxton_audio_card.name = "cmlda7219max";
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) {
|
for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) {
|
||||||
/* MAXIM_CODEC is connected to SSP1. */
|
/* MAXIM_CODEC is connected to SSP1. */
|
||||||
|
@ -710,6 +809,11 @@ static int broxton_audio_probe(struct platform_device *pdev)
|
||||||
BXT_MAXIM_CODEC_DAI)) {
|
BXT_MAXIM_CODEC_DAI)) {
|
||||||
broxton_dais[i].name = "SSP1-Codec";
|
broxton_dais[i].name = "SSP1-Codec";
|
||||||
broxton_dais[i].cpus->dai_name = "SSP1 Pin";
|
broxton_dais[i].cpus->dai_name = "SSP1 Pin";
|
||||||
|
|
||||||
|
if (ctx->spkamp == SPKAMP_MAX98390) {
|
||||||
|
broxton_dais[i].codecs = max98390_codec;
|
||||||
|
broxton_dais[i].num_codecs = ARRAY_SIZE(max98390_codec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* DIALOG_CODEC is connected to SSP0 */
|
/* DIALOG_CODEC is connected to SSP0 */
|
||||||
else if (!strcmp(broxton_dais[i].codecs->dai_name,
|
else if (!strcmp(broxton_dais[i].codecs->dai_name,
|
||||||
|
@ -759,6 +863,7 @@ MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>");
|
||||||
MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>");
|
MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>");
|
||||||
MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
|
MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>");
|
||||||
MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
|
MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
|
||||||
|
MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
MODULE_ALIAS("platform:bxt_da7219_max98357a");
|
MODULE_ALIAS("platform:bxt_da7219_max98357a");
|
||||||
MODULE_ALIAS("platform:glk_da7219_max98357a");
|
MODULE_ALIAS("platform:glk_da7219_max98357a");
|
||||||
|
|
|
@ -19,6 +19,11 @@ static struct snd_soc_acpi_codecs max98357a_spk_codecs = {
|
||||||
.codecs = {"MX98357A"}
|
.codecs = {"MX98357A"}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct snd_soc_acpi_codecs max98390_spk_codecs = {
|
||||||
|
.num_codecs = 1,
|
||||||
|
.codecs = {"MX98390"}
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The order of the three entries with .id = "10EC5682" matters
|
* The order of the three entries with .id = "10EC5682" matters
|
||||||
* here, because DSDT tables expose an ACPI HID for the MAX98357A
|
* here, because DSDT tables expose an ACPI HID for the MAX98357A
|
||||||
|
@ -55,6 +60,14 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_cml_machines[] = {
|
||||||
.sof_fw_filename = "sof-cml.ri",
|
.sof_fw_filename = "sof-cml.ri",
|
||||||
.sof_tplg_filename = "sof-cml-da7219-max98357a.tplg",
|
.sof_tplg_filename = "sof-cml-da7219-max98357a.tplg",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.id = "DLGS7219",
|
||||||
|
.drv_name = "cml_da7219_max98357a",
|
||||||
|
.machine_quirk = snd_soc_acpi_codec_list,
|
||||||
|
.quirk_data = &max98390_spk_codecs,
|
||||||
|
.sof_fw_filename = "sof-cml.ri",
|
||||||
|
.sof_tplg_filename = "sof-cml-da7219-max98357a.tplg",
|
||||||
|
},
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cml_machines);
|
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cml_machines);
|
||||||
|
|
Loading…
Add table
Reference in a new issue