virtio_kctl.c 13 KB

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