Lines Matching +full:max +full:- +full:msg +full:- +full:size
1 // SPDX-License-Identifier: GPL-2.0+
3 * virtio-snd: Virtio sound device
40 * virtsnd_kctl_info() - Returns information about the control.
45 * Return: 0 on success, -errno on failure.
50 struct virtio_snd *snd = kcontrol->private_data; in virtsnd_kctl_info()
51 struct virtio_kctl *kctl = &snd->kctls[kcontrol->private_value]; in virtsnd_kctl_info()
53 &snd->kctl_infos[kcontrol->private_value]; in virtsnd_kctl_info()
56 uinfo->type = g_v2a_type_map[le32_to_cpu(kinfo->type)]; in virtsnd_kctl_info()
57 uinfo->count = le32_to_cpu(kinfo->count); in virtsnd_kctl_info()
59 switch (uinfo->type) { in virtsnd_kctl_info()
61 uinfo->value.integer.min = in virtsnd_kctl_info()
62 le32_to_cpu(kinfo->value.integer.min); in virtsnd_kctl_info()
63 uinfo->value.integer.max = in virtsnd_kctl_info()
64 le32_to_cpu(kinfo->value.integer.max); in virtsnd_kctl_info()
65 uinfo->value.integer.step = in virtsnd_kctl_info()
66 le32_to_cpu(kinfo->value.integer.step); in virtsnd_kctl_info()
70 uinfo->value.integer64.min = in virtsnd_kctl_info()
71 le64_to_cpu(kinfo->value.integer64.min); in virtsnd_kctl_info()
72 uinfo->value.integer64.max = in virtsnd_kctl_info()
73 le64_to_cpu(kinfo->value.integer64.max); in virtsnd_kctl_info()
74 uinfo->value.integer64.step = in virtsnd_kctl_info()
75 le64_to_cpu(kinfo->value.integer64.step); in virtsnd_kctl_info()
79 uinfo->value.enumerated.items = in virtsnd_kctl_info()
80 le32_to_cpu(kinfo->value.enumerated.items); in virtsnd_kctl_info()
81 i = uinfo->value.enumerated.item; in virtsnd_kctl_info()
82 if (i >= uinfo->value.enumerated.items) in virtsnd_kctl_info()
83 return -EINVAL; in virtsnd_kctl_info()
85 strscpy(uinfo->value.enumerated.name, kctl->items[i].item, in virtsnd_kctl_info()
86 sizeof(uinfo->value.enumerated.name)); in virtsnd_kctl_info()
95 * virtsnd_kctl_get() - Read the value from the control.
100 * Return: 0 on success, -errno on failure.
105 struct virtio_snd *snd = kcontrol->private_data; in virtsnd_kctl_get()
107 &snd->kctl_infos[kcontrol->private_value]; in virtsnd_kctl_get()
108 unsigned int type = le32_to_cpu(kinfo->type); in virtsnd_kctl_get()
109 unsigned int count = le32_to_cpu(kinfo->count); in virtsnd_kctl_get()
110 struct virtio_snd_msg *msg; in virtsnd_kctl_get() local
118 msg = virtsnd_ctl_msg_alloc(request_size, response_size, GFP_KERNEL); in virtsnd_kctl_get()
119 if (!msg) in virtsnd_kctl_get()
120 return -ENOMEM; in virtsnd_kctl_get()
122 virtsnd_ctl_msg_ref(msg); in virtsnd_kctl_get()
124 hdr = virtsnd_ctl_msg_request(msg); in virtsnd_kctl_get()
125 hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_READ); in virtsnd_kctl_get()
126 hdr->control_id = cpu_to_le32(kcontrol->private_value); in virtsnd_kctl_get()
128 rc = virtsnd_ctl_msg_send_sync(snd, msg); in virtsnd_kctl_get()
132 kvalue = (void *)((u8 *)virtsnd_ctl_msg_response(msg) + in virtsnd_kctl_get()
139 uvalue->value.integer.value[i] = in virtsnd_kctl_get()
140 le32_to_cpu(kvalue->value.integer[i]); in virtsnd_kctl_get()
144 uvalue->value.integer64.value[i] = in virtsnd_kctl_get()
145 le64_to_cpu(kvalue->value.integer64[i]); in virtsnd_kctl_get()
149 uvalue->value.enumerated.item[i] = in virtsnd_kctl_get()
150 le32_to_cpu(kvalue->value.enumerated[i]); in virtsnd_kctl_get()
153 memcpy(uvalue->value.bytes.data, kvalue->value.bytes, count); in virtsnd_kctl_get()
156 memcpy(&uvalue->value.iec958, &kvalue->value.iec958, in virtsnd_kctl_get()
157 sizeof(uvalue->value.iec958)); in virtsnd_kctl_get()
162 virtsnd_ctl_msg_unref(msg); in virtsnd_kctl_get()
168 * virtsnd_kctl_put() - Write the value to the control.
173 * Return: 0 on success, -errno on failure.
178 struct virtio_snd *snd = kcontrol->private_data; in virtsnd_kctl_put()
180 &snd->kctl_infos[kcontrol->private_value]; in virtsnd_kctl_put()
181 unsigned int type = le32_to_cpu(kinfo->type); in virtsnd_kctl_put()
182 unsigned int count = le32_to_cpu(kinfo->count); in virtsnd_kctl_put()
183 struct virtio_snd_msg *msg; in virtsnd_kctl_put() local
190 msg = virtsnd_ctl_msg_alloc(request_size, response_size, GFP_KERNEL); in virtsnd_kctl_put()
191 if (!msg) in virtsnd_kctl_put()
192 return -ENOMEM; in virtsnd_kctl_put()
194 hdr = virtsnd_ctl_msg_request(msg); in virtsnd_kctl_put()
195 hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_WRITE); in virtsnd_kctl_put()
196 hdr->control_id = cpu_to_le32(kcontrol->private_value); in virtsnd_kctl_put()
204 kvalue->value.integer[i] = in virtsnd_kctl_put()
205 cpu_to_le32(uvalue->value.integer.value[i]); in virtsnd_kctl_put()
209 kvalue->value.integer64[i] = in virtsnd_kctl_put()
210 cpu_to_le64(uvalue->value.integer64.value[i]); in virtsnd_kctl_put()
214 kvalue->value.enumerated[i] = in virtsnd_kctl_put()
215 cpu_to_le32(uvalue->value.enumerated.item[i]); in virtsnd_kctl_put()
218 memcpy(kvalue->value.bytes, uvalue->value.bytes.data, count); in virtsnd_kctl_put()
221 memcpy(&kvalue->value.iec958, &uvalue->value.iec958, in virtsnd_kctl_put()
222 sizeof(kvalue->value.iec958)); in virtsnd_kctl_put()
226 return virtsnd_ctl_msg_send_sync(snd, msg); in virtsnd_kctl_put()
230 * virtsnd_kctl_tlv_op() - Perform an operation on the control's metadata.
233 * @size: Size of the TLV data in bytes.
237 * Return: 0 on success, -errno on failure.
240 unsigned int size, unsigned int __user *utlv) in virtsnd_kctl_tlv_op() argument
242 struct virtio_snd *snd = kcontrol->private_data; in virtsnd_kctl_tlv_op()
243 struct virtio_snd_msg *msg; in virtsnd_kctl_tlv_op() local
249 msg = virtsnd_ctl_msg_alloc(sizeof(*hdr), sizeof(struct virtio_snd_hdr), in virtsnd_kctl_tlv_op()
251 if (!msg) in virtsnd_kctl_tlv_op()
252 return -ENOMEM; in virtsnd_kctl_tlv_op()
254 tlv = kzalloc(size, GFP_KERNEL); in virtsnd_kctl_tlv_op()
256 rc = -ENOMEM; in virtsnd_kctl_tlv_op()
260 sg_init_one(&sg, tlv, size); in virtsnd_kctl_tlv_op()
262 hdr = virtsnd_ctl_msg_request(msg); in virtsnd_kctl_tlv_op()
263 hdr->control_id = cpu_to_le32(kcontrol->private_value); in virtsnd_kctl_tlv_op()
267 hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_TLV_READ); in virtsnd_kctl_tlv_op()
269 rc = virtsnd_ctl_msg_send(snd, msg, NULL, &sg, false); in virtsnd_kctl_tlv_op()
271 if (copy_to_user(utlv, tlv, size)) in virtsnd_kctl_tlv_op()
272 rc = -EFAULT; in virtsnd_kctl_tlv_op()
279 hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_TLV_WRITE); in virtsnd_kctl_tlv_op()
281 hdr->hdr.code = in virtsnd_kctl_tlv_op()
284 if (copy_from_user(tlv, utlv, size)) { in virtsnd_kctl_tlv_op()
285 rc = -EFAULT; in virtsnd_kctl_tlv_op()
288 rc = virtsnd_ctl_msg_send(snd, msg, &sg, NULL, false); in virtsnd_kctl_tlv_op()
293 rc = -EINVAL; in virtsnd_kctl_tlv_op()
294 /* We never get here - we listed all values for op_flag */ in virtsnd_kctl_tlv_op()
302 virtsnd_ctl_msg_unref(msg); in virtsnd_kctl_tlv_op()
309 * virtsnd_kctl_get_enum_items() - Query items for the ENUMERATED element type.
316 * Return: 0 on success, -errno on failure.
320 struct virtio_device *vdev = snd->vdev; in virtsnd_kctl_get_enum_items()
321 struct virtio_snd_ctl_info *kinfo = &snd->kctl_infos[cid]; in virtsnd_kctl_get_enum_items()
322 struct virtio_kctl *kctl = &snd->kctls[cid]; in virtsnd_kctl_get_enum_items()
323 struct virtio_snd_msg *msg; in virtsnd_kctl_get_enum_items() local
325 unsigned int n = le32_to_cpu(kinfo->value.enumerated.items); in virtsnd_kctl_get_enum_items()
328 msg = virtsnd_ctl_msg_alloc(sizeof(*hdr), in virtsnd_kctl_get_enum_items()
330 if (!msg) in virtsnd_kctl_get_enum_items()
331 return -ENOMEM; in virtsnd_kctl_get_enum_items()
333 kctl->items = devm_kcalloc(&vdev->dev, n, sizeof(*kctl->items), in virtsnd_kctl_get_enum_items()
335 if (!kctl->items) { in virtsnd_kctl_get_enum_items()
336 virtsnd_ctl_msg_unref(msg); in virtsnd_kctl_get_enum_items()
337 return -ENOMEM; in virtsnd_kctl_get_enum_items()
340 sg_init_one(&sg, kctl->items, n * sizeof(*kctl->items)); in virtsnd_kctl_get_enum_items()
342 hdr = virtsnd_ctl_msg_request(msg); in virtsnd_kctl_get_enum_items()
343 hdr->hdr.code = cpu_to_le32(VIRTIO_SND_R_CTL_ENUM_ITEMS); in virtsnd_kctl_get_enum_items()
344 hdr->control_id = cpu_to_le32(cid); in virtsnd_kctl_get_enum_items()
346 return virtsnd_ctl_msg_send(snd, msg, NULL, &sg, false); in virtsnd_kctl_get_enum_items()
350 * virtsnd_kctl_parse_cfg() - Parse the control element configuration.
356 * Return: 0 on success, -errno on failure.
360 struct virtio_device *vdev = snd->vdev; in virtsnd_kctl_parse_cfg()
365 &snd->nkctls); in virtsnd_kctl_parse_cfg()
366 if (!snd->nkctls) in virtsnd_kctl_parse_cfg()
369 snd->kctl_infos = devm_kcalloc(&vdev->dev, snd->nkctls, in virtsnd_kctl_parse_cfg()
370 sizeof(*snd->kctl_infos), GFP_KERNEL); in virtsnd_kctl_parse_cfg()
371 if (!snd->kctl_infos) in virtsnd_kctl_parse_cfg()
372 return -ENOMEM; in virtsnd_kctl_parse_cfg()
374 snd->kctls = devm_kcalloc(&vdev->dev, snd->nkctls, sizeof(*snd->kctls), in virtsnd_kctl_parse_cfg()
376 if (!snd->kctls) in virtsnd_kctl_parse_cfg()
377 return -ENOMEM; in virtsnd_kctl_parse_cfg()
379 rc = virtsnd_ctl_query_info(snd, VIRTIO_SND_R_CTL_INFO, 0, snd->nkctls, in virtsnd_kctl_parse_cfg()
380 sizeof(*snd->kctl_infos), snd->kctl_infos); in virtsnd_kctl_parse_cfg()
384 for (i = 0; i < snd->nkctls; ++i) { in virtsnd_kctl_parse_cfg()
385 struct virtio_snd_ctl_info *kinfo = &snd->kctl_infos[i]; in virtsnd_kctl_parse_cfg()
386 unsigned int type = le32_to_cpu(kinfo->type); in virtsnd_kctl_parse_cfg()
399 * virtsnd_kctl_build_devs() - Build ALSA control elements.
403 * Return: 0 on success, -errno on failure.
409 for (cid = 0; cid < snd->nkctls; ++cid) { in virtsnd_kctl_build_devs()
410 struct virtio_snd_ctl_info *kinfo = &snd->kctl_infos[cid]; in virtsnd_kctl_build_devs()
411 struct virtio_kctl *kctl = &snd->kctls[cid]; in virtsnd_kctl_build_devs()
419 kctl_new.name = kinfo->name; in virtsnd_kctl_build_devs()
420 kctl_new.index = le32_to_cpu(kinfo->index); in virtsnd_kctl_build_devs()
423 if (le32_to_cpu(kinfo->access) & (1 << i)) in virtsnd_kctl_build_devs()
438 kctl->kctl = snd_ctl_new1(&kctl_new, snd); in virtsnd_kctl_build_devs()
439 if (!kctl->kctl) in virtsnd_kctl_build_devs()
440 return -ENOMEM; in virtsnd_kctl_build_devs()
442 rc = snd_ctl_add(snd->card, kctl->kctl); in virtsnd_kctl_build_devs()
451 * virtsnd_kctl_event() - Handle the control element event notification.
462 unsigned int cid = le16_to_cpu(kevent->control_id); in virtsnd_kctl_event()
466 if (cid >= snd->nkctls) in virtsnd_kctl_event()
470 if (le16_to_cpu(kevent->mask) & (1 << i)) in virtsnd_kctl_event()
474 kctl = &snd->kctls[cid]; in virtsnd_kctl_event()
476 snd_ctl_notify(snd->card, mask, &kctl->kctl->id); in virtsnd_kctl_event()