1 // SPDX-License-Identifier: GPL-2.0+
3 * virtio-snd: Virtio sound device
4 * Copyright (C) 2021 OpenSynergy GmbH
6 #include <sound/pcm_params.h>
8 #include "virtio_card.h"
11 * I/O messages lifetime
12 * ---------------------
15 * Messages are initially allocated in the ops->hw_params() after the size and
16 * number of periods have been successfully negotiated.
19 * Messages can be safely freed after the queue has been successfully flushed
20 * (RELEASE command in the ops->sync_stop()) and the ops->hw_free() has been
23 * When the substream stops, the ops->sync_stop() waits until the device has
24 * completed all pending messages. This wait can be interrupted either by a
25 * signal or due to a timeout. In this case, the device can still access
26 * messages even after calling ops->hw_free(). It can also issue an interrupt,
27 * and the interrupt handler will also try to access message structures.
29 * Therefore, freeing of already allocated messages occurs:
31 * - in ops->hw_params(), if this operator was called several times in a row,
32 * or if ops->hw_free() failed to free messages previously;
34 * - in ops->hw_free(), if the queue has been successfully flushed;
36 * - in dev->release().
39 /* Map for converting ALSA format to VirtIO format. */
40 struct virtsnd_a2v_format
{
41 snd_pcm_format_t alsa_bit
;
45 static const struct virtsnd_a2v_format g_a2v_format_map
[] = {
46 { SNDRV_PCM_FORMAT_IMA_ADPCM
, VIRTIO_SND_PCM_FMT_IMA_ADPCM
},
47 { SNDRV_PCM_FORMAT_MU_LAW
, VIRTIO_SND_PCM_FMT_MU_LAW
},
48 { SNDRV_PCM_FORMAT_A_LAW
, VIRTIO_SND_PCM_FMT_A_LAW
},
49 { SNDRV_PCM_FORMAT_S8
, VIRTIO_SND_PCM_FMT_S8
},
50 { SNDRV_PCM_FORMAT_U8
, VIRTIO_SND_PCM_FMT_U8
},
51 { SNDRV_PCM_FORMAT_S16_LE
, VIRTIO_SND_PCM_FMT_S16
},
52 { SNDRV_PCM_FORMAT_U16_LE
, VIRTIO_SND_PCM_FMT_U16
},
53 { SNDRV_PCM_FORMAT_S18_3LE
, VIRTIO_SND_PCM_FMT_S18_3
},
54 { SNDRV_PCM_FORMAT_U18_3LE
, VIRTIO_SND_PCM_FMT_U18_3
},
55 { SNDRV_PCM_FORMAT_S20_3LE
, VIRTIO_SND_PCM_FMT_S20_3
},
56 { SNDRV_PCM_FORMAT_U20_3LE
, VIRTIO_SND_PCM_FMT_U20_3
},
57 { SNDRV_PCM_FORMAT_S24_3LE
, VIRTIO_SND_PCM_FMT_S24_3
},
58 { SNDRV_PCM_FORMAT_U24_3LE
, VIRTIO_SND_PCM_FMT_U24_3
},
59 { SNDRV_PCM_FORMAT_S20_LE
, VIRTIO_SND_PCM_FMT_S20
},
60 { SNDRV_PCM_FORMAT_U20_LE
, VIRTIO_SND_PCM_FMT_U20
},
61 { SNDRV_PCM_FORMAT_S24_LE
, VIRTIO_SND_PCM_FMT_S24
},
62 { SNDRV_PCM_FORMAT_U24_LE
, VIRTIO_SND_PCM_FMT_U24
},
63 { SNDRV_PCM_FORMAT_S32_LE
, VIRTIO_SND_PCM_FMT_S32
},
64 { SNDRV_PCM_FORMAT_U32_LE
, VIRTIO_SND_PCM_FMT_U32
},
65 { SNDRV_PCM_FORMAT_FLOAT_LE
, VIRTIO_SND_PCM_FMT_FLOAT
},
66 { SNDRV_PCM_FORMAT_FLOAT64_LE
, VIRTIO_SND_PCM_FMT_FLOAT64
},
67 { SNDRV_PCM_FORMAT_DSD_U8
, VIRTIO_SND_PCM_FMT_DSD_U8
},
68 { SNDRV_PCM_FORMAT_DSD_U16_LE
, VIRTIO_SND_PCM_FMT_DSD_U16
},
69 { SNDRV_PCM_FORMAT_DSD_U32_LE
, VIRTIO_SND_PCM_FMT_DSD_U32
},
70 { SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE
,
71 VIRTIO_SND_PCM_FMT_IEC958_SUBFRAME
}
74 /* Map for converting ALSA frame rate to VirtIO frame rate. */
75 struct virtsnd_a2v_rate
{
80 static const struct virtsnd_a2v_rate g_a2v_rate_map
[] = {
81 { 5512, VIRTIO_SND_PCM_RATE_5512
},
82 { 8000, VIRTIO_SND_PCM_RATE_8000
},
83 { 11025, VIRTIO_SND_PCM_RATE_11025
},
84 { 16000, VIRTIO_SND_PCM_RATE_16000
},
85 { 22050, VIRTIO_SND_PCM_RATE_22050
},
86 { 32000, VIRTIO_SND_PCM_RATE_32000
},
87 { 44100, VIRTIO_SND_PCM_RATE_44100
},
88 { 48000, VIRTIO_SND_PCM_RATE_48000
},
89 { 64000, VIRTIO_SND_PCM_RATE_64000
},
90 { 88200, VIRTIO_SND_PCM_RATE_88200
},
91 { 96000, VIRTIO_SND_PCM_RATE_96000
},
92 { 176400, VIRTIO_SND_PCM_RATE_176400
},
93 { 192000, VIRTIO_SND_PCM_RATE_192000
}
96 static int virtsnd_pcm_sync_stop(struct snd_pcm_substream
*substream
);
99 * virtsnd_pcm_open() - Open the PCM substream.
100 * @substream: Kernel ALSA substream.
102 * Context: Process context.
103 * Return: 0 on success, -errno on failure.
105 static int virtsnd_pcm_open(struct snd_pcm_substream
*substream
)
107 struct virtio_pcm
*vpcm
= snd_pcm_substream_chip(substream
);
108 struct virtio_pcm_stream
*vs
= &vpcm
->streams
[substream
->stream
];
109 struct virtio_pcm_substream
*vss
= vs
->substreams
[substream
->number
];
111 substream
->runtime
->hw
= vss
->hw
;
112 substream
->private_data
= vss
;
114 snd_pcm_hw_constraint_integer(substream
->runtime
,
115 SNDRV_PCM_HW_PARAM_PERIODS
);
117 vss
->stopped
= !!virtsnd_pcm_msg_pending_num(vss
);
118 vss
->suspended
= false;
121 * If the substream has already been used, then the I/O queue may be in
122 * an invalid state. Just in case, we do a check and try to return the
123 * queue to its original state, if necessary.
125 return virtsnd_pcm_sync_stop(substream
);
129 * virtsnd_pcm_close() - Close the PCM substream.
130 * @substream: Kernel ALSA substream.
132 * Context: Process context.
135 static int virtsnd_pcm_close(struct snd_pcm_substream
*substream
)
141 * virtsnd_pcm_dev_set_params() - Set the parameters of the PCM substream on
143 * @vss: VirtIO PCM substream.
144 * @buffer_bytes: Size of the hardware buffer.
145 * @period_bytes: Size of the hardware period.
146 * @channels: Selected number of channels.
147 * @format: Selected sample format (SNDRV_PCM_FORMAT_XXX).
148 * @rate: Selected frame rate.
150 * Context: Any context that permits to sleep.
151 * Return: 0 on success, -errno on failure.
153 static int virtsnd_pcm_dev_set_params(struct virtio_pcm_substream
*vss
,
154 unsigned int buffer_bytes
,
155 unsigned int period_bytes
,
156 unsigned int channels
,
157 snd_pcm_format_t format
,
160 struct virtio_snd_msg
*msg
;
161 struct virtio_snd_pcm_set_params
*request
;
166 for (i
= 0; i
< ARRAY_SIZE(g_a2v_format_map
); ++i
)
167 if (g_a2v_format_map
[i
].alsa_bit
== format
) {
168 vformat
= g_a2v_format_map
[i
].vio_bit
;
173 for (i
= 0; i
< ARRAY_SIZE(g_a2v_rate_map
); ++i
)
174 if (g_a2v_rate_map
[i
].rate
== rate
) {
175 vrate
= g_a2v_rate_map
[i
].vio_bit
;
180 if (vformat
== -1 || vrate
== -1)
183 msg
= virtsnd_pcm_ctl_msg_alloc(vss
, VIRTIO_SND_R_PCM_SET_PARAMS
,
188 request
= virtsnd_ctl_msg_request(msg
);
189 request
->buffer_bytes
= cpu_to_le32(buffer_bytes
);
190 request
->period_bytes
= cpu_to_le32(period_bytes
);
191 request
->channels
= channels
;
192 request
->format
= vformat
;
193 request
->rate
= vrate
;
195 if (vss
->features
& (1U << VIRTIO_SND_PCM_F_MSG_POLLING
))
197 cpu_to_le32(1U << VIRTIO_SND_PCM_F_MSG_POLLING
);
199 if (vss
->features
& (1U << VIRTIO_SND_PCM_F_EVT_XRUNS
))
201 cpu_to_le32(1U << VIRTIO_SND_PCM_F_EVT_XRUNS
);
203 return virtsnd_ctl_msg_send_sync(vss
->snd
, msg
);
207 * virtsnd_pcm_hw_params() - Set the parameters of the PCM substream.
208 * @substream: Kernel ALSA substream.
209 * @hw_params: Hardware parameters.
211 * Context: Process context.
212 * Return: 0 on success, -errno on failure.
214 static int virtsnd_pcm_hw_params(struct snd_pcm_substream
*substream
,
215 struct snd_pcm_hw_params
*hw_params
)
217 struct virtio_pcm_substream
*vss
= snd_pcm_substream_chip(substream
);
218 struct virtio_device
*vdev
= vss
->snd
->vdev
;
221 if (virtsnd_pcm_msg_pending_num(vss
)) {
222 dev_err(&vdev
->dev
, "SID %u: invalid I/O queue state\n",
227 rc
= virtsnd_pcm_dev_set_params(vss
, params_buffer_bytes(hw_params
),
228 params_period_bytes(hw_params
),
229 params_channels(hw_params
),
230 params_format(hw_params
),
231 params_rate(hw_params
));
236 * Free previously allocated messages if ops->hw_params() is called
237 * several times in a row, or if ops->hw_free() failed to free messages.
239 virtsnd_pcm_msg_free(vss
);
241 return virtsnd_pcm_msg_alloc(vss
, params_periods(hw_params
),
242 params_period_bytes(hw_params
));
246 * virtsnd_pcm_hw_free() - Reset the parameters of the PCM substream.
247 * @substream: Kernel ALSA substream.
249 * Context: Process context.
252 static int virtsnd_pcm_hw_free(struct snd_pcm_substream
*substream
)
254 struct virtio_pcm_substream
*vss
= snd_pcm_substream_chip(substream
);
256 /* If the queue is flushed, we can safely free the messages here. */
257 if (!virtsnd_pcm_msg_pending_num(vss
))
258 virtsnd_pcm_msg_free(vss
);
264 * virtsnd_pcm_prepare() - Prepare the PCM substream.
265 * @substream: Kernel ALSA substream.
267 * Context: Process context.
268 * Return: 0 on success, -errno on failure.
270 static int virtsnd_pcm_prepare(struct snd_pcm_substream
*substream
)
272 struct virtio_pcm_substream
*vss
= snd_pcm_substream_chip(substream
);
273 struct virtio_device
*vdev
= vss
->snd
->vdev
;
274 struct virtio_snd_msg
*msg
;
276 if (!vss
->suspended
) {
277 if (virtsnd_pcm_msg_pending_num(vss
)) {
278 dev_err(&vdev
->dev
, "SID %u: invalid I/O queue state\n",
283 vss
->buffer_bytes
= snd_pcm_lib_buffer_bytes(substream
);
286 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
287 unsigned int buffer_bytes
= snd_pcm_lib_buffer_bytes(substream
);
288 unsigned int period_bytes
= snd_pcm_lib_period_bytes(substream
);
291 rc
= virtsnd_pcm_dev_set_params(vss
, buffer_bytes
, period_bytes
,
293 runtime
->format
, runtime
->rate
);
298 vss
->xfer_xrun
= false;
299 vss
->suspended
= false;
302 memset(&vss
->pcm_indirect
, 0, sizeof(vss
->pcm_indirect
));
303 vss
->pcm_indirect
.sw_buffer_size
=
304 vss
->pcm_indirect
.hw_buffer_size
=
305 snd_pcm_lib_buffer_bytes(substream
);
307 msg
= virtsnd_pcm_ctl_msg_alloc(vss
, VIRTIO_SND_R_PCM_PREPARE
,
312 return virtsnd_ctl_msg_send_sync(vss
->snd
, msg
);
316 * virtsnd_pcm_trigger() - Process command for the PCM substream.
317 * @substream: Kernel ALSA substream.
318 * @command: Substream command (SNDRV_PCM_TRIGGER_XXX).
320 * Context: Any context. Takes and releases the VirtIO substream spinlock.
321 * May take and release the tx/rx queue spinlock.
322 * Return: 0 on success, -errno on failure.
324 static int virtsnd_pcm_trigger(struct snd_pcm_substream
*substream
, int command
)
326 struct virtio_pcm_substream
*vss
= snd_pcm_substream_chip(substream
);
327 struct virtio_snd
*snd
= vss
->snd
;
328 struct virtio_snd_queue
*queue
;
329 struct virtio_snd_msg
*msg
;
334 case SNDRV_PCM_TRIGGER_START
:
335 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
336 queue
= virtsnd_pcm_queue(vss
);
338 spin_lock_irqsave(&queue
->lock
, flags
);
339 spin_lock(&vss
->lock
);
340 if (vss
->direction
== SNDRV_PCM_STREAM_CAPTURE
)
341 rc
= virtsnd_pcm_msg_send(vss
, 0, vss
->buffer_bytes
);
343 vss
->xfer_enabled
= true;
344 spin_unlock(&vss
->lock
);
345 spin_unlock_irqrestore(&queue
->lock
, flags
);
349 msg
= virtsnd_pcm_ctl_msg_alloc(vss
, VIRTIO_SND_R_PCM_START
,
352 spin_lock_irqsave(&vss
->lock
, flags
);
353 vss
->xfer_enabled
= false;
354 spin_unlock_irqrestore(&vss
->lock
, flags
);
359 return virtsnd_ctl_msg_send_sync(snd
, msg
);
360 case SNDRV_PCM_TRIGGER_SUSPEND
:
361 vss
->suspended
= true;
363 case SNDRV_PCM_TRIGGER_STOP
:
366 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
367 spin_lock_irqsave(&vss
->lock
, flags
);
368 vss
->xfer_enabled
= false;
369 spin_unlock_irqrestore(&vss
->lock
, flags
);
371 msg
= virtsnd_pcm_ctl_msg_alloc(vss
, VIRTIO_SND_R_PCM_STOP
,
376 return virtsnd_ctl_msg_send_sync(snd
, msg
);
383 * virtsnd_pcm_sync_stop() - Synchronous PCM substream stop.
384 * @substream: Kernel ALSA substream.
386 * The function can be called both from the upper level or from the driver
389 * Context: Process context. Takes and releases the VirtIO substream spinlock.
390 * Return: 0 on success, -errno on failure.
392 static int virtsnd_pcm_sync_stop(struct snd_pcm_substream
*substream
)
394 struct virtio_pcm_substream
*vss
= snd_pcm_substream_chip(substream
);
395 struct virtio_snd
*snd
= vss
->snd
;
396 struct virtio_snd_msg
*msg
;
397 unsigned int js
= msecs_to_jiffies(virtsnd_msg_timeout_ms
);
400 cancel_work_sync(&vss
->elapsed_period
);
405 msg
= virtsnd_pcm_ctl_msg_alloc(vss
, VIRTIO_SND_R_PCM_RELEASE
,
410 rc
= virtsnd_ctl_msg_send_sync(snd
, msg
);
415 * The spec states that upon receipt of the RELEASE command "the device
416 * MUST complete all pending I/O messages for the specified stream ID".
417 * Thus, we consider the absence of I/O messages in the queue as an
418 * indication that the substream has been released.
420 rc
= wait_event_interruptible_timeout(vss
->msg_empty
,
421 !virtsnd_pcm_msg_pending_num(vss
),
424 dev_warn(&snd
->vdev
->dev
, "SID %u: failed to flush I/O queue\n",
427 return !rc
? -ETIMEDOUT
: rc
;
430 vss
->stopped
= false;
436 * virtsnd_pcm_pb_pointer() - Get the current hardware position for the PCM
437 * substream for playback.
438 * @substream: Kernel ALSA substream.
440 * Context: Any context.
441 * Return: Hardware position in frames inside [0 ... buffer_size) range.
443 static snd_pcm_uframes_t
444 virtsnd_pcm_pb_pointer(struct snd_pcm_substream
*substream
)
446 struct virtio_pcm_substream
*vss
= snd_pcm_substream_chip(substream
);
448 return snd_pcm_indirect_playback_pointer(substream
,
454 * virtsnd_pcm_cp_pointer() - Get the current hardware position for the PCM
455 * substream for capture.
456 * @substream: Kernel ALSA substream.
458 * Context: Any context.
459 * Return: Hardware position in frames inside [0 ... buffer_size) range.
461 static snd_pcm_uframes_t
462 virtsnd_pcm_cp_pointer(struct snd_pcm_substream
*substream
)
464 struct virtio_pcm_substream
*vss
= snd_pcm_substream_chip(substream
);
466 return snd_pcm_indirect_capture_pointer(substream
,
471 static void virtsnd_pcm_trans_copy(struct snd_pcm_substream
*substream
,
472 struct snd_pcm_indirect
*rec
, size_t bytes
)
474 struct virtio_pcm_substream
*vss
= snd_pcm_substream_chip(substream
);
476 virtsnd_pcm_msg_send(vss
, rec
->sw_data
, bytes
);
479 static int virtsnd_pcm_pb_ack(struct snd_pcm_substream
*substream
)
481 struct virtio_pcm_substream
*vss
= snd_pcm_substream_chip(substream
);
482 struct virtio_snd_queue
*queue
= virtsnd_pcm_queue(vss
);
486 spin_lock_irqsave(&queue
->lock
, flags
);
487 spin_lock(&vss
->lock
);
489 rc
= snd_pcm_indirect_playback_transfer(substream
, &vss
->pcm_indirect
,
490 virtsnd_pcm_trans_copy
);
492 spin_unlock(&vss
->lock
);
493 spin_unlock_irqrestore(&queue
->lock
, flags
);
498 static int virtsnd_pcm_cp_ack(struct snd_pcm_substream
*substream
)
500 struct virtio_pcm_substream
*vss
= snd_pcm_substream_chip(substream
);
501 struct virtio_snd_queue
*queue
= virtsnd_pcm_queue(vss
);
505 spin_lock_irqsave(&queue
->lock
, flags
);
506 spin_lock(&vss
->lock
);
508 rc
= snd_pcm_indirect_capture_transfer(substream
, &vss
->pcm_indirect
,
509 virtsnd_pcm_trans_copy
);
511 spin_unlock(&vss
->lock
);
512 spin_unlock_irqrestore(&queue
->lock
, flags
);
517 /* PCM substream operators map. */
518 const struct snd_pcm_ops virtsnd_pcm_ops
[] = {
520 .open
= virtsnd_pcm_open
,
521 .close
= virtsnd_pcm_close
,
522 .ioctl
= snd_pcm_lib_ioctl
,
523 .hw_params
= virtsnd_pcm_hw_params
,
524 .hw_free
= virtsnd_pcm_hw_free
,
525 .prepare
= virtsnd_pcm_prepare
,
526 .trigger
= virtsnd_pcm_trigger
,
527 .sync_stop
= virtsnd_pcm_sync_stop
,
528 .pointer
= virtsnd_pcm_pb_pointer
,
529 .ack
= virtsnd_pcm_pb_ack
,
532 .open
= virtsnd_pcm_open
,
533 .close
= virtsnd_pcm_close
,
534 .ioctl
= snd_pcm_lib_ioctl
,
535 .hw_params
= virtsnd_pcm_hw_params
,
536 .hw_free
= virtsnd_pcm_hw_free
,
537 .prepare
= virtsnd_pcm_prepare
,
538 .trigger
= virtsnd_pcm_trigger
,
539 .sync_stop
= virtsnd_pcm_sync_stop
,
540 .pointer
= virtsnd_pcm_cp_pointer
,
541 .ack
= virtsnd_pcm_cp_ack
,