forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
kernel/sound/soc/intel/boards/bdw-rt5677.c
....@@ -1,19 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * ASoC machine driver for Intel Broadwell platforms with RT5677 codec
34 *
45 * Copyright (c) 2014, The Chromium OS Authors. All rights reserved.
5
- *
6
- * This program is free software; you can redistribute it and/or modify it
7
- * under the terms and conditions of the GNU General Public License,
8
- * version 2, as published by the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope it will be useful, but WITHOUT
11
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13
- * more details.
14
- *
15
- * You should have received a copy of the GNU General Public License
16
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
176 */
187
198 #include <linux/acpi.h>
....@@ -26,9 +15,7 @@
2615 #include <sound/soc.h>
2716 #include <sound/pcm_params.h>
2817 #include <sound/jack.h>
29
-
30
-#include "../common/sst-dsp.h"
31
-#include "../haswell/sst-haswell-ipc.h"
18
+#include <sound/soc-acpi.h>
3219
3320 #include "../../codecs/rt5677.h"
3421
....@@ -84,6 +71,11 @@
8471 /* CODEC BE connections */
8572 {"SSP0 CODEC IN", NULL, "AIF1 Capture"},
8673 {"AIF1 Playback", NULL, "SSP0 CODEC OUT"},
74
+ {"DSP Capture", NULL, "DSP Buffer"},
75
+
76
+ /* DSP Clock Connections */
77
+ { "DSP Buffer", NULL, "SSP0 CODEC IN" },
78
+ { "SSP0 CODEC IN", NULL, "DSPTX" },
8779 };
8880
8981 static const struct snd_kcontrol_new bdw_rt5677_controls[] = {
....@@ -145,13 +137,13 @@
145137 struct snd_pcm_hw_params *params)
146138 {
147139 struct snd_interval *rate = hw_param_interval(params,
148
- SNDRV_PCM_HW_PARAM_RATE);
149
- struct snd_interval *channels = hw_param_interval(params,
150
- SNDRV_PCM_HW_PARAM_CHANNELS);
140
+ SNDRV_PCM_HW_PARAM_RATE);
141
+ struct snd_interval *chan = hw_param_interval(params,
142
+ SNDRV_PCM_HW_PARAM_CHANNELS);
151143
152144 /* The ADSP will covert the FE rate to 48k, stereo */
153145 rate->min = rate->max = 48000;
154
- channels->min = channels->max = 2;
146
+ chan->min = chan->max = 2;
155147
156148 /* set SSP0 to 16 bit */
157149 params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
....@@ -161,8 +153,8 @@
161153 static int bdw_rt5677_hw_params(struct snd_pcm_substream *substream,
162154 struct snd_pcm_hw_params *params)
163155 {
164
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
165
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
156
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
157
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
166158 int ret;
167159
168160 ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_MCLK, 24576000,
....@@ -175,34 +167,67 @@
175167 return ret;
176168 }
177169
178
-static const struct snd_soc_ops bdw_rt5677_ops = {
179
- .hw_params = bdw_rt5677_hw_params,
180
-};
181
-
182
-static int bdw_rt5677_rtd_init(struct snd_soc_pcm_runtime *rtd)
170
+static int bdw_rt5677_dsp_hw_params(struct snd_pcm_substream *substream,
171
+ struct snd_pcm_hw_params *params)
183172 {
184
- struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
185
- struct sst_pdata *pdata = dev_get_platdata(component->dev);
186
- struct sst_hsw *broadwell = pdata->dsp;
173
+ struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
174
+ struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
187175 int ret;
188176
189
- /* Set ADSP SSP port settings */
190
- ret = sst_hsw_device_set_config(broadwell, SST_HSW_DEVICE_SSP_0,
191
- SST_HSW_DEVICE_MCLK_FREQ_24_MHZ,
192
- SST_HSW_DEVICE_CLOCK_MASTER, 9);
177
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5677_SCLK_S_PLL1, 24576000,
178
+ SND_SOC_CLOCK_IN);
193179 if (ret < 0) {
194
- dev_err(rtd->dev, "error: failed to set device config\n");
180
+ dev_err(rtd->dev, "can't set codec sysclk configuration\n");
181
+ return ret;
182
+ }
183
+ ret = snd_soc_dai_set_pll(codec_dai, 0, RT5677_PLL1_S_MCLK,
184
+ 24000000, 24576000);
185
+ if (ret < 0) {
186
+ dev_err(rtd->dev, "can't set codec pll configuration\n");
195187 return ret;
196188 }
197189
198190 return 0;
199191 }
200192
193
+static const struct snd_soc_ops bdw_rt5677_ops = {
194
+ .hw_params = bdw_rt5677_hw_params,
195
+};
196
+
197
+static const struct snd_soc_ops bdw_rt5677_dsp_ops = {
198
+ .hw_params = bdw_rt5677_dsp_hw_params,
199
+};
200
+
201
+static const unsigned int channels[] = {
202
+ 2,
203
+};
204
+
205
+static const struct snd_pcm_hw_constraint_list constraints_channels = {
206
+ .count = ARRAY_SIZE(channels),
207
+ .list = channels,
208
+ .mask = 0,
209
+};
210
+
211
+static int bdw_rt5677_fe_startup(struct snd_pcm_substream *substream)
212
+{
213
+ struct snd_pcm_runtime *runtime = substream->runtime;
214
+
215
+ /* Board supports stereo configuration only */
216
+ runtime->hw.channels_max = 2;
217
+ return snd_pcm_hw_constraint_list(runtime, 0,
218
+ SNDRV_PCM_HW_PARAM_CHANNELS,
219
+ &constraints_channels);
220
+}
221
+
222
+static const struct snd_soc_ops bdw_rt5677_fe_ops = {
223
+ .startup = bdw_rt5677_fe_startup,
224
+};
225
+
201226 static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
202227 {
203228 struct bdw_rt5677_priv *bdw_rt5677 =
204229 snd_soc_card_get_drvdata(rtd->card);
205
- struct snd_soc_component *component = rtd->codec_dai->component;
230
+ struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
206231 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
207232 int ret;
208233
....@@ -216,10 +241,15 @@
216241 rt5677_sel_asrc_clk_src(component, RT5677_DA_STEREO_FILTER |
217242 RT5677_AD_STEREO1_FILTER | RT5677_I2S1_SOURCE,
218243 RT5677_CLK_SEL_I2S1_ASRC);
244
+ /* Enable codec ASRC function for Mono ADC L.
245
+ * The ASRC clock source is clk_sys2_asrc.
246
+ */
247
+ rt5677_sel_asrc_clk_src(component, RT5677_AD_MONO_L_FILTER,
248
+ RT5677_CLK_SEL_SYS2);
219249
220250 /* Request rt5677 GPIO for headphone amp control */
221
- bdw_rt5677->gpio_hp_en = devm_gpiod_get(component->dev, "headphone-enable",
222
- GPIOD_OUT_LOW);
251
+ bdw_rt5677->gpio_hp_en = gpiod_get(component->dev, "headphone-enable",
252
+ GPIOD_OUT_LOW);
223253 if (IS_ERR(bdw_rt5677->gpio_hp_en)) {
224254 dev_err(component->dev, "Can't find HP_AMP_SHDN_L gpio\n");
225255 return PTR_ERR(bdw_rt5677->gpio_hp_en);
....@@ -253,24 +283,65 @@
253283 return 0;
254284 }
255285
286
+static void bdw_rt5677_exit(struct snd_soc_pcm_runtime *rtd)
287
+{
288
+ struct bdw_rt5677_priv *bdw_rt5677 =
289
+ snd_soc_card_get_drvdata(rtd->card);
290
+
291
+ /*
292
+ * The .exit() can be reached without going through the .init()
293
+ * so explicitly test if the gpiod is valid
294
+ */
295
+ if (!IS_ERR_OR_NULL(bdw_rt5677->gpio_hp_en))
296
+ gpiod_put(bdw_rt5677->gpio_hp_en);
297
+}
298
+
256299 /* broadwell digital audio interface glue - connects codec <--> CPU */
300
+SND_SOC_DAILINK_DEF(dummy,
301
+ DAILINK_COMP_ARRAY(COMP_DUMMY()));
302
+
303
+SND_SOC_DAILINK_DEF(fe,
304
+ DAILINK_COMP_ARRAY(COMP_CPU("System Pin")));
305
+
306
+SND_SOC_DAILINK_DEF(platform,
307
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("haswell-pcm-audio")));
308
+
309
+SND_SOC_DAILINK_DEF(be,
310
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RT5677CE:00", "rt5677-aif1")));
311
+
312
+SND_SOC_DAILINK_DEF(ssp0_port,
313
+ DAILINK_COMP_ARRAY(COMP_CPU("ssp0-port")));
314
+
315
+/* Wake on voice interface */
316
+SND_SOC_DAILINK_DEFS(dsp,
317
+ DAILINK_COMP_ARRAY(COMP_CPU("spi-RT5677AA:00")),
318
+ DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RT5677CE:00", "rt5677-dspbuffer")),
319
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("spi-RT5677AA:00")));
320
+
257321 static struct snd_soc_dai_link bdw_rt5677_dais[] = {
258322 /* Front End DAI links */
259323 {
260324 .name = "System PCM",
261325 .stream_name = "System Playback/Capture",
262
- .cpu_dai_name = "System Pin",
263
- .platform_name = "haswell-pcm-audio",
326
+ .nonatomic = 1,
264327 .dynamic = 1,
265
- .codec_name = "snd-soc-dummy",
266
- .codec_dai_name = "snd-soc-dummy-dai",
267
- .init = bdw_rt5677_rtd_init,
268328 .trigger = {
269329 SND_SOC_DPCM_TRIGGER_POST,
270330 SND_SOC_DPCM_TRIGGER_POST
271331 },
272332 .dpcm_capture = 1,
273333 .dpcm_playback = 1,
334
+ .ops = &bdw_rt5677_fe_ops,
335
+ SND_SOC_DAILINK_REG(fe, dummy, platform),
336
+ },
337
+
338
+ /* Non-DPCM links */
339
+ {
340
+ .name = "Codec DSP",
341
+ .stream_name = "Wake on Voice",
342
+ .capture_only = 1,
343
+ .ops = &bdw_rt5677_dsp_ops,
344
+ SND_SOC_DAILINK_REG(dsp),
274345 },
275346
276347 /* Back End DAI links */
....@@ -278,20 +349,17 @@
278349 /* SSP0 - Codec */
279350 .name = "Codec",
280351 .id = 0,
281
- .cpu_dai_name = "snd-soc-dummy-dai",
282
- .platform_name = "snd-soc-dummy",
283352 .no_pcm = 1,
284
- .codec_name = "i2c-RT5677CE:00",
285
- .codec_dai_name = "rt5677-aif1",
286353 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
287354 SND_SOC_DAIFMT_CBS_CFS,
288
- .ignore_suspend = 1,
289355 .ignore_pmdown_time = 1,
290356 .be_hw_params_fixup = broadwell_ssp0_fixup,
291357 .ops = &bdw_rt5677_ops,
292358 .dpcm_playback = 1,
293359 .dpcm_capture = 1,
294360 .init = bdw_rt5677_init,
361
+ .exit = bdw_rt5677_exit,
362
+ SND_SOC_DAILINK_REG(ssp0_port, be, platform),
295363 },
296364 };
297365
....@@ -319,9 +387,19 @@
319387 return 0;
320388 }
321389
390
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
391
+/* use space before codec name to simplify card ID, and simplify driver name */
392
+#define CARD_NAME "bdw rt5677" /* card name will be 'sof-bdw rt5677' */
393
+#define DRIVER_NAME "SOF"
394
+#else
395
+#define CARD_NAME "bdw-rt5677"
396
+#define DRIVER_NAME NULL /* card name will be used for driver name */
397
+#endif
398
+
322399 /* ASoC machine driver for Broadwell DSP + RT5677 */
323400 static struct snd_soc_card bdw_rt5677_card = {
324
- .name = "bdw-rt5677",
401
+ .name = CARD_NAME,
402
+ .driver_name = DRIVER_NAME,
325403 .owner = THIS_MODULE,
326404 .dai_link = bdw_rt5677_dais,
327405 .num_links = ARRAY_SIZE(bdw_rt5677_dais),
....@@ -339,6 +417,8 @@
339417 static int bdw_rt5677_probe(struct platform_device *pdev)
340418 {
341419 struct bdw_rt5677_priv *bdw_rt5677;
420
+ struct snd_soc_acpi_mach *mach;
421
+ int ret;
342422
343423 bdw_rt5677_card.dev = &pdev->dev;
344424
....@@ -350,6 +430,13 @@
350430 return -ENOMEM;
351431 }
352432
433
+ /* override plaform name, if required */
434
+ mach = pdev->dev.platform_data;
435
+ ret = snd_soc_fixup_dai_links_platform_name(&bdw_rt5677_card,
436
+ mach->mach_params.platform);
437
+ if (ret)
438
+ return ret;
439
+
353440 snd_soc_card_set_drvdata(&bdw_rt5677_card, bdw_rt5677);
354441
355442 return devm_snd_soc_register_card(&pdev->dev, &bdw_rt5677_card);