0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <linux/init.h>
0020 #include <linux/list.h>
0021 #include <linux/mutex.h>
0022 #include <linux/slab.h>
0023 #include <linux/usb.h>
0024
0025 #include <sound/pcm.h>
0026 #include <sound/core.h>
0027
0028 #include "usbaudio.h"
0029 #include "card.h"
0030 #include "mixer.h"
0031 #include "media.h"
0032
0033 int snd_media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm,
0034 int stream)
0035 {
0036 struct media_device *mdev;
0037 struct media_ctl *mctl;
0038 struct device *pcm_dev = &pcm->streams[stream].dev;
0039 u32 intf_type;
0040 int ret = 0;
0041 u16 mixer_pad;
0042 struct media_entity *entity;
0043
0044 mdev = subs->stream->chip->media_dev;
0045 if (!mdev)
0046 return 0;
0047
0048 if (subs->media_ctl)
0049 return 0;
0050
0051
0052 mctl = kzalloc(sizeof(*mctl), GFP_KERNEL);
0053 if (!mctl)
0054 return -ENOMEM;
0055
0056 mctl->media_dev = mdev;
0057 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
0058 intf_type = MEDIA_INTF_T_ALSA_PCM_PLAYBACK;
0059 mctl->media_entity.function = MEDIA_ENT_F_AUDIO_PLAYBACK;
0060 mctl->media_pad.flags = MEDIA_PAD_FL_SOURCE;
0061 mixer_pad = 1;
0062 } else {
0063 intf_type = MEDIA_INTF_T_ALSA_PCM_CAPTURE;
0064 mctl->media_entity.function = MEDIA_ENT_F_AUDIO_CAPTURE;
0065 mctl->media_pad.flags = MEDIA_PAD_FL_SINK;
0066 mixer_pad = 2;
0067 }
0068 mctl->media_entity.name = pcm->name;
0069 media_entity_pads_init(&mctl->media_entity, 1, &mctl->media_pad);
0070 ret = media_device_register_entity(mctl->media_dev,
0071 &mctl->media_entity);
0072 if (ret)
0073 goto free_mctl;
0074
0075 mctl->intf_devnode = media_devnode_create(mdev, intf_type, 0,
0076 MAJOR(pcm_dev->devt),
0077 MINOR(pcm_dev->devt));
0078 if (!mctl->intf_devnode) {
0079 ret = -ENOMEM;
0080 goto unregister_entity;
0081 }
0082 mctl->intf_link = media_create_intf_link(&mctl->media_entity,
0083 &mctl->intf_devnode->intf,
0084 MEDIA_LNK_FL_ENABLED);
0085 if (!mctl->intf_link) {
0086 ret = -ENOMEM;
0087 goto devnode_remove;
0088 }
0089
0090
0091 media_device_for_each_entity(entity, mdev) {
0092 switch (entity->function) {
0093 case MEDIA_ENT_F_AUDIO_MIXER:
0094 ret = media_create_pad_link(entity, mixer_pad,
0095 &mctl->media_entity, 0,
0096 MEDIA_LNK_FL_ENABLED);
0097 if (ret)
0098 goto remove_intf_link;
0099 break;
0100 }
0101 }
0102
0103 subs->media_ctl = mctl;
0104 return 0;
0105
0106 remove_intf_link:
0107 media_remove_intf_link(mctl->intf_link);
0108 devnode_remove:
0109 media_devnode_remove(mctl->intf_devnode);
0110 unregister_entity:
0111 media_device_unregister_entity(&mctl->media_entity);
0112 free_mctl:
0113 kfree(mctl);
0114 return ret;
0115 }
0116
0117 void snd_media_stream_delete(struct snd_usb_substream *subs)
0118 {
0119 struct media_ctl *mctl = subs->media_ctl;
0120
0121 if (mctl) {
0122 struct media_device *mdev;
0123
0124 mdev = mctl->media_dev;
0125 if (mdev && media_devnode_is_registered(mdev->devnode)) {
0126 media_devnode_remove(mctl->intf_devnode);
0127 media_device_unregister_entity(&mctl->media_entity);
0128 media_entity_cleanup(&mctl->media_entity);
0129 }
0130 kfree(mctl);
0131 subs->media_ctl = NULL;
0132 }
0133 }
0134
0135 int snd_media_start_pipeline(struct snd_usb_substream *subs)
0136 {
0137 struct media_ctl *mctl = subs->media_ctl;
0138 int ret = 0;
0139
0140 if (!mctl)
0141 return 0;
0142
0143 mutex_lock(&mctl->media_dev->graph_mutex);
0144 if (mctl->media_dev->enable_source)
0145 ret = mctl->media_dev->enable_source(&mctl->media_entity,
0146 &mctl->media_pipe);
0147 mutex_unlock(&mctl->media_dev->graph_mutex);
0148 return ret;
0149 }
0150
0151 void snd_media_stop_pipeline(struct snd_usb_substream *subs)
0152 {
0153 struct media_ctl *mctl = subs->media_ctl;
0154
0155 if (!mctl)
0156 return;
0157
0158 mutex_lock(&mctl->media_dev->graph_mutex);
0159 if (mctl->media_dev->disable_source)
0160 mctl->media_dev->disable_source(&mctl->media_entity);
0161 mutex_unlock(&mctl->media_dev->graph_mutex);
0162 }
0163
0164 static int snd_media_mixer_init(struct snd_usb_audio *chip)
0165 {
0166 struct device *ctl_dev = &chip->card->ctl_dev;
0167 struct media_intf_devnode *ctl_intf;
0168 struct usb_mixer_interface *mixer;
0169 struct media_device *mdev = chip->media_dev;
0170 struct media_mixer_ctl *mctl;
0171 u32 intf_type = MEDIA_INTF_T_ALSA_CONTROL;
0172 int ret;
0173
0174 if (!mdev)
0175 return -ENODEV;
0176
0177 ctl_intf = chip->ctl_intf_media_devnode;
0178 if (!ctl_intf) {
0179 ctl_intf = media_devnode_create(mdev, intf_type, 0,
0180 MAJOR(ctl_dev->devt),
0181 MINOR(ctl_dev->devt));
0182 if (!ctl_intf)
0183 return -ENOMEM;
0184 chip->ctl_intf_media_devnode = ctl_intf;
0185 }
0186
0187 list_for_each_entry(mixer, &chip->mixer_list, list) {
0188
0189 if (mixer->media_mixer_ctl)
0190 continue;
0191
0192
0193 mctl = kzalloc(sizeof(*mctl), GFP_KERNEL);
0194 if (!mctl)
0195 return -ENOMEM;
0196
0197 mctl->media_dev = mdev;
0198 mctl->media_entity.function = MEDIA_ENT_F_AUDIO_MIXER;
0199 mctl->media_entity.name = chip->card->mixername;
0200 mctl->media_pad[0].flags = MEDIA_PAD_FL_SINK;
0201 mctl->media_pad[1].flags = MEDIA_PAD_FL_SOURCE;
0202 mctl->media_pad[2].flags = MEDIA_PAD_FL_SOURCE;
0203 media_entity_pads_init(&mctl->media_entity, MEDIA_MIXER_PAD_MAX,
0204 mctl->media_pad);
0205 ret = media_device_register_entity(mctl->media_dev,
0206 &mctl->media_entity);
0207 if (ret) {
0208 kfree(mctl);
0209 return ret;
0210 }
0211
0212 mctl->intf_link = media_create_intf_link(&mctl->media_entity,
0213 &ctl_intf->intf,
0214 MEDIA_LNK_FL_ENABLED);
0215 if (!mctl->intf_link) {
0216 media_device_unregister_entity(&mctl->media_entity);
0217 media_entity_cleanup(&mctl->media_entity);
0218 kfree(mctl);
0219 return -ENOMEM;
0220 }
0221 mctl->intf_devnode = ctl_intf;
0222 mixer->media_mixer_ctl = mctl;
0223 }
0224 return 0;
0225 }
0226
0227 static void snd_media_mixer_delete(struct snd_usb_audio *chip)
0228 {
0229 struct usb_mixer_interface *mixer;
0230 struct media_device *mdev = chip->media_dev;
0231
0232 if (!mdev)
0233 return;
0234
0235 list_for_each_entry(mixer, &chip->mixer_list, list) {
0236 struct media_mixer_ctl *mctl;
0237
0238 mctl = mixer->media_mixer_ctl;
0239 if (!mixer->media_mixer_ctl)
0240 continue;
0241
0242 if (media_devnode_is_registered(mdev->devnode)) {
0243 media_device_unregister_entity(&mctl->media_entity);
0244 media_entity_cleanup(&mctl->media_entity);
0245 }
0246 kfree(mctl);
0247 mixer->media_mixer_ctl = NULL;
0248 }
0249 if (media_devnode_is_registered(mdev->devnode))
0250 media_devnode_remove(chip->ctl_intf_media_devnode);
0251 chip->ctl_intf_media_devnode = NULL;
0252 }
0253
0254 int snd_media_device_create(struct snd_usb_audio *chip,
0255 struct usb_interface *iface)
0256 {
0257 struct media_device *mdev;
0258 struct usb_device *usbdev = interface_to_usbdev(iface);
0259 int ret = 0;
0260
0261
0262
0263
0264
0265
0266 if (chip->media_dev) {
0267 mdev = chip->media_dev;
0268 goto snd_mixer_init;
0269 }
0270
0271 mdev = media_device_usb_allocate(usbdev, KBUILD_MODNAME, THIS_MODULE);
0272 if (IS_ERR(mdev))
0273 return -ENOMEM;
0274
0275
0276 chip->media_dev = mdev;
0277
0278 snd_mixer_init:
0279
0280 ret = snd_media_mixer_init(chip);
0281
0282 if (ret)
0283 dev_err(&usbdev->dev,
0284 "Couldn't create media mixer entities. Error: %d\n",
0285 ret);
0286
0287 if (!media_devnode_is_registered(mdev->devnode)) {
0288
0289 if (ret)
0290 goto create_fail;
0291
0292
0293 ret = media_device_register(mdev);
0294 create_fail:
0295 if (ret) {
0296 snd_media_mixer_delete(chip);
0297 media_device_delete(mdev, KBUILD_MODNAME, THIS_MODULE);
0298
0299 chip->media_dev = NULL;
0300 dev_err(&usbdev->dev,
0301 "Couldn't register media device. Error: %d\n",
0302 ret);
0303 return ret;
0304 }
0305 }
0306
0307 return ret;
0308 }
0309
0310 void snd_media_device_delete(struct snd_usb_audio *chip)
0311 {
0312 struct media_device *mdev = chip->media_dev;
0313 struct snd_usb_stream *stream;
0314
0315
0316 list_for_each_entry(stream, &chip->pcm_list, list) {
0317 snd_media_stream_delete(&stream->substream[0]);
0318 snd_media_stream_delete(&stream->substream[1]);
0319 }
0320
0321 snd_media_mixer_delete(chip);
0322
0323 if (mdev) {
0324 media_device_delete(mdev, KBUILD_MODNAME, THIS_MODULE);
0325 chip->media_dev = NULL;
0326 }
0327 }