summaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/em28xx/em28xx-audio.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-04 09:50:07 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-04 09:50:07 -0700
commit3c83e61e67256e0bb08c46cc2db43b58fd617251 (patch)
tree0233e1e04e6449c60b01ff5dea8bea85bcf22f08 /drivers/media/usb/em28xx/em28xx-audio.c
parent4a4389abdd9822fdf3cc2ac6ed87eb811fd43acc (diff)
parenta83b93a7480441a47856dc9104bea970e84cda87 (diff)
downloadop-kernel-dev-3c83e61e67256e0bb08c46cc2db43b58fd617251.zip
op-kernel-dev-3c83e61e67256e0bb08c46cc2db43b58fd617251.tar.gz
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: "The main set of series of patches for media subsystem, including: - document RC sysfs class - added an API to setup scancode to allow waking up systems using the Remote Controller - add API for SDR devices. Drivers are still on staging - some API improvements for getting EDID data from media inputs/outputs - new DVB frontend driver for drx-j (ATSC) - one driver (it913x/it9137) got removed, in favor of an improvement on another driver (af9035) - added a skeleton V4L2 PCI driver at documentation - added a dual flash driver (lm3646) - added a new IR driver (img-ir) - added an IR scancode decoder for the Sharp protocol - some improvements at the usbtv driver, to allow its core to be reused. - added a new SDR driver (rtl2832u_sdr) - added a new tuner driver (msi001) - several improvements at em28xx driver to fix PM support, device removal and to split the V4L2 specific bits into a separate sub-driver - one driver got converted to videobuf2 (s2255drv) - the e4000 tuner driver now follows an improved binding model - some fixes at V4L2 compat32 code - several fixes and enhancements at videobuf2 code - some cleanups at V4L2 API documentation - usual driver enhancements, new board additions and misc fixups" [ NOTE! This merge effective drops commit 4329b93b283c ("of: Reduce indentation in of_graph_get_next_endpoint"). The of_graph_get_next_endpoint() function was moved and renamed by commit fd9fdb78a9bf ("[media] of: move graph helpers from drivers/media/v4l2-core to drivers/of"). It was originally called v4l2_of_get_next_endpoint() and lived in the file drivers/media/v4l2-core/v4l2-of.c. In that original location, it was then fixed to support empty port nodes by commit b9db140c1e46 ("[media] v4l: of: Support empty port nodes"), and that commit clashes badly with the dropped "Reduce intendation" commit. I had to choose one or the other, and decided that the "Support empty port nodes" commit was more important ] * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (426 commits) [media] em28xx-dvb: fix PCTV 461e tuner I2C binding Revert "[media] em28xx-dvb: fix PCTV 461e tuner I2C binding" [media] em28xx: fix PCTV 290e LNA oops [media] em28xx-dvb: fix PCTV 461e tuner I2C binding [media] m88ds3103: fix bug on .set_tone() [media] saa7134: fix WARN_ON during resume [media] v4l2-dv-timings: add module name, description, license [media] videodev2.h: add parenthesis around macro arguments [media] saa6752hs: depends on CRC32 [media] si4713: fix Kconfig dependencies [media] Sensoray 2255 uses videobuf2 [media] adv7180: free an interrupt on failure paths in init_device() [media] e4000: make VIDEO_V4L2 dependency optional [media] af9033: Don't export functions for the hardware filter [media] af9035: use af9033 PID filters [media] af9033: implement PID filter [media] rtl2832_sdr: do not use dynamic stack allocation [media] e4000: fix 32-bit build error [media] em28xx-audio: make sure audio is unmuted on open() [media] DocBook media: v4l2_format_sdr was renamed to v4l2_sdr_format ...
Diffstat (limited to 'drivers/media/usb/em28xx/em28xx-audio.c')
-rw-r--r--drivers/media/usb/em28xx/em28xx-audio.c103
1 files changed, 70 insertions, 33 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c
index 1a28897..342490f 100644
--- a/drivers/media/usb/em28xx/em28xx-audio.c
+++ b/drivers/media/usb/em28xx/em28xx-audio.c
@@ -252,7 +252,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
{
struct em28xx *dev = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
- int ret = 0;
+ int nonblock, ret = 0;
if (!dev) {
em28xx_err("BUG: em28xx can't find device struct."
@@ -265,45 +265,48 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
dprintk("opening device and trying to acquire exclusive lock\n");
+ nonblock = !!(substream->f_flags & O_NONBLOCK);
+ if (nonblock) {
+ if (!mutex_trylock(&dev->lock))
+ return -EAGAIN;
+ } else
+ mutex_lock(&dev->lock);
+
runtime->hw = snd_em28xx_hw_capture;
- if ((dev->alt == 0 || dev->is_audio_only) && dev->adev.users == 0) {
- int nonblock = !!(substream->f_flags & O_NONBLOCK);
-
- if (nonblock) {
- if (!mutex_trylock(&dev->lock))
- return -EAGAIN;
- } else
- mutex_lock(&dev->lock);
- if (dev->is_audio_only)
- /* vendor audio is on a separate interface */
- dev->alt = 1;
- else
- /* vendor audio is on the same interface as video */
- dev->alt = 7;
- /*
- * FIXME: The intention seems to be to select the alt
- * setting with the largest wMaxPacketSize for the video
- * endpoint.
- * At least dev->alt should be used instead, but we
- * should probably not touch it at all if it is
- * already >0, because wMaxPacketSize of the audio
- * endpoints seems to be the same for all.
- */
-
- dprintk("changing alternate number on interface %d to %d\n",
- dev->ifnum, dev->alt);
- usb_set_interface(dev->udev, dev->ifnum, dev->alt);
+
+ if (dev->adev.users == 0) {
+ if (dev->alt == 0 || dev->is_audio_only) {
+ if (dev->is_audio_only)
+ /* audio is on a separate interface */
+ dev->alt = 1;
+ else
+ /* audio is on the same interface as video */
+ dev->alt = 7;
+ /*
+ * FIXME: The intention seems to be to select
+ * the alt setting with the largest
+ * wMaxPacketSize for the video endpoint.
+ * At least dev->alt should be used instead, but
+ * we should probably not touch it at all if it
+ * is already >0, because wMaxPacketSize of the
+ * audio endpoints seems to be the same for all.
+ */
+ dprintk("changing alternate number on interface %d to %d\n",
+ dev->ifnum, dev->alt);
+ usb_set_interface(dev->udev, dev->ifnum, dev->alt);
+ }
/* Sets volume, mute, etc */
dev->mute = 0;
ret = em28xx_audio_analog_set(dev);
if (ret < 0)
goto err;
-
- dev->adev.users++;
- mutex_unlock(&dev->lock);
}
+ kref_get(&dev->ref);
+ dev->adev.users++;
+ mutex_unlock(&dev->lock);
+
/* Dynamically adjust the period size */
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
@@ -341,6 +344,7 @@ static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
substream->runtime->dma_area = NULL;
}
mutex_unlock(&dev->lock);
+ kref_put(&dev->ref, em28xx_free_device);
return 0;
}
@@ -895,6 +899,8 @@ static int em28xx_audio_init(struct em28xx *dev)
em28xx_info("Binding audio extension\n");
+ kref_get(&dev->ref);
+
printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
"Rechberger\n");
printk(KERN_INFO
@@ -966,7 +972,7 @@ static int em28xx_audio_fini(struct em28xx *dev)
if (dev == NULL)
return 0;
- if (dev->has_alsa_audio != 1) {
+ if (!dev->has_alsa_audio) {
/* This device does not support the extension (in this case
the device is expecting the snd-usb-audio module or
doesn't have analog audio support at all) */
@@ -985,6 +991,35 @@ static int em28xx_audio_fini(struct em28xx *dev)
dev->adev.sndcard = NULL;
}
+ kref_put(&dev->ref, em28xx_free_device);
+ return 0;
+}
+
+static int em28xx_audio_suspend(struct em28xx *dev)
+{
+ if (dev == NULL)
+ return 0;
+
+ if (!dev->has_alsa_audio)
+ return 0;
+
+ em28xx_info("Suspending audio extension");
+ em28xx_deinit_isoc_audio(dev);
+ atomic_set(&dev->stream_started, 0);
+ return 0;
+}
+
+static int em28xx_audio_resume(struct em28xx *dev)
+{
+ if (dev == NULL)
+ return 0;
+
+ if (!dev->has_alsa_audio)
+ return 0;
+
+ em28xx_info("Resuming audio extension");
+ /* Nothing to do other than schedule_work() ?? */
+ schedule_work(&dev->wq_trigger);
return 0;
}
@@ -993,6 +1028,8 @@ static struct em28xx_ops audio_ops = {
.name = "Em28xx Audio Extension",
.init = em28xx_audio_init,
.fini = em28xx_audio_fini,
+ .suspend = em28xx_audio_suspend,
+ .resume = em28xx_audio_resume,
};
static int __init em28xx_alsa_register(void)
@@ -1007,7 +1044,7 @@ static void __exit em28xx_alsa_unregister(void)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Markus Rechberger <mrechberger@gmail.com>");
-MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_AUTHOR("Mauro Carvalho Chehab");
MODULE_DESCRIPTION(DRIVER_DESC " - audio interface");
MODULE_VERSION(EM28XX_VERSION);
OpenPOWER on IntegriCloud