1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * virtio-snd: Virtio sound device 4 * Copyright (C) 2022 OpenSynergy GmbH 5 */ 6 #include <sound/control.h> 7 #include <linux/virtio_config.h> 8 9 #include "virtio_card.h" 10 11 /* Map for converting VirtIO types to ALSA types. */ 12 static const snd_ctl_elem_type_t g_v2a_type_map[] = { 13 [VIRTIO_SND_CTL_TYPE_BOOLEAN] = SNDRV_CTL_ELEM_TYPE_BOOLEAN, 14 [VIRTIO_SND_CTL_TYPE_INTEGER] = SNDRV_CTL_ELEM_TYPE_INTEGER, 15 [VIRTIO_SND_CTL_TYPE_INTEGER64] = SNDRV_CTL_ELEM_TYPE_INTEGER64, 16 [VIRTIO_SND_CTL_TYPE_ENUMERATED] = SNDRV_CTL_ELEM_TYPE_ENUMERATED, 17 [VIRTIO_SND_CTL_TYPE_BYTES] = SNDRV_CTL_ELEM_TYPE_BYTES, 18 [VIRTIO_SND_CTL_TYPE_IEC958] = SNDRV_CTL_ELEM_TYPE_IEC958 19 }; 20 21 /* Map for converting VirtIO access rights to ALSA access rights. */ 22 static const unsigned int g_v2a_access_map[] = { 23 [VIRTIO_SND_CTL_ACCESS_READ] = SNDRV_CTL_ELEM_ACCESS_READ, 24 [VIRTIO_SND_CTL_ACCESS_WRITE] = SNDRV_CTL_ELEM_ACCESS_WRITE, 25 [VIRTIO_SND_CTL_ACCESS_VOLATILE] = SNDRV_CTL_ELEM_ACCESS_VOLATILE, 26 [VIRTIO_SND_CTL_ACCESS_INACTIVE] = SNDRV_CTL_ELEM_ACCESS_INACTIVE, 27 [VIRTIO_SND_CTL_ACCESS_TLV_READ] = SNDRV_CTL_ELEM_ACCESS_TLV_READ, 28 [VIRTIO_SND_CTL_ACCESS_TLV_WRITE] = SNDRV_CTL_ELEM_ACCESS_TLV_WRITE, 29 [VIRTIO_SND_CTL_ACCESS_TLV_COMMAND] = SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND 30 }; 31 32 /* Map for converting VirtIO event masks to ALSA event masks. */ 33 static const unsigned int g_v2a_mask_map[] = { 34 [VIRTIO_SND_CTL_EVT_MASK_VALUE] = SNDRV_CTL_EVENT_MASK_VALUE, 35 [VIRTIO_SND_CTL_EVT_MASK_INFO] = SNDRV_CTL_EVENT_MASK_INFO, 36 [VIRTIO_SND_CTL_EVT_MASK_TLV] = SNDRV_CTL_EVENT_MASK_TLV 37 }; 38 39 /** 40 * virtsnd_kctl_info() - Returns information about the control. 41 * @kcontrol: ALSA control element. 42 * @uinfo: Element information. 43 * 44 * Context: Process context. 45 * Return: 0 on success, -errno on failure. 46 */ 47 static int virtsnd_kctl_info(struct snd_kcontrol *kcontrol, 48 struct snd_ctl_elem_info *uinfo) 49 { 50 struct virtio_snd *snd = kcontrol->private_data; 51 struct virtio_kctl *kctl = &snd->kctls[kcontrol->private_value]; 52 struct virtio_snd_ctl_info *kinfo = 53 &snd->kctl_infos[kcontrol->private_value]; 54 unsigned int i; 55 56 uinfo->type = g_v2a_type_map[le32_to_cpu(kinfo->type)]; 57 uinfo->count = le32_to_cpu(kinfo->count); 58 59 switch (uinfo->type) { 60 case SNDRV_CTL_ELEM_TYPE_INTEGER: 61 uinfo->value.integer.min = 62 le32_to_cpu(kinfo->value.integer.min); 63 uinfo->value.integer.max = 64 le32_to_cpu(kinfo->value.integer.max); 65 uinfo->value.integer.step = 66 le32_to_cpu(kinfo->value.integer.step); 67 68 break; 69 case SNDRV_CTL_ELEM_TYPE_INTEGER64: 70 uinfo->value.integer64.min = 71 le64_to_cpu(kinfo->value.integer64.min); 72 uinfo->value.integer64.max = 73 le64_to_cpu(kinfo->value.integer64.max); 74 uinfo->value.integer64.step = 75 le64_to_cpu(kinfo->value.integer64.step); 76 77 break; 78 case SNDRV_CTL_ELEM_TYPE_ENUMERATED: 79 uinfo->value.enumerated.items = 80 le32_to_cpu(kinfo->value.enumerated.items); 81 i = uinfo->value.enumerated.item; 82 if (i >= uinfo->value.enumerated.items) 83 return -EINVAL; 84 85 strscpy(uinfo->value.enumerated.name, kctl->items[i].item, 86 sizeof(uinfo->value.enumerated.name)); 87 88 break; 89 } 90 91 return 0; 92 } 93 94 /** 95 * virtsnd_kctl_get() - Read the value from the control. 96 * @kcontrol: ALSA control element. 97 * @uvalue: Element value. 98 * 99 * Context: Process context. 100 * Return: 0 on success, -errno on failure. 101 */ 102 static int virtsnd_kctl_get(struct snd_kcontrol *kcontrol, 103 struct snd_ctl_elem_value *uvalue) 104 { 105 struct virtio_snd *snd = kcontrol->private_data; 106 struct virtio_snd_ctl_info *kinfo = 107 &snd->kctl_infos[kcontrol->private_value]; 108 unsigned int type = le32_to_cpu(kinfo->type); 109 unsigned int count = le32_to_cpu(kinfo->count); 110 struct virtio_snd_msg *msg; 111 struct virtio_snd_ctl_hdr *hdr; 112 struct virtio_snd_ctl_value *kvalue; 113 size_t request_size = sizeof(*hdr); 114 size_t response_size = sizeof(struct virtio_snd_hdr) + sizeof(*kvalue); 115 unsigned int i; 116 int rc; 117 118 msg = virtsnd_ctl_msg_alloc(request_size, response_size, GFP_KERNEL); 119 if (!msg) 120 return -ENOMEM; 121 122 virtsnd_ctl_msg_ref(msg); 123 124 hdr = virtsnd_ctl_msg_request(msg); 125 hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_READ); 126 hdr->control_id = cpu_to_le32(kcontrol->private_value); 127 128 rc = virtsnd_ctl_msg_send_sync(snd, msg); 129 if (rc) 130 goto on_failure; 131 132 kvalue = (void *)((u8 *)virtsnd_ctl_msg_response(msg) + 133 sizeof(struct virtio_snd_hdr)); 134 135 switch (type) { 136 case VIRTIO_SND_CTL_TYPE_BOOLEAN: 137 case VIRTIO_SND_CTL_TYPE_INTEGER: 138 for (i = 0; i < count; ++i) 139 uvalue->value.integer.value[i] = 140 le32_to_cpu(kvalue->value.integer[i]); 141 break; 142 case VIRTIO_SND_CTL_TYPE_INTEGER64: 143 for (i = 0; i < count; ++i) 144 uvalue->value.integer64.value[i] = 145 le64_to_cpu(kvalue->value.integer64[i]); 146 break; 147 case VIRTIO_SND_CTL_TYPE_ENUMERATED: 148 for (i = 0; i < count; ++i) 149 uvalue->value.enumerated.item[i] = 150 le32_to_cpu(kvalue->value.enumerated[i]); 151 break; 152 case VIRTIO_SND_CTL_TYPE_BYTES: 153 memcpy(uvalue->value.bytes.data, kvalue->value.bytes, count); 154 break; 155 case VIRTIO_SND_CTL_TYPE_IEC958: 156 memcpy(&uvalue->value.iec958, &kvalue->value.iec958, 157 sizeof(uvalue->value.iec958)); 158 break; 159 } 160 161 on_failure: 162 virtsnd_ctl_msg_unref(msg); 163 164 return rc; 165 } 166 167 /** 168 * virtsnd_kctl_put() - Write the value to the control. 169 * @kcontrol: ALSA control element. 170 * @uvalue: Element value. 171 * 172 * Context: Process context. 173 * Return: 0 on success, -errno on failure. 174 */ 175 static int virtsnd_kctl_put(struct snd_kcontrol *kcontrol, 176 struct snd_ctl_elem_value *uvalue) 177 { 178 struct virtio_snd *snd = kcontrol->private_data; 179 struct virtio_snd_ctl_info *kinfo = 180 &snd->kctl_infos[kcontrol->private_value]; 181 unsigned int type = le32_to_cpu(kinfo->type); 182 unsigned int count = le32_to_cpu(kinfo->count); 183 struct virtio_snd_msg *msg; 184 struct virtio_snd_ctl_hdr *hdr; 185 struct virtio_snd_ctl_value *kvalue; 186 size_t request_size = sizeof(*hdr) + sizeof(*kvalue); 187 size_t response_size = sizeof(struct virtio_snd_hdr); 188 unsigned int i; 189 190 msg = virtsnd_ctl_msg_alloc(request_size, response_size, GFP_KERNEL); 191 if (!msg) 192 return -ENOMEM; 193 194 hdr = virtsnd_ctl_msg_request(msg); 195 hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_WRITE); 196 hdr->control_id = cpu_to_le32(kcontrol->private_value); 197 198 kvalue = (void *)((u8 *)hdr + sizeof(*hdr)); 199 200 switch (type) { 201 case VIRTIO_SND_CTL_TYPE_BOOLEAN: 202 case VIRTIO_SND_CTL_TYPE_INTEGER: 203 for (i = 0; i < count; ++i) 204 kvalue->value.integer[i] = 205 cpu_to_le32(uvalue->value.integer.value[i]); 206 break; 207 case VIRTIO_SND_CTL_TYPE_INTEGER64: 208 for (i = 0; i < count; ++i) 209 kvalue->value.integer64[i] = 210 cpu_to_le64(uvalue->value.integer64.value[i]); 211 break; 212 case VIRTIO_SND_CTL_TYPE_ENUMERATED: 213 for (i = 0; i < count; ++i) 214 kvalue->value.enumerated[i] = 215 cpu_to_le32(uvalue->value.enumerated.item[i]); 216 break; 217 case VIRTIO_SND_CTL_TYPE_BYTES: 218 memcpy(kvalue->value.bytes, uvalue->value.bytes.data, count); 219 break; 220 case VIRTIO_SND_CTL_TYPE_IEC958: 221 memcpy(&kvalue->value.iec958, &uvalue->value.iec958, 222 sizeof(kvalue->value.iec958)); 223 break; 224 } 225 226 return virtsnd_ctl_msg_send_sync(snd, msg); 227 } 228 229 /** 230 * virtsnd_kctl_tlv_op() - Perform an operation on the control's metadata. 231 * @kcontrol: ALSA control element. 232 * @op_flag: Operation code (SNDRV_CTL_TLV_OP_XXX). 233 * @size: Size of the TLV data in bytes. 234 * @utlv: TLV data. 235 * 236 * Context: Process context. 237 * Return: 0 on success, -errno on failure. 238 */ 239 static int virtsnd_kctl_tlv_op(struct snd_kcontrol *kcontrol, int op_flag, 240 unsigned int size, unsigned int __user *utlv) 241 { 242 struct virtio_snd *snd = kcontrol->private_data; 243 struct virtio_snd_msg *msg; 244 struct virtio_snd_ctl_hdr *hdr; 245 unsigned int *tlv; 246 struct scatterlist sg; 247 int rc; 248 249 msg = virtsnd_ctl_msg_alloc(sizeof(*hdr), sizeof(struct virtio_snd_hdr), 250 GFP_KERNEL); 251 if (!msg) 252 return -ENOMEM; 253 254 tlv = kzalloc(size, GFP_KERNEL); 255 if (!tlv) { 256 virtsnd_ctl_msg_unref(msg); 257 return -ENOMEM; 258 } 259 260 sg_init_one(&sg, tlv, size); 261 262 hdr = virtsnd_ctl_msg_request(msg); 263 hdr->control_id = cpu_to_le32(kcontrol->private_value); 264 265 switch (op_flag) { 266 case SNDRV_CTL_TLV_OP_READ: 267 hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_TLV_READ); 268 269 rc = virtsnd_ctl_msg_send(snd, msg, NULL, &sg, false); 270 if (!rc) { 271 if (copy_to_user(utlv, tlv, size)) 272 rc = -EFAULT; 273 } 274 275 break; 276 case SNDRV_CTL_TLV_OP_WRITE: 277 case SNDRV_CTL_TLV_OP_CMD: 278 if (op_flag == SNDRV_CTL_TLV_OP_WRITE) 279 hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_TLV_WRITE); 280 else 281 hdr->hdr.code = 282 cpu_to_le32(VIRTIO_SND_R_CTL_TLV_COMMAND); 283 284 if (copy_from_user(tlv, utlv, size)) 285 rc = -EFAULT; 286 else 287 rc = virtsnd_ctl_msg_send(snd, msg, &sg, NULL, false); 288 289 break; 290 } 291 292 kfree(tlv); 293 294 return rc; 295 } 296 297 /** 298 * virtsnd_kctl_get_enum_items() - Query items for the ENUMERATED element type. 299 * @snd: VirtIO sound device. 300 * @cid: Control element ID. 301 * 302 * This function is called during initial device initialization. 303 * 304 * Context: Any context that permits to sleep. 305 * Return: 0 on success, -errno on failure. 306 */ 307 static int virtsnd_kctl_get_enum_items(struct virtio_snd *snd, unsigned int cid) 308 { 309 struct virtio_device *vdev = snd->vdev; 310 struct virtio_snd_ctl_info *kinfo = &snd->kctl_infos[cid]; 311 struct virtio_kctl *kctl = &snd->kctls[cid]; 312 struct virtio_snd_msg *msg; 313 struct virtio_snd_ctl_hdr *hdr; 314 unsigned int n = le32_to_cpu(kinfo->value.enumerated.items); 315 struct scatterlist sg; 316 317 msg = virtsnd_ctl_msg_alloc(sizeof(*hdr), 318 sizeof(struct virtio_snd_hdr), GFP_KERNEL); 319 if (!msg) 320 return -ENOMEM; 321 322 kctl->items = devm_kcalloc(&vdev->dev, n, sizeof(*kctl->items), 323 GFP_KERNEL); 324 if (!kctl->items) { 325 virtsnd_ctl_msg_unref(msg); 326 return -ENOMEM; 327 } 328 329 sg_init_one(&sg, kctl->items, n * sizeof(*kctl->items)); 330 331 hdr = virtsnd_ctl_msg_request(msg); 332 hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_ENUM_ITEMS); 333 hdr->control_id = cpu_to_le32(cid); 334 335 return virtsnd_ctl_msg_send(snd, msg, NULL, &sg, false); 336 } 337 338 /** 339 * virtsnd_kctl_parse_cfg() - Parse the control element configuration. 340 * @snd: VirtIO sound device. 341 * 342 * This function is called during initial device initialization. 343 * 344 * Context: Any context that permits to sleep. 345 * Return: 0 on success, -errno on failure. 346 */ 347 int virtsnd_kctl_parse_cfg(struct virtio_snd *snd) 348 { 349 struct virtio_device *vdev = snd->vdev; 350 u32 i; 351 int rc; 352 353 virtio_cread_le(vdev, struct virtio_snd_config, controls, 354 &snd->nkctls); 355 if (!snd->nkctls) 356 return 0; 357 358 snd->kctl_infos = devm_kcalloc(&vdev->dev, snd->nkctls, 359 sizeof(*snd->kctl_infos), GFP_KERNEL); 360 if (!snd->kctl_infos) 361 return -ENOMEM; 362 363 snd->kctls = devm_kcalloc(&vdev->dev, snd->nkctls, sizeof(*snd->kctls), 364 GFP_KERNEL); 365 if (!snd->kctls) 366 return -ENOMEM; 367 368 rc = virtsnd_ctl_query_info(snd, VIRTIO_SND_R_CTL_INFO, 0, snd->nkctls, 369 sizeof(*snd->kctl_infos), snd->kctl_infos); 370 if (rc) 371 return rc; 372 373 for (i = 0; i < snd->nkctls; ++i) { 374 struct virtio_snd_ctl_info *kinfo = &snd->kctl_infos[i]; 375 unsigned int type = le32_to_cpu(kinfo->type); 376 377 if (type == VIRTIO_SND_CTL_TYPE_ENUMERATED) { 378 rc = virtsnd_kctl_get_enum_items(snd, i); 379 if (rc) 380 return rc; 381 } 382 } 383 384 return 0; 385 } 386 387 /** 388 * virtsnd_kctl_build_devs() - Build ALSA control elements. 389 * @snd: VirtIO sound device. 390 * 391 * Context: Any context that permits to sleep. 392 * Return: 0 on success, -errno on failure. 393 */ 394 int virtsnd_kctl_build_devs(struct virtio_snd *snd) 395 { 396 unsigned int cid; 397 398 for (cid = 0; cid < snd->nkctls; ++cid) { 399 struct virtio_snd_ctl_info *kinfo = &snd->kctl_infos[cid]; 400 struct virtio_kctl *kctl = &snd->kctls[cid]; 401 struct snd_kcontrol_new kctl_new; 402 unsigned int i; 403 int rc; 404 405 memset(&kctl_new, 0, sizeof(kctl_new)); 406 407 kctl_new.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 408 kctl_new.name = kinfo->name; 409 kctl_new.index = le32_to_cpu(kinfo->index); 410 411 for (i = 0; i < ARRAY_SIZE(g_v2a_access_map); ++i) 412 if (le32_to_cpu(kinfo->access) & (1 << i)) 413 kctl_new.access |= g_v2a_access_map[i]; 414 415 if (kctl_new.access & (SNDRV_CTL_ELEM_ACCESS_TLV_READ | 416 SNDRV_CTL_ELEM_ACCESS_TLV_WRITE | 417 SNDRV_CTL_ELEM_ACCESS_TLV_COMMAND)) { 418 kctl_new.access |= SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; 419 kctl_new.tlv.c = virtsnd_kctl_tlv_op; 420 } 421 422 kctl_new.info = virtsnd_kctl_info; 423 kctl_new.get = virtsnd_kctl_get; 424 kctl_new.put = virtsnd_kctl_put; 425 kctl_new.private_value = cid; 426 427 kctl->kctl = snd_ctl_new1(&kctl_new, snd); 428 if (!kctl->kctl) 429 return -ENOMEM; 430 431 rc = snd_ctl_add(snd->card, kctl->kctl); 432 if (rc) 433 return rc; 434 } 435 436 return 0; 437 } 438 439 /** 440 * virtsnd_kctl_event() - Handle the control element event notification. 441 * @snd: VirtIO sound device. 442 * @event: VirtIO sound event. 443 * 444 * Context: Interrupt context. 445 */ 446 void virtsnd_kctl_event(struct virtio_snd *snd, struct virtio_snd_event *event) 447 { 448 struct virtio_snd_ctl_event *kevent = 449 (struct virtio_snd_ctl_event *)event; 450 struct virtio_kctl *kctl; 451 unsigned int cid = le16_to_cpu(kevent->control_id); 452 unsigned int mask = 0; 453 unsigned int i; 454 455 if (cid >= snd->nkctls) 456 return; 457 458 for (i = 0; i < ARRAY_SIZE(g_v2a_mask_map); ++i) 459 if (le16_to_cpu(kevent->mask) & (1 << i)) 460 mask |= g_v2a_mask_map[i]; 461 462 463 kctl = &snd->kctls[cid]; 464 465 snd_ctl_notify(snd->card, mask, &kctl->kctl->id); 466 } 467