Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/intel/avs/pcm.c
48889 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
//
3
// Copyright(c) 2021-2022 Intel Corporation
4
//
5
// Authors: Cezary Rojewski <[email protected]>
6
// Amadeusz Slawinski <[email protected]>
7
//
8
9
#include <linux/debugfs.h>
10
#include <linux/device.h>
11
#include <sound/hda_register.h>
12
#include <sound/hdaudio_ext.h>
13
#include <sound/pcm_params.h>
14
#include <sound/soc-acpi.h>
15
#include <sound/soc-acpi-intel-match.h>
16
#include <sound/soc-component.h>
17
#include "avs.h"
18
#include "path.h"
19
#include "pcm.h"
20
#include "topology.h"
21
#include "utils.h"
22
#include "../../codecs/hda.h"
23
24
struct avs_dma_data {
25
struct avs_tplg_path_template *template;
26
struct avs_path *path;
27
struct avs_dev *adev;
28
29
/* LINK-stream utilized in BE operations while HOST in FE ones. */
30
union {
31
struct hdac_ext_stream *link_stream;
32
struct hdac_ext_stream *host_stream;
33
};
34
35
struct snd_pcm_hw_constraint_list rate_list;
36
struct snd_pcm_hw_constraint_list channels_list;
37
struct snd_pcm_hw_constraint_list sample_bits_list;
38
39
struct work_struct period_elapsed_work;
40
struct hdac_ext_link *link;
41
struct snd_pcm_substream *substream;
42
};
43
44
static struct avs_tplg_path_template *
45
avs_dai_find_path_template(struct snd_soc_dai *dai, bool is_fe, int direction)
46
{
47
struct snd_soc_dapm_widget *dw = snd_soc_dai_get_widget(dai, direction);
48
struct snd_soc_dapm_path *dp;
49
enum snd_soc_dapm_direction dir;
50
51
if (direction == SNDRV_PCM_STREAM_CAPTURE) {
52
dir = is_fe ? SND_SOC_DAPM_DIR_OUT : SND_SOC_DAPM_DIR_IN;
53
} else {
54
dir = is_fe ? SND_SOC_DAPM_DIR_IN : SND_SOC_DAPM_DIR_OUT;
55
}
56
57
dp = list_first_entry_or_null(&dw->edges[dir], typeof(*dp), list_node[dir]);
58
if (!dp)
59
return NULL;
60
61
/* Get the other widget, with actual path template data */
62
dw = (dp->source == dw) ? dp->sink : dp->source;
63
64
return dw->priv;
65
}
66
67
static void avs_period_elapsed_work(struct work_struct *work)
68
{
69
struct avs_dma_data *data = container_of(work, struct avs_dma_data, period_elapsed_work);
70
71
snd_pcm_period_elapsed(data->substream);
72
}
73
74
void avs_period_elapsed(struct snd_pcm_substream *substream)
75
{
76
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
77
struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);
78
struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
79
80
schedule_work(&data->period_elapsed_work);
81
}
82
83
static int hw_rule_param_size(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule);
84
static int avs_hw_constraints_init(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
85
{
86
struct snd_pcm_runtime *runtime = substream->runtime;
87
struct snd_pcm_hw_constraint_list *r, *c, *s;
88
struct avs_dma_data *data;
89
int ret;
90
91
ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
92
if (ret < 0)
93
return ret;
94
95
data = snd_soc_dai_get_dma_data(dai, substream);
96
r = &(data->rate_list);
97
c = &(data->channels_list);
98
s = &(data->sample_bits_list);
99
100
ret = avs_path_set_constraint(data->adev, data->template, r, c, s);
101
if (ret <= 0)
102
return ret;
103
104
ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, r);
105
if (ret < 0)
106
return ret;
107
108
ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, c);
109
if (ret < 0)
110
return ret;
111
112
ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, s);
113
if (ret < 0)
114
return ret;
115
116
return 0;
117
}
118
119
static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
120
{
121
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
122
struct avs_dev *adev = to_avs_dev(dai->component->dev);
123
struct avs_tplg_path_template *template;
124
struct avs_dma_data *data;
125
126
template = avs_dai_find_path_template(dai, !rtd->dai_link->no_pcm, substream->stream);
127
if (!template) {
128
dev_err(dai->dev, "no %s path for dai %s, invalid tplg?\n",
129
snd_pcm_stream_str(substream), dai->name);
130
return -EINVAL;
131
}
132
133
data = kzalloc(sizeof(*data), GFP_KERNEL);
134
if (!data)
135
return -ENOMEM;
136
137
data->substream = substream;
138
data->template = template;
139
data->adev = adev;
140
INIT_WORK(&data->period_elapsed_work, avs_period_elapsed_work);
141
snd_soc_dai_set_dma_data(dai, substream, data);
142
143
if (rtd->dai_link->ignore_suspend)
144
adev->num_lp_paths++;
145
146
return avs_hw_constraints_init(substream, dai);
147
}
148
149
static void avs_dai_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
150
{
151
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
152
struct avs_dma_data *data;
153
154
data = snd_soc_dai_get_dma_data(dai, substream);
155
156
if (rtd->dai_link->ignore_suspend)
157
data->adev->num_lp_paths--;
158
159
kfree(data->rate_list.list);
160
kfree(data->channels_list.list);
161
kfree(data->sample_bits_list.list);
162
163
snd_soc_dai_set_dma_data(dai, substream, NULL);
164
kfree(data);
165
}
166
167
static int avs_dai_hw_params(struct snd_pcm_substream *substream,
168
struct snd_pcm_hw_params *fe_hw_params,
169
struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
170
int dma_id)
171
{
172
struct avs_dma_data *data;
173
struct avs_path *path;
174
int ret;
175
176
data = snd_soc_dai_get_dma_data(dai, substream);
177
178
dev_dbg(dai->dev, "%s FE hw_params str %p rtd %p",
179
__func__, substream, substream->runtime);
180
dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
181
params_rate(fe_hw_params), params_channels(fe_hw_params),
182
params_width(fe_hw_params), params_physical_width(fe_hw_params));
183
184
dev_dbg(dai->dev, "%s BE hw_params str %p rtd %p",
185
__func__, substream, substream->runtime);
186
dev_dbg(dai->dev, "rate %d chn %d vbd %d bd %d\n",
187
params_rate(be_hw_params), params_channels(be_hw_params),
188
params_width(be_hw_params), params_physical_width(be_hw_params));
189
190
path = avs_path_create(data->adev, dma_id, data->template, fe_hw_params, be_hw_params);
191
if (IS_ERR(path)) {
192
ret = PTR_ERR(path);
193
dev_err(dai->dev, "create path failed: %d\n", ret);
194
return ret;
195
}
196
197
data->path = path;
198
return 0;
199
}
200
201
static int avs_dai_be_hw_params(struct snd_pcm_substream *substream,
202
struct snd_pcm_hw_params *be_hw_params, struct snd_soc_dai *dai,
203
int dma_id)
204
{
205
struct snd_pcm_hw_params *fe_hw_params = NULL;
206
struct snd_soc_pcm_runtime *fe, *be;
207
struct snd_soc_dpcm *dpcm;
208
209
be = snd_soc_substream_to_rtd(substream);
210
/* dpcm_fe_dai_open() guarantees the list is not empty at this point. */
211
for_each_dpcm_fe(be, substream->stream, dpcm) {
212
fe = dpcm->fe;
213
fe_hw_params = &fe->dpcm[substream->stream].hw_params;
214
}
215
216
return avs_dai_hw_params(substream, fe_hw_params, be_hw_params, dai, dma_id);
217
}
218
219
static int avs_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
220
{
221
struct avs_dma_data *data;
222
int ret;
223
224
data = snd_soc_dai_get_dma_data(dai, substream);
225
if (!data->path)
226
return 0;
227
228
ret = avs_path_reset(data->path);
229
if (ret < 0) {
230
dev_err(dai->dev, "reset path failed: %d\n", ret);
231
return ret;
232
}
233
234
ret = avs_path_pause(data->path);
235
if (ret < 0)
236
dev_err(dai->dev, "pause path failed: %d\n", ret);
237
return ret;
238
}
239
240
static int avs_dai_nonhda_be_hw_params(struct snd_pcm_substream *substream,
241
struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
242
{
243
struct avs_dma_data *data;
244
245
data = snd_soc_dai_get_dma_data(dai, substream);
246
if (data->path)
247
return 0;
248
249
/* Actual port-id comes from topology. */
250
return avs_dai_be_hw_params(substream, hw_params, dai, 0);
251
}
252
253
static int avs_dai_nonhda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
254
{
255
struct avs_dma_data *data;
256
257
dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
258
259
data = snd_soc_dai_get_dma_data(dai, substream);
260
if (data->path) {
261
avs_path_free(data->path);
262
data->path = NULL;
263
}
264
265
return 0;
266
}
267
268
static int avs_dai_nonhda_be_trigger(struct snd_pcm_substream *substream, int cmd,
269
struct snd_soc_dai *dai)
270
{
271
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
272
struct avs_dma_data *data;
273
int ret = 0;
274
275
data = snd_soc_dai_get_dma_data(dai, substream);
276
277
switch (cmd) {
278
case SNDRV_PCM_TRIGGER_RESUME:
279
if (rtd->dai_link->ignore_suspend)
280
break;
281
fallthrough;
282
case SNDRV_PCM_TRIGGER_START:
283
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
284
ret = avs_path_pause(data->path);
285
if (ret < 0) {
286
dev_err(dai->dev, "pause BE path failed: %d\n", ret);
287
break;
288
}
289
290
ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
291
if (ret < 0)
292
dev_err(dai->dev, "run BE path failed: %d\n", ret);
293
break;
294
295
case SNDRV_PCM_TRIGGER_SUSPEND:
296
if (rtd->dai_link->ignore_suspend)
297
break;
298
fallthrough;
299
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
300
case SNDRV_PCM_TRIGGER_STOP:
301
ret = avs_path_pause(data->path);
302
if (ret < 0)
303
dev_err(dai->dev, "pause BE path failed: %d\n", ret);
304
305
ret = avs_path_reset(data->path);
306
if (ret < 0)
307
dev_err(dai->dev, "reset BE path failed: %d\n", ret);
308
break;
309
310
default:
311
ret = -EINVAL;
312
break;
313
}
314
315
return ret;
316
}
317
318
static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops = {
319
.startup = avs_dai_startup,
320
.shutdown = avs_dai_shutdown,
321
.hw_params = avs_dai_nonhda_be_hw_params,
322
.hw_free = avs_dai_nonhda_be_hw_free,
323
.prepare = avs_dai_prepare,
324
.trigger = avs_dai_nonhda_be_trigger,
325
};
326
327
static int __avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai,
328
struct hdac_ext_link *link)
329
{
330
struct hdac_ext_stream *link_stream;
331
struct avs_dma_data *data;
332
int ret;
333
334
ret = avs_dai_startup(substream, dai);
335
if (ret)
336
return ret;
337
338
data = snd_soc_dai_get_dma_data(dai, substream);
339
link_stream = snd_hdac_ext_stream_assign(&data->adev->base.core, substream,
340
HDAC_EXT_STREAM_TYPE_LINK);
341
if (!link_stream) {
342
avs_dai_shutdown(substream, dai);
343
return -EBUSY;
344
}
345
346
data->link_stream = link_stream;
347
data->link = link;
348
return 0;
349
}
350
351
static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
352
{
353
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
354
struct hdac_ext_link *link;
355
struct avs_dma_data *data;
356
struct hda_codec *codec;
357
int ret;
358
359
codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
360
361
link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr);
362
if (!link)
363
return -EINVAL;
364
365
ret = __avs_dai_hda_be_startup(substream, dai, link);
366
if (!ret) {
367
data = snd_soc_dai_get_dma_data(dai, substream);
368
substream->runtime->private_data = data->link_stream;
369
}
370
371
return ret;
372
}
373
374
static int avs_dai_i2shda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
375
{
376
struct avs_dev *adev = to_avs_dev(dai->component->dev);
377
struct hdac_ext_link *link;
378
379
link = snd_hdac_ext_bus_get_hlink_by_id(&adev->base.core, AZX_REG_ML_LEPTR_ID_INTEL_SSP);
380
if (!link)
381
return -EINVAL;
382
return __avs_dai_hda_be_startup(substream, dai, link);
383
}
384
385
static int avs_dai_dmichda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
386
{
387
struct avs_dev *adev = to_avs_dev(dai->component->dev);
388
struct hdac_ext_link *link;
389
390
link = snd_hdac_ext_bus_get_hlink_by_id(&adev->base.core, AZX_REG_ML_LEPTR_ID_INTEL_DMIC);
391
if (!link)
392
return -EINVAL;
393
return __avs_dai_hda_be_startup(substream, dai, link);
394
}
395
396
static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
397
{
398
struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
399
400
snd_hdac_ext_stream_release(data->link_stream, HDAC_EXT_STREAM_TYPE_LINK);
401
substream->runtime->private_data = NULL;
402
avs_dai_shutdown(substream, dai);
403
}
404
405
static void avs_dai_althda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
406
{
407
struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
408
409
snd_hdac_ext_stream_release(data->link_stream, HDAC_EXT_STREAM_TYPE_LINK);
410
avs_dai_shutdown(substream, dai);
411
}
412
413
static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream,
414
struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
415
{
416
struct avs_dma_data *data;
417
418
data = snd_soc_dai_get_dma_data(dai, substream);
419
if (data->path)
420
return 0;
421
422
return avs_dai_be_hw_params(substream, hw_params, dai,
423
hdac_stream(data->link_stream)->stream_tag - 1);
424
}
425
426
static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
427
{
428
struct hdac_ext_stream *link_stream;
429
struct avs_dma_data *data;
430
431
data = snd_soc_dai_get_dma_data(dai, substream);
432
if (!data->path)
433
return 0;
434
435
link_stream = data->link_stream;
436
link_stream->link_prepared = false;
437
avs_path_free(data->path);
438
data->path = NULL;
439
440
/* clear link <-> stream mapping */
441
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
442
snd_hdac_ext_bus_link_clear_stream_id(data->link,
443
hdac_stream(link_stream)->stream_tag);
444
445
return 0;
446
}
447
448
static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
449
{
450
struct snd_soc_pcm_runtime *be = snd_soc_substream_to_rtd(substream);
451
const struct snd_soc_pcm_stream *stream_info;
452
struct hdac_ext_stream *link_stream;
453
const struct snd_pcm_hw_params *p;
454
struct avs_dma_data *data;
455
unsigned int format_val;
456
unsigned int bits;
457
int ret;
458
459
data = snd_soc_dai_get_dma_data(dai, substream);
460
link_stream = data->link_stream;
461
p = &be->dpcm[substream->stream].hw_params;
462
463
if (link_stream->link_prepared)
464
return 0;
465
466
stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
467
bits = snd_hdac_stream_format_bits(params_format(p), params_subformat(p),
468
stream_info->sig_bits);
469
format_val = snd_hdac_stream_format(params_channels(p), bits, params_rate(p));
470
471
snd_hdac_ext_stream_decouple(&data->adev->base.core, link_stream, true);
472
snd_hdac_ext_stream_reset(link_stream);
473
snd_hdac_ext_stream_setup(link_stream, format_val);
474
475
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
476
snd_hdac_ext_bus_link_set_stream_id(data->link,
477
hdac_stream(link_stream)->stream_tag);
478
479
ret = avs_dai_prepare(substream, dai);
480
if (ret)
481
return ret;
482
483
link_stream->link_prepared = true;
484
return 0;
485
}
486
487
static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd,
488
struct snd_soc_dai *dai)
489
{
490
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
491
struct avs_dma_data *data;
492
int ret = 0;
493
494
dev_dbg(dai->dev, "entry %s cmd=%d\n", __func__, cmd);
495
496
data = snd_soc_dai_get_dma_data(dai, substream);
497
498
switch (cmd) {
499
case SNDRV_PCM_TRIGGER_RESUME:
500
if (rtd->dai_link->ignore_suspend)
501
break;
502
fallthrough;
503
case SNDRV_PCM_TRIGGER_START:
504
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
505
snd_hdac_ext_stream_start(data->link_stream);
506
507
ret = avs_path_pause(data->path);
508
if (ret < 0) {
509
dev_err(dai->dev, "pause BE path failed: %d\n", ret);
510
break;
511
}
512
513
ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
514
if (ret < 0)
515
dev_err(dai->dev, "run BE path failed: %d\n", ret);
516
break;
517
518
case SNDRV_PCM_TRIGGER_SUSPEND:
519
if (rtd->dai_link->ignore_suspend)
520
break;
521
fallthrough;
522
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
523
case SNDRV_PCM_TRIGGER_STOP:
524
ret = avs_path_pause(data->path);
525
if (ret < 0)
526
dev_err(dai->dev, "pause BE path failed: %d\n", ret);
527
528
snd_hdac_ext_stream_clear(data->link_stream);
529
530
ret = avs_path_reset(data->path);
531
if (ret < 0)
532
dev_err(dai->dev, "reset BE path failed: %d\n", ret);
533
break;
534
535
default:
536
ret = -EINVAL;
537
break;
538
}
539
540
return ret;
541
}
542
543
static const struct snd_soc_dai_ops avs_dai_hda_be_ops = {
544
.startup = avs_dai_hda_be_startup,
545
.shutdown = avs_dai_hda_be_shutdown,
546
.hw_params = avs_dai_hda_be_hw_params,
547
.hw_free = avs_dai_hda_be_hw_free,
548
.prepare = avs_dai_hda_be_prepare,
549
.trigger = avs_dai_hda_be_trigger,
550
};
551
552
static const struct snd_soc_dai_ops avs_dai_i2shda_be_ops = {
553
.startup = avs_dai_i2shda_be_startup,
554
.shutdown = avs_dai_althda_be_shutdown,
555
.hw_params = avs_dai_hda_be_hw_params,
556
.hw_free = avs_dai_hda_be_hw_free,
557
.prepare = avs_dai_hda_be_prepare,
558
.trigger = avs_dai_hda_be_trigger,
559
};
560
561
static const struct snd_soc_dai_ops avs_dai_dmichda_be_ops = {
562
.startup = avs_dai_dmichda_be_startup,
563
.shutdown = avs_dai_althda_be_shutdown,
564
.hw_params = avs_dai_hda_be_hw_params,
565
.hw_free = avs_dai_hda_be_hw_free,
566
.prepare = avs_dai_hda_be_prepare,
567
.trigger = avs_dai_hda_be_trigger,
568
};
569
570
static int hw_rule_param_size(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
571
{
572
struct snd_interval *interval = hw_param_interval(params, rule->var);
573
struct snd_interval to;
574
575
snd_interval_any(&to);
576
to.integer = interval->integer;
577
to.max = interval->max;
578
/*
579
* Commonly 2ms buffer size is used in HDA scenarios whereas 4ms is used
580
* when streaming through GPDMA. Align to the latter to account for both.
581
*/
582
to.min = params_rate(params) / 1000 * 4;
583
584
if (rule->var == SNDRV_PCM_HW_PARAM_PERIOD_SIZE)
585
to.min /= params_periods(params);
586
587
return snd_interval_refine(interval, &to);
588
}
589
590
static int avs_pcm_hw_constraints_init(struct snd_pcm_substream *substream)
591
{
592
struct snd_pcm_runtime *runtime = substream->runtime;
593
int ret;
594
595
ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
596
if (ret < 0)
597
return ret;
598
599
/* Avoid wrap-around with wall-clock. */
600
ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME, 20, 178000000);
601
if (ret < 0)
602
return ret;
603
604
/* Adjust buffer and period size based on the audio format. */
605
snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, hw_rule_param_size, NULL,
606
SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_CHANNELS,
607
SNDRV_PCM_HW_PARAM_RATE, -1);
608
snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, hw_rule_param_size, NULL,
609
SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_CHANNELS,
610
SNDRV_PCM_HW_PARAM_RATE, -1);
611
612
return 0;
613
}
614
615
static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
616
{
617
struct hdac_ext_stream *host_stream;
618
struct avs_dma_data *data;
619
struct hdac_bus *bus;
620
int ret;
621
622
ret = avs_pcm_hw_constraints_init(substream);
623
if (ret)
624
return ret;
625
626
ret = avs_dai_startup(substream, dai);
627
if (ret)
628
return ret;
629
630
data = snd_soc_dai_get_dma_data(dai, substream);
631
bus = &data->adev->base.core;
632
633
host_stream = snd_hdac_ext_stream_assign(bus, substream, HDAC_EXT_STREAM_TYPE_HOST);
634
if (!host_stream) {
635
avs_dai_shutdown(substream, dai);
636
return -EBUSY;
637
}
638
639
data->host_stream = host_stream;
640
snd_pcm_set_sync(substream);
641
642
dev_dbg(dai->dev, "%s fe STARTUP tag %d str %p",
643
__func__, hdac_stream(host_stream)->stream_tag, substream);
644
645
return 0;
646
}
647
648
static void avs_dai_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
649
{
650
struct avs_dma_data *data;
651
652
data = snd_soc_dai_get_dma_data(dai, substream);
653
654
disable_work_sync(&data->period_elapsed_work);
655
snd_hdac_ext_stream_release(data->host_stream, HDAC_EXT_STREAM_TYPE_HOST);
656
avs_dai_shutdown(substream, dai);
657
}
658
659
static int avs_dai_fe_hw_params(struct snd_pcm_substream *substream,
660
struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
661
{
662
struct snd_pcm_hw_params *be_hw_params = NULL;
663
struct snd_soc_pcm_runtime *fe, *be;
664
struct snd_soc_dpcm *dpcm;
665
struct avs_dma_data *data;
666
struct hdac_ext_stream *host_stream;
667
int ret;
668
669
data = snd_soc_dai_get_dma_data(dai, substream);
670
if (data->path)
671
return 0;
672
673
host_stream = data->host_stream;
674
675
hdac_stream(host_stream)->bufsize = 0;
676
hdac_stream(host_stream)->period_bytes = 0;
677
hdac_stream(host_stream)->format_val = 0;
678
679
fe = snd_soc_substream_to_rtd(substream);
680
/* dpcm_fe_dai_open() guarantees the list is not empty at this point. */
681
for_each_dpcm_be(fe, substream->stream, dpcm) {
682
be = dpcm->be;
683
be_hw_params = &be->dpcm[substream->stream].hw_params;
684
}
685
686
ret = avs_dai_hw_params(substream, hw_params, be_hw_params, dai,
687
hdac_stream(host_stream)->stream_tag - 1);
688
if (ret)
689
goto create_err;
690
691
ret = avs_path_bind(data->path);
692
if (ret < 0) {
693
dev_err(dai->dev, "bind FE <-> BE failed: %d\n", ret);
694
goto bind_err;
695
}
696
697
return 0;
698
699
bind_err:
700
avs_path_free(data->path);
701
data->path = NULL;
702
create_err:
703
snd_pcm_lib_free_pages(substream);
704
return ret;
705
}
706
707
static int __avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
708
{
709
struct avs_dma_data *data;
710
struct hdac_ext_stream *host_stream;
711
int ret;
712
713
dev_dbg(dai->dev, "%s fe HW_FREE str %p rtd %p",
714
__func__, substream, substream->runtime);
715
716
data = snd_soc_dai_get_dma_data(dai, substream);
717
if (!data->path)
718
return 0;
719
720
host_stream = data->host_stream;
721
722
ret = avs_path_unbind(data->path);
723
if (ret < 0)
724
dev_err(dai->dev, "unbind FE <-> BE failed: %d\n", ret);
725
726
avs_path_free(data->path);
727
data->path = NULL;
728
snd_hdac_stream_cleanup(hdac_stream(host_stream));
729
hdac_stream(host_stream)->prepared = false;
730
731
return ret;
732
}
733
734
static int avs_dai_fe_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
735
{
736
int ret;
737
738
ret = __avs_dai_fe_hw_free(substream, dai);
739
snd_pcm_lib_free_pages(substream);
740
741
return ret;
742
}
743
744
static int avs_dai_fe_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
745
{
746
struct snd_pcm_runtime *runtime = substream->runtime;
747
const struct snd_soc_pcm_stream *stream_info;
748
struct avs_dma_data *data;
749
struct hdac_ext_stream *host_stream;
750
unsigned int format_val;
751
struct hdac_bus *bus;
752
unsigned int bits;
753
int ret;
754
755
data = snd_soc_dai_get_dma_data(dai, substream);
756
host_stream = data->host_stream;
757
758
if (runtime->state == SNDRV_PCM_STATE_XRUN)
759
hdac_stream(host_stream)->prepared = false;
760
if (hdac_stream(host_stream)->prepared)
761
return 0;
762
763
bus = hdac_stream(host_stream)->bus;
764
snd_hdac_ext_stream_decouple(bus, data->host_stream, true);
765
snd_hdac_stream_reset(hdac_stream(host_stream));
766
767
stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
768
bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
769
stream_info->sig_bits);
770
format_val = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
771
772
ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val);
773
if (ret < 0)
774
return ret;
775
776
ret = snd_hdac_ext_host_stream_setup(host_stream, false);
777
if (ret < 0)
778
return ret;
779
780
ret = avs_dai_prepare(substream, dai);
781
if (ret)
782
return ret;
783
784
hdac_stream(host_stream)->prepared = true;
785
return 0;
786
}
787
788
static void avs_hda_stream_start(struct hdac_bus *bus, struct hdac_ext_stream *host_stream)
789
{
790
struct hdac_stream *first_running = NULL;
791
struct hdac_stream *pos;
792
struct avs_dev *adev = hdac_to_avs(bus);
793
794
list_for_each_entry(pos, &bus->stream_list, list) {
795
if (pos->running) {
796
if (first_running)
797
break; /* more than one running */
798
first_running = pos;
799
}
800
}
801
802
/*
803
* If host_stream is a CAPTURE stream and will be the only one running,
804
* disable L1SEN to avoid sound clipping.
805
*/
806
if (!first_running) {
807
if (hdac_stream(host_stream)->direction == SNDRV_PCM_STREAM_CAPTURE)
808
avs_hda_l1sen_enable(adev, false);
809
snd_hdac_stream_start(hdac_stream(host_stream));
810
return;
811
}
812
813
snd_hdac_stream_start(hdac_stream(host_stream));
814
/*
815
* If host_stream is the first stream to break the rule above,
816
* re-enable L1SEN.
817
*/
818
if (list_entry_is_head(pos, &bus->stream_list, list) &&
819
first_running->direction == SNDRV_PCM_STREAM_CAPTURE)
820
avs_hda_l1sen_enable(adev, true);
821
}
822
823
static void avs_hda_stream_stop(struct hdac_bus *bus, struct hdac_ext_stream *host_stream)
824
{
825
struct hdac_stream *first_running = NULL;
826
struct hdac_stream *pos;
827
struct avs_dev *adev = hdac_to_avs(bus);
828
829
list_for_each_entry(pos, &bus->stream_list, list) {
830
if (pos == hdac_stream(host_stream))
831
continue; /* ignore stream that is about to be stopped */
832
if (pos->running) {
833
if (first_running)
834
break; /* more than one running */
835
first_running = pos;
836
}
837
}
838
839
/*
840
* If host_stream is a CAPTURE stream and is the only one running,
841
* re-enable L1SEN.
842
*/
843
if (!first_running) {
844
snd_hdac_stream_stop(hdac_stream(host_stream));
845
if (hdac_stream(host_stream)->direction == SNDRV_PCM_STREAM_CAPTURE)
846
avs_hda_l1sen_enable(adev, true);
847
return;
848
}
849
850
/*
851
* If by stopping host_stream there is only a single, CAPTURE stream running
852
* left, disable L1SEN to avoid sound clipping.
853
*/
854
if (list_entry_is_head(pos, &bus->stream_list, list) &&
855
first_running->direction == SNDRV_PCM_STREAM_CAPTURE)
856
avs_hda_l1sen_enable(adev, false);
857
858
snd_hdac_stream_stop(hdac_stream(host_stream));
859
}
860
861
static int avs_dai_fe_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
862
{
863
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
864
struct avs_dma_data *data;
865
struct hdac_ext_stream *host_stream;
866
struct hdac_bus *bus;
867
unsigned long flags;
868
int ret = 0;
869
870
data = snd_soc_dai_get_dma_data(dai, substream);
871
host_stream = data->host_stream;
872
bus = hdac_stream(host_stream)->bus;
873
874
switch (cmd) {
875
case SNDRV_PCM_TRIGGER_RESUME:
876
if (rtd->dai_link->ignore_suspend)
877
break;
878
fallthrough;
879
case SNDRV_PCM_TRIGGER_START:
880
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
881
spin_lock_irqsave(&bus->reg_lock, flags);
882
avs_hda_stream_start(bus, host_stream);
883
spin_unlock_irqrestore(&bus->reg_lock, flags);
884
885
/* Timeout on DRSM poll shall not stop the resume so ignore the result. */
886
if (cmd == SNDRV_PCM_TRIGGER_RESUME)
887
snd_hdac_stream_wait_drsm(hdac_stream(host_stream));
888
889
ret = avs_path_pause(data->path);
890
if (ret < 0) {
891
dev_err(dai->dev, "pause FE path failed: %d\n", ret);
892
break;
893
}
894
895
ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO);
896
if (ret < 0)
897
dev_err(dai->dev, "run FE path failed: %d\n", ret);
898
899
break;
900
901
case SNDRV_PCM_TRIGGER_SUSPEND:
902
if (rtd->dai_link->ignore_suspend)
903
break;
904
fallthrough;
905
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
906
case SNDRV_PCM_TRIGGER_STOP:
907
ret = avs_path_pause(data->path);
908
if (ret < 0)
909
dev_err(dai->dev, "pause FE path failed: %d\n", ret);
910
911
spin_lock_irqsave(&bus->reg_lock, flags);
912
avs_hda_stream_stop(bus, host_stream);
913
spin_unlock_irqrestore(&bus->reg_lock, flags);
914
915
ret = avs_path_reset(data->path);
916
if (ret < 0)
917
dev_err(dai->dev, "reset FE path failed: %d\n", ret);
918
break;
919
920
default:
921
ret = -EINVAL;
922
break;
923
}
924
925
return ret;
926
}
927
928
const struct snd_soc_dai_ops avs_dai_fe_ops = {
929
.startup = avs_dai_fe_startup,
930
.shutdown = avs_dai_fe_shutdown,
931
.hw_params = avs_dai_fe_hw_params,
932
.hw_free = avs_dai_fe_hw_free,
933
.prepare = avs_dai_fe_prepare,
934
.trigger = avs_dai_fe_trigger,
935
};
936
937
static ssize_t topology_name_read(struct file *file, char __user *user_buf, size_t count,
938
loff_t *ppos)
939
{
940
struct snd_soc_component *component = file->private_data;
941
struct snd_soc_card *card = component->card;
942
struct snd_soc_acpi_mach *mach = dev_get_platdata(card->dev);
943
char buf[64];
944
size_t len;
945
946
len = scnprintf(buf, sizeof(buf), "%s/%s\n", component->driver->topology_name_prefix,
947
mach->tplg_filename);
948
949
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
950
}
951
952
static const struct file_operations topology_name_fops = {
953
.open = simple_open,
954
.read = topology_name_read,
955
.llseek = default_llseek,
956
};
957
958
static int avs_component_load_libraries(struct avs_soc_component *acomp)
959
{
960
struct avs_tplg *tplg = acomp->tplg;
961
struct avs_dev *adev = to_avs_dev(acomp->base.dev);
962
int ret;
963
964
if (!tplg->num_libs)
965
return 0;
966
967
/* Parent device may be asleep and library loading involves IPCs. */
968
ret = pm_runtime_resume_and_get(adev->dev);
969
if (ret < 0)
970
return ret;
971
972
avs_hda_power_gating_enable(adev, false);
973
avs_hda_clock_gating_enable(adev, false);
974
avs_hda_l1sen_enable(adev, false);
975
976
ret = avs_dsp_load_libraries(adev, tplg->libs, tplg->num_libs);
977
978
avs_hda_l1sen_enable(adev, true);
979
avs_hda_clock_gating_enable(adev, true);
980
avs_hda_power_gating_enable(adev, true);
981
982
if (!ret)
983
ret = avs_module_info_init(adev, false);
984
985
pm_runtime_put_autosuspend(adev->dev);
986
987
return ret;
988
}
989
990
static int avs_component_probe(struct snd_soc_component *component)
991
{
992
struct snd_soc_card *card = component->card;
993
struct snd_soc_acpi_mach *mach;
994
struct avs_soc_component *acomp;
995
struct avs_dev *adev;
996
char *filename;
997
int ret;
998
999
dev_dbg(card->dev, "probing %s card %s\n", component->name, card->name);
1000
mach = dev_get_platdata(card->dev);
1001
acomp = to_avs_soc_component(component);
1002
adev = to_avs_dev(component->dev);
1003
1004
acomp->tplg = avs_tplg_new(component);
1005
if (!acomp->tplg)
1006
return -ENOMEM;
1007
1008
if (!mach->tplg_filename)
1009
goto finalize;
1010
1011
/* Load specified topology and create debugfs for it. */
1012
filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
1013
mach->tplg_filename);
1014
if (!filename)
1015
return -ENOMEM;
1016
1017
ret = avs_load_topology(component, filename);
1018
kfree(filename);
1019
if (ret == -ENOENT && !strncmp(mach->tplg_filename, "hda-", 4)) {
1020
unsigned int vendor_id;
1021
1022
if (sscanf(mach->tplg_filename, "hda-%08x-tplg.bin", &vendor_id) != 1)
1023
return ret;
1024
1025
if (((vendor_id >> 16) & 0xFFFF) == 0x8086)
1026
mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
1027
"hda-8086-generic-tplg.bin");
1028
else
1029
mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
1030
"hda-generic-tplg.bin");
1031
if (!mach->tplg_filename)
1032
return -ENOMEM;
1033
filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
1034
mach->tplg_filename);
1035
if (!filename)
1036
return -ENOMEM;
1037
1038
dev_info(card->dev, "trying to load fallback topology %s\n", mach->tplg_filename);
1039
ret = avs_load_topology(component, filename);
1040
kfree(filename);
1041
}
1042
if (ret < 0)
1043
return ret;
1044
1045
ret = avs_component_load_libraries(acomp);
1046
if (ret < 0) {
1047
dev_err(card->dev, "libraries loading failed: %d\n", ret);
1048
goto err_load_libs;
1049
}
1050
1051
finalize:
1052
debugfs_create_file("topology_name", 0444, component->debugfs_root, component,
1053
&topology_name_fops);
1054
1055
mutex_lock(&adev->comp_list_mutex);
1056
list_add_tail(&acomp->node, &adev->comp_list);
1057
mutex_unlock(&adev->comp_list_mutex);
1058
1059
return 0;
1060
1061
err_load_libs:
1062
avs_remove_topology(component);
1063
return ret;
1064
}
1065
1066
static void avs_component_remove(struct snd_soc_component *component)
1067
{
1068
struct avs_soc_component *acomp = to_avs_soc_component(component);
1069
struct snd_soc_acpi_mach *mach;
1070
struct avs_dev *adev = to_avs_dev(component->dev);
1071
int ret;
1072
1073
mach = dev_get_platdata(component->card->dev);
1074
1075
mutex_lock(&adev->comp_list_mutex);
1076
list_del(&acomp->node);
1077
mutex_unlock(&adev->comp_list_mutex);
1078
1079
if (mach->tplg_filename) {
1080
ret = avs_remove_topology(component);
1081
if (ret < 0)
1082
dev_err(component->dev, "unload topology failed: %d\n", ret);
1083
}
1084
}
1085
1086
static int avs_dai_resume_hw_params(struct snd_soc_dai *dai, struct avs_dma_data *data)
1087
{
1088
struct snd_pcm_substream *substream;
1089
struct snd_soc_pcm_runtime *rtd;
1090
int ret;
1091
1092
substream = data->substream;
1093
rtd = snd_soc_substream_to_rtd(substream);
1094
1095
ret = dai->driver->ops->hw_params(substream, &rtd->dpcm[substream->stream].hw_params, dai);
1096
if (ret)
1097
dev_err(dai->dev, "hw_params on resume failed: %d\n", ret);
1098
1099
return ret;
1100
}
1101
1102
static int avs_dai_resume_fe_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
1103
{
1104
struct hdac_ext_stream *host_stream;
1105
struct hdac_stream *hstream;
1106
struct hdac_bus *bus;
1107
int ret;
1108
1109
host_stream = data->host_stream;
1110
hstream = hdac_stream(host_stream);
1111
bus = hdac_stream(host_stream)->bus;
1112
1113
/* Set DRSM before programming stream and position registers. */
1114
snd_hdac_stream_drsm_enable(bus, true, hstream->index);
1115
1116
ret = dai->driver->ops->prepare(data->substream, dai);
1117
if (ret) {
1118
dev_err(dai->dev, "prepare FE on resume failed: %d\n", ret);
1119
return ret;
1120
}
1121
1122
writel(host_stream->pphcllpl, host_stream->pphc_addr + AZX_REG_PPHCLLPL);
1123
writel(host_stream->pphcllpu, host_stream->pphc_addr + AZX_REG_PPHCLLPU);
1124
writel(host_stream->pphcldpl, host_stream->pphc_addr + AZX_REG_PPHCLDPL);
1125
writel(host_stream->pphcldpu, host_stream->pphc_addr + AZX_REG_PPHCLDPU);
1126
1127
/* As per HW spec recommendation, program LPIB and DPIB to the same value. */
1128
snd_hdac_stream_set_lpib(hstream, hstream->lpib);
1129
snd_hdac_stream_set_dpibr(bus, hstream, hstream->lpib);
1130
1131
return 0;
1132
}
1133
1134
static int avs_dai_resume_be_prepare(struct snd_soc_dai *dai, struct avs_dma_data *data)
1135
{
1136
int ret;
1137
1138
ret = dai->driver->ops->prepare(data->substream, dai);
1139
if (ret)
1140
dev_err(dai->dev, "prepare BE on resume failed: %d\n", ret);
1141
1142
return ret;
1143
}
1144
1145
static int avs_dai_suspend_fe_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
1146
{
1147
struct hdac_ext_stream *host_stream;
1148
int ret;
1149
1150
host_stream = data->host_stream;
1151
1152
/* Store position addresses so we can resume from them later on. */
1153
hdac_stream(host_stream)->lpib = snd_hdac_stream_get_pos_lpib(hdac_stream(host_stream));
1154
host_stream->pphcllpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPL);
1155
host_stream->pphcllpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLLPU);
1156
host_stream->pphcldpl = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPL);
1157
host_stream->pphcldpu = readl(host_stream->pphc_addr + AZX_REG_PPHCLDPU);
1158
1159
ret = __avs_dai_fe_hw_free(data->substream, dai);
1160
if (ret < 0)
1161
dev_err(dai->dev, "hw_free FE on suspend failed: %d\n", ret);
1162
1163
return ret;
1164
}
1165
1166
static int avs_dai_suspend_be_hw_free(struct snd_soc_dai *dai, struct avs_dma_data *data)
1167
{
1168
int ret;
1169
1170
ret = dai->driver->ops->hw_free(data->substream, dai);
1171
if (ret < 0)
1172
dev_err(dai->dev, "hw_free BE on suspend failed: %d\n", ret);
1173
1174
return ret;
1175
}
1176
1177
static int avs_component_pm_op(struct snd_soc_component *component, bool be,
1178
int (*op)(struct snd_soc_dai *, struct avs_dma_data *))
1179
{
1180
struct snd_soc_pcm_runtime *rtd;
1181
struct avs_dma_data *data;
1182
struct snd_soc_dai *dai;
1183
int ret;
1184
1185
for_each_component_dais(component, dai) {
1186
data = snd_soc_dai_dma_data_get_playback(dai);
1187
if (data) {
1188
rtd = snd_soc_substream_to_rtd(data->substream);
1189
if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
1190
ret = op(dai, data);
1191
if (ret < 0) {
1192
__snd_pcm_set_state(data->substream->runtime,
1193
SNDRV_PCM_STATE_DISCONNECTED);
1194
return ret;
1195
}
1196
}
1197
}
1198
1199
data = snd_soc_dai_dma_data_get_capture(dai);
1200
if (data) {
1201
rtd = snd_soc_substream_to_rtd(data->substream);
1202
if (rtd->dai_link->no_pcm == be && !rtd->dai_link->ignore_suspend) {
1203
ret = op(dai, data);
1204
if (ret < 0) {
1205
__snd_pcm_set_state(data->substream->runtime,
1206
SNDRV_PCM_STATE_DISCONNECTED);
1207
return ret;
1208
}
1209
}
1210
}
1211
}
1212
1213
return 0;
1214
}
1215
1216
static int avs_component_resume_hw_params(struct snd_soc_component *component, bool be)
1217
{
1218
return avs_component_pm_op(component, be, &avs_dai_resume_hw_params);
1219
}
1220
1221
static int avs_component_resume_prepare(struct snd_soc_component *component, bool be)
1222
{
1223
int (*prepare_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
1224
1225
if (be)
1226
prepare_cb = &avs_dai_resume_be_prepare;
1227
else
1228
prepare_cb = &avs_dai_resume_fe_prepare;
1229
1230
return avs_component_pm_op(component, be, prepare_cb);
1231
}
1232
1233
static int avs_component_suspend_hw_free(struct snd_soc_component *component, bool be)
1234
{
1235
int (*hw_free_cb)(struct snd_soc_dai *dai, struct avs_dma_data *data);
1236
1237
if (be)
1238
hw_free_cb = &avs_dai_suspend_be_hw_free;
1239
else
1240
hw_free_cb = &avs_dai_suspend_fe_hw_free;
1241
1242
return avs_component_pm_op(component, be, hw_free_cb);
1243
}
1244
1245
static int avs_component_suspend(struct snd_soc_component *component)
1246
{
1247
int ret;
1248
1249
/*
1250
* When freeing paths, FEs need to be first as they perform
1251
* path unbinding.
1252
*/
1253
ret = avs_component_suspend_hw_free(component, false);
1254
if (ret)
1255
return ret;
1256
1257
return avs_component_suspend_hw_free(component, true);
1258
}
1259
1260
static int avs_component_resume(struct snd_soc_component *component)
1261
{
1262
int ret;
1263
1264
/*
1265
* When creating paths, FEs need to be last as they perform
1266
* path binding.
1267
*/
1268
ret = avs_component_resume_hw_params(component, true);
1269
if (ret)
1270
return ret;
1271
1272
ret = avs_component_resume_hw_params(component, false);
1273
if (ret)
1274
return ret;
1275
1276
/* It is expected that the LINK stream is prepared first. */
1277
ret = avs_component_resume_prepare(component, true);
1278
if (ret)
1279
return ret;
1280
1281
return avs_component_resume_prepare(component, false);
1282
}
1283
1284
static const struct snd_pcm_hardware avs_pcm_hardware = {
1285
.info = SNDRV_PCM_INFO_MMAP |
1286
SNDRV_PCM_INFO_MMAP_VALID |
1287
SNDRV_PCM_INFO_INTERLEAVED |
1288
SNDRV_PCM_INFO_PAUSE |
1289
SNDRV_PCM_INFO_RESUME |
1290
SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
1291
.formats = SNDRV_PCM_FMTBIT_S16_LE |
1292
SNDRV_PCM_FMTBIT_S32_LE,
1293
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1294
SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1295
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1296
.buffer_bytes_max = AZX_MAX_BUF_SIZE,
1297
.period_bytes_min = 128,
1298
.period_bytes_max = AZX_MAX_BUF_SIZE / 2,
1299
.periods_min = 2,
1300
.periods_max = AZX_MAX_FRAG,
1301
.fifo_size = 0,
1302
};
1303
1304
static int avs_component_open(struct snd_soc_component *component,
1305
struct snd_pcm_substream *substream)
1306
{
1307
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1308
1309
/* only FE DAI links are handled here */
1310
if (rtd->dai_link->no_pcm)
1311
return 0;
1312
1313
return snd_soc_set_runtime_hwparams(substream, &avs_pcm_hardware);
1314
}
1315
1316
static unsigned int avs_hda_stream_dpib_read(struct hdac_ext_stream *stream)
1317
{
1318
return readl(hdac_stream(stream)->bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
1319
(AZX_REG_VS_SDXDPIB_XINTERVAL * hdac_stream(stream)->index));
1320
}
1321
1322
static snd_pcm_uframes_t
1323
avs_component_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream)
1324
{
1325
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1326
struct avs_dma_data *data;
1327
struct hdac_ext_stream *host_stream;
1328
unsigned int pos;
1329
1330
data = snd_soc_dai_get_dma_data(snd_soc_rtd_to_cpu(rtd, 0), substream);
1331
if (!data->host_stream)
1332
return 0;
1333
1334
host_stream = data->host_stream;
1335
pos = avs_hda_stream_dpib_read(host_stream);
1336
1337
if (pos >= hdac_stream(host_stream)->bufsize)
1338
pos = 0;
1339
1340
return bytes_to_frames(substream->runtime, pos);
1341
}
1342
1343
static int avs_component_mmap(struct snd_soc_component *component,
1344
struct snd_pcm_substream *substream,
1345
struct vm_area_struct *vma)
1346
{
1347
return snd_pcm_lib_default_mmap(substream, vma);
1348
}
1349
1350
#define MAX_PREALLOC_SIZE (32 * 1024 * 1024)
1351
1352
static int avs_component_construct(struct snd_soc_component *component,
1353
struct snd_soc_pcm_runtime *rtd)
1354
{
1355
struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);
1356
struct snd_pcm *pcm = rtd->pcm;
1357
1358
if (dai->driver->playback.channels_min)
1359
snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
1360
SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1361
MAX_PREALLOC_SIZE);
1362
1363
if (dai->driver->capture.channels_min)
1364
snd_pcm_set_managed_buffer(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream,
1365
SNDRV_DMA_TYPE_DEV_SG, component->dev, 0,
1366
MAX_PREALLOC_SIZE);
1367
1368
return 0;
1369
}
1370
1371
static struct snd_soc_component_driver avs_component_driver = {
1372
.name = "avs-pcm",
1373
.probe = avs_component_probe,
1374
.remove = avs_component_remove,
1375
.suspend = avs_component_suspend,
1376
.resume = avs_component_resume,
1377
.open = avs_component_open,
1378
.pointer = avs_component_pointer,
1379
.mmap = avs_component_mmap,
1380
.pcm_construct = avs_component_construct,
1381
.module_get_upon_open = 1, /* increment refcount when a pcm is opened */
1382
.topology_name_prefix = "intel/avs",
1383
};
1384
1385
int avs_register_component(struct device *dev, const char *name,
1386
struct snd_soc_component_driver *drv,
1387
struct snd_soc_dai_driver *cpu_dais, int num_cpu_dais)
1388
{
1389
struct avs_soc_component *acomp;
1390
int ret;
1391
1392
acomp = devm_kzalloc(dev, sizeof(*acomp), GFP_KERNEL);
1393
if (!acomp)
1394
return -ENOMEM;
1395
1396
acomp->base.name = devm_kstrdup(dev, name, GFP_KERNEL);
1397
if (!acomp->base.name)
1398
return -ENOMEM;
1399
1400
INIT_LIST_HEAD(&acomp->node);
1401
1402
drv->use_dai_pcm_id = !obsolete_card_names;
1403
1404
ret = snd_soc_component_initialize(&acomp->base, drv, dev);
1405
if (ret < 0)
1406
return ret;
1407
1408
return snd_soc_add_component(&acomp->base, cpu_dais, num_cpu_dais);
1409
}
1410
1411
static struct snd_soc_dai_driver dmic_cpu_dais[] = {
1412
{
1413
.name = "DMIC Pin",
1414
.capture = {
1415
.stream_name = "DMIC Rx",
1416
.channels_min = 1,
1417
.channels_max = 4,
1418
.rates = SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000,
1419
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
1420
},
1421
},
1422
{
1423
.name = "DMIC WoV Pin",
1424
.capture = {
1425
.stream_name = "DMIC WoV Rx",
1426
.channels_min = 1,
1427
.channels_max = 4,
1428
.rates = SNDRV_PCM_RATE_16000,
1429
.formats = SNDRV_PCM_FMTBIT_S16_LE,
1430
},
1431
},
1432
};
1433
1434
int avs_register_dmic_component(struct avs_dev *adev, const char *name)
1435
{
1436
const struct snd_soc_dai_ops *ops;
1437
1438
if (avs_platattr_test(adev, ALTHDA))
1439
ops = &avs_dai_dmichda_be_ops;
1440
else
1441
ops = &avs_dai_nonhda_be_ops;
1442
1443
dmic_cpu_dais[0].ops = ops;
1444
dmic_cpu_dais[1].ops = ops;
1445
return avs_register_component(adev->dev, name, &avs_component_driver, dmic_cpu_dais,
1446
ARRAY_SIZE(dmic_cpu_dais));
1447
}
1448
1449
static const struct snd_soc_dai_driver i2s_dai_template = {
1450
.playback = {
1451
.channels_min = 1,
1452
.channels_max = AVS_CHANNELS_MAX,
1453
.rates = SNDRV_PCM_RATE_8000_192000 |
1454
SNDRV_PCM_RATE_12000 |
1455
SNDRV_PCM_RATE_24000 |
1456
SNDRV_PCM_RATE_128000,
1457
.formats = SNDRV_PCM_FMTBIT_S16_LE |
1458
SNDRV_PCM_FMTBIT_S32_LE,
1459
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1460
SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1461
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1462
},
1463
.capture = {
1464
.channels_min = 1,
1465
.channels_max = AVS_CHANNELS_MAX,
1466
.rates = SNDRV_PCM_RATE_8000_192000 |
1467
SNDRV_PCM_RATE_12000 |
1468
SNDRV_PCM_RATE_24000 |
1469
SNDRV_PCM_RATE_128000,
1470
.formats = SNDRV_PCM_FMTBIT_S16_LE |
1471
SNDRV_PCM_FMTBIT_S32_LE,
1472
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1473
SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1474
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1475
},
1476
};
1477
1478
int avs_register_i2s_component(struct avs_dev *adev, const char *name, unsigned long port_mask,
1479
unsigned long *tdms)
1480
{
1481
struct snd_soc_dai_driver *cpus, *dai;
1482
const struct snd_soc_dai_ops *ops;
1483
size_t ssp_count, cpu_count;
1484
int i, j;
1485
1486
ssp_count = adev->hw_cfg.i2s_caps.ctrl_count;
1487
if (avs_platattr_test(adev, ALTHDA))
1488
ops = &avs_dai_i2shda_be_ops;
1489
else
1490
ops = &avs_dai_nonhda_be_ops;
1491
1492
cpu_count = 0;
1493
for_each_set_bit(i, &port_mask, ssp_count)
1494
if (!tdms || test_bit(0, &tdms[i]))
1495
cpu_count++;
1496
if (tdms)
1497
for_each_set_bit(i, &port_mask, ssp_count)
1498
cpu_count += hweight_long(tdms[i]);
1499
1500
cpus = devm_kcalloc(adev->dev, cpu_count, sizeof(*cpus), GFP_KERNEL);
1501
if (!cpus)
1502
return -ENOMEM;
1503
1504
dai = cpus;
1505
for_each_set_bit(i, &port_mask, ssp_count) {
1506
if (!tdms || test_bit(0, &tdms[i])) {
1507
memcpy(dai, &i2s_dai_template, sizeof(*dai));
1508
1509
dai->name =
1510
devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d Pin", i);
1511
dai->playback.stream_name =
1512
devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Tx", i);
1513
dai->capture.stream_name =
1514
devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d Rx", i);
1515
1516
if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1517
return -ENOMEM;
1518
dai->ops = ops;
1519
dai++;
1520
}
1521
}
1522
1523
if (!tdms)
1524
goto plat_register;
1525
1526
for_each_set_bit(i, &port_mask, ssp_count) {
1527
for_each_set_bit(j, &tdms[i], AVS_CHANNELS_MAX) {
1528
memcpy(dai, &i2s_dai_template, sizeof(*dai));
1529
1530
dai->name =
1531
devm_kasprintf(adev->dev, GFP_KERNEL, "SSP%d:%d Pin", i, j);
1532
dai->playback.stream_name =
1533
devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Tx", i, j);
1534
dai->capture.stream_name =
1535
devm_kasprintf(adev->dev, GFP_KERNEL, "ssp%d:%d Rx", i, j);
1536
1537
if (!dai->name || !dai->playback.stream_name || !dai->capture.stream_name)
1538
return -ENOMEM;
1539
dai->ops = ops;
1540
dai++;
1541
}
1542
}
1543
1544
plat_register:
1545
return avs_register_component(adev->dev, name, &avs_component_driver, cpus, cpu_count);
1546
}
1547
1548
/* HD-Audio CPU DAI template */
1549
static const struct snd_soc_dai_driver hda_cpu_dai = {
1550
.ops = &avs_dai_hda_be_ops,
1551
.playback = {
1552
.channels_min = 1,
1553
.channels_max = AVS_CHANNELS_MAX,
1554
.rates = SNDRV_PCM_RATE_8000_192000,
1555
.formats = SNDRV_PCM_FMTBIT_S16_LE |
1556
SNDRV_PCM_FMTBIT_S32_LE,
1557
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1558
SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1559
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1560
},
1561
.capture = {
1562
.channels_min = 1,
1563
.channels_max = AVS_CHANNELS_MAX,
1564
.rates = SNDRV_PCM_RATE_8000_192000,
1565
.formats = SNDRV_PCM_FMTBIT_S16_LE |
1566
SNDRV_PCM_FMTBIT_S32_LE,
1567
.subformats = SNDRV_PCM_SUBFMTBIT_MSBITS_20 |
1568
SNDRV_PCM_SUBFMTBIT_MSBITS_24 |
1569
SNDRV_PCM_SUBFMTBIT_MSBITS_MAX,
1570
},
1571
};
1572
1573
static void avs_component_hda_unregister_dais(struct snd_soc_component *component)
1574
{
1575
struct snd_soc_acpi_mach *mach;
1576
struct snd_soc_dai *dai, *save;
1577
struct avs_mach_pdata *pdata;
1578
struct hda_codec *codec;
1579
char name[32];
1580
1581
mach = dev_get_platdata(component->card->dev);
1582
pdata = mach->pdata;
1583
codec = pdata->codec;
1584
snprintf(name, sizeof(name), "%s-cpu", dev_name(&codec->core.dev));
1585
1586
for_each_component_dais_safe(component, dai, save) {
1587
int stream;
1588
1589
if (!strstr(dai->driver->name, name))
1590
continue;
1591
1592
for_each_pcm_streams(stream)
1593
snd_soc_dapm_free_widget(snd_soc_dai_get_widget(dai, stream));
1594
1595
snd_soc_unregister_dai(dai);
1596
}
1597
}
1598
1599
static int avs_component_hda_probe(struct snd_soc_component *component)
1600
{
1601
struct snd_soc_dapm_context *dapm;
1602
struct snd_soc_dai_driver *dais;
1603
struct snd_soc_acpi_mach *mach;
1604
struct avs_mach_pdata *pdata;
1605
struct hda_codec *codec;
1606
struct hda_pcm *pcm;
1607
const char *cname;
1608
int pcm_count = 0, ret, i;
1609
1610
mach = dev_get_platdata(component->card->dev);
1611
if (!mach)
1612
return -EINVAL;
1613
1614
pdata = mach->pdata;
1615
codec = pdata->codec;
1616
if (list_empty(&codec->pcm_list_head))
1617
return -EINVAL;
1618
list_for_each_entry(pcm, &codec->pcm_list_head, list)
1619
pcm_count++;
1620
1621
dais = devm_kcalloc(component->dev, pcm_count, sizeof(*dais),
1622
GFP_KERNEL);
1623
if (!dais)
1624
return -ENOMEM;
1625
1626
cname = dev_name(&codec->core.dev);
1627
dapm = snd_soc_component_to_dapm(component);
1628
pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list);
1629
1630
for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) {
1631
struct snd_soc_dai *dai;
1632
1633
memcpy(&dais[i], &hda_cpu_dai, sizeof(*dais));
1634
dais[i].id = i;
1635
dais[i].name = devm_kasprintf(component->dev, GFP_KERNEL,
1636
"%s-cpu%d", cname, i);
1637
if (!dais[i].name) {
1638
ret = -ENOMEM;
1639
goto exit;
1640
}
1641
1642
if (pcm->stream[0].substreams) {
1643
dais[i].playback.stream_name =
1644
devm_kasprintf(component->dev, GFP_KERNEL,
1645
"%s-cpu%d Tx", cname, i);
1646
if (!dais[i].playback.stream_name) {
1647
ret = -ENOMEM;
1648
goto exit;
1649
}
1650
1651
if (!hda_codec_is_display(codec)) {
1652
dais[i].playback.formats = pcm->stream[0].formats;
1653
dais[i].playback.subformats = pcm->stream[0].subformats;
1654
dais[i].playback.rates = pcm->stream[0].rates;
1655
dais[i].playback.channels_min = pcm->stream[0].channels_min;
1656
dais[i].playback.channels_max = pcm->stream[0].channels_max;
1657
dais[i].playback.sig_bits = pcm->stream[0].maxbps;
1658
}
1659
}
1660
1661
if (pcm->stream[1].substreams) {
1662
dais[i].capture.stream_name =
1663
devm_kasprintf(component->dev, GFP_KERNEL,
1664
"%s-cpu%d Rx", cname, i);
1665
if (!dais[i].capture.stream_name) {
1666
ret = -ENOMEM;
1667
goto exit;
1668
}
1669
1670
if (!hda_codec_is_display(codec)) {
1671
dais[i].capture.formats = pcm->stream[1].formats;
1672
dais[i].capture.subformats = pcm->stream[1].subformats;
1673
dais[i].capture.rates = pcm->stream[1].rates;
1674
dais[i].capture.channels_min = pcm->stream[1].channels_min;
1675
dais[i].capture.channels_max = pcm->stream[1].channels_max;
1676
dais[i].capture.sig_bits = pcm->stream[1].maxbps;
1677
}
1678
}
1679
1680
dai = snd_soc_register_dai(component, &dais[i], false);
1681
if (!dai) {
1682
dev_err(component->dev, "register dai for %s failed\n",
1683
pcm->name);
1684
ret = -EINVAL;
1685
goto exit;
1686
}
1687
1688
ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1689
if (ret < 0) {
1690
dev_err(component->dev, "create widgets failed: %d\n",
1691
ret);
1692
snd_soc_unregister_dai(dai);
1693
goto exit;
1694
}
1695
}
1696
1697
ret = avs_component_probe(component);
1698
exit:
1699
if (ret)
1700
avs_component_hda_unregister_dais(component);
1701
1702
return ret;
1703
}
1704
1705
static void avs_component_hda_remove(struct snd_soc_component *component)
1706
{
1707
avs_component_remove(component);
1708
avs_component_hda_unregister_dais(component);
1709
}
1710
1711
static int avs_component_hda_open(struct snd_soc_component *component,
1712
struct snd_pcm_substream *substream)
1713
{
1714
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1715
1716
if (!rtd->dai_link->no_pcm) {
1717
struct snd_pcm_hardware hwparams = avs_pcm_hardware;
1718
struct snd_soc_pcm_runtime *be;
1719
struct snd_soc_dpcm *dpcm;
1720
int dir = substream->stream;
1721
1722
/*
1723
* Support the DPCM reparenting while still fulfilling expectations of HDAudio
1724
* common code - a valid stream pointer at substream->runtime->private_data -
1725
* by having all FEs point to the same private data.
1726
*/
1727
for_each_dpcm_be(rtd, dir, dpcm) {
1728
struct snd_pcm_substream *be_substream;
1729
1730
be = dpcm->be;
1731
if (be->dpcm[dir].users == 1)
1732
break;
1733
1734
be_substream = snd_soc_dpcm_get_substream(be, dir);
1735
substream->runtime->private_data = be_substream->runtime->private_data;
1736
break;
1737
}
1738
1739
/* RESUME unsupported for de-coupled HD-Audio capture. */
1740
if (dir == SNDRV_PCM_STREAM_CAPTURE)
1741
hwparams.info &= ~SNDRV_PCM_INFO_RESUME;
1742
1743
return snd_soc_set_runtime_hwparams(substream, &hwparams);
1744
}
1745
1746
return 0;
1747
}
1748
1749
static struct snd_soc_component_driver avs_hda_component_driver = {
1750
.name = "avs-hda-pcm",
1751
.probe = avs_component_hda_probe,
1752
.remove = avs_component_hda_remove,
1753
.suspend = avs_component_suspend,
1754
.resume = avs_component_resume,
1755
.open = avs_component_hda_open,
1756
.pointer = avs_component_pointer,
1757
.mmap = avs_component_mmap,
1758
.pcm_construct = avs_component_construct,
1759
/*
1760
* hda platform component's probe() is dependent on
1761
* codec->pcm_list_head, it needs to be initialized after codec
1762
* component. remove_order is here for completeness sake
1763
*/
1764
.probe_order = SND_SOC_COMP_ORDER_LATE,
1765
.remove_order = SND_SOC_COMP_ORDER_EARLY,
1766
.module_get_upon_open = 1,
1767
.topology_name_prefix = "intel/avs",
1768
};
1769
1770
int avs_register_hda_component(struct avs_dev *adev, const char *name)
1771
{
1772
return avs_register_component(adev->dev, name, &avs_hda_component_driver, NULL, 0);
1773
}
1774
1775