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
					
				| @ -288,6 +288,7 @@ config SND_SOC_INTEL_DA7219_MAX98357A_GENERIC | ||||
| 	tristate | ||||
| 	select SND_SOC_DA7219 | ||||
| 	select SND_SOC_MAX98357A | ||||
| 	select SND_SOC_MAX98390 | ||||
| 	select SND_SOC_DMIC | ||||
| 	select SND_SOC_HDAC_HDMI | ||||
| 
 | ||||
| @ -298,14 +299,14 @@ config SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON | ||||
| if SND_SOC_INTEL_APL | ||||
| 
 | ||||
| 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 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 + 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. | ||||
| 	   If unsure select "N". | ||||
| 
 | ||||
|  | ||||
| @ -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, err, 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; | ||||
| 	} | ||||
| 
 | ||||
| 	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()) | ||||
| 		snd_soc_dapm_add_routes(&card->dapm, 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); | ||||
| 
 | ||||
| 	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"); | ||||
|  | ||||
| @ -19,6 +19,11 @@ static struct snd_soc_acpi_codecs max98357a_spk_codecs = { | ||||
| 	.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 | ||||
|  * 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_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); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user