Lines Matching +full:per +full:- +full:context

1 // SPDX-License-Identifier: GPL-2.0+
3 * virtio-snd: Virtio sound device
10 /* VirtIO->ALSA channel position map */
52 * virtsnd_chmap_parse_cfg() - Parse the channel map configuration.
57 * Context: Any context that permits to sleep.
58 * Return: 0 on success, -errno on failure.
62 struct virtio_device *vdev = snd->vdev; in virtsnd_chmap_parse_cfg()
66 virtio_cread_le(vdev, struct virtio_snd_config, chmaps, &snd->nchmaps); in virtsnd_chmap_parse_cfg()
67 if (!snd->nchmaps) in virtsnd_chmap_parse_cfg()
70 snd->chmaps = devm_kcalloc(&vdev->dev, snd->nchmaps, in virtsnd_chmap_parse_cfg()
71 sizeof(*snd->chmaps), GFP_KERNEL); in virtsnd_chmap_parse_cfg()
72 if (!snd->chmaps) in virtsnd_chmap_parse_cfg()
73 return -ENOMEM; in virtsnd_chmap_parse_cfg()
76 snd->nchmaps, sizeof(*snd->chmaps), in virtsnd_chmap_parse_cfg()
77 snd->chmaps); in virtsnd_chmap_parse_cfg()
81 /* Count the number of channel maps per each PCM device/stream. */ in virtsnd_chmap_parse_cfg()
82 for (i = 0; i < snd->nchmaps; ++i) { in virtsnd_chmap_parse_cfg()
83 struct virtio_snd_chmap_info *info = &snd->chmaps[i]; in virtsnd_chmap_parse_cfg()
84 u32 nid = le32_to_cpu(info->hdr.hda_fn_nid); in virtsnd_chmap_parse_cfg()
92 switch (info->direction) { in virtsnd_chmap_parse_cfg()
94 vs = &vpcm->streams[SNDRV_PCM_STREAM_PLAYBACK]; in virtsnd_chmap_parse_cfg()
97 vs = &vpcm->streams[SNDRV_PCM_STREAM_CAPTURE]; in virtsnd_chmap_parse_cfg()
100 dev_err(&vdev->dev, in virtsnd_chmap_parse_cfg()
102 info->direction); in virtsnd_chmap_parse_cfg()
103 return -EINVAL; in virtsnd_chmap_parse_cfg()
106 vs->nchmaps++; in virtsnd_chmap_parse_cfg()
113 * virtsnd_chmap_add_ctls() - Create an ALSA control for channel maps.
118 * Context: Any context.
119 * Return: 0 on success, -errno on failure.
127 for (i = 0; i < vs->nchmaps; i++) in virtsnd_chmap_add_ctls()
128 if (max_channels < vs->chmaps[i].channels) in virtsnd_chmap_add_ctls()
129 max_channels = vs->chmaps[i].channels; in virtsnd_chmap_add_ctls()
131 return snd_pcm_add_chmap_ctls(pcm, direction, vs->chmaps, max_channels, in virtsnd_chmap_add_ctls()
136 * virtsnd_chmap_build_devs() - Build ALSA controls for channel maps.
139 * Context: Any context.
140 * Return: 0 on success, -errno on failure.
144 struct virtio_device *vdev = snd->vdev; in virtsnd_chmap_build_devs()
150 /* Allocate channel map elements per each PCM device/stream. */ in virtsnd_chmap_build_devs()
151 list_for_each_entry(vpcm, &snd->pcm_list, list) { in virtsnd_chmap_build_devs()
152 for (i = 0; i < ARRAY_SIZE(vpcm->streams); ++i) { in virtsnd_chmap_build_devs()
153 vs = &vpcm->streams[i]; in virtsnd_chmap_build_devs()
155 if (!vs->nchmaps) in virtsnd_chmap_build_devs()
158 vs->chmaps = devm_kcalloc(&vdev->dev, vs->nchmaps + 1, in virtsnd_chmap_build_devs()
159 sizeof(*vs->chmaps), in virtsnd_chmap_build_devs()
161 if (!vs->chmaps) in virtsnd_chmap_build_devs()
162 return -ENOMEM; in virtsnd_chmap_build_devs()
164 vs->nchmaps = 0; in virtsnd_chmap_build_devs()
168 /* Initialize channel maps per each PCM device/stream. */ in virtsnd_chmap_build_devs()
169 for (i = 0; i < snd->nchmaps; ++i) { in virtsnd_chmap_build_devs()
170 struct virtio_snd_chmap_info *info = &snd->chmaps[i]; in virtsnd_chmap_build_devs()
171 unsigned int channels = info->channels; in virtsnd_chmap_build_devs()
175 vpcm = virtsnd_pcm_find(snd, le32_to_cpu(info->hdr.hda_fn_nid)); in virtsnd_chmap_build_devs()
179 if (info->direction == VIRTIO_SND_D_OUTPUT) in virtsnd_chmap_build_devs()
180 vs = &vpcm->streams[SNDRV_PCM_STREAM_PLAYBACK]; in virtsnd_chmap_build_devs()
182 vs = &vpcm->streams[SNDRV_PCM_STREAM_CAPTURE]; in virtsnd_chmap_build_devs()
184 chmap = &vs->chmaps[vs->nchmaps++]; in virtsnd_chmap_build_devs()
186 if (channels > ARRAY_SIZE(chmap->map)) in virtsnd_chmap_build_devs()
187 channels = ARRAY_SIZE(chmap->map); in virtsnd_chmap_build_devs()
189 chmap->channels = channels; in virtsnd_chmap_build_devs()
192 u8 position = info->positions[ch]; in virtsnd_chmap_build_devs()
195 return -EINVAL; in virtsnd_chmap_build_devs()
197 chmap->map[ch] = g_v2a_position_map[position]; in virtsnd_chmap_build_devs()
201 /* Create an ALSA control per each PCM device/stream. */ in virtsnd_chmap_build_devs()
202 list_for_each_entry(vpcm, &snd->pcm_list, list) { in virtsnd_chmap_build_devs()
203 if (!vpcm->pcm) in virtsnd_chmap_build_devs()
206 for (i = 0; i < ARRAY_SIZE(vpcm->streams); ++i) { in virtsnd_chmap_build_devs()
207 vs = &vpcm->streams[i]; in virtsnd_chmap_build_devs()
209 if (!vs->nchmaps) in virtsnd_chmap_build_devs()
212 rc = virtsnd_chmap_add_ctls(vpcm->pcm, i, vs); in virtsnd_chmap_build_devs()