diff options
Diffstat (limited to 'sound/soc/intel/boards/glk_rt5682_max98357a.c')
-rw-r--r-- | sound/soc/intel/boards/glk_rt5682_max98357a.c | 99 |
1 files changed, 73 insertions, 26 deletions
diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c b/sound/soc/intel/boards/glk_rt5682_max98357a.c index 62cca511522e..657e4658234c 100644 --- a/sound/soc/intel/boards/glk_rt5682_max98357a.c +++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c @@ -18,14 +18,18 @@ #include <sound/soc.h> #include <sound/soc-acpi.h> #include "../../codecs/rt5682.h" +#include "../../codecs/rt5682s.h" #include "../../codecs/hdac_hdmi.h" #include "hda_dsp_common.h" /* The platform clock outputs 19.2Mhz clock to codec as I2S MCLK */ #define GLK_PLAT_CLK_FREQ 19200000 #define RT5682_PLL_FREQ (48000 * 512) -#define GLK_REALTEK_CODEC_DAI "rt5682-aif1" +#define RT5682_DAI_NAME "rt5682-aif1" +#define RT5682S_DAI_NAME "rt5682s-aif1" #define GLK_MAXIM_CODEC_DAI "HiFi" +#define RT5682_DEV0_NAME "i2c-10EC5682:00" +#define RT5682S_DEV0_NAME "i2c-RTL5682:00" #define MAXIM_DEV0_NAME "MX98357A:00" #define DUAL_CHANNEL 2 #define QUAD_CHANNEL 4 @@ -43,6 +47,7 @@ struct glk_card_private { struct snd_soc_jack geminilake_headset; struct list_head hdmi_pcm_list; bool common_hdmi_codec_drv; + int is_rt5682s; }; enum { @@ -73,6 +78,17 @@ static const struct snd_soc_dapm_widget geminilake_widgets[] = { SND_SOC_DAPM_SPK("HDMI3", NULL), }; +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + static const struct snd_soc_dapm_route geminilake_map[] = { /* HP jack connectors - unknown if we have jack detection */ { "Headphone Jack", NULL, "HPOL" }, @@ -136,12 +152,22 @@ static int geminilake_ssp_fixup(struct snd_soc_pcm_runtime *rtd, static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) { struct glk_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_jack *jack; - int ret; + int pll_id, pll_source, clk_id, ret; + + if (ctx->is_rt5682s) { + pll_id = RT5682S_PLL2; + pll_source = RT5682S_PLL_S_MCLK; + clk_id = RT5682S_SCLK_S_PLL2; + } else { + pll_id = RT5682_PLL1; + pll_source = RT5682_PLL1_S_MCLK; + clk_id = RT5682_SCLK_S_PLL1; + } - ret = snd_soc_dai_set_pll(codec_dai, 0, RT5682_PLL1_S_MCLK, + ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source, GLK_PLAT_CLK_FREQ, RT5682_PLL_FREQ); if (ret < 0) { dev_err(rtd->dev, "can't set codec pll: %d\n", ret); @@ -149,7 +175,7 @@ static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) } /* Configure sysclk for codec */ - ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1, + ret = snd_soc_dai_set_sysclk(codec_dai, clk_id, RT5682_PLL_FREQ, SND_SOC_CLOCK_IN); if (ret < 0) dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret); @@ -158,10 +184,12 @@ static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) * Headset buttons map to the google Reference headset. * These can be configured by userspace. */ - ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | - SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, - &ctx->geminilake_headset, NULL, 0); + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | + SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_LINEOUT, + &ctx->geminilake_headset, + jack_pins, + ARRAY_SIZE(jack_pins)); if (ret) { dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); return ret; @@ -187,8 +215,8 @@ static int geminilake_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd) static int geminilake_rt5682_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); int ret; /* Set valid bitmask & configuration for I2S in 24 bit */ @@ -208,7 +236,7 @@ static struct snd_soc_ops geminilake_rt5682_ops = { static int geminilake_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct glk_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct glk_hdmi_pcm *pcm; pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); @@ -225,7 +253,7 @@ static int geminilake_hdmi_init(struct snd_soc_pcm_runtime *rtd) static int geminilake_rt5682_fe_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_cpu(rtd, 0)->component; struct snd_soc_dapm_context *dapm; int ret; @@ -344,9 +372,12 @@ SND_SOC_DAILINK_DEF(ssp1_codec, SND_SOC_DAILINK_DEF(ssp2_pin, DAILINK_COMP_ARRAY(COMP_CPU("SSP2 Pin"))); -SND_SOC_DAILINK_DEF(ssp2_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", - GLK_REALTEK_CODEC_DAI))); +SND_SOC_DAILINK_DEF(ssp2_codec_5682, + DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME, + RT5682_DAI_NAME))); +SND_SOC_DAILINK_DEF(ssp2_codec_5682s, + DAILINK_COMP_ARRAY(COMP_CODEC(RT5682S_DEV0_NAME, + RT5682S_DAI_NAME))); SND_SOC_DAILINK_DEF(dmic_pin, DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); @@ -473,7 +504,7 @@ static struct snd_soc_dai_link geminilake_dais[] = { .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .ignore_pmdown_time = 1, .be_hw_params_fixup = geminilake_ssp_fixup, .dpcm_playback = 1, @@ -486,13 +517,13 @@ static struct snd_soc_dai_link geminilake_dais[] = { .no_pcm = 1, .init = geminilake_rt5682_codec_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, + SND_SOC_DAIFMT_CBC_CFC, .ignore_pmdown_time = 1, .be_hw_params_fixup = geminilake_ssp_fixup, .ops = &geminilake_rt5682_ops, .dpcm_playback = 1, .dpcm_capture = 1, - SND_SOC_DAILINK_REG(ssp2_pin, ssp2_codec, platform), + SND_SOC_DAILINK_REG(ssp2_pin, ssp2_codec_5682, platform), }, { .name = "dmic01", @@ -553,8 +584,7 @@ static int glk_card_late_probe(struct snd_soc_card *card) snprintf(jack_name, sizeof(jack_name), "HDMI/DP, pcm=%d Jack", pcm->device); err = snd_soc_card_jack_new(card, jack_name, - SND_JACK_AVOUT, &geminilake_hdmi[i], - NULL, 0); + SND_JACK_AVOUT, &geminilake_hdmi[i]); if (err) return err; @@ -592,19 +622,35 @@ static int geminilake_audio_probe(struct platform_device *pdev) struct snd_soc_acpi_mach *mach; const char *platform_name; struct snd_soc_card *card; - int ret; + int ret, i; ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); if (!ctx) return -ENOMEM; + /* Detect the headset codec variant */ + if (acpi_dev_present("RTL5682", NULL, -1)) { + /* ALC5682I-VS is detected */ + ctx->is_rt5682s = 1; + + for (i = 0; i < glk_audio_card_rt5682_m98357a.num_links; i++) { + if (strcmp(geminilake_dais[i].name, "SSP2-Codec")) + continue; + + /* update the dai link to use rt5682s codec */ + geminilake_dais[i].codecs = ssp2_codec_5682s; + geminilake_dais[i].num_codecs = ARRAY_SIZE(ssp2_codec_5682s); + break; + } + } + INIT_LIST_HEAD(&ctx->hdmi_pcm_list); card = &glk_audio_card_rt5682_m98357a; card->dev = &pdev->dev; snd_soc_card_set_drvdata(card, ctx); - /* override plaform name, if required */ + /* override platform name, if required */ mach = pdev->dev.platform_data; platform_name = mach->mach_params.platform; @@ -619,12 +665,13 @@ static int geminilake_audio_probe(struct platform_device *pdev) static const struct platform_device_id glk_board_ids[] = { { - .name = "glk_rt5682_max98357a", + .name = "glk_rt5682_mx98357a", .driver_data = (kernel_ulong_t)&glk_audio_card_rt5682_m98357a, }, { } }; +MODULE_DEVICE_TABLE(platform, glk_board_ids); static struct platform_driver geminilake_audio = { .probe = geminilake_audio_probe, @@ -641,4 +688,4 @@ MODULE_DESCRIPTION("Geminilake Audio Machine driver-RT5682 & MAX98357A in I2S mo MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>"); MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:glk_rt5682_max98357a"); +MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); |