2 * Intel Broxton-P I2S Machine Driver
4 * Copyright (C) 2014-2016, Intel Corporation. All rights reserved.
7 * Intel Skylake I2S Machine driver
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.
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.
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <sound/core.h>
22 #include <sound/pcm.h>
23 #include <sound/soc.h>
24 #include <sound/jack.h>
25 #include <sound/pcm_params.h>
26 #include "../../codecs/hdac_hdmi.h"
27 #include "../../codecs/rt298.h"
29 static struct snd_soc_jack broxton_headset
;
30 /* Headset jack detection DAPM pins */
33 BXT_DPCM_AUDIO_PB
= 0,
35 BXT_DPCM_AUDIO_REF_CP
,
36 BXT_DPCM_AUDIO_HDMI1_PB
,
37 BXT_DPCM_AUDIO_HDMI2_PB
,
38 BXT_DPCM_AUDIO_HDMI3_PB
,
41 static struct snd_soc_jack_pin broxton_headset_pins
[] = {
44 .mask
= SND_JACK_MICROPHONE
,
47 .pin
= "Headphone Jack",
48 .mask
= SND_JACK_HEADPHONE
,
52 static const struct snd_kcontrol_new broxton_controls
[] = {
53 SOC_DAPM_PIN_SWITCH("Speaker"),
54 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
55 SOC_DAPM_PIN_SWITCH("Mic Jack"),
58 static const struct snd_soc_dapm_widget broxton_widgets
[] = {
59 SND_SOC_DAPM_HP("Headphone Jack", NULL
),
60 SND_SOC_DAPM_SPK("Speaker", NULL
),
61 SND_SOC_DAPM_MIC("Mic Jack", NULL
),
62 SND_SOC_DAPM_MIC("DMIC2", NULL
),
63 SND_SOC_DAPM_MIC("SoC DMIC", NULL
),
64 SND_SOC_DAPM_SPK("HDMI1", NULL
),
65 SND_SOC_DAPM_SPK("HDMI2", NULL
),
66 SND_SOC_DAPM_SPK("HDMI3", NULL
),
69 static const struct snd_soc_dapm_route broxton_rt298_map
[] = {
71 {"Speaker", NULL
, "SPOR"},
72 {"Speaker", NULL
, "SPOL"},
74 /* HP jack connectors - unknown if we have jack detect */
75 {"Headphone Jack", NULL
, "HPO Pin"},
78 {"MIC1", NULL
, "Mic Jack"},
81 {"DMIC1 Pin", NULL
, "DMIC2"},
82 {"DMic", NULL
, "SoC DMIC"},
84 {"HDMI1", NULL
, "hif5 Output"},
85 {"HDMI2", NULL
, "hif6 Output"},
86 {"HDMI3", NULL
, "hif7 Output"},
88 /* CODEC BE connections */
89 { "AIF1 Playback", NULL
, "ssp5 Tx"},
90 { "ssp5 Tx", NULL
, "codec0_out"},
92 { "codec0_in", NULL
, "ssp5 Rx" },
93 { "ssp5 Rx", NULL
, "AIF1 Capture" },
95 { "dmic01_hifi", NULL
, "DMIC01 Rx" },
96 { "DMIC01 Rx", NULL
, "Capture" },
98 { "hifi3", NULL
, "iDisp3 Tx"},
99 { "iDisp3 Tx", NULL
, "iDisp3_out"},
100 { "hifi2", NULL
, "iDisp2 Tx"},
101 { "iDisp2 Tx", NULL
, "iDisp2_out"},
102 { "hifi1", NULL
, "iDisp1 Tx"},
103 { "iDisp1 Tx", NULL
, "iDisp1_out"},
107 static int broxton_rt298_codec_init(struct snd_soc_pcm_runtime
*rtd
)
109 struct snd_soc_codec
*codec
= rtd
->codec
;
112 ret
= snd_soc_card_jack_new(rtd
->card
, "Headset",
113 SND_JACK_HEADSET
| SND_JACK_BTN_0
,
115 broxton_headset_pins
, ARRAY_SIZE(broxton_headset_pins
));
120 rt298_mic_detect(codec
, &broxton_headset
);
124 static int broxton_hdmi_init(struct snd_soc_pcm_runtime
*rtd
)
126 struct snd_soc_dai
*dai
= rtd
->codec_dai
;
128 return hdac_hdmi_jack_init(dai
, BXT_DPCM_AUDIO_HDMI1_PB
+ dai
->id
);
131 static int broxton_ssp5_fixup(struct snd_soc_pcm_runtime
*rtd
,
132 struct snd_pcm_hw_params
*params
)
134 struct snd_interval
*rate
= hw_param_interval(params
,
135 SNDRV_PCM_HW_PARAM_RATE
);
136 struct snd_interval
*channels
= hw_param_interval(params
,
137 SNDRV_PCM_HW_PARAM_CHANNELS
);
138 struct snd_mask
*fmt
= hw_param_mask(params
, SNDRV_PCM_HW_PARAM_FORMAT
);
140 /* The ADSP will covert the FE rate to 48k, stereo */
141 rate
->min
= rate
->max
= 48000;
142 channels
->min
= channels
->max
= 2;
144 /* set SSP5 to 24 bit */
146 snd_mask_set(fmt
, SNDRV_PCM_FORMAT_S24_LE
);
151 static int broxton_rt298_hw_params(struct snd_pcm_substream
*substream
,
152 struct snd_pcm_hw_params
*params
)
154 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
155 struct snd_soc_dai
*codec_dai
= rtd
->codec_dai
;
158 ret
= snd_soc_dai_set_sysclk(codec_dai
, RT298_SCLK_S_PLL
,
159 19200000, SND_SOC_CLOCK_IN
);
161 dev_err(rtd
->dev
, "can't set codec sysclk configuration\n");
168 static struct snd_soc_ops broxton_rt298_ops
= {
169 .hw_params
= broxton_rt298_hw_params
,
172 /* broxton digital audio interface glue - connects codec <--> CPU */
173 static struct snd_soc_dai_link broxton_rt298_dais
[] = {
174 /* Front End DAI links */
177 .name
= "Bxt Audio Port",
178 .stream_name
= "Audio",
179 .cpu_dai_name
= "System Pin",
180 .platform_name
= "0000:00:0e.0",
183 .codec_name
= "snd-soc-dummy",
184 .codec_dai_name
= "snd-soc-dummy-dai",
185 .trigger
= {SND_SOC_DPCM_TRIGGER_POST
, SND_SOC_DPCM_TRIGGER_POST
},
190 .name
= "Bxt Audio Capture Port",
191 .stream_name
= "Audio Record",
192 .cpu_dai_name
= "System Pin",
193 .platform_name
= "0000:00:0e.0",
196 .codec_name
= "snd-soc-dummy",
197 .codec_dai_name
= "snd-soc-dummy-dai",
198 .trigger
= {SND_SOC_DPCM_TRIGGER_POST
, SND_SOC_DPCM_TRIGGER_POST
},
201 [BXT_DPCM_AUDIO_REF_CP
]
203 .name
= "Bxt Audio Reference cap",
204 .stream_name
= "refcap",
205 .cpu_dai_name
= "Reference Pin",
206 .codec_name
= "snd-soc-dummy",
207 .codec_dai_name
= "snd-soc-dummy-dai",
208 .platform_name
= "0000:00:0e.0",
214 [BXT_DPCM_AUDIO_HDMI1_PB
]
216 .name
= "Bxt HDMI Port1",
217 .stream_name
= "Hdmi1",
218 .cpu_dai_name
= "HDMI1 Pin",
219 .codec_name
= "snd-soc-dummy",
220 .codec_dai_name
= "snd-soc-dummy-dai",
221 .platform_name
= "0000:00:0e.0",
227 [BXT_DPCM_AUDIO_HDMI2_PB
]
229 .name
= "Bxt HDMI Port2",
230 .stream_name
= "Hdmi2",
231 .cpu_dai_name
= "HDMI2 Pin",
232 .codec_name
= "snd-soc-dummy",
233 .codec_dai_name
= "snd-soc-dummy-dai",
234 .platform_name
= "0000:00:0e.0",
240 [BXT_DPCM_AUDIO_HDMI3_PB
]
242 .name
= "Bxt HDMI Port3",
243 .stream_name
= "Hdmi3",
244 .cpu_dai_name
= "HDMI3 Pin",
245 .codec_name
= "snd-soc-dummy",
246 .codec_dai_name
= "snd-soc-dummy-dai",
247 .platform_name
= "0000:00:0e.0",
253 /* Back End DAI links */
256 .name
= "SSP5-Codec",
258 .cpu_dai_name
= "SSP5 Pin",
259 .platform_name
= "0000:00:0e.0",
261 .codec_name
= "i2c-INT343A:00",
262 .codec_dai_name
= "rt298-aif1",
263 .init
= broxton_rt298_codec_init
,
264 .dai_fmt
= SND_SOC_DAIFMT_DSP_A
| SND_SOC_DAIFMT_NB_NF
|
265 SND_SOC_DAIFMT_CBS_CFS
,
266 .ignore_pmdown_time
= 1,
267 .be_hw_params_fixup
= broxton_ssp5_fixup
,
268 .ops
= &broxton_rt298_ops
,
275 .cpu_dai_name
= "DMIC01 Pin",
276 .codec_name
= "dmic-codec",
277 .codec_dai_name
= "dmic-hifi",
278 .platform_name
= "0000:00:0e.0",
286 .cpu_dai_name
= "iDisp1 Pin",
287 .codec_name
= "ehdaudio0D2",
288 .codec_dai_name
= "intel-hdmi-hifi1",
289 .platform_name
= "0000:00:0e.0",
290 .init
= broxton_hdmi_init
,
297 .cpu_dai_name
= "iDisp2 Pin",
298 .codec_name
= "ehdaudio0D2",
299 .codec_dai_name
= "intel-hdmi-hifi2",
300 .platform_name
= "0000:00:0e.0",
301 .init
= broxton_hdmi_init
,
308 .cpu_dai_name
= "iDisp3 Pin",
309 .codec_name
= "ehdaudio0D2",
310 .codec_dai_name
= "intel-hdmi-hifi3",
311 .platform_name
= "0000:00:0e.0",
312 .init
= broxton_hdmi_init
,
318 /* broxton audio machine driver for SPT + RT298S */
319 static struct snd_soc_card broxton_rt298
= {
320 .name
= "broxton-rt298",
321 .owner
= THIS_MODULE
,
322 .dai_link
= broxton_rt298_dais
,
323 .num_links
= ARRAY_SIZE(broxton_rt298_dais
),
324 .controls
= broxton_controls
,
325 .num_controls
= ARRAY_SIZE(broxton_controls
),
326 .dapm_widgets
= broxton_widgets
,
327 .num_dapm_widgets
= ARRAY_SIZE(broxton_widgets
),
328 .dapm_routes
= broxton_rt298_map
,
329 .num_dapm_routes
= ARRAY_SIZE(broxton_rt298_map
),
330 .fully_routed
= true,
333 static int broxton_audio_probe(struct platform_device
*pdev
)
335 broxton_rt298
.dev
= &pdev
->dev
;
337 return devm_snd_soc_register_card(&pdev
->dev
, &broxton_rt298
);
340 static struct platform_driver broxton_audio
= {
341 .probe
= broxton_audio_probe
,
343 .name
= "bxt_alc298s_i2s",
346 module_platform_driver(broxton_audio
)
348 /* Module information */
349 MODULE_AUTHOR("Ramesh Babu <Ramesh.Babu@intel.com>");
350 MODULE_AUTHOR("Senthilnathan Veppur <senthilnathanx.veppur@intel.com>");
351 MODULE_DESCRIPTION("Intel SST Audio for Broxton");
352 MODULE_LICENSE("GPL v2");
353 MODULE_ALIAS("platform:bxt_alc298s_i2s");