1 // SPDX-License-Identifier: GPL-2.0+
3 * virtio-snd: Virtio sound device
4 * Copyright (C) 2021 OpenSynergy GmbH
6 #include <linux/moduleparam.h>
7 #include <linux/virtio_config.h>
9 #include "virtio_card.h"
11 static u32 pcm_buffer_ms
= 160;
12 module_param(pcm_buffer_ms
, uint
, 0644);
13 MODULE_PARM_DESC(pcm_buffer_ms
, "PCM substream buffer time in milliseconds");
15 static u32 pcm_periods_min
= 2;
16 module_param(pcm_periods_min
, uint
, 0644);
17 MODULE_PARM_DESC(pcm_periods_min
, "Minimum number of PCM periods");
19 static u32 pcm_periods_max
= 16;
20 module_param(pcm_periods_max
, uint
, 0644);
21 MODULE_PARM_DESC(pcm_periods_max
, "Maximum number of PCM periods");
23 static u32 pcm_period_ms_min
= 10;
24 module_param(pcm_period_ms_min
, uint
, 0644);
25 MODULE_PARM_DESC(pcm_period_ms_min
, "Minimum PCM period time in milliseconds");
27 static u32 pcm_period_ms_max
= 80;
28 module_param(pcm_period_ms_max
, uint
, 0644);
29 MODULE_PARM_DESC(pcm_period_ms_max
, "Maximum PCM period time in milliseconds");
31 /* Map for converting VirtIO format to ALSA format. */
32 static const snd_pcm_format_t g_v2a_format_map
[] = {
33 [VIRTIO_SND_PCM_FMT_IMA_ADPCM
] = SNDRV_PCM_FORMAT_IMA_ADPCM
,
34 [VIRTIO_SND_PCM_FMT_MU_LAW
] = SNDRV_PCM_FORMAT_MU_LAW
,
35 [VIRTIO_SND_PCM_FMT_A_LAW
] = SNDRV_PCM_FORMAT_A_LAW
,
36 [VIRTIO_SND_PCM_FMT_S8
] = SNDRV_PCM_FORMAT_S8
,
37 [VIRTIO_SND_PCM_FMT_U8
] = SNDRV_PCM_FORMAT_U8
,
38 [VIRTIO_SND_PCM_FMT_S16
] = SNDRV_PCM_FORMAT_S16_LE
,
39 [VIRTIO_SND_PCM_FMT_U16
] = SNDRV_PCM_FORMAT_U16_LE
,
40 [VIRTIO_SND_PCM_FMT_S18_3
] = SNDRV_PCM_FORMAT_S18_3LE
,
41 [VIRTIO_SND_PCM_FMT_U18_3
] = SNDRV_PCM_FORMAT_U18_3LE
,
42 [VIRTIO_SND_PCM_FMT_S20_3
] = SNDRV_PCM_FORMAT_S20_3LE
,
43 [VIRTIO_SND_PCM_FMT_U20_3
] = SNDRV_PCM_FORMAT_U20_3LE
,
44 [VIRTIO_SND_PCM_FMT_S24_3
] = SNDRV_PCM_FORMAT_S24_3LE
,
45 [VIRTIO_SND_PCM_FMT_U24_3
] = SNDRV_PCM_FORMAT_U24_3LE
,
46 [VIRTIO_SND_PCM_FMT_S20
] = SNDRV_PCM_FORMAT_S20_LE
,
47 [VIRTIO_SND_PCM_FMT_U20
] = SNDRV_PCM_FORMAT_U20_LE
,
48 [VIRTIO_SND_PCM_FMT_S24
] = SNDRV_PCM_FORMAT_S24_LE
,
49 [VIRTIO_SND_PCM_FMT_U24
] = SNDRV_PCM_FORMAT_U24_LE
,
50 [VIRTIO_SND_PCM_FMT_S32
] = SNDRV_PCM_FORMAT_S32_LE
,
51 [VIRTIO_SND_PCM_FMT_U32
] = SNDRV_PCM_FORMAT_U32_LE
,
52 [VIRTIO_SND_PCM_FMT_FLOAT
] = SNDRV_PCM_FORMAT_FLOAT_LE
,
53 [VIRTIO_SND_PCM_FMT_FLOAT64
] = SNDRV_PCM_FORMAT_FLOAT64_LE
,
54 [VIRTIO_SND_PCM_FMT_DSD_U8
] = SNDRV_PCM_FORMAT_DSD_U8
,
55 [VIRTIO_SND_PCM_FMT_DSD_U16
] = SNDRV_PCM_FORMAT_DSD_U16_LE
,
56 [VIRTIO_SND_PCM_FMT_DSD_U32
] = SNDRV_PCM_FORMAT_DSD_U32_LE
,
57 [VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME
] =
58 SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
61 /* Map for converting VirtIO frame rate to ALSA frame rate. */
62 struct virtsnd_v2a_rate
{
63 unsigned int alsa_bit
;
67 static const struct virtsnd_v2a_rate g_v2a_rate_map
[] = {
68 [VIRTIO_SND_PCM_RATE_5512
] = { SNDRV_PCM_RATE_5512
, 5512 },
69 [VIRTIO_SND_PCM_RATE_8000
] = { SNDRV_PCM_RATE_8000
, 8000 },
70 [VIRTIO_SND_PCM_RATE_11025
] = { SNDRV_PCM_RATE_11025
, 11025 },
71 [VIRTIO_SND_PCM_RATE_16000
] = { SNDRV_PCM_RATE_16000
, 16000 },
72 [VIRTIO_SND_PCM_RATE_22050
] = { SNDRV_PCM_RATE_22050
, 22050 },
73 [VIRTIO_SND_PCM_RATE_32000
] = { SNDRV_PCM_RATE_32000
, 32000 },
74 [VIRTIO_SND_PCM_RATE_44100
] = { SNDRV_PCM_RATE_44100
, 44100 },
75 [VIRTIO_SND_PCM_RATE_48000
] = { SNDRV_PCM_RATE_48000
, 48000 },
76 [VIRTIO_SND_PCM_RATE_64000
] = { SNDRV_PCM_RATE_64000
, 64000 },
77 [VIRTIO_SND_PCM_RATE_88200
] = { SNDRV_PCM_RATE_88200
, 88200 },
78 [VIRTIO_SND_PCM_RATE_96000
] = { SNDRV_PCM_RATE_96000
, 96000 },
79 [VIRTIO_SND_PCM_RATE_176400
] = { SNDRV_PCM_RATE_176400
, 176400 },
80 [VIRTIO_SND_PCM_RATE_192000
] = { SNDRV_PCM_RATE_192000
, 192000 }
84 * virtsnd_pcm_build_hw() - Parse substream config and build HW descriptor.
85 * @vss: VirtIO substream.
86 * @info: VirtIO substream information entry.
88 * Context: Any context.
89 * Return: 0 on success, -EINVAL if configuration is invalid.
91 static int virtsnd_pcm_build_hw(struct virtio_pcm_substream
*vss
,
92 struct virtio_snd_pcm_info
*info
)
94 struct virtio_device
*vdev
= vss
->snd
->vdev
;
97 size_t sample_max
= 0;
98 size_t sample_min
= 0;
100 vss
->features
= le32_to_cpu(info
->features
);
103 * TODO: set SNDRV_PCM_INFO_{BATCH,BLOCK_TRANSFER} if device supports
104 * only message-based transport.
107 SNDRV_PCM_INFO_MMAP
|
108 SNDRV_PCM_INFO_MMAP_VALID
|
109 SNDRV_PCM_INFO_BATCH
|
110 SNDRV_PCM_INFO_BLOCK_TRANSFER
|
111 SNDRV_PCM_INFO_INTERLEAVED
|
112 SNDRV_PCM_INFO_PAUSE
;
114 if (!info
->channels_min
|| info
->channels_min
> info
->channels_max
) {
116 "SID %u: invalid channel range [%u %u]\n",
117 vss
->sid
, info
->channels_min
, info
->channels_max
);
121 vss
->hw
.channels_min
= info
->channels_min
;
122 vss
->hw
.channels_max
= info
->channels_max
;
124 values
= le64_to_cpu(info
->formats
);
128 for (i
= 0; i
< ARRAY_SIZE(g_v2a_format_map
); ++i
)
129 if (values
& (1ULL << i
)) {
130 snd_pcm_format_t alsa_fmt
= g_v2a_format_map
[i
];
131 int bytes
= snd_pcm_format_physical_width(alsa_fmt
) / 8;
133 if (!sample_min
|| sample_min
> bytes
)
136 if (sample_max
< bytes
)
139 vss
->hw
.formats
|= pcm_format_to_bits(alsa_fmt
);
142 if (!vss
->hw
.formats
) {
144 "SID %u: no supported PCM sample formats found\n",
149 values
= le64_to_cpu(info
->rates
);
153 for (i
= 0; i
< ARRAY_SIZE(g_v2a_rate_map
); ++i
)
154 if (values
& (1ULL << i
)) {
155 if (!vss
->hw
.rate_min
||
156 vss
->hw
.rate_min
> g_v2a_rate_map
[i
].rate
)
157 vss
->hw
.rate_min
= g_v2a_rate_map
[i
].rate
;
159 if (vss
->hw
.rate_max
< g_v2a_rate_map
[i
].rate
)
160 vss
->hw
.rate_max
= g_v2a_rate_map
[i
].rate
;
162 vss
->hw
.rates
|= g_v2a_rate_map
[i
].alsa_bit
;
165 if (!vss
->hw
.rates
) {
167 "SID %u: no supported PCM frame rates found\n",
172 vss
->hw
.periods_min
= pcm_periods_min
;
173 vss
->hw
.periods_max
= pcm_periods_max
;
176 * We must ensure that there is enough space in the buffer to store
177 * pcm_buffer_ms ms for the combination (Cmax, Smax, Rmax), where:
178 * Cmax = maximum supported number of channels,
179 * Smax = maximum supported sample size in bytes,
180 * Rmax = maximum supported frame rate.
182 vss
->hw
.buffer_bytes_max
=
183 PAGE_ALIGN(sample_max
* vss
->hw
.channels_max
* pcm_buffer_ms
*
184 (vss
->hw
.rate_max
/ MSEC_PER_SEC
));
187 * We must ensure that the minimum period size is enough to store
188 * pcm_period_ms_min ms for the combination (Cmin, Smin, Rmin), where:
189 * Cmin = minimum supported number of channels,
190 * Smin = minimum supported sample size in bytes,
191 * Rmin = minimum supported frame rate.
193 vss
->hw
.period_bytes_min
=
194 sample_min
* vss
->hw
.channels_min
* pcm_period_ms_min
*
195 (vss
->hw
.rate_min
/ MSEC_PER_SEC
);
198 * We must ensure that the maximum period size is enough to store
199 * pcm_period_ms_max ms for the combination (Cmax, Smax, Rmax).
201 vss
->hw
.period_bytes_max
=
202 sample_max
* vss
->hw
.channels_max
* pcm_period_ms_max
*
203 (vss
->hw
.rate_max
/ MSEC_PER_SEC
);
209 * virtsnd_pcm_find() - Find the PCM device for the specified node ID.
210 * @snd: VirtIO sound device.
211 * @nid: Function node ID.
213 * Context: Any context.
214 * Return: a pointer to the PCM device or ERR_PTR(-ENOENT).
216 struct virtio_pcm
*virtsnd_pcm_find(struct virtio_snd
*snd
, u32 nid
)
218 struct virtio_pcm
*vpcm
;
220 list_for_each_entry(vpcm
, &snd
->pcm_list
, list
)
221 if (vpcm
->nid
== nid
)
224 return ERR_PTR(-ENOENT
);
228 * virtsnd_pcm_find_or_create() - Find or create the PCM device for the
230 * @snd: VirtIO sound device.
231 * @nid: Function node ID.
233 * Context: Any context that permits to sleep.
234 * Return: a pointer to the PCM device or ERR_PTR(-errno).
236 struct virtio_pcm
*virtsnd_pcm_find_or_create(struct virtio_snd
*snd
, u32 nid
)
238 struct virtio_device
*vdev
= snd
->vdev
;
239 struct virtio_pcm
*vpcm
;
241 vpcm
= virtsnd_pcm_find(snd
, nid
);
245 vpcm
= devm_kzalloc(&vdev
->dev
, sizeof(*vpcm
), GFP_KERNEL
);
247 return ERR_PTR(-ENOMEM
);
250 list_add_tail(&vpcm
->list
, &snd
->pcm_list
);
256 * virtsnd_pcm_validate() - Validate if the device can be started.
257 * @vdev: VirtIO parent device.
259 * Context: Any context.
260 * Return: 0 on success, -EINVAL on failure.
262 int virtsnd_pcm_validate(struct virtio_device
*vdev
)
264 if (pcm_periods_min
< 2 || pcm_periods_min
> pcm_periods_max
) {
266 "invalid range [%u %u] of the number of PCM periods\n",
267 pcm_periods_min
, pcm_periods_max
);
271 if (!pcm_period_ms_min
|| pcm_period_ms_min
> pcm_period_ms_max
) {
273 "invalid range [%u %u] of the size of the PCM period\n",
274 pcm_period_ms_min
, pcm_period_ms_max
);
278 if (pcm_buffer_ms
< pcm_periods_min
* pcm_period_ms_min
) {
280 "pcm_buffer_ms(=%u) value cannot be < %u ms\n",
281 pcm_buffer_ms
, pcm_periods_min
* pcm_period_ms_min
);
285 if (pcm_period_ms_max
> pcm_buffer_ms
/ 2) {
287 "pcm_period_ms_max(=%u) value cannot be > %u ms\n",
288 pcm_period_ms_max
, pcm_buffer_ms
/ 2);
296 * virtsnd_pcm_period_elapsed() - Kernel work function to handle the elapsed
298 * @work: Elapsed period work.
300 * The main purpose of this function is to call snd_pcm_period_elapsed() in
301 * a process context, not in an interrupt context. This is necessary because PCM
302 * devices operate in non-atomic mode.
304 * Context: Process context.
306 static void virtsnd_pcm_period_elapsed(struct work_struct
*work
)
308 struct virtio_pcm_substream
*vss
=
309 container_of(work
, struct virtio_pcm_substream
, elapsed_period
);
311 snd_pcm_period_elapsed(vss
->substream
);
315 * virtsnd_pcm_parse_cfg() - Parse the stream configuration.
316 * @snd: VirtIO sound device.
318 * This function is called during initial device initialization.
320 * Context: Any context that permits to sleep.
321 * Return: 0 on success, -errno on failure.
323 int virtsnd_pcm_parse_cfg(struct virtio_snd
*snd
)
325 struct virtio_device
*vdev
= snd
->vdev
;
326 struct virtio_snd_pcm_info
*info
;
330 virtio_cread_le(vdev
, struct virtio_snd_config
, streams
,
332 if (!snd
->nsubstreams
)
335 snd
->substreams
= devm_kcalloc(&vdev
->dev
, snd
->nsubstreams
,
336 sizeof(*snd
->substreams
), GFP_KERNEL
);
337 if (!snd
->substreams
)
340 info
= kcalloc(snd
->nsubstreams
, sizeof(*info
), GFP_KERNEL
);
344 rc
= virtsnd_ctl_query_info(snd
, VIRTIO_SND_R_PCM_INFO
, 0,
345 snd
->nsubstreams
, sizeof(*info
), info
);
349 for (i
= 0; i
< snd
->nsubstreams
; ++i
) {
350 struct virtio_pcm_substream
*vss
= &snd
->substreams
[i
];
351 struct virtio_pcm
*vpcm
;
355 INIT_WORK(&vss
->elapsed_period
, virtsnd_pcm_period_elapsed
);
356 init_waitqueue_head(&vss
->msg_empty
);
357 spin_lock_init(&vss
->lock
);
359 rc
= virtsnd_pcm_build_hw(vss
, &info
[i
]);
363 vss
->nid
= le32_to_cpu(info
[i
].hdr
.hda_fn_nid
);
365 vpcm
= virtsnd_pcm_find_or_create(snd
, vss
->nid
);
371 switch (info
[i
].direction
) {
372 case VIRTIO_SND_D_OUTPUT
:
373 vss
->direction
= SNDRV_PCM_STREAM_PLAYBACK
;
375 case VIRTIO_SND_D_INPUT
:
376 vss
->direction
= SNDRV_PCM_STREAM_CAPTURE
;
379 dev_err(&vdev
->dev
, "SID %u: unknown direction (%u)\n",
380 vss
->sid
, info
[i
].direction
);
385 vpcm
->streams
[vss
->direction
].nsubstreams
++;
395 * virtsnd_pcm_build_devs() - Build ALSA PCM devices.
396 * @snd: VirtIO sound device.
398 * Context: Any context that permits to sleep.
399 * Return: 0 on success, -errno on failure.
401 int virtsnd_pcm_build_devs(struct virtio_snd
*snd
)
403 struct virtio_device
*vdev
= snd
->vdev
;
404 struct virtio_pcm
*vpcm
;
408 list_for_each_entry(vpcm
, &snd
->pcm_list
, list
) {
410 vpcm
->streams
[SNDRV_PCM_STREAM_PLAYBACK
].nsubstreams
;
412 vpcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].nsubstreams
;
417 rc
= snd_pcm_new(snd
->card
, VIRTIO_SND_CARD_DRIVER
, vpcm
->nid
,
418 npbs
, ncps
, &vpcm
->pcm
);
420 dev_err(&vdev
->dev
, "snd_pcm_new[%u] failed: %d\n",
425 vpcm
->pcm
->info_flags
= 0;
426 vpcm
->pcm
->dev_class
= SNDRV_PCM_CLASS_GENERIC
;
427 vpcm
->pcm
->dev_subclass
= SNDRV_PCM_SUBCLASS_GENERIC_MIX
;
428 snprintf(vpcm
->pcm
->name
, sizeof(vpcm
->pcm
->name
),
429 VIRTIO_SND_PCM_NAME
" %u", vpcm
->pcm
->device
);
430 vpcm
->pcm
->private_data
= vpcm
;
431 vpcm
->pcm
->nonatomic
= true;
433 for (i
= 0; i
< ARRAY_SIZE(vpcm
->streams
); ++i
) {
434 struct virtio_pcm_stream
*stream
= &vpcm
->streams
[i
];
436 if (!stream
->nsubstreams
)
440 devm_kcalloc(&vdev
->dev
, stream
->nsubstreams
,
441 sizeof(*stream
->substreams
),
443 if (!stream
->substreams
)
446 stream
->nsubstreams
= 0;
450 for (i
= 0; i
< snd
->nsubstreams
; ++i
) {
451 struct virtio_pcm_stream
*vs
;
452 struct virtio_pcm_substream
*vss
= &snd
->substreams
[i
];
454 vpcm
= virtsnd_pcm_find(snd
, vss
->nid
);
456 return PTR_ERR(vpcm
);
458 vs
= &vpcm
->streams
[vss
->direction
];
459 vs
->substreams
[vs
->nsubstreams
++] = vss
;
462 list_for_each_entry(vpcm
, &snd
->pcm_list
, list
) {
463 for (i
= 0; i
< ARRAY_SIZE(vpcm
->streams
); ++i
) {
464 struct virtio_pcm_stream
*vs
= &vpcm
->streams
[i
];
465 struct snd_pcm_str
*ks
= &vpcm
->pcm
->streams
[i
];
466 struct snd_pcm_substream
*kss
;
468 if (!vs
->nsubstreams
)
471 for (kss
= ks
->substream
; kss
; kss
= kss
->next
)
472 vs
->substreams
[kss
->number
]->substream
= kss
;
474 snd_pcm_set_ops(vpcm
->pcm
, i
, &virtsnd_pcm_ops
);
477 snd_pcm_set_managed_buffer_all(vpcm
->pcm
,
478 SNDRV_DMA_TYPE_VMALLOC
, NULL
,
486 * virtsnd_pcm_event() - Handle the PCM device event notification.
487 * @snd: VirtIO sound device.
488 * @event: VirtIO sound event.
490 * Context: Interrupt context.
492 void virtsnd_pcm_event(struct virtio_snd
*snd
, struct virtio_snd_event
*event
)
494 struct virtio_pcm_substream
*vss
;
495 u32 sid
= le32_to_cpu(event
->data
);
497 if (sid
>= snd
->nsubstreams
)
500 vss
= &snd
->substreams
[sid
];
502 switch (le32_to_cpu(event
->hdr
.code
)) {
503 case VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED
:
504 /* TODO: deal with shmem elapsed period */
506 case VIRTIO_SND_EVT_PCM_XRUN
:
507 spin_lock(&vss
->lock
);
508 if (vss
->xfer_enabled
)
509 vss
->xfer_xrun
= true;
510 spin_unlock(&vss
->lock
);