virtio_pcm.c (14671B)
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * virtio-snd: Virtio sound device 4 * Copyright (C) 2021 OpenSynergy GmbH 5 */ 6#include <linux/moduleparam.h> 7#include <linux/virtio_config.h> 8 9#include "virtio_card.h" 10 11static u32 pcm_buffer_ms = 160; 12module_param(pcm_buffer_ms, uint, 0644); 13MODULE_PARM_DESC(pcm_buffer_ms, "PCM substream buffer time in milliseconds"); 14 15static u32 pcm_periods_min = 2; 16module_param(pcm_periods_min, uint, 0644); 17MODULE_PARM_DESC(pcm_periods_min, "Minimum number of PCM periods"); 18 19static u32 pcm_periods_max = 16; 20module_param(pcm_periods_max, uint, 0644); 21MODULE_PARM_DESC(pcm_periods_max, "Maximum number of PCM periods"); 22 23static u32 pcm_period_ms_min = 10; 24module_param(pcm_period_ms_min, uint, 0644); 25MODULE_PARM_DESC(pcm_period_ms_min, "Minimum PCM period time in milliseconds"); 26 27static u32 pcm_period_ms_max = 80; 28module_param(pcm_period_ms_max, uint, 0644); 29MODULE_PARM_DESC(pcm_period_ms_max, "Maximum PCM period time in milliseconds"); 30 31/* Map for converting VirtIO format to ALSA format. */ 32static 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 59}; 60 61/* Map for converting VirtIO frame rate to ALSA frame rate. */ 62struct virtsnd_v2a_rate { 63 unsigned int alsa_bit; 64 unsigned int rate; 65}; 66 67static 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 } 81}; 82 83/** 84 * virtsnd_pcm_build_hw() - Parse substream config and build HW descriptor. 85 * @vss: VirtIO substream. 86 * @info: VirtIO substream information entry. 87 * 88 * Context: Any context. 89 * Return: 0 on success, -EINVAL if configuration is invalid. 90 */ 91static int virtsnd_pcm_build_hw(struct virtio_pcm_substream *vss, 92 struct virtio_snd_pcm_info *info) 93{ 94 struct virtio_device *vdev = vss->snd->vdev; 95 unsigned int i; 96 u64 values; 97 size_t sample_max = 0; 98 size_t sample_min = 0; 99 100 vss->features = le32_to_cpu(info->features); 101 102 /* 103 * TODO: set SNDRV_PCM_INFO_{BATCH,BLOCK_TRANSFER} if device supports 104 * only message-based transport. 105 */ 106 vss->hw.info = 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; 113 114 if (!info->channels_min || info->channels_min > info->channels_max) { 115 dev_err(&vdev->dev, 116 "SID %u: invalid channel range [%u %u]\n", 117 vss->sid, info->channels_min, info->channels_max); 118 return -EINVAL; 119 } 120 121 vss->hw.channels_min = info->channels_min; 122 vss->hw.channels_max = info->channels_max; 123 124 values = le64_to_cpu(info->formats); 125 126 vss->hw.formats = 0; 127 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; 132 133 if (!sample_min || sample_min > bytes) 134 sample_min = bytes; 135 136 if (sample_max < bytes) 137 sample_max = bytes; 138 139 vss->hw.formats |= pcm_format_to_bits(alsa_fmt); 140 } 141 142 if (!vss->hw.formats) { 143 dev_err(&vdev->dev, 144 "SID %u: no supported PCM sample formats found\n", 145 vss->sid); 146 return -EINVAL; 147 } 148 149 values = le64_to_cpu(info->rates); 150 151 vss->hw.rates = 0; 152 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; 158 159 if (vss->hw.rate_max < g_v2a_rate_map[i].rate) 160 vss->hw.rate_max = g_v2a_rate_map[i].rate; 161 162 vss->hw.rates |= g_v2a_rate_map[i].alsa_bit; 163 } 164 165 if (!vss->hw.rates) { 166 dev_err(&vdev->dev, 167 "SID %u: no supported PCM frame rates found\n", 168 vss->sid); 169 return -EINVAL; 170 } 171 172 vss->hw.periods_min = pcm_periods_min; 173 vss->hw.periods_max = pcm_periods_max; 174 175 /* 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. 181 */ 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)); 185 186 /* 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. 192 */ 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); 196 197 /* 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). 200 */ 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); 204 205 return 0; 206} 207 208/** 209 * virtsnd_pcm_find() - Find the PCM device for the specified node ID. 210 * @snd: VirtIO sound device. 211 * @nid: Function node ID. 212 * 213 * Context: Any context. 214 * Return: a pointer to the PCM device or ERR_PTR(-ENOENT). 215 */ 216struct virtio_pcm *virtsnd_pcm_find(struct virtio_snd *snd, u32 nid) 217{ 218 struct virtio_pcm *vpcm; 219 220 list_for_each_entry(vpcm, &snd->pcm_list, list) 221 if (vpcm->nid == nid) 222 return vpcm; 223 224 return ERR_PTR(-ENOENT); 225} 226 227/** 228 * virtsnd_pcm_find_or_create() - Find or create the PCM device for the 229 * specified node ID. 230 * @snd: VirtIO sound device. 231 * @nid: Function node ID. 232 * 233 * Context: Any context that permits to sleep. 234 * Return: a pointer to the PCM device or ERR_PTR(-errno). 235 */ 236struct virtio_pcm *virtsnd_pcm_find_or_create(struct virtio_snd *snd, u32 nid) 237{ 238 struct virtio_device *vdev = snd->vdev; 239 struct virtio_pcm *vpcm; 240 241 vpcm = virtsnd_pcm_find(snd, nid); 242 if (!IS_ERR(vpcm)) 243 return vpcm; 244 245 vpcm = devm_kzalloc(&vdev->dev, sizeof(*vpcm), GFP_KERNEL); 246 if (!vpcm) 247 return ERR_PTR(-ENOMEM); 248 249 vpcm->nid = nid; 250 list_add_tail(&vpcm->list, &snd->pcm_list); 251 252 return vpcm; 253} 254 255/** 256 * virtsnd_pcm_validate() - Validate if the device can be started. 257 * @vdev: VirtIO parent device. 258 * 259 * Context: Any context. 260 * Return: 0 on success, -EINVAL on failure. 261 */ 262int virtsnd_pcm_validate(struct virtio_device *vdev) 263{ 264 if (pcm_periods_min < 2 || pcm_periods_min > pcm_periods_max) { 265 dev_err(&vdev->dev, 266 "invalid range [%u %u] of the number of PCM periods\n", 267 pcm_periods_min, pcm_periods_max); 268 return -EINVAL; 269 } 270 271 if (!pcm_period_ms_min || pcm_period_ms_min > pcm_period_ms_max) { 272 dev_err(&vdev->dev, 273 "invalid range [%u %u] of the size of the PCM period\n", 274 pcm_period_ms_min, pcm_period_ms_max); 275 return -EINVAL; 276 } 277 278 if (pcm_buffer_ms < pcm_periods_min * pcm_period_ms_min) { 279 dev_err(&vdev->dev, 280 "pcm_buffer_ms(=%u) value cannot be < %u ms\n", 281 pcm_buffer_ms, pcm_periods_min * pcm_period_ms_min); 282 return -EINVAL; 283 } 284 285 if (pcm_period_ms_max > pcm_buffer_ms / 2) { 286 dev_err(&vdev->dev, 287 "pcm_period_ms_max(=%u) value cannot be > %u ms\n", 288 pcm_period_ms_max, pcm_buffer_ms / 2); 289 return -EINVAL; 290 } 291 292 return 0; 293} 294 295/** 296 * virtsnd_pcm_period_elapsed() - Kernel work function to handle the elapsed 297 * period state. 298 * @work: Elapsed period work. 299 * 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. 303 * 304 * Context: Process context. 305 */ 306static void virtsnd_pcm_period_elapsed(struct work_struct *work) 307{ 308 struct virtio_pcm_substream *vss = 309 container_of(work, struct virtio_pcm_substream, elapsed_period); 310 311 snd_pcm_period_elapsed(vss->substream); 312} 313 314/** 315 * virtsnd_pcm_parse_cfg() - Parse the stream configuration. 316 * @snd: VirtIO sound device. 317 * 318 * This function is called during initial device initialization. 319 * 320 * Context: Any context that permits to sleep. 321 * Return: 0 on success, -errno on failure. 322 */ 323int virtsnd_pcm_parse_cfg(struct virtio_snd *snd) 324{ 325 struct virtio_device *vdev = snd->vdev; 326 struct virtio_snd_pcm_info *info; 327 u32 i; 328 int rc; 329 330 virtio_cread_le(vdev, struct virtio_snd_config, streams, 331 &snd->nsubstreams); 332 if (!snd->nsubstreams) 333 return 0; 334 335 snd->substreams = devm_kcalloc(&vdev->dev, snd->nsubstreams, 336 sizeof(*snd->substreams), GFP_KERNEL); 337 if (!snd->substreams) 338 return -ENOMEM; 339 340 info = kcalloc(snd->nsubstreams, sizeof(*info), GFP_KERNEL); 341 if (!info) 342 return -ENOMEM; 343 344 rc = virtsnd_ctl_query_info(snd, VIRTIO_SND_R_PCM_INFO, 0, 345 snd->nsubstreams, sizeof(*info), info); 346 if (rc) 347 goto on_exit; 348 349 for (i = 0; i < snd->nsubstreams; ++i) { 350 struct virtio_pcm_substream *vss = &snd->substreams[i]; 351 struct virtio_pcm *vpcm; 352 353 vss->snd = snd; 354 vss->sid = i; 355 INIT_WORK(&vss->elapsed_period, virtsnd_pcm_period_elapsed); 356 init_waitqueue_head(&vss->msg_empty); 357 spin_lock_init(&vss->lock); 358 359 rc = virtsnd_pcm_build_hw(vss, &info[i]); 360 if (rc) 361 goto on_exit; 362 363 vss->nid = le32_to_cpu(info[i].hdr.hda_fn_nid); 364 365 vpcm = virtsnd_pcm_find_or_create(snd, vss->nid); 366 if (IS_ERR(vpcm)) { 367 rc = PTR_ERR(vpcm); 368 goto on_exit; 369 } 370 371 switch (info[i].direction) { 372 case VIRTIO_SND_D_OUTPUT: 373 vss->direction = SNDRV_PCM_STREAM_PLAYBACK; 374 break; 375 case VIRTIO_SND_D_INPUT: 376 vss->direction = SNDRV_PCM_STREAM_CAPTURE; 377 break; 378 default: 379 dev_err(&vdev->dev, "SID %u: unknown direction (%u)\n", 380 vss->sid, info[i].direction); 381 rc = -EINVAL; 382 goto on_exit; 383 } 384 385 vpcm->streams[vss->direction].nsubstreams++; 386 } 387 388on_exit: 389 kfree(info); 390 391 return rc; 392} 393 394/** 395 * virtsnd_pcm_build_devs() - Build ALSA PCM devices. 396 * @snd: VirtIO sound device. 397 * 398 * Context: Any context that permits to sleep. 399 * Return: 0 on success, -errno on failure. 400 */ 401int virtsnd_pcm_build_devs(struct virtio_snd *snd) 402{ 403 struct virtio_device *vdev = snd->vdev; 404 struct virtio_pcm *vpcm; 405 u32 i; 406 int rc; 407 408 list_for_each_entry(vpcm, &snd->pcm_list, list) { 409 unsigned int npbs = 410 vpcm->streams[SNDRV_PCM_STREAM_PLAYBACK].nsubstreams; 411 unsigned int ncps = 412 vpcm->streams[SNDRV_PCM_STREAM_CAPTURE].nsubstreams; 413 414 if (!npbs && !ncps) 415 continue; 416 417 rc = snd_pcm_new(snd->card, VIRTIO_SND_CARD_DRIVER, vpcm->nid, 418 npbs, ncps, &vpcm->pcm); 419 if (rc) { 420 dev_err(&vdev->dev, "snd_pcm_new[%u] failed: %d\n", 421 vpcm->nid, rc); 422 return rc; 423 } 424 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; 432 433 for (i = 0; i < ARRAY_SIZE(vpcm->streams); ++i) { 434 struct virtio_pcm_stream *stream = &vpcm->streams[i]; 435 436 if (!stream->nsubstreams) 437 continue; 438 439 stream->substreams = 440 devm_kcalloc(&vdev->dev, stream->nsubstreams, 441 sizeof(*stream->substreams), 442 GFP_KERNEL); 443 if (!stream->substreams) 444 return -ENOMEM; 445 446 stream->nsubstreams = 0; 447 } 448 } 449 450 for (i = 0; i < snd->nsubstreams; ++i) { 451 struct virtio_pcm_stream *vs; 452 struct virtio_pcm_substream *vss = &snd->substreams[i]; 453 454 vpcm = virtsnd_pcm_find(snd, vss->nid); 455 if (IS_ERR(vpcm)) 456 return PTR_ERR(vpcm); 457 458 vs = &vpcm->streams[vss->direction]; 459 vs->substreams[vs->nsubstreams++] = vss; 460 } 461 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; 467 468 if (!vs->nsubstreams) 469 continue; 470 471 for (kss = ks->substream; kss; kss = kss->next) 472 vs->substreams[kss->number]->substream = kss; 473 474 snd_pcm_set_ops(vpcm->pcm, i, &virtsnd_pcm_ops); 475 } 476 477 snd_pcm_set_managed_buffer_all(vpcm->pcm, 478 SNDRV_DMA_TYPE_VMALLOC, NULL, 479 0, 0); 480 } 481 482 return 0; 483} 484 485/** 486 * virtsnd_pcm_event() - Handle the PCM device event notification. 487 * @snd: VirtIO sound device. 488 * @event: VirtIO sound event. 489 * 490 * Context: Interrupt context. 491 */ 492void virtsnd_pcm_event(struct virtio_snd *snd, struct virtio_snd_event *event) 493{ 494 struct virtio_pcm_substream *vss; 495 u32 sid = le32_to_cpu(event->data); 496 497 if (sid >= snd->nsubstreams) 498 return; 499 500 vss = &snd->substreams[sid]; 501 502 switch (le32_to_cpu(event->hdr.code)) { 503 case VIRTIO_SND_EVT_PCM_PERIOD_ELAPSED: 504 /* TODO: deal with shmem elapsed period */ 505 break; 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); 511 break; 512 } 513}