From 01ae3b51af7144ea29eb28ba718b65ad59ab9493 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Fri, 17 Jan 2014 14:18:42 -0300 Subject: [media] em28xx-audio: fix user counting in snd_em28xx_capture_open() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dev->adev.users always needs to be increased when snd_em28xx_capture_open() is called and succeeds. Signed-off-by: Frank Schäfer Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-audio.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/media/usb/em28xx/em28xx-audio.c') diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 05e9bd11a3ff..dfdfa772eb1e 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,15 +265,15 @@ 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; @@ -299,11 +299,11 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) ret = em28xx_audio_analog_set(dev); if (ret < 0) goto err; - - dev->adev.users++; - mutex_unlock(&dev->lock); } + 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, -- cgit v1.2.1 From 37e59f876bc710d67a30b660826a5e83e07101ce Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 7 Feb 2014 08:03:07 -0200 Subject: [media, edac] Change my email address There are several left overs with my old email address. Remove their occurrences and add myself at CREDITS, to allow people to be able to reach me on my new addresses. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/usb/em28xx/em28xx-audio.c') diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index dfdfa772eb1e..566fa096eaf8 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -1008,7 +1008,7 @@ static void __exit em28xx_alsa_unregister(void) MODULE_LICENSE("GPL"); MODULE_AUTHOR("Markus Rechberger "); -MODULE_AUTHOR("Mauro Carvalho Chehab "); +MODULE_AUTHOR("Mauro Carvalho Chehab"); MODULE_DESCRIPTION(DRIVER_DESC " - audio interface"); MODULE_VERSION(EM28XX_VERSION); -- cgit v1.2.1 From 6d746f91f23098c7613938b85e9b345d53b6de3f Mon Sep 17 00:00:00 2001 From: Shuah Khan Date: Fri, 21 Feb 2014 21:50:14 -0300 Subject: [media] em28xx-audio: implement em28xx_ops: suspend/resume hooks Implement em28xx_ops: suspend/resume hooks. em28xx usb driver will invoke em28xx_ops: suspend and resume hooks for all its extensions from its suspend() and resume() interfaces. Signed-off-by: Shuah Khan Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-audio.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers/media/usb/em28xx/em28xx-audio.c') diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 566fa096eaf8..0f5b6f3e7a3f 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -989,11 +989,41 @@ static int em28xx_audio_fini(struct em28xx *dev) 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; +} + static struct em28xx_ops audio_ops = { .id = EM28XX_AUDIO, .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) -- cgit v1.2.1 From 47677e51e2a4040c204d7971a5103592600185b1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 5 Mar 2014 11:21:07 -0300 Subject: [media] em28xx: Only deallocate struct em28xx after finishing all extensions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can't free struct em28xx while one of the extensions is still using it. So, add a kref() to control it, freeing it only after the extensions fini calls. Reviewed-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-audio.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/media/usb/em28xx/em28xx-audio.c') diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index 0f5b6f3e7a3f..f75c0a5494d6 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -301,6 +301,7 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) goto err; } + kref_get(&dev->ref); dev->adev.users++; mutex_unlock(&dev->lock); @@ -341,6 +342,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 +897,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 @@ -967,7 +971,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) */ @@ -986,6 +990,7 @@ static int em28xx_audio_fini(struct em28xx *dev) dev->adev.sndcard = NULL; } + kref_put(&dev->ref, em28xx_free_device); return 0; } -- cgit v1.2.1 From ba35ca07080268af1badeb47de0f9eff28126339 Mon Sep 17 00:00:00 2001 From: Frank Schaefer Date: Fri, 17 Jan 2014 14:18:43 -0300 Subject: [media] em28xx-audio: make sure audio is unmuted on open() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In all cases, when the first capture is called, we need to call the code that unmutes the volume. Signed-off-by: Frank Schäfer Signed-off-by: Mauro Carvalho Chehab --- drivers/media/usb/em28xx/em28xx-audio.c | 42 +++++++++++++++++---------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'drivers/media/usb/em28xx/em28xx-audio.c') diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index f75c0a5494d6..c1937ea1fca3 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -273,26 +273,28 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) mutex_lock(&dev->lock); runtime->hw = snd_em28xx_hw_capture; - if ((dev->alt == 0 || dev->is_audio_only) && dev->adev.users == 0) { - 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; -- cgit v1.2.1