From 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 11 Dec 2023 02:46:07 +0000 Subject: [PATCH] add audio --- kernel/sound/soc/intel/boards/bxt_da7219_max98357a.c | 436 +++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 345 insertions(+), 91 deletions(-) diff --git a/kernel/sound/soc/intel/boards/bxt_da7219_max98357a.c b/kernel/sound/soc/intel/boards/bxt_da7219_max98357a.c index 6f052fc..0c0a717 100644 --- a/kernel/sound/soc/intel/boards/bxt_da7219_max98357a.c +++ b/kernel/sound/soc/intel/boards/bxt_da7219_max98357a.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Intel Broxton-P I2S Machine Driver * @@ -5,17 +6,9 @@ * * Modified from: * Intel Skylake I2S Machine driver - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ +#include <linux/input.h> #include <linux/module.h> #include <linux/platform_device.h> #include <sound/core.h> @@ -23,14 +16,22 @@ #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> +#include <sound/soc-acpi.h> #include "../../codecs/hdac_hdmi.h" #include "../../codecs/da7219.h" #include "../../codecs/da7219-aad.h" +#include "../common/soc-intel-quirks.h" +#include "hda_dsp_common.h" #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]; @@ -43,11 +44,14 @@ struct bxt_card_private { struct list_head hdmi_pcm_list; + bool common_hdmi_codec_drv; + int spkamp; }; enum { BXT_DPCM_AUDIO_PB = 0, BXT_DPCM_AUDIO_CP, + BXT_DPCM_AUDIO_HS_PB, BXT_DPCM_AUDIO_REF_CP, BXT_DPCM_AUDIO_DMIC_CP, BXT_DPCM_AUDIO_HDMI1_PB, @@ -87,13 +91,20 @@ 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), @@ -102,13 +113,19 @@ platform_clock_control, SND_SOC_DAPM_POST_PMD|SND_SOC_DAPM_PRE_PMU), }; -static const struct snd_soc_dapm_route broxton_map[] = { +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"}, @@ -117,15 +134,6 @@ {"DMic", NULL, "SoC DMIC"}, /* CODEC BE connections */ - {"HiFi Playback", NULL, "ssp5 Tx"}, - {"ssp5 Tx", NULL, "codec0_out"}, - - {"Playback", NULL, "ssp1 Tx"}, - {"ssp1 Tx", NULL, "codec1_out"}, - - {"codec0_in", NULL, "ssp1 Rx"}, - {"ssp1 Rx", NULL, "Capture"}, - {"HDMI1", NULL, "hif5-0 Output"}, {"HDMI2", NULL, "hif6-0 Output"}, {"HDMI2", NULL, "hif7-0 Output"}, @@ -145,18 +153,51 @@ { "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"}, + + {"Playback", NULL, "ssp1 Tx"}, + {"ssp1 Tx", NULL, "codec1_out"}, + + {"codec0_in", NULL, "ssp1 Rx"}, + {"ssp1 Rx", NULL, "Capture"}, +}; + +static const struct snd_soc_dapm_route gemini_map[] = { + {"HiFi Playback", NULL, "ssp1 Tx"}, + {"ssp1 Tx", NULL, "codec0_out"}, + + {"Playback", NULL, "ssp2 Tx"}, + {"ssp2 Tx", NULL, "codec1_out"}, + + {"codec0_in", NULL, "ssp2 Rx"}, + {"ssp2 Rx", NULL, "Capture"}, +}; + static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); - struct snd_interval *channels = hw_param_interval(params, + struct snd_interval *chan = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); /* The ADSP will convert the FE rate to 48k, stereo */ rate->min = rate->max = 48000; - channels->min = channels->max = DUAL_CHANNEL; + chan->min = chan->max = DUAL_CHANNEL; /* set SSP to 24 bit */ snd_mask_none(fmt); @@ -168,12 +209,19 @@ static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) { int ret; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_component *component = rtd->codec_dai->component; + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + int clk_freq; /* Configure sysclk for codec */ - ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 19200000, + if (soc_intel_is_cml()) + clk_freq = 24000000; + else + clk_freq = 19200000; + + ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq, SND_SOC_CLOCK_IN); + if (ret) { dev_err(rtd->dev, "can't set codec sysclk configuration\n"); return ret; @@ -192,6 +240,12 @@ return ret; } + snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); + snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); + snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_3, + KEY_VOICECOMMAND); + da7219_aad_jack_det(component, &broxton_headset); snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); @@ -202,7 +256,7 @@ static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct bxt_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = rtd->codec_dai; + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); struct bxt_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -220,7 +274,7 @@ static int broxton_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dapm_context *dapm; - struct snd_soc_component *component = rtd->cpu_dai->component; + struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; dapm = snd_soc_component_get_dapm(component); snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); @@ -289,12 +343,12 @@ static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { - struct snd_interval *channels = hw_param_interval(params, + struct snd_interval *chan = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); if (params_channels(params) == 2) - channels->min = channels->max = 2; + chan->min = chan->max = 2; else - channels->min = channels->max = 4; + chan->min = chan->max = 4; return 0; } @@ -350,132 +404,185 @@ }; /* broxton digital audio interface glue - connects codec <--> CPU */ +SND_SOC_DAILINK_DEF(dummy, + DAILINK_COMP_ARRAY(COMP_DUMMY())); + +SND_SOC_DAILINK_DEF(system, + DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); + +SND_SOC_DAILINK_DEF(system2, + DAILINK_COMP_ARRAY(COMP_CPU("System Pin2"))); + +SND_SOC_DAILINK_DEF(reference, + DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); + +SND_SOC_DAILINK_DEF(dmic, + DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); + +SND_SOC_DAILINK_DEF(hdmi1, + DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); + +SND_SOC_DAILINK_DEF(hdmi2, + DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); + +SND_SOC_DAILINK_DEF(hdmi3, + DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); + + /* Back End DAI */ +SND_SOC_DAILINK_DEF(ssp5_pin, + DAILINK_COMP_ARRAY(COMP_CPU("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"))); +SND_SOC_DAILINK_DEF(ssp1_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00", + BXT_DIALOG_CODEC_DAI))); + +SND_SOC_DAILINK_DEF(dmic_pin, + DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); + +SND_SOC_DAILINK_DEF(dmic16k_pin, + DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin"))); + +SND_SOC_DAILINK_DEF(dmic_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); + +SND_SOC_DAILINK_DEF(idisp1_pin, + DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); +SND_SOC_DAILINK_DEF(idisp1_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); + +SND_SOC_DAILINK_DEF(idisp2_pin, + DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); +SND_SOC_DAILINK_DEF(idisp2_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", + "intel-hdmi-hifi2"))); + +SND_SOC_DAILINK_DEF(idisp3_pin, + DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); +SND_SOC_DAILINK_DEF(idisp3_codec, + DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", + "intel-hdmi-hifi3"))); + +SND_SOC_DAILINK_DEF(platform, + DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:0e.0"))); + static struct snd_soc_dai_link broxton_dais[] = { /* Front End DAI links */ [BXT_DPCM_AUDIO_PB] = { .name = "Bxt Audio Port", .stream_name = "Audio", - .cpu_dai_name = "System Pin", - .platform_name = "0000:00:0e.0", .dynamic = 1, - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", .nonatomic = 1, .init = broxton_da7219_fe_init, .trigger = { SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .dpcm_playback = 1, .ops = &broxton_da7219_fe_ops, + SND_SOC_DAILINK_REG(system, dummy, platform), }, [BXT_DPCM_AUDIO_CP] = { .name = "Bxt Audio Capture Port", .stream_name = "Audio Record", - .cpu_dai_name = "System Pin", - .platform_name = "0000:00:0e.0", .dynamic = 1, - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", .nonatomic = 1, .trigger = { SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, .dpcm_capture = 1, .ops = &broxton_da7219_fe_ops, + SND_SOC_DAILINK_REG(system, dummy, platform), + }, + [BXT_DPCM_AUDIO_HS_PB] = { + .name = "Bxt Audio Headset Playback", + .stream_name = "Headset Playback", + .dynamic = 1, + .nonatomic = 1, + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, + .dpcm_playback = 1, + .ops = &broxton_da7219_fe_ops, + SND_SOC_DAILINK_REG(system2, dummy, platform), }, [BXT_DPCM_AUDIO_REF_CP] = { .name = "Bxt Audio Reference cap", .stream_name = "Refcap", - .cpu_dai_name = "Reference Pin", - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", - .platform_name = "0000:00:0e.0", .init = NULL, .dpcm_capture = 1, .nonatomic = 1, .dynamic = 1, .ops = &broxton_refcap_ops, + SND_SOC_DAILINK_REG(reference, dummy, platform), }, [BXT_DPCM_AUDIO_DMIC_CP] = { .name = "Bxt Audio DMIC cap", .stream_name = "dmiccap", - .cpu_dai_name = "DMIC Pin", - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", - .platform_name = "0000:00:0e.0", .init = NULL, .dpcm_capture = 1, .nonatomic = 1, .dynamic = 1, .ops = &broxton_dmic_ops, + SND_SOC_DAILINK_REG(dmic, dummy, platform), }, [BXT_DPCM_AUDIO_HDMI1_PB] = { .name = "Bxt HDMI Port1", .stream_name = "Hdmi1", - .cpu_dai_name = "HDMI1 Pin", - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", - .platform_name = "0000:00:0e.0", .dpcm_playback = 1, .init = NULL, .nonatomic = 1, .dynamic = 1, + SND_SOC_DAILINK_REG(hdmi1, dummy, platform), }, [BXT_DPCM_AUDIO_HDMI2_PB] = { .name = "Bxt HDMI Port2", .stream_name = "Hdmi2", - .cpu_dai_name = "HDMI2 Pin", - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", - .platform_name = "0000:00:0e.0", .dpcm_playback = 1, .init = NULL, .nonatomic = 1, .dynamic = 1, + SND_SOC_DAILINK_REG(hdmi2, dummy, platform), }, [BXT_DPCM_AUDIO_HDMI3_PB] = { .name = "Bxt HDMI Port3", .stream_name = "Hdmi3", - .cpu_dai_name = "HDMI3 Pin", - .codec_name = "snd-soc-dummy", - .codec_dai_name = "snd-soc-dummy-dai", - .platform_name = "0000:00:0e.0", .dpcm_playback = 1, .init = NULL, .nonatomic = 1, .dynamic = 1, + SND_SOC_DAILINK_REG(hdmi3, dummy, platform), }, /* Back End DAI links */ { /* SSP5 - Codec */ .name = "SSP5-Codec", .id = 0, - .cpu_dai_name = "SSP5 Pin", - .platform_name = "0000:00:0e.0", .no_pcm = 1, - .codec_name = "MX98357A:00", - .codec_dai_name = BXT_MAXIM_CODEC_DAI, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, .ignore_pmdown_time = 1, .be_hw_params_fixup = broxton_ssp_fixup, .dpcm_playback = 1, + SND_SOC_DAILINK_REG(ssp5_pin, ssp5_codec, platform), }, { /* SSP1 - Codec */ .name = "SSP1-Codec", .id = 1, - .cpu_dai_name = "SSP1 Pin", - .platform_name = "0000:00:0e.0", .no_pcm = 1, - .codec_name = "i2c-DLGS7219:00", - .codec_dai_name = BXT_DIALOG_CODEC_DAI, .init = broxton_da7219_codec_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, @@ -483,51 +590,59 @@ .be_hw_params_fixup = broxton_ssp_fixup, .dpcm_playback = 1, .dpcm_capture = 1, + SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform), }, { .name = "dmic01", .id = 2, - .cpu_dai_name = "DMIC01 Pin", - .codec_name = "dmic-codec", - .codec_dai_name = "dmic-hifi", - .platform_name = "0000:00:0e.0", .ignore_suspend = 1, .be_hw_params_fixup = broxton_dmic_fixup, .dpcm_capture = 1, .no_pcm = 1, + SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), }, { .name = "iDisp1", .id = 3, - .cpu_dai_name = "iDisp1 Pin", - .codec_name = "ehdaudio0D2", - .codec_dai_name = "intel-hdmi-hifi1", - .platform_name = "0000:00:0e.0", .init = broxton_hdmi_init, .dpcm_playback = 1, .no_pcm = 1, + SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), }, { .name = "iDisp2", .id = 4, - .cpu_dai_name = "iDisp2 Pin", - .codec_name = "ehdaudio0D2", - .codec_dai_name = "intel-hdmi-hifi2", - .platform_name = "0000:00:0e.0", .init = broxton_hdmi_init, .dpcm_playback = 1, .no_pcm = 1, + SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), }, { .name = "iDisp3", .id = 5, - .cpu_dai_name = "iDisp3 Pin", - .codec_name = "ehdaudio0D2", - .codec_dai_name = "intel-hdmi-hifi3", - .platform_name = "0000:00:0e.0", .init = broxton_hdmi_init, .dpcm_playback = 1, .no_pcm = 1, + SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), + }, + { + .name = "dmic16k", + .id = 6, + .be_hw_params_fixup = broxton_dmic_fixup, + .dpcm_capture = 1, + .no_pcm = 1, + SND_SOC_DAILINK_REG(dmic16k_pin, dmic_codec, platform), + }, +}; + +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", }, }; @@ -537,8 +652,68 @@ 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); + return -EINVAL; + } + + 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)); + else + snd_soc_dapm_add_routes(&card->dapm, broxton_map, + ARRAY_SIZE(broxton_map)); + + if (list_empty(&ctx->hdmi_pcm_list)) + return -EINVAL; + + if (ctx->common_hdmi_codec_drv) { + pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm, + head); + component = pcm->codec_dai->component; + return hda_dsp_hdmi_build_controls(card, component); + } list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { component = pcm->codec_dai->component; @@ -559,9 +734,6 @@ i++; } - if (!component) - return -EINVAL; - return hdac_hdmi_jack_port_init(component, &card->dapm); } @@ -575,8 +747,8 @@ .num_controls = ARRAY_SIZE(broxton_controls), .dapm_widgets = broxton_widgets, .num_dapm_widgets = ARRAY_SIZE(broxton_widgets), - .dapm_routes = broxton_map, - .num_dapm_routes = ARRAY_SIZE(broxton_map), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), .fully_routed = true, .late_probe = bxt_card_late_probe, }; @@ -584,6 +756,9 @@ static int broxton_audio_probe(struct platform_device *pdev) { struct bxt_card_private *ctx; + struct snd_soc_acpi_mach *mach; + const char *platform_name; + int ret; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) @@ -591,11 +766,84 @@ 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()) { + unsigned int i; + + broxton_audio_card.name = "glkda7219max"; + /* Fixup the SSP entries for geminilake */ + for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) { + /* MAXIM_CODEC is connected to SSP1. */ + if (!strcmp(broxton_dais[i].codecs->dai_name, + BXT_MAXIM_CODEC_DAI)) { + broxton_dais[i].name = "SSP1-Codec"; + broxton_dais[i].cpus->dai_name = "SSP1 Pin"; + } + /* DIALOG_CODE is connected to SSP2 */ + else if (!strcmp(broxton_dais[i].codecs->dai_name, + BXT_DIALOG_CODEC_DAI)) { + broxton_dais[i].name = "SSP2-Codec"; + broxton_dais[i].cpus->dai_name = "SSP2 Pin"; + } + } + } else if (soc_intel_is_cml()) { + unsigned int i; + + 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. */ + if (!strcmp(broxton_dais[i].codecs->dai_name, + 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, + BXT_DIALOG_CODEC_DAI)) { + broxton_dais[i].name = "SSP0-Codec"; + broxton_dais[i].cpus->dai_name = "SSP0 Pin"; + } + } + } + + /* override plaform name, if required */ + mach = pdev->dev.platform_data; + platform_name = mach->mach_params.platform; + + ret = snd_soc_fixup_dai_links_platform_name(&broxton_audio_card, + platform_name); + if (ret) + return ret; + + ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; return devm_snd_soc_register_card(&pdev->dev, &broxton_audio_card); } + +static const struct platform_device_id bxt_board_ids[] = { + { .name = "bxt_da7219_max98357a" }, + { .name = "glk_da7219_max98357a" }, + { .name = "cml_da7219_max98357a" }, + { } +}; static struct platform_driver broxton_audio = { .probe = broxton_audio_probe, @@ -603,6 +851,7 @@ .name = "bxt_da7219_max98357a", .pm = &snd_soc_pm_ops, }, + .id_table = bxt_board_ids, }; module_platform_driver(broxton_audio) @@ -612,5 +861,10 @@ MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com>"); 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"); +MODULE_ALIAS("platform:cml_da7219_max98357a"); -- Gitblit v1.6.2