Message ID | 1593498722-7074-1-git-send-email-brent.lu@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | ASoC: Intel: bxt-da7219-max98357a: support MAX98390 speaker amp | expand |
> > 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> This patch is from Chrome-v4.19 branch to support the combination of DA7219 and MAX98390 on a CML Chromebook. It reuses the topology file sof-cml-da7219-max98357a.tplg > --- > sound/soc/intel/boards/Kconfig | 20 ++++ > sound/soc/intel/boards/bxt_da7219_max98357a.c | 129 > ++++++++++++++++++++-- > sound/soc/intel/common/soc-acpi-intel-cml-match.c | 4 +- > 3 files changed, 139 insertions(+), 14 deletions(-) > > diff --git a/sound/soc/intel/boards/Kconfig > b/sound/soc/intel/boards/Kconfig index 3d820e1..b3b863e 100644 > --- a/sound/soc/intel/boards/Kconfig > +++ b/sound/soc/intel/boards/Kconfig > @@ -291,9 +291,17 @@ config > SND_SOC_INTEL_DA7219_MAX98357A_GENERIC > select SND_SOC_DMIC > select SND_SOC_HDAC_HDMI > > +config SND_SOC_INTEL_DA7219_MAX98390_GENERIC > + tristate > + select SND_SOC_DA7219 > + select SND_SOC_MAX98390 > + select SND_SOC_DMIC > + select SND_SOC_HDAC_HDMI > + > config SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON > tristate > select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC > + select SND_SOC_INTEL_DA7219_MAX98390_GENERIC > > if SND_SOC_INTEL_APL > > @@ -309,6 +317,18 @@ config > SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH > Say Y or m if you have such a device. This is a recommended option. > If unsure select "N". > > +config SND_SOC_INTEL_BXT_DA7219_MAX98390_MACH > + tristate "Broxton with DA7219 and MAX98390 in I2S Mode" > + depends on I2C && ACPI && GPIOLIB > + depends on MFD_INTEL_LPSS || COMPILE_TEST > + depends on SND_HDA_CODEC_HDMI > + select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON > + help > + This adds support for ASoC machine driver for Broxton-P platforms > + with DA7219 + MAX98390 I2S audio codec. > + Say Y or m if you have such a device. This is a recommended option. > + If unsure select "N". > + > config SND_SOC_INTEL_BXT_RT298_MACH > tristate "Broxton with RT298 I2S mode" > depends on I2C && ACPI && GPIOLIB > diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c > b/sound/soc/intel/boards/bxt_da7219_max98357a.c > index 44016c1..12f07e1 100644 > --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c > +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c > @@ -25,9 +25,14 @@ > > #define BXT_DIALOG_CODEC_DAI "da7219-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 QUAD_CHANNEL 4 > > +#define SPKAMP_MAX98357A 1 > +#define SPKAMP_MAX98390 2 > + > static struct snd_soc_jack broxton_headset; static struct snd_soc_jack > broxton_hdmi[3]; > > @@ -40,6 +45,7 @@ struct bxt_hdmi_pcm { > struct bxt_card_private { > struct list_head hdmi_pcm_list; > bool common_hdmi_codec_drv; > + int spkamp; > }; > > enum { > @@ -85,13 +91,20 @@ static int platform_clock_control(struct > snd_soc_dapm_widget *w, static const struct snd_kcontrol_new > broxton_controls[] = { > SOC_DAPM_PIN_SWITCH("Headphone Jack"), > SOC_DAPM_PIN_SWITCH("Headset Mic"), > +}; > + > +static const struct snd_kcontrol_new max98357a_controls[] = { > 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[] = { > SND_SOC_DAPM_HP("Headphone Jack", NULL), > SND_SOC_DAPM_MIC("Headset Mic", NULL), > - SND_SOC_DAPM_SPK("Spk", NULL), > SND_SOC_DAPM_MIC("SoC DMIC", NULL), > SND_SOC_DAPM_SPK("HDMI1", 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), > }; > > +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[] = { > /* HP jack connectors - unknown if we have jack detection */ > {"Headphone Jack", NULL, "HPL"}, > {"Headphone Jack", NULL, "HPR"}, > > - /* speaker */ > - {"Spk", NULL, "Speaker"}, > - > /* other jacks */ > {"MIC", NULL, "Headset Mic"}, > > @@ -134,6 +153,17 @@ static const struct snd_soc_dapm_route audio_map[] > = { > { "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[] = { > {"HiFi Playback", NULL, "ssp5 Tx"}, > {"ssp5 Tx", NULL, "codec0_out"}, > @@ -404,6 +434,10 @@ SND_SOC_DAILINK_DEF(ssp5_pin, > SND_SOC_DAILINK_DEF(ssp5_codec, > DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", > 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, > 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 > static int bxt_card_late_probe(struct snd_soc_card *card) { > struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card); > struct bxt_hdmi_pcm *pcm; > 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, ret, i = 0; > 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; > + } > + > + ret = snd_soc_dapm_new_controls(&card->dapm, widgets, > num_widgets); > + if (ret) { > + dev_err(card->dev, "Fail to new widgets\n"); > + return ret; > + } > + > + ret = snd_soc_add_card_controls(card, controls, num_controls); > + if (ret) { > + dev_err(card->dev, "Fail to add controls\n"); > + return ret; > + } > + > + ret = snd_soc_dapm_add_routes(&card->dapm, routes, > num_routes); > + if (ret) { > + dev_err(card->dev, "Fail to add routes\n"); > + return ret; > + } > + > if (soc_intel_is_glk()) > snd_soc_dapm_add_routes(&card->dapm, gemini_map, > ARRAY_SIZE(gemini_map)); > @@ -631,17 +719,17 @@ static int bxt_card_late_probe(struct snd_soc_card > *card) > component = pcm->codec_dai->component; > snprintf(jack_name, sizeof(jack_name), > "HDMI/DP, pcm=%d Jack", pcm->device); > - err = snd_soc_card_jack_new(card, jack_name, > + ret = snd_soc_card_jack_new(card, jack_name, > SND_JACK_AVOUT, > &broxton_hdmi[i], > NULL, 0); > > - if (err) > - return err; > + if (ret) > + return ret; > > - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, > + ret = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, > &broxton_hdmi[i]); > - if (err < 0) > - return err; > + if (ret < 0) > + return ret; > > i++; > } > @@ -678,6 +766,11 @@ static int broxton_audio_probe(struct > platform_device *pdev) > > 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; > snd_soc_card_set_drvdata(&broxton_audio_card, ctx); > if (soc_intel_is_glk()) { > @@ -702,7 +795,13 @@ static int broxton_audio_probe(struct > platform_device *pdev) > } else if (soc_intel_is_cml()) { > 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++) { > /* MAXIM_CODEC is connected to SSP1. */ @@ - > 710,6 +809,11 @@ static int broxton_audio_probe(struct platform_device > *pdev) > BXT_MAXIM_CODEC_DAI)) { > broxton_dais[i].name = "SSP1-Codec"; > 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 */ > 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("Naveen Manohar > <naveen.m@intel.com>"); MODULE_AUTHOR("Mac Chiang > <mac.chiang@intel.com>"); > +MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); > MODULE_LICENSE("GPL v2"); > MODULE_ALIAS("platform:bxt_da7219_max98357a"); > MODULE_ALIAS("platform:glk_da7219_max98357a"); > diff --git a/sound/soc/intel/common/soc-acpi-intel-cml-match.c > b/sound/soc/intel/common/soc-acpi-intel-cml-match.c > index cdea0c0..7dc9ba9 100644 > --- a/sound/soc/intel/common/soc-acpi-intel-cml-match.c > +++ b/sound/soc/intel/common/soc-acpi-intel-cml-match.c > @@ -15,8 +15,8 @@ static struct snd_soc_acpi_codecs rt1011_spk_codecs = > { }; > > static struct snd_soc_acpi_codecs max98357a_spk_codecs = { > - .num_codecs = 1, > - .codecs = {"MX98357A"} > + .num_codecs = 2, > + .codecs = {"MX98357A", "MX98390"} > }; > > /* > -- > 2.7.4
>> diff --git a/sound/soc/intel/boards/Kconfig >> b/sound/soc/intel/boards/Kconfig index 3d820e1..b3b863e 100644 >> --- a/sound/soc/intel/boards/Kconfig >> +++ b/sound/soc/intel/boards/Kconfig >> @@ -291,9 +291,17 @@ config >> SND_SOC_INTEL_DA7219_MAX98357A_GENERIC >> select SND_SOC_DMIC >> select SND_SOC_HDAC_HDMI >> >> +config SND_SOC_INTEL_DA7219_MAX98390_GENERIC >> + tristate >> + select SND_SOC_DA7219 >> + select SND_SOC_MAX98390 >> + select SND_SOC_DMIC >> + select SND_SOC_HDAC_HDMI >> + >> config SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON >> tristate >> select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC >> + select SND_SOC_INTEL_DA7219_MAX98390_GENERIC this doesn't look too good, the only difference is the addition of MAX98090 which should be added in SND_SOC_INTEL_DA7219_MAX98357A_GENERIC above. >> >> if SND_SOC_INTEL_APL >> >> @@ -309,6 +317,18 @@ config >> SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH >> Say Y or m if you have such a device. This is a recommended option. >> If unsure select "N". >> >> +config SND_SOC_INTEL_BXT_DA7219_MAX98390_MACH >> + tristate "Broxton with DA7219 and MAX98390 in I2S Mode" >> + depends on I2C && ACPI && GPIOLIB >> + depends on MFD_INTEL_LPSS || COMPILE_TEST >> + depends on SND_HDA_CODEC_HDMI >> + select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON >> + help >> + This adds support for ASoC machine driver for Broxton-P platforms >> + with DA7219 + MAX98390 I2S audio codec. >> + Say Y or m if you have such a device. This is a recommended option. >> + If unsure select "N". >> + i don't think you need a different top-level config, just extend the existing one to say MAX98357A or MAX98390. [...] >> if (soc_intel_is_glk()) >> snd_soc_dapm_add_routes(&card->dapm, gemini_map, >> ARRAY_SIZE(gemini_map)); >> @@ -631,17 +719,17 @@ static int bxt_card_late_probe(struct snd_soc_card >> *card) >> component = pcm->codec_dai->component; >> snprintf(jack_name, sizeof(jack_name), >> "HDMI/DP, pcm=%d Jack", pcm->device); >> - err = snd_soc_card_jack_new(card, jack_name, >> + ret = snd_soc_card_jack_new(card, jack_name, >> SND_JACK_AVOUT, >> &broxton_hdmi[i], >> NULL, 0); >> >> - if (err) >> - return err; >> + if (ret) >> + return ret; >> >> - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, >> + ret = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, >> &broxton_hdmi[i]); >> - if (err < 0) >> - return err; >> + if (ret < 0) >> + return ret; these look like unrelated changes? >> --- a/sound/soc/intel/common/soc-acpi-intel-cml-match.c >> +++ b/sound/soc/intel/common/soc-acpi-intel-cml-match.c >> @@ -15,8 +15,8 @@ static struct snd_soc_acpi_codecs rt1011_spk_codecs = >> { }; >> >> static struct snd_soc_acpi_codecs max98357a_spk_codecs = { >> - .num_codecs = 1, >> - .codecs = {"MX98357A"} >> + .num_codecs = 2, >> + .codecs = {"MX98357A", "MX98390"} That looks just wrong? It would be really odd to list two devices as prerequisites for loading a driver, when in practice they are mutually exclusive? Something's broken in coreboot if both are present. see below what we used for JSL: see static struct snd_soc_acpi_codecs jsl_7219_98373_codecs = { .num_codecs = 1, .codecs = {"MX98373"} }; static struct snd_soc_acpi_codecs mx98360a_spk = { .num_codecs = 1, .codecs = {"MX98360A"} };
> > this doesn't look too good, the only difference is the addition of > MAX98090 which should be added in > SND_SOC_INTEL_DA7219_MAX98357A_GENERIC > above. Will do > > i don't think you need a different top-level config, just extend the existing > one to say MAX98357A or MAX98390. > > [...] > OK. I'll modify the description for MAX98390 > > these look like unrelated changes? > > Will revert those changes. > > That looks just wrong? > > It would be really odd to list two devices as prerequisites for loading a driver, > when in practice they are mutually exclusive? Something's broken in > coreboot if both are present. > > see below what we used for JSL: > > see static struct snd_soc_acpi_codecs jsl_7219_98373_codecs = { > .num_codecs = 1, > .codecs = {"MX98373"} > }; > > static struct snd_soc_acpi_codecs mx98360a_spk = { > .num_codecs = 1, > .codecs = {"MX98360A"} > }; Err... I misread the snd_soc_acpi_codec_list function and made this error. Will fix it in the V2 patch. I will also fix the Chrome v4.19 branch. Thank you for the review. Regards, Brent
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 3d820e1..b3b863e 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -291,9 +291,17 @@ config SND_SOC_INTEL_DA7219_MAX98357A_GENERIC select SND_SOC_DMIC select SND_SOC_HDAC_HDMI +config SND_SOC_INTEL_DA7219_MAX98390_GENERIC + tristate + select SND_SOC_DA7219 + select SND_SOC_MAX98390 + select SND_SOC_DMIC + select SND_SOC_HDAC_HDMI + config SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON tristate select SND_SOC_INTEL_DA7219_MAX98357A_GENERIC + select SND_SOC_INTEL_DA7219_MAX98390_GENERIC if SND_SOC_INTEL_APL @@ -309,6 +317,18 @@ config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH Say Y or m if you have such a device. This is a recommended option. If unsure select "N". +config SND_SOC_INTEL_BXT_DA7219_MAX98390_MACH + tristate "Broxton with DA7219 and MAX98390 in I2S Mode" + depends on I2C && ACPI && GPIOLIB + depends on MFD_INTEL_LPSS || COMPILE_TEST + depends on SND_HDA_CODEC_HDMI + select SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON + help + This adds support for ASoC machine driver for Broxton-P platforms + with DA7219 + MAX98390 I2S audio codec. + Say Y or m if you have such a device. This is a recommended option. + If unsure select "N". + config SND_SOC_INTEL_BXT_RT298_MACH tristate "Broxton with RT298 I2S mode" depends on I2C && ACPI && GPIOLIB diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c index 44016c1..12f07e1 100644 --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c @@ -25,9 +25,14 @@ #define BXT_DIALOG_CODEC_DAI "da7219-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 QUAD_CHANNEL 4 +#define SPKAMP_MAX98357A 1 +#define SPKAMP_MAX98390 2 + static struct snd_soc_jack broxton_headset; static struct snd_soc_jack broxton_hdmi[3]; @@ -40,6 +45,7 @@ struct bxt_hdmi_pcm { struct bxt_card_private { struct list_head hdmi_pcm_list; bool common_hdmi_codec_drv; + int spkamp; }; enum { @@ -85,13 +91,20 @@ static int platform_clock_control(struct snd_soc_dapm_widget *w, static const struct snd_kcontrol_new broxton_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone Jack"), SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static const struct snd_kcontrol_new max98357a_controls[] = { 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[] = { SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_SPK("Spk", NULL), SND_SOC_DAPM_MIC("SoC DMIC", NULL), SND_SOC_DAPM_SPK("HDMI1", 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), }; +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[] = { /* HP jack connectors - unknown if we have jack detection */ {"Headphone Jack", NULL, "HPL"}, {"Headphone Jack", NULL, "HPR"}, - /* speaker */ - {"Spk", NULL, "Speaker"}, - /* other jacks */ {"MIC", NULL, "Headset Mic"}, @@ -134,6 +153,17 @@ static const struct snd_soc_dapm_route audio_map[] = { { "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[] = { {"HiFi Playback", NULL, "ssp5 Tx"}, {"ssp5 Tx", NULL, "codec0_out"}, @@ -404,6 +434,10 @@ SND_SOC_DAILINK_DEF(ssp5_pin, SND_SOC_DAILINK_DEF(ssp5_codec, DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", 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, 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 static int bxt_card_late_probe(struct snd_soc_card *card) { struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card); struct bxt_hdmi_pcm *pcm; 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, ret, i = 0; 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; + } + + ret = snd_soc_dapm_new_controls(&card->dapm, widgets, num_widgets); + if (ret) { + dev_err(card->dev, "Fail to new widgets\n"); + return ret; + } + + ret = snd_soc_add_card_controls(card, controls, num_controls); + if (ret) { + dev_err(card->dev, "Fail to add controls\n"); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, routes, num_routes); + if (ret) { + dev_err(card->dev, "Fail to add routes\n"); + return ret; + } + if (soc_intel_is_glk()) snd_soc_dapm_add_routes(&card->dapm, gemini_map, ARRAY_SIZE(gemini_map)); @@ -631,17 +719,17 @@ static int bxt_card_late_probe(struct snd_soc_card *card) component = pcm->codec_dai->component; snprintf(jack_name, sizeof(jack_name), "HDMI/DP, pcm=%d Jack", pcm->device); - err = snd_soc_card_jack_new(card, jack_name, + ret = snd_soc_card_jack_new(card, jack_name, SND_JACK_AVOUT, &broxton_hdmi[i], NULL, 0); - if (err) - return err; + if (ret) + return ret; - err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, + ret = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device, &broxton_hdmi[i]); - if (err < 0) - return err; + if (ret < 0) + return ret; i++; } @@ -678,6 +766,11 @@ static int broxton_audio_probe(struct platform_device *pdev) 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; snd_soc_card_set_drvdata(&broxton_audio_card, ctx); if (soc_intel_is_glk()) { @@ -702,7 +795,13 @@ static int broxton_audio_probe(struct platform_device *pdev) } else if (soc_intel_is_cml()) { 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++) { /* MAXIM_CODEC is connected to SSP1. */ @@ -710,6 +809,11 @@ static int broxton_audio_probe(struct platform_device *pdev) BXT_MAXIM_CODEC_DAI)) { broxton_dais[i].name = "SSP1-Codec"; 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 */ 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("Naveen Manohar <naveen.m@intel.com>"); MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); +MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:bxt_da7219_max98357a"); MODULE_ALIAS("platform:glk_da7219_max98357a"); diff --git a/sound/soc/intel/common/soc-acpi-intel-cml-match.c b/sound/soc/intel/common/soc-acpi-intel-cml-match.c index cdea0c0..7dc9ba9 100644 --- a/sound/soc/intel/common/soc-acpi-intel-cml-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-cml-match.c @@ -15,8 +15,8 @@ static struct snd_soc_acpi_codecs rt1011_spk_codecs = { }; static struct snd_soc_acpi_codecs max98357a_spk_codecs = { - .num_codecs = 1, - .codecs = {"MX98357A"} + .num_codecs = 2, + .codecs = {"MX98357A", "MX98390"} }; /*
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> --- sound/soc/intel/boards/Kconfig | 20 ++++ sound/soc/intel/boards/bxt_da7219_max98357a.c | 129 ++++++++++++++++++++-- sound/soc/intel/common/soc-acpi-intel-cml-match.c | 4 +- 3 files changed, 139 insertions(+), 14 deletions(-)