1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * media.c - Media Controller specific ALSA driver code 4 * 5 * Copyright (c) 2019 Shuah Khan <shuah@kernel.org> 6 * 7 */ 8 9 /* 10 * This file adds Media Controller support to the ALSA driver 11 * to use the Media Controller API to share the tuner with DVB 12 * and V4L2 drivers that control the media device. 13 * 14 * The media device is created based on the existing quirks framework. 15 * Using this approach, the media controller API usage can be added for 16 * a specific device. 17 */ 18 19 #include <linux/init.h> 20 #include <linux/list.h> 21 #include <linux/mutex.h> 22 #include <linux/slab.h> 23 #include <linux/usb.h> 24 25 #include <sound/pcm.h> 26 #include <sound/core.h> 27 28 #include "usbaudio.h" 29 #include "card.h" 30 #include "mixer.h" 31 #include "media.h" 32 33 int snd_media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm, 34 int stream) 35 { 36 struct media_device *mdev; 37 struct media_ctl *mctl; 38 struct device *pcm_dev = pcm->streams[stream].dev; 39 u32 intf_type; 40 int ret = 0; 41 u16 mixer_pad; 42 struct media_entity *entity; 43 44 mdev = subs->stream->chip->media_dev; 45 if (!mdev) 46 return 0; 47 48 if (subs->media_ctl) 49 return 0; 50 51 /* allocate media_ctl */ 52 mctl = kzalloc(sizeof(*mctl), GFP_KERNEL); 53 if (!mctl) 54 return -ENOMEM; 55 56 mctl->media_dev = mdev; 57 if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 58 intf_type = MEDIA_INTF_T_ALSA_PCM_PLAYBACK; 59 mctl->media_entity.function = MEDIA_ENT_F_AUDIO_PLAYBACK; 60 mctl->media_pad.flags = MEDIA_PAD_FL_SOURCE; 61 mixer_pad = 1; 62 } else { 63 intf_type = MEDIA_INTF_T_ALSA_PCM_CAPTURE; 64 mctl->media_entity.function = MEDIA_ENT_F_AUDIO_CAPTURE; 65 mctl->media_pad.flags = MEDIA_PAD_FL_SINK; 66 mixer_pad = 2; 67 } 68 mctl->media_entity.name = pcm->name; 69 media_entity_pads_init(&mctl->media_entity, 1, &mctl->media_pad); 70 ret = media_device_register_entity(mctl->media_dev, 71 &mctl->media_entity); 72 if (ret) 73 goto free_mctl; 74 75 mctl->intf_devnode = media_devnode_create(mdev, intf_type, 0, 76 MAJOR(pcm_dev->devt), 77 MINOR(pcm_dev->devt)); 78 if (!mctl->intf_devnode) { 79 ret = -ENOMEM; 80 goto unregister_entity; 81 } 82 mctl->intf_link = media_create_intf_link(&mctl->media_entity, 83 &mctl->intf_devnode->intf, 84 MEDIA_LNK_FL_ENABLED); 85 if (!mctl->intf_link) { 86 ret = -ENOMEM; 87 goto devnode_remove; 88 } 89 90 /* create link between mixer and audio */ 91 media_device_for_each_entity(entity, mdev) { 92 switch (entity->function) { 93 case MEDIA_ENT_F_AUDIO_MIXER: 94 ret = media_create_pad_link(entity, mixer_pad, 95 &mctl->media_entity, 0, 96 MEDIA_LNK_FL_ENABLED); 97 if (ret) 98 goto remove_intf_link; 99 break; 100 } 101 } 102 103 subs->media_ctl = mctl; 104 return 0; 105 106 remove_intf_link: 107 media_remove_intf_link(mctl->intf_link); 108 devnode_remove: 109 media_devnode_remove(mctl->intf_devnode); 110 unregister_entity: 111 media_device_unregister_entity(&mctl->media_entity); 112 free_mctl: 113 kfree(mctl); 114 return ret; 115 } 116 117 void snd_media_stream_delete(struct snd_usb_substream *subs) 118 { 119 struct media_ctl *mctl = subs->media_ctl; 120 121 if (mctl) { 122 struct media_device *mdev; 123 124 mdev = mctl->media_dev; 125 if (mdev && media_devnode_is_registered(mdev->devnode)) { 126 media_devnode_remove(mctl->intf_devnode); 127 media_device_unregister_entity(&mctl->media_entity); 128 media_entity_cleanup(&mctl->media_entity); 129 } 130 kfree(mctl); 131 subs->media_ctl = NULL; 132 } 133 } 134 135 int snd_media_start_pipeline(struct snd_usb_substream *subs) 136 { 137 struct media_ctl *mctl = subs->media_ctl; 138 int ret = 0; 139 140 if (!mctl) 141 return 0; 142 143 guard(mutex)(&mctl->media_dev->graph_mutex); 144 if (mctl->media_dev->enable_source) 145 ret = mctl->media_dev->enable_source(&mctl->media_entity, 146 &mctl->media_pipe); 147 return ret; 148 } 149 150 void snd_media_stop_pipeline(struct snd_usb_substream *subs) 151 { 152 struct media_ctl *mctl = subs->media_ctl; 153 154 if (!mctl) 155 return; 156 157 guard(mutex)(&mctl->media_dev->graph_mutex); 158 if (mctl->media_dev->disable_source) 159 mctl->media_dev->disable_source(&mctl->media_entity); 160 } 161 162 static int snd_media_mixer_init(struct snd_usb_audio *chip) 163 { 164 struct device *ctl_dev = chip->card->ctl_dev; 165 struct media_intf_devnode *ctl_intf; 166 struct usb_mixer_interface *mixer; 167 struct media_device *mdev = chip->media_dev; 168 struct media_mixer_ctl *mctl; 169 u32 intf_type = MEDIA_INTF_T_ALSA_CONTROL; 170 int ret; 171 172 if (!mdev) 173 return -ENODEV; 174 175 ctl_intf = chip->ctl_intf_media_devnode; 176 if (!ctl_intf) { 177 ctl_intf = media_devnode_create(mdev, intf_type, 0, 178 MAJOR(ctl_dev->devt), 179 MINOR(ctl_dev->devt)); 180 if (!ctl_intf) 181 return -ENOMEM; 182 chip->ctl_intf_media_devnode = ctl_intf; 183 } 184 185 list_for_each_entry(mixer, &chip->mixer_list, list) { 186 187 if (mixer->media_mixer_ctl) 188 continue; 189 190 /* allocate media_mixer_ctl */ 191 mctl = kzalloc(sizeof(*mctl), GFP_KERNEL); 192 if (!mctl) 193 return -ENOMEM; 194 195 mctl->media_dev = mdev; 196 mctl->media_entity.function = MEDIA_ENT_F_AUDIO_MIXER; 197 mctl->media_entity.name = chip->card->mixername; 198 mctl->media_pad[0].flags = MEDIA_PAD_FL_SINK; 199 mctl->media_pad[1].flags = MEDIA_PAD_FL_SOURCE; 200 mctl->media_pad[2].flags = MEDIA_PAD_FL_SOURCE; 201 media_entity_pads_init(&mctl->media_entity, MEDIA_MIXER_PAD_MAX, 202 mctl->media_pad); 203 ret = media_device_register_entity(mctl->media_dev, 204 &mctl->media_entity); 205 if (ret) { 206 kfree(mctl); 207 return ret; 208 } 209 210 mctl->intf_link = media_create_intf_link(&mctl->media_entity, 211 &ctl_intf->intf, 212 MEDIA_LNK_FL_ENABLED); 213 if (!mctl->intf_link) { 214 media_device_unregister_entity(&mctl->media_entity); 215 media_entity_cleanup(&mctl->media_entity); 216 kfree(mctl); 217 return -ENOMEM; 218 } 219 mctl->intf_devnode = ctl_intf; 220 mixer->media_mixer_ctl = mctl; 221 } 222 return 0; 223 } 224 225 static void snd_media_mixer_delete(struct snd_usb_audio *chip) 226 { 227 struct usb_mixer_interface *mixer; 228 struct media_device *mdev = chip->media_dev; 229 230 if (!mdev) 231 return; 232 233 list_for_each_entry(mixer, &chip->mixer_list, list) { 234 struct media_mixer_ctl *mctl; 235 236 mctl = mixer->media_mixer_ctl; 237 if (!mixer->media_mixer_ctl) 238 continue; 239 240 if (media_devnode_is_registered(mdev->devnode)) { 241 media_device_unregister_entity(&mctl->media_entity); 242 media_entity_cleanup(&mctl->media_entity); 243 } 244 kfree(mctl); 245 mixer->media_mixer_ctl = NULL; 246 } 247 if (media_devnode_is_registered(mdev->devnode)) 248 media_devnode_remove(chip->ctl_intf_media_devnode); 249 chip->ctl_intf_media_devnode = NULL; 250 } 251 252 int snd_media_device_create(struct snd_usb_audio *chip, 253 struct usb_interface *iface) 254 { 255 struct media_device *mdev; 256 struct usb_device *usbdev = interface_to_usbdev(iface); 257 int ret = 0; 258 259 /* usb-audio driver is probed for each usb interface, and 260 * there are multiple interfaces per device. Avoid calling 261 * media_device_usb_allocate() each time usb_audio_probe() 262 * is called. Do it only once. 263 */ 264 if (chip->media_dev) { 265 mdev = chip->media_dev; 266 goto snd_mixer_init; 267 } 268 269 mdev = media_device_usb_allocate(usbdev, KBUILD_MODNAME, THIS_MODULE); 270 if (IS_ERR(mdev)) 271 return -ENOMEM; 272 273 /* save media device - avoid lookups */ 274 chip->media_dev = mdev; 275 276 snd_mixer_init: 277 /* Create media entities for mixer and control dev */ 278 ret = snd_media_mixer_init(chip); 279 /* media_device might be registered, print error and continue */ 280 if (ret) 281 dev_err(&usbdev->dev, 282 "Couldn't create media mixer entities. Error: %d\n", 283 ret); 284 285 if (!media_devnode_is_registered(mdev->devnode)) { 286 /* don't register if snd_media_mixer_init() failed */ 287 if (ret) 288 goto create_fail; 289 290 /* register media_device */ 291 ret = media_device_register(mdev); 292 create_fail: 293 if (ret) { 294 snd_media_mixer_delete(chip); 295 media_device_delete(mdev, KBUILD_MODNAME, THIS_MODULE); 296 /* clear saved media_dev */ 297 chip->media_dev = NULL; 298 dev_err(&usbdev->dev, 299 "Couldn't register media device. Error: %d\n", 300 ret); 301 return ret; 302 } 303 } 304 305 return ret; 306 } 307 308 void snd_media_device_delete(struct snd_usb_audio *chip) 309 { 310 struct media_device *mdev = chip->media_dev; 311 struct snd_usb_stream *stream; 312 313 /* release resources */ 314 list_for_each_entry(stream, &chip->pcm_list, list) { 315 snd_media_stream_delete(&stream->substream[0]); 316 snd_media_stream_delete(&stream->substream[1]); 317 } 318 319 snd_media_mixer_delete(chip); 320 321 if (mdev) { 322 media_device_delete(mdev, KBUILD_MODNAME, THIS_MODULE); 323 chip->media_dev = NULL; 324 } 325 } 326