.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Intel Broxton-P I2S Machine Driver |
---|
3 | 4 | * |
---|
.. | .. |
---|
5 | 6 | * |
---|
6 | 7 | * Modified from: |
---|
7 | 8 | * Intel Skylake I2S Machine driver |
---|
8 | | - * |
---|
9 | | - * This program is free software; you can redistribute it and/or |
---|
10 | | - * modify it under the terms of the GNU General Public License version |
---|
11 | | - * 2 as published by the Free Software Foundation. |
---|
12 | | - * |
---|
13 | | - * This program is distributed in the hope that it will be useful, |
---|
14 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
16 | | - * GNU General Public License for more details. |
---|
17 | 9 | */ |
---|
18 | 10 | |
---|
| 11 | +#include <linux/input.h> |
---|
19 | 12 | #include <linux/module.h> |
---|
20 | 13 | #include <linux/platform_device.h> |
---|
21 | 14 | #include <sound/core.h> |
---|
.. | .. |
---|
23 | 16 | #include <sound/pcm.h> |
---|
24 | 17 | #include <sound/pcm_params.h> |
---|
25 | 18 | #include <sound/soc.h> |
---|
| 19 | +#include <sound/soc-acpi.h> |
---|
26 | 20 | #include "../../codecs/hdac_hdmi.h" |
---|
27 | 21 | #include "../../codecs/da7219.h" |
---|
28 | 22 | #include "../../codecs/da7219-aad.h" |
---|
| 23 | +#include "../common/soc-intel-quirks.h" |
---|
| 24 | +#include "hda_dsp_common.h" |
---|
29 | 25 | |
---|
30 | 26 | #define BXT_DIALOG_CODEC_DAI "da7219-hifi" |
---|
31 | 27 | #define BXT_MAXIM_CODEC_DAI "HiFi" |
---|
| 28 | +#define MAX98390_DEV0_NAME "i2c-MX98390:00" |
---|
| 29 | +#define MAX98390_DEV1_NAME "i2c-MX98390:01" |
---|
32 | 30 | #define DUAL_CHANNEL 2 |
---|
33 | 31 | #define QUAD_CHANNEL 4 |
---|
| 32 | + |
---|
| 33 | +#define SPKAMP_MAX98357A 1 |
---|
| 34 | +#define SPKAMP_MAX98390 2 |
---|
34 | 35 | |
---|
35 | 36 | static struct snd_soc_jack broxton_headset; |
---|
36 | 37 | static struct snd_soc_jack broxton_hdmi[3]; |
---|
.. | .. |
---|
43 | 44 | |
---|
44 | 45 | struct bxt_card_private { |
---|
45 | 46 | struct list_head hdmi_pcm_list; |
---|
| 47 | + bool common_hdmi_codec_drv; |
---|
| 48 | + int spkamp; |
---|
46 | 49 | }; |
---|
47 | 50 | |
---|
48 | 51 | enum { |
---|
49 | 52 | BXT_DPCM_AUDIO_PB = 0, |
---|
50 | 53 | BXT_DPCM_AUDIO_CP, |
---|
| 54 | + BXT_DPCM_AUDIO_HS_PB, |
---|
51 | 55 | BXT_DPCM_AUDIO_REF_CP, |
---|
52 | 56 | BXT_DPCM_AUDIO_DMIC_CP, |
---|
53 | 57 | BXT_DPCM_AUDIO_HDMI1_PB, |
---|
.. | .. |
---|
87 | 91 | static const struct snd_kcontrol_new broxton_controls[] = { |
---|
88 | 92 | SOC_DAPM_PIN_SWITCH("Headphone Jack"), |
---|
89 | 93 | SOC_DAPM_PIN_SWITCH("Headset Mic"), |
---|
| 94 | +}; |
---|
| 95 | + |
---|
| 96 | +static const struct snd_kcontrol_new max98357a_controls[] = { |
---|
90 | 97 | SOC_DAPM_PIN_SWITCH("Spk"), |
---|
| 98 | +}; |
---|
| 99 | + |
---|
| 100 | +static const struct snd_kcontrol_new max98390_controls[] = { |
---|
| 101 | + SOC_DAPM_PIN_SWITCH("Left Spk"), |
---|
| 102 | + SOC_DAPM_PIN_SWITCH("Right Spk"), |
---|
91 | 103 | }; |
---|
92 | 104 | |
---|
93 | 105 | static const struct snd_soc_dapm_widget broxton_widgets[] = { |
---|
94 | 106 | SND_SOC_DAPM_HP("Headphone Jack", NULL), |
---|
95 | 107 | SND_SOC_DAPM_MIC("Headset Mic", NULL), |
---|
96 | | - SND_SOC_DAPM_SPK("Spk", NULL), |
---|
97 | 108 | SND_SOC_DAPM_MIC("SoC DMIC", NULL), |
---|
98 | 109 | SND_SOC_DAPM_SPK("HDMI1", NULL), |
---|
99 | 110 | SND_SOC_DAPM_SPK("HDMI2", NULL), |
---|
.. | .. |
---|
102 | 113 | platform_clock_control, SND_SOC_DAPM_POST_PMD|SND_SOC_DAPM_PRE_PMU), |
---|
103 | 114 | }; |
---|
104 | 115 | |
---|
105 | | -static const struct snd_soc_dapm_route broxton_map[] = { |
---|
| 116 | +static const struct snd_soc_dapm_widget max98357a_widgets[] = { |
---|
| 117 | + SND_SOC_DAPM_SPK("Spk", NULL), |
---|
| 118 | +}; |
---|
| 119 | + |
---|
| 120 | +static const struct snd_soc_dapm_widget max98390_widgets[] = { |
---|
| 121 | + SND_SOC_DAPM_SPK("Left Spk", NULL), |
---|
| 122 | + SND_SOC_DAPM_SPK("Right Spk", NULL), |
---|
| 123 | +}; |
---|
| 124 | + |
---|
| 125 | +static const struct snd_soc_dapm_route audio_map[] = { |
---|
106 | 126 | /* HP jack connectors - unknown if we have jack detection */ |
---|
107 | 127 | {"Headphone Jack", NULL, "HPL"}, |
---|
108 | 128 | {"Headphone Jack", NULL, "HPR"}, |
---|
109 | | - |
---|
110 | | - /* speaker */ |
---|
111 | | - {"Spk", NULL, "Speaker"}, |
---|
112 | 129 | |
---|
113 | 130 | /* other jacks */ |
---|
114 | 131 | {"MIC", NULL, "Headset Mic"}, |
---|
.. | .. |
---|
117 | 134 | {"DMic", NULL, "SoC DMIC"}, |
---|
118 | 135 | |
---|
119 | 136 | /* CODEC BE connections */ |
---|
120 | | - {"HiFi Playback", NULL, "ssp5 Tx"}, |
---|
121 | | - {"ssp5 Tx", NULL, "codec0_out"}, |
---|
122 | | - |
---|
123 | | - {"Playback", NULL, "ssp1 Tx"}, |
---|
124 | | - {"ssp1 Tx", NULL, "codec1_out"}, |
---|
125 | | - |
---|
126 | | - {"codec0_in", NULL, "ssp1 Rx"}, |
---|
127 | | - {"ssp1 Rx", NULL, "Capture"}, |
---|
128 | | - |
---|
129 | 137 | {"HDMI1", NULL, "hif5-0 Output"}, |
---|
130 | 138 | {"HDMI2", NULL, "hif6-0 Output"}, |
---|
131 | 139 | {"HDMI2", NULL, "hif7-0 Output"}, |
---|
.. | .. |
---|
145 | 153 | { "Headset Mic", NULL, "Platform Clock" }, |
---|
146 | 154 | }; |
---|
147 | 155 | |
---|
| 156 | +static const struct snd_soc_dapm_route max98357a_routes[] = { |
---|
| 157 | + /* speaker */ |
---|
| 158 | + {"Spk", NULL, "Speaker"}, |
---|
| 159 | +}; |
---|
| 160 | + |
---|
| 161 | +static const struct snd_soc_dapm_route max98390_routes[] = { |
---|
| 162 | + /* Speaker */ |
---|
| 163 | + {"Left Spk", NULL, "Left BE_OUT"}, |
---|
| 164 | + {"Right Spk", NULL, "Right BE_OUT"}, |
---|
| 165 | +}; |
---|
| 166 | + |
---|
| 167 | +static const struct snd_soc_dapm_route broxton_map[] = { |
---|
| 168 | + {"HiFi Playback", NULL, "ssp5 Tx"}, |
---|
| 169 | + {"ssp5 Tx", NULL, "codec0_out"}, |
---|
| 170 | + |
---|
| 171 | + {"Playback", NULL, "ssp1 Tx"}, |
---|
| 172 | + {"ssp1 Tx", NULL, "codec1_out"}, |
---|
| 173 | + |
---|
| 174 | + {"codec0_in", NULL, "ssp1 Rx"}, |
---|
| 175 | + {"ssp1 Rx", NULL, "Capture"}, |
---|
| 176 | +}; |
---|
| 177 | + |
---|
| 178 | +static const struct snd_soc_dapm_route gemini_map[] = { |
---|
| 179 | + {"HiFi Playback", NULL, "ssp1 Tx"}, |
---|
| 180 | + {"ssp1 Tx", NULL, "codec0_out"}, |
---|
| 181 | + |
---|
| 182 | + {"Playback", NULL, "ssp2 Tx"}, |
---|
| 183 | + {"ssp2 Tx", NULL, "codec1_out"}, |
---|
| 184 | + |
---|
| 185 | + {"codec0_in", NULL, "ssp2 Rx"}, |
---|
| 186 | + {"ssp2 Rx", NULL, "Capture"}, |
---|
| 187 | +}; |
---|
| 188 | + |
---|
148 | 189 | static int broxton_ssp_fixup(struct snd_soc_pcm_runtime *rtd, |
---|
149 | 190 | struct snd_pcm_hw_params *params) |
---|
150 | 191 | { |
---|
151 | 192 | struct snd_interval *rate = hw_param_interval(params, |
---|
152 | 193 | SNDRV_PCM_HW_PARAM_RATE); |
---|
153 | | - struct snd_interval *channels = hw_param_interval(params, |
---|
| 194 | + struct snd_interval *chan = hw_param_interval(params, |
---|
154 | 195 | SNDRV_PCM_HW_PARAM_CHANNELS); |
---|
155 | 196 | struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); |
---|
156 | 197 | |
---|
157 | 198 | /* The ADSP will convert the FE rate to 48k, stereo */ |
---|
158 | 199 | rate->min = rate->max = 48000; |
---|
159 | | - channels->min = channels->max = DUAL_CHANNEL; |
---|
| 200 | + chan->min = chan->max = DUAL_CHANNEL; |
---|
160 | 201 | |
---|
161 | 202 | /* set SSP to 24 bit */ |
---|
162 | 203 | snd_mask_none(fmt); |
---|
.. | .. |
---|
168 | 209 | static int broxton_da7219_codec_init(struct snd_soc_pcm_runtime *rtd) |
---|
169 | 210 | { |
---|
170 | 211 | int ret; |
---|
171 | | - struct snd_soc_dai *codec_dai = rtd->codec_dai; |
---|
172 | | - struct snd_soc_component *component = rtd->codec_dai->component; |
---|
| 212 | + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); |
---|
| 213 | + struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; |
---|
| 214 | + int clk_freq; |
---|
173 | 215 | |
---|
174 | 216 | /* Configure sysclk for codec */ |
---|
175 | | - ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, 19200000, |
---|
| 217 | + if (soc_intel_is_cml()) |
---|
| 218 | + clk_freq = 24000000; |
---|
| 219 | + else |
---|
| 220 | + clk_freq = 19200000; |
---|
| 221 | + |
---|
| 222 | + ret = snd_soc_dai_set_sysclk(codec_dai, DA7219_CLKSRC_MCLK, clk_freq, |
---|
176 | 223 | SND_SOC_CLOCK_IN); |
---|
| 224 | + |
---|
177 | 225 | if (ret) { |
---|
178 | 226 | dev_err(rtd->dev, "can't set codec sysclk configuration\n"); |
---|
179 | 227 | return ret; |
---|
.. | .. |
---|
192 | 240 | return ret; |
---|
193 | 241 | } |
---|
194 | 242 | |
---|
| 243 | + snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); |
---|
| 244 | + snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); |
---|
| 245 | + snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); |
---|
| 246 | + snd_jack_set_key(broxton_headset.jack, SND_JACK_BTN_3, |
---|
| 247 | + KEY_VOICECOMMAND); |
---|
| 248 | + |
---|
195 | 249 | da7219_aad_jack_det(component, &broxton_headset); |
---|
196 | 250 | |
---|
197 | 251 | snd_soc_dapm_ignore_suspend(&rtd->card->dapm, "SoC DMIC"); |
---|
.. | .. |
---|
202 | 256 | static int broxton_hdmi_init(struct snd_soc_pcm_runtime *rtd) |
---|
203 | 257 | { |
---|
204 | 258 | struct bxt_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); |
---|
205 | | - struct snd_soc_dai *dai = rtd->codec_dai; |
---|
| 259 | + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); |
---|
206 | 260 | struct bxt_hdmi_pcm *pcm; |
---|
207 | 261 | |
---|
208 | 262 | pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL); |
---|
.. | .. |
---|
220 | 274 | static int broxton_da7219_fe_init(struct snd_soc_pcm_runtime *rtd) |
---|
221 | 275 | { |
---|
222 | 276 | struct snd_soc_dapm_context *dapm; |
---|
223 | | - struct snd_soc_component *component = rtd->cpu_dai->component; |
---|
| 277 | + struct snd_soc_component *component = asoc_rtd_to_cpu(rtd, 0)->component; |
---|
224 | 278 | |
---|
225 | 279 | dapm = snd_soc_component_get_dapm(component); |
---|
226 | 280 | snd_soc_dapm_ignore_suspend(dapm, "Reference Capture"); |
---|
.. | .. |
---|
289 | 343 | static int broxton_dmic_fixup(struct snd_soc_pcm_runtime *rtd, |
---|
290 | 344 | struct snd_pcm_hw_params *params) |
---|
291 | 345 | { |
---|
292 | | - struct snd_interval *channels = hw_param_interval(params, |
---|
| 346 | + struct snd_interval *chan = hw_param_interval(params, |
---|
293 | 347 | SNDRV_PCM_HW_PARAM_CHANNELS); |
---|
294 | 348 | if (params_channels(params) == 2) |
---|
295 | | - channels->min = channels->max = 2; |
---|
| 349 | + chan->min = chan->max = 2; |
---|
296 | 350 | else |
---|
297 | | - channels->min = channels->max = 4; |
---|
| 351 | + chan->min = chan->max = 4; |
---|
298 | 352 | |
---|
299 | 353 | return 0; |
---|
300 | 354 | } |
---|
.. | .. |
---|
350 | 404 | }; |
---|
351 | 405 | |
---|
352 | 406 | /* broxton digital audio interface glue - connects codec <--> CPU */ |
---|
| 407 | +SND_SOC_DAILINK_DEF(dummy, |
---|
| 408 | + DAILINK_COMP_ARRAY(COMP_DUMMY())); |
---|
| 409 | + |
---|
| 410 | +SND_SOC_DAILINK_DEF(system, |
---|
| 411 | + DAILINK_COMP_ARRAY(COMP_CPU("System Pin"))); |
---|
| 412 | + |
---|
| 413 | +SND_SOC_DAILINK_DEF(system2, |
---|
| 414 | + DAILINK_COMP_ARRAY(COMP_CPU("System Pin2"))); |
---|
| 415 | + |
---|
| 416 | +SND_SOC_DAILINK_DEF(reference, |
---|
| 417 | + DAILINK_COMP_ARRAY(COMP_CPU("Reference Pin"))); |
---|
| 418 | + |
---|
| 419 | +SND_SOC_DAILINK_DEF(dmic, |
---|
| 420 | + DAILINK_COMP_ARRAY(COMP_CPU("DMIC Pin"))); |
---|
| 421 | + |
---|
| 422 | +SND_SOC_DAILINK_DEF(hdmi1, |
---|
| 423 | + DAILINK_COMP_ARRAY(COMP_CPU("HDMI1 Pin"))); |
---|
| 424 | + |
---|
| 425 | +SND_SOC_DAILINK_DEF(hdmi2, |
---|
| 426 | + DAILINK_COMP_ARRAY(COMP_CPU("HDMI2 Pin"))); |
---|
| 427 | + |
---|
| 428 | +SND_SOC_DAILINK_DEF(hdmi3, |
---|
| 429 | + DAILINK_COMP_ARRAY(COMP_CPU("HDMI3 Pin"))); |
---|
| 430 | + |
---|
| 431 | + /* Back End DAI */ |
---|
| 432 | +SND_SOC_DAILINK_DEF(ssp5_pin, |
---|
| 433 | + DAILINK_COMP_ARRAY(COMP_CPU("SSP5 Pin"))); |
---|
| 434 | +SND_SOC_DAILINK_DEF(ssp5_codec, |
---|
| 435 | + DAILINK_COMP_ARRAY(COMP_CODEC("MX98357A:00", |
---|
| 436 | + BXT_MAXIM_CODEC_DAI))); |
---|
| 437 | +SND_SOC_DAILINK_DEF(max98390_codec, |
---|
| 438 | + DAILINK_COMP_ARRAY( |
---|
| 439 | + /* Left */ COMP_CODEC(MAX98390_DEV0_NAME, "max98390-aif1"), |
---|
| 440 | + /* Right */ COMP_CODEC(MAX98390_DEV1_NAME, "max98390-aif1"))); |
---|
| 441 | + |
---|
| 442 | +SND_SOC_DAILINK_DEF(ssp1_pin, |
---|
| 443 | + DAILINK_COMP_ARRAY(COMP_CPU("SSP1 Pin"))); |
---|
| 444 | +SND_SOC_DAILINK_DEF(ssp1_codec, |
---|
| 445 | + DAILINK_COMP_ARRAY(COMP_CODEC("i2c-DLGS7219:00", |
---|
| 446 | + BXT_DIALOG_CODEC_DAI))); |
---|
| 447 | + |
---|
| 448 | +SND_SOC_DAILINK_DEF(dmic_pin, |
---|
| 449 | + DAILINK_COMP_ARRAY(COMP_CPU("DMIC01 Pin"))); |
---|
| 450 | + |
---|
| 451 | +SND_SOC_DAILINK_DEF(dmic16k_pin, |
---|
| 452 | + DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin"))); |
---|
| 453 | + |
---|
| 454 | +SND_SOC_DAILINK_DEF(dmic_codec, |
---|
| 455 | + DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi"))); |
---|
| 456 | + |
---|
| 457 | +SND_SOC_DAILINK_DEF(idisp1_pin, |
---|
| 458 | + DAILINK_COMP_ARRAY(COMP_CPU("iDisp1 Pin"))); |
---|
| 459 | +SND_SOC_DAILINK_DEF(idisp1_codec, |
---|
| 460 | + DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", "intel-hdmi-hifi1"))); |
---|
| 461 | + |
---|
| 462 | +SND_SOC_DAILINK_DEF(idisp2_pin, |
---|
| 463 | + DAILINK_COMP_ARRAY(COMP_CPU("iDisp2 Pin"))); |
---|
| 464 | +SND_SOC_DAILINK_DEF(idisp2_codec, |
---|
| 465 | + DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", |
---|
| 466 | + "intel-hdmi-hifi2"))); |
---|
| 467 | + |
---|
| 468 | +SND_SOC_DAILINK_DEF(idisp3_pin, |
---|
| 469 | + DAILINK_COMP_ARRAY(COMP_CPU("iDisp3 Pin"))); |
---|
| 470 | +SND_SOC_DAILINK_DEF(idisp3_codec, |
---|
| 471 | + DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D2", |
---|
| 472 | + "intel-hdmi-hifi3"))); |
---|
| 473 | + |
---|
| 474 | +SND_SOC_DAILINK_DEF(platform, |
---|
| 475 | + DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:0e.0"))); |
---|
| 476 | + |
---|
353 | 477 | static struct snd_soc_dai_link broxton_dais[] = { |
---|
354 | 478 | /* Front End DAI links */ |
---|
355 | 479 | [BXT_DPCM_AUDIO_PB] = |
---|
356 | 480 | { |
---|
357 | 481 | .name = "Bxt Audio Port", |
---|
358 | 482 | .stream_name = "Audio", |
---|
359 | | - .cpu_dai_name = "System Pin", |
---|
360 | | - .platform_name = "0000:00:0e.0", |
---|
361 | 483 | .dynamic = 1, |
---|
362 | | - .codec_name = "snd-soc-dummy", |
---|
363 | | - .codec_dai_name = "snd-soc-dummy-dai", |
---|
364 | 484 | .nonatomic = 1, |
---|
365 | 485 | .init = broxton_da7219_fe_init, |
---|
366 | 486 | .trigger = { |
---|
367 | 487 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, |
---|
368 | 488 | .dpcm_playback = 1, |
---|
369 | 489 | .ops = &broxton_da7219_fe_ops, |
---|
| 490 | + SND_SOC_DAILINK_REG(system, dummy, platform), |
---|
370 | 491 | }, |
---|
371 | 492 | [BXT_DPCM_AUDIO_CP] = |
---|
372 | 493 | { |
---|
373 | 494 | .name = "Bxt Audio Capture Port", |
---|
374 | 495 | .stream_name = "Audio Record", |
---|
375 | | - .cpu_dai_name = "System Pin", |
---|
376 | | - .platform_name = "0000:00:0e.0", |
---|
377 | 496 | .dynamic = 1, |
---|
378 | | - .codec_name = "snd-soc-dummy", |
---|
379 | | - .codec_dai_name = "snd-soc-dummy-dai", |
---|
380 | 497 | .nonatomic = 1, |
---|
381 | 498 | .trigger = { |
---|
382 | 499 | SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, |
---|
383 | 500 | .dpcm_capture = 1, |
---|
384 | 501 | .ops = &broxton_da7219_fe_ops, |
---|
| 502 | + SND_SOC_DAILINK_REG(system, dummy, platform), |
---|
| 503 | + }, |
---|
| 504 | + [BXT_DPCM_AUDIO_HS_PB] = { |
---|
| 505 | + .name = "Bxt Audio Headset Playback", |
---|
| 506 | + .stream_name = "Headset Playback", |
---|
| 507 | + .dynamic = 1, |
---|
| 508 | + .nonatomic = 1, |
---|
| 509 | + .trigger = { |
---|
| 510 | + SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST}, |
---|
| 511 | + .dpcm_playback = 1, |
---|
| 512 | + .ops = &broxton_da7219_fe_ops, |
---|
| 513 | + SND_SOC_DAILINK_REG(system2, dummy, platform), |
---|
385 | 514 | }, |
---|
386 | 515 | [BXT_DPCM_AUDIO_REF_CP] = |
---|
387 | 516 | { |
---|
388 | 517 | .name = "Bxt Audio Reference cap", |
---|
389 | 518 | .stream_name = "Refcap", |
---|
390 | | - .cpu_dai_name = "Reference Pin", |
---|
391 | | - .codec_name = "snd-soc-dummy", |
---|
392 | | - .codec_dai_name = "snd-soc-dummy-dai", |
---|
393 | | - .platform_name = "0000:00:0e.0", |
---|
394 | 519 | .init = NULL, |
---|
395 | 520 | .dpcm_capture = 1, |
---|
396 | 521 | .nonatomic = 1, |
---|
397 | 522 | .dynamic = 1, |
---|
398 | 523 | .ops = &broxton_refcap_ops, |
---|
| 524 | + SND_SOC_DAILINK_REG(reference, dummy, platform), |
---|
399 | 525 | }, |
---|
400 | 526 | [BXT_DPCM_AUDIO_DMIC_CP] = |
---|
401 | 527 | { |
---|
402 | 528 | .name = "Bxt Audio DMIC cap", |
---|
403 | 529 | .stream_name = "dmiccap", |
---|
404 | | - .cpu_dai_name = "DMIC Pin", |
---|
405 | | - .codec_name = "snd-soc-dummy", |
---|
406 | | - .codec_dai_name = "snd-soc-dummy-dai", |
---|
407 | | - .platform_name = "0000:00:0e.0", |
---|
408 | 530 | .init = NULL, |
---|
409 | 531 | .dpcm_capture = 1, |
---|
410 | 532 | .nonatomic = 1, |
---|
411 | 533 | .dynamic = 1, |
---|
412 | 534 | .ops = &broxton_dmic_ops, |
---|
| 535 | + SND_SOC_DAILINK_REG(dmic, dummy, platform), |
---|
413 | 536 | }, |
---|
414 | 537 | [BXT_DPCM_AUDIO_HDMI1_PB] = |
---|
415 | 538 | { |
---|
416 | 539 | .name = "Bxt HDMI Port1", |
---|
417 | 540 | .stream_name = "Hdmi1", |
---|
418 | | - .cpu_dai_name = "HDMI1 Pin", |
---|
419 | | - .codec_name = "snd-soc-dummy", |
---|
420 | | - .codec_dai_name = "snd-soc-dummy-dai", |
---|
421 | | - .platform_name = "0000:00:0e.0", |
---|
422 | 541 | .dpcm_playback = 1, |
---|
423 | 542 | .init = NULL, |
---|
424 | 543 | .nonatomic = 1, |
---|
425 | 544 | .dynamic = 1, |
---|
| 545 | + SND_SOC_DAILINK_REG(hdmi1, dummy, platform), |
---|
426 | 546 | }, |
---|
427 | 547 | [BXT_DPCM_AUDIO_HDMI2_PB] = |
---|
428 | 548 | { |
---|
429 | 549 | .name = "Bxt HDMI Port2", |
---|
430 | 550 | .stream_name = "Hdmi2", |
---|
431 | | - .cpu_dai_name = "HDMI2 Pin", |
---|
432 | | - .codec_name = "snd-soc-dummy", |
---|
433 | | - .codec_dai_name = "snd-soc-dummy-dai", |
---|
434 | | - .platform_name = "0000:00:0e.0", |
---|
435 | 551 | .dpcm_playback = 1, |
---|
436 | 552 | .init = NULL, |
---|
437 | 553 | .nonatomic = 1, |
---|
438 | 554 | .dynamic = 1, |
---|
| 555 | + SND_SOC_DAILINK_REG(hdmi2, dummy, platform), |
---|
439 | 556 | }, |
---|
440 | 557 | [BXT_DPCM_AUDIO_HDMI3_PB] = |
---|
441 | 558 | { |
---|
442 | 559 | .name = "Bxt HDMI Port3", |
---|
443 | 560 | .stream_name = "Hdmi3", |
---|
444 | | - .cpu_dai_name = "HDMI3 Pin", |
---|
445 | | - .codec_name = "snd-soc-dummy", |
---|
446 | | - .codec_dai_name = "snd-soc-dummy-dai", |
---|
447 | | - .platform_name = "0000:00:0e.0", |
---|
448 | 561 | .dpcm_playback = 1, |
---|
449 | 562 | .init = NULL, |
---|
450 | 563 | .nonatomic = 1, |
---|
451 | 564 | .dynamic = 1, |
---|
| 565 | + SND_SOC_DAILINK_REG(hdmi3, dummy, platform), |
---|
452 | 566 | }, |
---|
453 | 567 | /* Back End DAI links */ |
---|
454 | 568 | { |
---|
455 | 569 | /* SSP5 - Codec */ |
---|
456 | 570 | .name = "SSP5-Codec", |
---|
457 | 571 | .id = 0, |
---|
458 | | - .cpu_dai_name = "SSP5 Pin", |
---|
459 | | - .platform_name = "0000:00:0e.0", |
---|
460 | 572 | .no_pcm = 1, |
---|
461 | | - .codec_name = "MX98357A:00", |
---|
462 | | - .codec_dai_name = BXT_MAXIM_CODEC_DAI, |
---|
463 | 573 | .dai_fmt = SND_SOC_DAIFMT_I2S | |
---|
464 | 574 | SND_SOC_DAIFMT_NB_NF | |
---|
465 | 575 | SND_SOC_DAIFMT_CBS_CFS, |
---|
466 | 576 | .ignore_pmdown_time = 1, |
---|
467 | 577 | .be_hw_params_fixup = broxton_ssp_fixup, |
---|
468 | 578 | .dpcm_playback = 1, |
---|
| 579 | + SND_SOC_DAILINK_REG(ssp5_pin, ssp5_codec, platform), |
---|
469 | 580 | }, |
---|
470 | 581 | { |
---|
471 | 582 | /* SSP1 - Codec */ |
---|
472 | 583 | .name = "SSP1-Codec", |
---|
473 | 584 | .id = 1, |
---|
474 | | - .cpu_dai_name = "SSP1 Pin", |
---|
475 | | - .platform_name = "0000:00:0e.0", |
---|
476 | 585 | .no_pcm = 1, |
---|
477 | | - .codec_name = "i2c-DLGS7219:00", |
---|
478 | | - .codec_dai_name = BXT_DIALOG_CODEC_DAI, |
---|
479 | 586 | .init = broxton_da7219_codec_init, |
---|
480 | 587 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
---|
481 | 588 | SND_SOC_DAIFMT_CBS_CFS, |
---|
.. | .. |
---|
483 | 590 | .be_hw_params_fixup = broxton_ssp_fixup, |
---|
484 | 591 | .dpcm_playback = 1, |
---|
485 | 592 | .dpcm_capture = 1, |
---|
| 593 | + SND_SOC_DAILINK_REG(ssp1_pin, ssp1_codec, platform), |
---|
486 | 594 | }, |
---|
487 | 595 | { |
---|
488 | 596 | .name = "dmic01", |
---|
489 | 597 | .id = 2, |
---|
490 | | - .cpu_dai_name = "DMIC01 Pin", |
---|
491 | | - .codec_name = "dmic-codec", |
---|
492 | | - .codec_dai_name = "dmic-hifi", |
---|
493 | | - .platform_name = "0000:00:0e.0", |
---|
494 | 598 | .ignore_suspend = 1, |
---|
495 | 599 | .be_hw_params_fixup = broxton_dmic_fixup, |
---|
496 | 600 | .dpcm_capture = 1, |
---|
497 | 601 | .no_pcm = 1, |
---|
| 602 | + SND_SOC_DAILINK_REG(dmic_pin, dmic_codec, platform), |
---|
498 | 603 | }, |
---|
499 | 604 | { |
---|
500 | 605 | .name = "iDisp1", |
---|
501 | 606 | .id = 3, |
---|
502 | | - .cpu_dai_name = "iDisp1 Pin", |
---|
503 | | - .codec_name = "ehdaudio0D2", |
---|
504 | | - .codec_dai_name = "intel-hdmi-hifi1", |
---|
505 | | - .platform_name = "0000:00:0e.0", |
---|
506 | 607 | .init = broxton_hdmi_init, |
---|
507 | 608 | .dpcm_playback = 1, |
---|
508 | 609 | .no_pcm = 1, |
---|
| 610 | + SND_SOC_DAILINK_REG(idisp1_pin, idisp1_codec, platform), |
---|
509 | 611 | }, |
---|
510 | 612 | { |
---|
511 | 613 | .name = "iDisp2", |
---|
512 | 614 | .id = 4, |
---|
513 | | - .cpu_dai_name = "iDisp2 Pin", |
---|
514 | | - .codec_name = "ehdaudio0D2", |
---|
515 | | - .codec_dai_name = "intel-hdmi-hifi2", |
---|
516 | | - .platform_name = "0000:00:0e.0", |
---|
517 | 615 | .init = broxton_hdmi_init, |
---|
518 | 616 | .dpcm_playback = 1, |
---|
519 | 617 | .no_pcm = 1, |
---|
| 618 | + SND_SOC_DAILINK_REG(idisp2_pin, idisp2_codec, platform), |
---|
520 | 619 | }, |
---|
521 | 620 | { |
---|
522 | 621 | .name = "iDisp3", |
---|
523 | 622 | .id = 5, |
---|
524 | | - .cpu_dai_name = "iDisp3 Pin", |
---|
525 | | - .codec_name = "ehdaudio0D2", |
---|
526 | | - .codec_dai_name = "intel-hdmi-hifi3", |
---|
527 | | - .platform_name = "0000:00:0e.0", |
---|
528 | 623 | .init = broxton_hdmi_init, |
---|
529 | 624 | .dpcm_playback = 1, |
---|
530 | 625 | .no_pcm = 1, |
---|
| 626 | + SND_SOC_DAILINK_REG(idisp3_pin, idisp3_codec, platform), |
---|
| 627 | + }, |
---|
| 628 | + { |
---|
| 629 | + .name = "dmic16k", |
---|
| 630 | + .id = 6, |
---|
| 631 | + .be_hw_params_fixup = broxton_dmic_fixup, |
---|
| 632 | + .dpcm_capture = 1, |
---|
| 633 | + .no_pcm = 1, |
---|
| 634 | + SND_SOC_DAILINK_REG(dmic16k_pin, dmic_codec, platform), |
---|
| 635 | + }, |
---|
| 636 | +}; |
---|
| 637 | + |
---|
| 638 | +static struct snd_soc_codec_conf max98390_codec_confs[] = { |
---|
| 639 | + { |
---|
| 640 | + .dlc = COMP_CODEC_CONF(MAX98390_DEV0_NAME), |
---|
| 641 | + .name_prefix = "Left", |
---|
| 642 | + }, |
---|
| 643 | + { |
---|
| 644 | + .dlc = COMP_CODEC_CONF(MAX98390_DEV1_NAME), |
---|
| 645 | + .name_prefix = "Right", |
---|
531 | 646 | }, |
---|
532 | 647 | }; |
---|
533 | 648 | |
---|
.. | .. |
---|
537 | 652 | struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card); |
---|
538 | 653 | struct bxt_hdmi_pcm *pcm; |
---|
539 | 654 | struct snd_soc_component *component = NULL; |
---|
540 | | - int err, i = 0; |
---|
| 655 | + const struct snd_kcontrol_new *controls; |
---|
| 656 | + const struct snd_soc_dapm_widget *widgets; |
---|
| 657 | + const struct snd_soc_dapm_route *routes; |
---|
| 658 | + int num_controls, num_widgets, num_routes, err, i = 0; |
---|
541 | 659 | char jack_name[NAME_SIZE]; |
---|
| 660 | + |
---|
| 661 | + switch (ctx->spkamp) { |
---|
| 662 | + case SPKAMP_MAX98357A: |
---|
| 663 | + controls = max98357a_controls; |
---|
| 664 | + num_controls = ARRAY_SIZE(max98357a_controls); |
---|
| 665 | + widgets = max98357a_widgets; |
---|
| 666 | + num_widgets = ARRAY_SIZE(max98357a_widgets); |
---|
| 667 | + routes = max98357a_routes; |
---|
| 668 | + num_routes = ARRAY_SIZE(max98357a_routes); |
---|
| 669 | + break; |
---|
| 670 | + case SPKAMP_MAX98390: |
---|
| 671 | + controls = max98390_controls; |
---|
| 672 | + num_controls = ARRAY_SIZE(max98390_controls); |
---|
| 673 | + widgets = max98390_widgets; |
---|
| 674 | + num_widgets = ARRAY_SIZE(max98390_widgets); |
---|
| 675 | + routes = max98390_routes; |
---|
| 676 | + num_routes = ARRAY_SIZE(max98390_routes); |
---|
| 677 | + break; |
---|
| 678 | + default: |
---|
| 679 | + dev_err(card->dev, "Invalid speaker amplifier %d\n", ctx->spkamp); |
---|
| 680 | + return -EINVAL; |
---|
| 681 | + } |
---|
| 682 | + |
---|
| 683 | + err = snd_soc_dapm_new_controls(&card->dapm, widgets, num_widgets); |
---|
| 684 | + if (err) { |
---|
| 685 | + dev_err(card->dev, "Fail to new widgets\n"); |
---|
| 686 | + return err; |
---|
| 687 | + } |
---|
| 688 | + |
---|
| 689 | + err = snd_soc_add_card_controls(card, controls, num_controls); |
---|
| 690 | + if (err) { |
---|
| 691 | + dev_err(card->dev, "Fail to add controls\n"); |
---|
| 692 | + return err; |
---|
| 693 | + } |
---|
| 694 | + |
---|
| 695 | + err = snd_soc_dapm_add_routes(&card->dapm, routes, num_routes); |
---|
| 696 | + if (err) { |
---|
| 697 | + dev_err(card->dev, "Fail to add routes\n"); |
---|
| 698 | + return err; |
---|
| 699 | + } |
---|
| 700 | + |
---|
| 701 | + if (soc_intel_is_glk()) |
---|
| 702 | + snd_soc_dapm_add_routes(&card->dapm, gemini_map, |
---|
| 703 | + ARRAY_SIZE(gemini_map)); |
---|
| 704 | + else |
---|
| 705 | + snd_soc_dapm_add_routes(&card->dapm, broxton_map, |
---|
| 706 | + ARRAY_SIZE(broxton_map)); |
---|
| 707 | + |
---|
| 708 | + if (list_empty(&ctx->hdmi_pcm_list)) |
---|
| 709 | + return -EINVAL; |
---|
| 710 | + |
---|
| 711 | + if (ctx->common_hdmi_codec_drv) { |
---|
| 712 | + pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm, |
---|
| 713 | + head); |
---|
| 714 | + component = pcm->codec_dai->component; |
---|
| 715 | + return hda_dsp_hdmi_build_controls(card, component); |
---|
| 716 | + } |
---|
542 | 717 | |
---|
543 | 718 | list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) { |
---|
544 | 719 | component = pcm->codec_dai->component; |
---|
.. | .. |
---|
559 | 734 | i++; |
---|
560 | 735 | } |
---|
561 | 736 | |
---|
562 | | - if (!component) |
---|
563 | | - return -EINVAL; |
---|
564 | | - |
---|
565 | 737 | return hdac_hdmi_jack_port_init(component, &card->dapm); |
---|
566 | 738 | } |
---|
567 | 739 | |
---|
.. | .. |
---|
575 | 747 | .num_controls = ARRAY_SIZE(broxton_controls), |
---|
576 | 748 | .dapm_widgets = broxton_widgets, |
---|
577 | 749 | .num_dapm_widgets = ARRAY_SIZE(broxton_widgets), |
---|
578 | | - .dapm_routes = broxton_map, |
---|
579 | | - .num_dapm_routes = ARRAY_SIZE(broxton_map), |
---|
| 750 | + .dapm_routes = audio_map, |
---|
| 751 | + .num_dapm_routes = ARRAY_SIZE(audio_map), |
---|
580 | 752 | .fully_routed = true, |
---|
581 | 753 | .late_probe = bxt_card_late_probe, |
---|
582 | 754 | }; |
---|
.. | .. |
---|
584 | 756 | static int broxton_audio_probe(struct platform_device *pdev) |
---|
585 | 757 | { |
---|
586 | 758 | struct bxt_card_private *ctx; |
---|
| 759 | + struct snd_soc_acpi_mach *mach; |
---|
| 760 | + const char *platform_name; |
---|
| 761 | + int ret; |
---|
587 | 762 | |
---|
588 | 763 | ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); |
---|
589 | 764 | if (!ctx) |
---|
.. | .. |
---|
591 | 766 | |
---|
592 | 767 | INIT_LIST_HEAD(&ctx->hdmi_pcm_list); |
---|
593 | 768 | |
---|
| 769 | + if (acpi_dev_present("MX98390", NULL, -1)) |
---|
| 770 | + ctx->spkamp = SPKAMP_MAX98390; |
---|
| 771 | + else |
---|
| 772 | + ctx->spkamp = SPKAMP_MAX98357A; |
---|
| 773 | + |
---|
594 | 774 | broxton_audio_card.dev = &pdev->dev; |
---|
595 | 775 | snd_soc_card_set_drvdata(&broxton_audio_card, ctx); |
---|
| 776 | + if (soc_intel_is_glk()) { |
---|
| 777 | + unsigned int i; |
---|
| 778 | + |
---|
| 779 | + broxton_audio_card.name = "glkda7219max"; |
---|
| 780 | + /* Fixup the SSP entries for geminilake */ |
---|
| 781 | + for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) { |
---|
| 782 | + /* MAXIM_CODEC is connected to SSP1. */ |
---|
| 783 | + if (!strcmp(broxton_dais[i].codecs->dai_name, |
---|
| 784 | + BXT_MAXIM_CODEC_DAI)) { |
---|
| 785 | + broxton_dais[i].name = "SSP1-Codec"; |
---|
| 786 | + broxton_dais[i].cpus->dai_name = "SSP1 Pin"; |
---|
| 787 | + } |
---|
| 788 | + /* DIALOG_CODE is connected to SSP2 */ |
---|
| 789 | + else if (!strcmp(broxton_dais[i].codecs->dai_name, |
---|
| 790 | + BXT_DIALOG_CODEC_DAI)) { |
---|
| 791 | + broxton_dais[i].name = "SSP2-Codec"; |
---|
| 792 | + broxton_dais[i].cpus->dai_name = "SSP2 Pin"; |
---|
| 793 | + } |
---|
| 794 | + } |
---|
| 795 | + } else if (soc_intel_is_cml()) { |
---|
| 796 | + unsigned int i; |
---|
| 797 | + |
---|
| 798 | + if (ctx->spkamp == SPKAMP_MAX98390) { |
---|
| 799 | + broxton_audio_card.name = "cml_max98390_da7219"; |
---|
| 800 | + |
---|
| 801 | + broxton_audio_card.codec_conf = max98390_codec_confs; |
---|
| 802 | + broxton_audio_card.num_configs = ARRAY_SIZE(max98390_codec_confs); |
---|
| 803 | + } else |
---|
| 804 | + broxton_audio_card.name = "cmlda7219max"; |
---|
| 805 | + |
---|
| 806 | + for (i = 0; i < ARRAY_SIZE(broxton_dais); i++) { |
---|
| 807 | + /* MAXIM_CODEC is connected to SSP1. */ |
---|
| 808 | + if (!strcmp(broxton_dais[i].codecs->dai_name, |
---|
| 809 | + BXT_MAXIM_CODEC_DAI)) { |
---|
| 810 | + broxton_dais[i].name = "SSP1-Codec"; |
---|
| 811 | + broxton_dais[i].cpus->dai_name = "SSP1 Pin"; |
---|
| 812 | + |
---|
| 813 | + if (ctx->spkamp == SPKAMP_MAX98390) { |
---|
| 814 | + broxton_dais[i].codecs = max98390_codec; |
---|
| 815 | + broxton_dais[i].num_codecs = ARRAY_SIZE(max98390_codec); |
---|
| 816 | + } |
---|
| 817 | + } |
---|
| 818 | + /* DIALOG_CODEC is connected to SSP0 */ |
---|
| 819 | + else if (!strcmp(broxton_dais[i].codecs->dai_name, |
---|
| 820 | + BXT_DIALOG_CODEC_DAI)) { |
---|
| 821 | + broxton_dais[i].name = "SSP0-Codec"; |
---|
| 822 | + broxton_dais[i].cpus->dai_name = "SSP0 Pin"; |
---|
| 823 | + } |
---|
| 824 | + } |
---|
| 825 | + } |
---|
| 826 | + |
---|
| 827 | + /* override plaform name, if required */ |
---|
| 828 | + mach = pdev->dev.platform_data; |
---|
| 829 | + platform_name = mach->mach_params.platform; |
---|
| 830 | + |
---|
| 831 | + ret = snd_soc_fixup_dai_links_platform_name(&broxton_audio_card, |
---|
| 832 | + platform_name); |
---|
| 833 | + if (ret) |
---|
| 834 | + return ret; |
---|
| 835 | + |
---|
| 836 | + ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv; |
---|
596 | 837 | |
---|
597 | 838 | return devm_snd_soc_register_card(&pdev->dev, &broxton_audio_card); |
---|
598 | 839 | } |
---|
| 840 | + |
---|
| 841 | +static const struct platform_device_id bxt_board_ids[] = { |
---|
| 842 | + { .name = "bxt_da7219_max98357a" }, |
---|
| 843 | + { .name = "glk_da7219_max98357a" }, |
---|
| 844 | + { .name = "cml_da7219_max98357a" }, |
---|
| 845 | + { } |
---|
| 846 | +}; |
---|
599 | 847 | |
---|
600 | 848 | static struct platform_driver broxton_audio = { |
---|
601 | 849 | .probe = broxton_audio_probe, |
---|
.. | .. |
---|
603 | 851 | .name = "bxt_da7219_max98357a", |
---|
604 | 852 | .pm = &snd_soc_pm_ops, |
---|
605 | 853 | }, |
---|
| 854 | + .id_table = bxt_board_ids, |
---|
606 | 855 | }; |
---|
607 | 856 | module_platform_driver(broxton_audio) |
---|
608 | 857 | |
---|
.. | .. |
---|
612 | 861 | MODULE_AUTHOR("Rohit Ainapure <rohit.m.ainapure@intel.com>"); |
---|
613 | 862 | MODULE_AUTHOR("Harsha Priya <harshapriya.n@intel.com>"); |
---|
614 | 863 | MODULE_AUTHOR("Conrad Cooke <conrad.cooke@intel.com>"); |
---|
| 864 | +MODULE_AUTHOR("Naveen Manohar <naveen.m@intel.com>"); |
---|
| 865 | +MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>"); |
---|
| 866 | +MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); |
---|
615 | 867 | MODULE_LICENSE("GPL v2"); |
---|
616 | 868 | MODULE_ALIAS("platform:bxt_da7219_max98357a"); |
---|
| 869 | +MODULE_ALIAS("platform:glk_da7219_max98357a"); |
---|
| 870 | +MODULE_ALIAS("platform:cml_da7219_max98357a"); |
---|