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