2008-01-05 09:55:47 -03:00
/*
* Empiatech em28x1 audio extension
*
* Copyright ( C ) 2006 Markus Rechberger < mrechberger @ gmail . com >
*
2013-12-28 21:16:26 -03:00
* Copyright ( C ) 2007 - 2014 Mauro Carvalho Chehab
2008-01-05 09:57:31 -03:00
* - Port to work with the in - kernel driver
2011-06-17 15:15:12 -03:00
* - Cleanups , fixes , alsa - controls , etc .
2008-01-05 09:57:31 -03:00
*
2008-01-05 09:55:47 -03:00
* This driver is based on my previous au600 usb pstn audio driver
* and inherits all the copyrights
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include <linux/kernel.h>
# include <linux/usb.h>
# include <linux/init.h>
# include <linux/sound.h>
# include <linux/spinlock.h>
# include <linux/soundcard.h>
# include <linux/slab.h>
# include <linux/vmalloc.h>
# include <linux/proc_fs.h>
2008-01-05 09:57:31 -03:00
# include <linux/module.h>
2008-01-05 09:55:47 -03:00
# include <sound/core.h>
# include <sound/pcm.h>
# include <sound/pcm_params.h>
# include <sound/info.h>
# include <sound/initval.h>
# include <sound/control.h>
2011-06-19 13:06:40 -03:00
# include <sound/tlv.h>
2012-06-11 15:17:23 -03:00
# include <sound/ac97_codec.h>
2008-01-05 09:55:47 -03:00
# include <media/v4l2-common.h>
# include "em28xx.h"
2008-01-05 09:57:31 -03:00
static int debug ;
module_param ( debug , int , 0644 ) ;
MODULE_PARM_DESC ( debug , " activates debug info " ) ;
2008-01-05 09:55:47 -03:00
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
# define EM28XX_MAX_AUDIO_BUFS 5
# define EM28XX_MIN_AUDIO_PACKETS 64
2008-01-05 09:57:31 -03:00
# define dprintk(fmt, arg...) do { \
if ( debug ) \
printk ( KERN_INFO " em28xx-audio %s: " fmt , \
2008-04-08 23:20:00 -03:00
__func__ , # # arg ) ; \
2008-01-05 09:57:31 -03:00
} while ( 0 )
2008-01-05 09:55:47 -03:00
2008-01-05 09:57:31 -03:00
static int index [ SNDRV_CARDS ] = SNDRV_DEFAULT_IDX ;
2008-01-05 09:55:47 -03:00
2009-02-08 13:09:11 -03:00
static int em28xx_deinit_isoc_audio ( struct em28xx * dev )
2008-01-05 09:55:47 -03:00
{
2008-01-05 09:57:31 -03:00
int i ;
2008-01-05 09:55:47 -03:00
2008-01-05 09:57:31 -03:00
dprintk ( " Stopping isoc \n " ) ;
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
for ( i = 0 ; i < dev - > adev . num_urb ; i + + ) {
2013-12-28 11:47:16 -03:00
struct urb * urb = dev - > adev . urb [ i ] ;
2009-01-25 13:08:07 -03:00
if ( ! irqs_disabled ( ) )
2013-12-28 11:47:16 -03:00
usb_kill_urb ( urb ) ;
2009-01-25 13:08:07 -03:00
else
2013-12-28 11:47:16 -03:00
usb_unlink_urb ( urb ) ;
2008-01-05 09:55:47 -03:00
}
return 0 ;
}
static void em28xx_audio_isocirq ( struct urb * urb )
{
2008-01-05 09:57:31 -03:00
struct em28xx * dev = urb - > context ;
int i ;
unsigned int oldptr ;
int period_elapsed = 0 ;
int status ;
unsigned char * cp ;
unsigned int stride ;
2008-01-05 09:55:47 -03:00
struct snd_pcm_substream * substream ;
2008-01-05 09:57:31 -03:00
struct snd_pcm_runtime * runtime ;
2009-02-08 13:09:11 -03:00
switch ( urb - > status ) {
case 0 : /* success */
case - ETIMEDOUT : /* NAK */
break ;
case - ECONNRESET : /* kill */
case - ENOENT :
case - ESHUTDOWN :
return ;
default : /* error */
dprintk ( " urb completition error %d. \n " , urb - > status ) ;
break ;
}
2010-10-09 15:53:58 -03:00
if ( atomic_read ( & dev - > stream_started ) = = 0 )
return ;
2008-12-31 09:37:33 -03:00
if ( dev - > adev . capture_pcm_substream ) {
substream = dev - > adev . capture_pcm_substream ;
2008-01-05 09:56:24 -03:00
runtime = substream - > runtime ;
2008-01-05 09:55:47 -03:00
stride = runtime - > frame_bits > > 3 ;
2008-01-05 09:57:31 -03:00
2008-01-05 09:56:24 -03:00
for ( i = 0 ; i < urb - > number_of_packets ; i + + ) {
int length =
urb - > iso_frame_desc [ i ] . actual_length / stride ;
cp = ( unsigned char * ) urb - > transfer_buffer +
urb - > iso_frame_desc [ i ] . offset ;
2008-01-05 09:55:47 -03:00
2008-01-05 09:56:24 -03:00
if ( ! length )
2008-01-05 09:55:47 -03:00
continue ;
2008-12-31 09:37:33 -03:00
oldptr = dev - > adev . hwptr_done_capture ;
2008-11-24 08:45:57 -03:00
if ( oldptr + length > = runtime - > buffer_size ) {
unsigned int cnt =
runtime - > buffer_size - oldptr ;
memcpy ( runtime - > dma_area + oldptr * stride , cp ,
cnt * stride ) ;
memcpy ( runtime - > dma_area , cp + cnt * stride ,
length * stride - cnt * stride ) ;
} else {
memcpy ( runtime - > dma_area + oldptr * stride , cp ,
length * stride ) ;
}
snd_pcm_stream_lock ( substream ) ;
2008-12-31 09:37:33 -03:00
dev - > adev . hwptr_done_capture + = length ;
if ( dev - > adev . hwptr_done_capture > =
2008-01-05 09:56:24 -03:00
runtime - > buffer_size )
2008-12-31 09:37:33 -03:00
dev - > adev . hwptr_done_capture - =
2008-01-05 09:56:24 -03:00
runtime - > buffer_size ;
2008-01-05 09:55:47 -03:00
2008-12-31 09:37:33 -03:00
dev - > adev . capture_transfer_done + = length ;
if ( dev - > adev . capture_transfer_done > =
2008-01-05 09:56:24 -03:00
runtime - > period_size ) {
2008-12-31 09:37:33 -03:00
dev - > adev . capture_transfer_done - =
2008-01-05 09:56:24 -03:00
runtime - > period_size ;
period_elapsed = 1 ;
2008-01-05 09:55:47 -03:00
}
2008-01-05 09:57:31 -03:00
2008-11-24 08:45:57 -03:00
snd_pcm_stream_unlock ( substream ) ;
2008-01-05 09:55:47 -03:00
}
2008-01-05 09:57:31 -03:00
if ( period_elapsed )
2008-01-05 09:55:47 -03:00
snd_pcm_period_elapsed ( substream ) ;
}
urb - > status = 0 ;
2008-01-05 09:56:24 -03:00
2008-01-05 09:57:31 -03:00
status = usb_submit_urb ( urb , GFP_ATOMIC ) ;
if ( status < 0 ) {
2008-01-05 09:56:24 -03:00
em28xx_errdev ( " resubmit of audio urb failed (error=%i) \n " ,
status ) ;
2008-01-05 09:55:47 -03:00
}
return ;
}
static int em28xx_init_audio_isoc ( struct em28xx * dev )
{
2008-01-05 09:57:31 -03:00
int i , errCode ;
dprintk ( " Starting isoc transfers \n " ) ;
2008-01-05 09:55:47 -03:00
2013-12-28 21:16:26 -03:00
/* Start streaming */
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
for ( i = 0 ; i < dev - > adev . num_urb ; i + + ) {
2013-12-28 21:16:26 -03:00
memset ( dev - > adev . transfer_buffer [ i ] , 0x80 ,
dev - > adev . urb [ i ] - > transfer_buffer_length ) ;
2008-01-05 09:57:31 -03:00
2008-12-31 09:37:33 -03:00
errCode = usb_submit_urb ( dev - > adev . urb [ i ] , GFP_ATOMIC ) ;
2008-01-05 09:56:24 -03:00
if ( errCode ) {
2011-06-19 10:15:35 -03:00
em28xx_errdev ( " submit of audio urb failed \n " ) ;
2009-02-08 13:09:11 -03:00
em28xx_deinit_isoc_audio ( dev ) ;
2011-06-19 10:15:35 -03:00
atomic_set ( & dev - > stream_started , 0 ) ;
2008-01-05 09:55:47 -03:00
return errCode ;
}
2011-06-19 10:15:35 -03:00
2008-01-05 09:55:47 -03:00
}
2008-01-05 09:57:31 -03:00
2008-01-05 09:55:47 -03:00
return 0 ;
}
2008-01-05 09:57:31 -03:00
static int snd_pcm_alloc_vmalloc_buffer ( struct snd_pcm_substream * subs ,
size_t size )
{
struct snd_pcm_runtime * runtime = subs - > runtime ;
2009-02-10 23:28:24 -03:00
dprintk ( " Allocating vbuffer \n " ) ;
2008-01-05 09:57:31 -03:00
if ( runtime - > dma_area ) {
if ( runtime - > dma_bytes > size )
return 0 ;
vfree ( runtime - > dma_area ) ;
}
runtime - > dma_area = vmalloc ( size ) ;
if ( ! runtime - > dma_area )
return - ENOMEM ;
runtime - > dma_bytes = size ;
return 0 ;
}
static struct snd_pcm_hardware snd_em28xx_hw_capture = {
. info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
2011-06-19 13:39:31 -03:00
SNDRV_PCM_INFO_BATCH |
2008-01-05 09:57:31 -03:00
SNDRV_PCM_INFO_MMAP_VALID ,
. formats = SNDRV_PCM_FMTBIT_S16_LE ,
. rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT ,
. rate_min = 48000 ,
. rate_max = 48000 ,
. channels_min = 2 ,
. channels_max = 2 ,
. buffer_bytes_max = 62720 * 8 , /* just about the value in usbaudio.c */
. period_bytes_min = 64 , /* 12544/2, */
. period_bytes_max = 12544 ,
. periods_min = 2 ,
. periods_max = 98 , /* 12544, */
} ;
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 ;
dprintk ( " opening device and trying to acquire exclusive lock \n " ) ;
2008-06-14 09:41:18 -03:00
if ( ! dev ) {
2009-11-04 15:31:25 -03:00
em28xx_err ( " BUG: em28xx can't find device struct. "
2008-06-14 09:41:18 -03:00
" Can't proceed with open \n " ) ;
return - ENODEV ;
}
2011-06-17 15:15:12 -03:00
runtime - > hw = snd_em28xx_hw_capture ;
if ( ( dev - > alt = = 0 | | dev - > audio_ifnum ) & & dev - > adev . users = = 0 ) {
if ( dev - > audio_ifnum )
dev - > alt = 1 ;
else
dev - > alt = 7 ;
2008-02-06 18:52:15 -03:00
2011-06-17 15:15:12 -03:00
dprintk ( " changing alternate number on interface %d to %d \n " ,
dev - > audio_ifnum , dev - > alt ) ;
usb_set_interface ( dev - > udev , dev - > audio_ifnum , dev - > alt ) ;
2008-01-05 09:57:31 -03:00
2011-06-17 15:15:12 -03:00
/* Sets volume, mute, etc */
dev - > mute = 0 ;
mutex_lock ( & dev - > lock ) ;
ret = em28xx_audio_analog_set ( dev ) ;
if ( ret < 0 )
goto err ;
2008-01-05 09:57:31 -03:00
2011-06-17 15:15:12 -03:00
dev - > adev . users + + ;
mutex_unlock ( & dev - > lock ) ;
}
2008-01-05 09:57:31 -03:00
snd_pcm_hw_constraint_integer ( runtime , SNDRV_PCM_HW_PARAM_PERIODS ) ;
2008-12-31 09:37:33 -03:00
dev - > adev . capture_pcm_substream = substream ;
2008-01-05 09:57:31 -03:00
return 0 ;
err :
2010-10-09 15:53:58 -03:00
mutex_unlock ( & dev - > lock ) ;
2009-11-04 15:31:25 -03:00
em28xx_err ( " Error while configuring em28xx mixer \n " ) ;
2008-01-05 09:57:31 -03:00
return ret ;
}
static int snd_em28xx_pcm_close ( struct snd_pcm_substream * substream )
{
struct em28xx * dev = snd_pcm_substream_chip ( substream ) ;
dprintk ( " closing device \n " ) ;
dev - > mute = 1 ;
2008-02-06 18:52:15 -03:00
mutex_lock ( & dev - > lock ) ;
2009-02-08 01:11:13 -03:00
dev - > adev . users - - ;
2010-10-09 15:53:58 -03:00
if ( atomic_read ( & dev - > stream_started ) > 0 ) {
atomic_set ( & dev - > stream_started , 0 ) ;
schedule_work ( & dev - > wq_trigger ) ;
}
2008-01-05 09:57:31 -03:00
em28xx_audio_analog_set ( dev ) ;
2009-05-28 11:16:19 -03:00
if ( substream - > runtime - > dma_area ) {
dprintk ( " freeing \n " ) ;
vfree ( substream - > runtime - > dma_area ) ;
substream - > runtime - > dma_area = NULL ;
}
2008-02-06 18:52:15 -03:00
mutex_unlock ( & dev - > lock ) ;
2008-01-05 09:57:31 -03:00
return 0 ;
}
static int snd_em28xx_hw_capture_params ( struct snd_pcm_substream * substream ,
struct snd_pcm_hw_params * hw_params )
{
int ret ;
dprintk ( " Setting capture parameters \n " ) ;
ret = snd_pcm_alloc_vmalloc_buffer ( substream ,
params_buffer_bytes ( hw_params ) ) ;
2011-06-17 20:28:51 -03:00
if ( ret < 0 )
return ret ;
2012-05-14 10:17:35 -03:00
#if 0
/* TODO: set up em28xx audio chip to deliver the correct audio format,
current default is 48000 hz multiplexed = > 96000 hz mono
which shouldn ' t matter since analogue TV only supports mono */
unsigned int channels , rate , format ;
2008-01-05 09:57:31 -03:00
format = params_format ( hw_params ) ;
rate = params_rate ( hw_params ) ;
channels = params_channels ( hw_params ) ;
2012-05-14 10:17:35 -03:00
# endif
2008-01-05 09:57:31 -03:00
return 0 ;
}
static int snd_em28xx_hw_capture_free ( struct snd_pcm_substream * substream )
{
struct em28xx * dev = snd_pcm_substream_chip ( substream ) ;
dprintk ( " Stop capture, if needed \n " ) ;
2010-10-09 15:53:58 -03:00
if ( atomic_read ( & dev - > stream_started ) > 0 ) {
atomic_set ( & dev - > stream_started , 0 ) ;
schedule_work ( & dev - > wq_trigger ) ;
}
2008-01-05 09:57:31 -03:00
return 0 ;
}
static int snd_em28xx_prepare ( struct snd_pcm_substream * substream )
{
2009-10-15 01:14:34 -03:00
struct em28xx * dev = snd_pcm_substream_chip ( substream ) ;
dev - > adev . hwptr_done_capture = 0 ;
dev - > adev . capture_transfer_done = 0 ;
2008-01-05 09:57:31 -03:00
return 0 ;
}
2010-10-09 15:53:58 -03:00
static void audio_trigger ( struct work_struct * work )
{
struct em28xx * dev = container_of ( work , struct em28xx , wq_trigger ) ;
if ( atomic_read ( & dev - > stream_started ) ) {
dprintk ( " starting capture " ) ;
em28xx_init_audio_isoc ( dev ) ;
} else {
dprintk ( " stopping capture " ) ;
em28xx_deinit_isoc_audio ( dev ) ;
}
}
2008-01-05 09:57:31 -03:00
static int snd_em28xx_capture_trigger ( struct snd_pcm_substream * substream ,
int cmd )
{
struct em28xx * dev = snd_pcm_substream_chip ( substream ) ;
2011-06-17 20:28:51 -03:00
int retval = 0 ;
2008-01-05 09:57:31 -03:00
switch ( cmd ) {
2011-06-19 13:39:31 -03:00
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE : /* fall through */
case SNDRV_PCM_TRIGGER_RESUME : /* fall through */
2008-01-05 09:57:31 -03:00
case SNDRV_PCM_TRIGGER_START :
2010-10-09 15:53:58 -03:00
atomic_set ( & dev - > stream_started , 1 ) ;
2009-02-08 14:17:15 -03:00
break ;
2011-06-19 13:39:31 -03:00
case SNDRV_PCM_TRIGGER_PAUSE_PUSH : /* fall through */
case SNDRV_PCM_TRIGGER_SUSPEND : /* fall through */
2008-01-05 09:57:31 -03:00
case SNDRV_PCM_TRIGGER_STOP :
2011-06-19 13:39:31 -03:00
atomic_set ( & dev - > stream_started , 0 ) ;
2009-02-08 14:17:15 -03:00
break ;
2008-01-05 09:57:31 -03:00
default :
2009-02-08 14:17:15 -03:00
retval = - EINVAL ;
2008-01-05 09:57:31 -03:00
}
2010-10-09 15:53:58 -03:00
schedule_work ( & dev - > wq_trigger ) ;
2011-06-17 20:28:51 -03:00
return retval ;
2008-01-05 09:57:31 -03:00
}
2008-01-05 09:56:24 -03:00
static snd_pcm_uframes_t snd_em28xx_capture_pointer ( struct snd_pcm_substream
* substream )
2008-01-05 09:55:47 -03:00
{
2009-02-10 23:28:24 -03:00
unsigned long flags ;
2009-01-16 11:23:25 -03:00
struct em28xx * dev ;
2008-01-05 09:55:47 -03:00
snd_pcm_uframes_t hwptr_done ;
2009-01-16 11:23:25 -03:00
2008-01-05 09:55:47 -03:00
dev = snd_pcm_substream_chip ( substream ) ;
2009-01-25 15:12:29 -03:00
spin_lock_irqsave ( & dev - > adev . slock , flags ) ;
2008-12-31 09:37:33 -03:00
hwptr_done = dev - > adev . hwptr_done_capture ;
2009-01-25 15:12:29 -03:00
spin_unlock_irqrestore ( & dev - > adev . slock , flags ) ;
2008-01-05 09:57:31 -03:00
2008-01-05 09:55:47 -03:00
return hwptr_done ;
}
static struct page * snd_pcm_get_vmalloc_page ( struct snd_pcm_substream * subs ,
unsigned long offset )
{
void * pageptr = subs - > runtime - > dma_area + offset ;
2008-01-05 09:57:31 -03:00
2008-01-05 09:55:47 -03:00
return vmalloc_to_page ( pageptr ) ;
}
2011-06-19 13:06:40 -03:00
/*
* AC97 volume control support
*/
static int em28xx_vol_info ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_info * info )
{
info - > type = SNDRV_CTL_ELEM_TYPE_INTEGER ;
info - > count = 2 ;
info - > value . integer . min = 0 ;
info - > value . integer . max = 0x1f ;
return 0 ;
}
static int em28xx_vol_put ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * value )
{
struct em28xx * dev = snd_kcontrol_chip ( kcontrol ) ;
2011-06-19 13:14:07 -03:00
u16 val = ( 0x1f - ( value - > value . integer . value [ 0 ] & 0x1f ) ) |
( 0x1f - ( value - > value . integer . value [ 1 ] & 0x1f ) ) < < 8 ;
2011-06-19 13:06:40 -03:00
int rc ;
mutex_lock ( & dev - > lock ) ;
rc = em28xx_read_ac97 ( dev , kcontrol - > private_value ) ;
if ( rc < 0 )
goto err ;
2011-06-19 13:08:46 -03:00
val | = rc & 0x8000 ; /* Preserve the mute flag */
2011-06-19 13:06:40 -03:00
rc = em28xx_write_ac97 ( dev , kcontrol - > private_value , val ) ;
2011-06-18 11:00:20 -03:00
if ( rc < 0 )
goto err ;
dprintk ( " %sleft vol %d, right vol %d (0x%04x) to ac97 volume control 0x%04x \n " ,
( val & 0x8000 ) ? " muted " : " " ,
0x1f - ( ( val > > 8 ) & 0x1f ) , 0x1f - ( val & 0x1f ) ,
val , ( int ) kcontrol - > private_value ) ;
2011-06-19 13:06:40 -03:00
err :
mutex_unlock ( & dev - > lock ) ;
return rc ;
}
static int em28xx_vol_get ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * value )
{
struct em28xx * dev = snd_kcontrol_chip ( kcontrol ) ;
int val ;
mutex_lock ( & dev - > lock ) ;
val = em28xx_read_ac97 ( dev , kcontrol - > private_value ) ;
mutex_unlock ( & dev - > lock ) ;
if ( val < 0 )
return val ;
2011-06-18 11:00:20 -03:00
dprintk ( " %sleft vol %d, right vol %d (0x%04x) from ac97 volume control 0x%04x \n " ,
( val & 0x8000 ) ? " muted " : " " ,
0x1f - ( ( val > > 8 ) & 0x1f ) , 0x1f - ( val & 0x1f ) ,
val , ( int ) kcontrol - > private_value ) ;
2011-06-19 13:14:07 -03:00
value - > value . integer . value [ 0 ] = 0x1f - ( val & 0x1f ) ;
value - > value . integer . value [ 1 ] = 0x1f - ( ( val < < 8 ) & 0x1f ) ;
2011-06-19 13:06:40 -03:00
return 0 ;
}
2011-06-19 13:08:46 -03:00
static int em28xx_vol_put_mute ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * value )
{
struct em28xx * dev = snd_kcontrol_chip ( kcontrol ) ;
u16 val = value - > value . integer . value [ 0 ] ;
int rc ;
mutex_lock ( & dev - > lock ) ;
rc = em28xx_read_ac97 ( dev , kcontrol - > private_value ) ;
if ( rc < 0 )
goto err ;
if ( val )
2011-06-19 13:14:07 -03:00
rc & = 0x1f1f ;
2011-06-19 13:08:46 -03:00
else
2011-06-19 13:14:07 -03:00
rc | = 0x8000 ;
2011-06-19 13:08:46 -03:00
rc = em28xx_write_ac97 ( dev , kcontrol - > private_value , rc ) ;
2011-06-18 11:00:20 -03:00
if ( rc < 0 )
goto err ;
dprintk ( " %sleft vol %d, right vol %d (0x%04x) to ac97 volume control 0x%04x \n " ,
( val & 0x8000 ) ? " muted " : " " ,
0x1f - ( ( val > > 8 ) & 0x1f ) , 0x1f - ( val & 0x1f ) ,
val , ( int ) kcontrol - > private_value ) ;
2011-06-19 13:08:46 -03:00
err :
mutex_unlock ( & dev - > lock ) ;
return rc ;
}
static int em28xx_vol_get_mute ( struct snd_kcontrol * kcontrol ,
struct snd_ctl_elem_value * value )
{
struct em28xx * dev = snd_kcontrol_chip ( kcontrol ) ;
int val ;
mutex_lock ( & dev - > lock ) ;
val = em28xx_read_ac97 ( dev , kcontrol - > private_value ) ;
mutex_unlock ( & dev - > lock ) ;
if ( val < 0 )
return val ;
if ( val & 0x8000 )
value - > value . integer . value [ 0 ] = 0 ;
2011-06-19 13:14:07 -03:00
else
value - > value . integer . value [ 0 ] = 1 ;
2011-06-19 13:08:46 -03:00
2011-06-18 11:00:20 -03:00
dprintk ( " %sleft vol %d, right vol %d (0x%04x) from ac97 volume control 0x%04x \n " ,
( val & 0x8000 ) ? " muted " : " " ,
0x1f - ( ( val > > 8 ) & 0x1f ) , 0x1f - ( val & 0x1f ) ,
val , ( int ) kcontrol - > private_value ) ;
2011-06-19 13:08:46 -03:00
return 0 ;
}
2011-06-19 13:06:40 -03:00
static const DECLARE_TLV_DB_SCALE ( em28xx_db_scale , - 3450 , 150 , 0 ) ;
static int em28xx_cvol_new ( struct snd_card * card , struct em28xx * dev ,
char * name , int id )
{
int err ;
2011-06-19 13:08:46 -03:00
char ctl_name [ 44 ] ;
2011-06-19 13:06:40 -03:00
struct snd_kcontrol * kctl ;
2011-06-19 13:08:46 -03:00
struct snd_kcontrol_new tmp ;
memset ( & tmp , 0 , sizeof ( tmp ) ) ;
tmp . iface = SNDRV_CTL_ELEM_IFACE_MIXER ,
tmp . private_value = id ,
tmp . name = ctl_name ,
/* Add Mute Control */
sprintf ( ctl_name , " %s Switch " , name ) ;
tmp . get = em28xx_vol_get_mute ;
tmp . put = em28xx_vol_put_mute ;
tmp . info = snd_ctl_boolean_mono_info ;
2011-06-19 13:06:40 -03:00
kctl = snd_ctl_new1 ( & tmp , dev ) ;
2011-06-19 13:08:46 -03:00
err = snd_ctl_add ( card , kctl ) ;
if ( err < 0 )
return err ;
2011-06-18 11:00:20 -03:00
dprintk ( " Added control %s for ac97 volume control 0x%04x \n " ,
ctl_name , id ) ;
2011-06-19 13:06:40 -03:00
2011-06-19 13:08:46 -03:00
memset ( & tmp , 0 , sizeof ( tmp ) ) ;
tmp . iface = SNDRV_CTL_ELEM_IFACE_MIXER ,
tmp . private_value = id ,
tmp . name = ctl_name ,
/* Add Volume Control */
sprintf ( ctl_name , " %s Volume " , name ) ;
tmp . get = em28xx_vol_get ;
tmp . put = em28xx_vol_put ;
tmp . info = em28xx_vol_info ;
tmp . tlv . p = em28xx_db_scale ,
kctl = snd_ctl_new1 ( & tmp , dev ) ;
2011-06-19 13:06:40 -03:00
err = snd_ctl_add ( card , kctl ) ;
if ( err < 0 )
return err ;
2011-06-18 11:00:20 -03:00
dprintk ( " Added control %s for ac97 volume control 0x%04x \n " ,
ctl_name , id ) ;
2011-06-19 13:06:40 -03:00
return 0 ;
}
/*
* register / unregister code and data
*/
2008-01-05 09:55:47 -03:00
static struct snd_pcm_ops snd_em28xx_pcm_capture = {
2008-01-05 09:57:31 -03:00
. open = snd_em28xx_capture_open ,
. close = snd_em28xx_pcm_close ,
. ioctl = snd_pcm_lib_ioctl ,
2008-01-05 09:55:47 -03:00
. hw_params = snd_em28xx_hw_capture_params ,
2008-01-05 09:57:31 -03:00
. hw_free = snd_em28xx_hw_capture_free ,
. prepare = snd_em28xx_prepare ,
. trigger = snd_em28xx_capture_trigger ,
. pointer = snd_em28xx_capture_pointer ,
. page = snd_pcm_get_vmalloc_page ,
2008-01-05 09:55:47 -03:00
} ;
2013-12-28 21:16:26 -03:00
static void em28xx_audio_free_urb ( struct em28xx * dev )
{
int i ;
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
for ( i = 0 ; i < dev - > adev . num_urb ; i + + ) {
2013-12-28 21:16:26 -03:00
struct urb * urb = dev - > adev . urb [ i ] ;
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
if ( ! urb )
2013-12-28 21:16:26 -03:00
continue ;
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
if ( dev - > adev . transfer_buffer [ i ] )
usb_free_coherent ( dev - > udev ,
urb - > transfer_buffer_length ,
dev - > adev . transfer_buffer [ i ] ,
urb - > transfer_dma ) ;
2013-12-28 21:16:26 -03:00
usb_free_urb ( urb ) ;
}
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
kfree ( dev - > adev . urb ) ;
kfree ( dev - > adev . transfer_buffer ) ;
dev - > adev . num_urb = 0 ;
}
/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
static int em28xx_audio_ep_packet_size ( struct usb_device * udev ,
struct usb_endpoint_descriptor * e )
{
int size = le16_to_cpu ( e - > wMaxPacketSize ) ;
if ( udev - > speed = = USB_SPEED_HIGH )
return ( size & 0x7ff ) * ( 1 + ( ( ( size ) > > 11 ) & 0x03 ) ) ;
return size & 0x7ff ;
2013-12-28 21:16:26 -03:00
}
2008-01-05 09:55:47 -03:00
static int em28xx_audio_init ( struct em28xx * dev )
{
2008-12-31 09:37:33 -03:00
struct em28xx_audio * adev = & dev - > adev ;
2008-01-05 09:57:31 -03:00
struct snd_pcm * pcm ;
struct snd_card * card ;
2014-01-10 05:43:09 -03:00
struct usb_interface * intf ;
struct usb_endpoint_descriptor * e , * ep = NULL ;
2008-01-05 09:57:31 -03:00
static int devnr ;
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
int err , i , ep_size , interval , num_urb , npackets ;
int urb_size , bytes_per_transfer ;
2014-01-10 05:43:09 -03:00
u8 alt ;
2008-01-05 09:57:31 -03:00
2011-06-17 15:15:12 -03:00
if ( ! dev - > has_alsa_audio | | dev - > audio_ifnum < 0 ) {
2008-06-10 12:34:35 -03:00
/* This device does not support the extension (in this case
2008-11-12 02:05:19 -03:00
the device is expecting the snd - usb - audio module or
doesn ' t have analog audio support at all ) */
2008-06-10 12:34:35 -03:00
return 0 ;
}
2013-12-26 12:41:03 -03:00
em28xx_info ( " Binding audio extension \n " ) ;
2008-01-05 09:57:31 -03:00
printk ( KERN_INFO " em28xx-audio.c: Copyright (C) 2006 Markus "
" Rechberger \n " ) ;
2013-12-28 21:16:26 -03:00
printk ( KERN_INFO
" em28xx-audio.c: Copyright (C) 2007-2014 Mauro Carvalho Chehab \n " ) ;
2008-01-05 09:57:31 -03:00
2009-01-12 15:17:09 +01:00
err = snd_card_create ( index [ devnr ] , " Em28xx Audio " , THIS_MODULE , 0 ,
& card ) ;
if ( err < 0 )
return err ;
2008-01-05 09:55:47 -03:00
spin_lock_init ( & adev - > slock ) ;
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
adev - > sndcard = card ;
adev - > udev = dev - > udev ;
2008-11-07 14:24:18 -03:00
err = snd_pcm_new ( card , " Em28xx Audio " , 0 , 0 , 1 , & pcm ) ;
if ( err < 0 ) {
snd_card_free ( card ) ;
return err ;
}
2008-01-05 09:55:47 -03:00
snd_pcm_set_ops ( pcm , SNDRV_PCM_STREAM_CAPTURE , & snd_em28xx_pcm_capture ) ;
pcm - > info_flags = 0 ;
pcm - > private_data = dev ;
2008-01-05 09:56:24 -03:00
strcpy ( pcm - > name , " Empia 28xx Capture " ) ;
2009-02-19 13:41:56 -03:00
snd_card_set_dev ( card , & dev - > udev - > dev ) ;
2010-03-23 08:40:43 -03:00
strcpy ( card - > driver , " Em28xx-Audio " ) ;
2008-01-05 09:55:47 -03:00
strcpy ( card - > shortname , " Em28xx Audio " ) ;
2008-01-05 09:56:24 -03:00
strcpy ( card - > longname , " Empia Em28xx Audio " ) ;
2008-01-05 09:55:47 -03:00
2010-10-09 15:53:58 -03:00
INIT_WORK ( & dev - > wq_trigger , audio_trigger ) ;
2011-06-19 13:06:40 -03:00
if ( dev - > audio_mode . ac97 ! = EM28XX_NO_AC97 ) {
2012-06-11 15:17:23 -03:00
em28xx_cvol_new ( card , dev , " Video " , AC97_VIDEO ) ;
em28xx_cvol_new ( card , dev , " Line In " , AC97_LINE ) ;
em28xx_cvol_new ( card , dev , " Phone " , AC97_PHONE ) ;
em28xx_cvol_new ( card , dev , " Microphone " , AC97_MIC ) ;
em28xx_cvol_new ( card , dev , " CD " , AC97_CD ) ;
em28xx_cvol_new ( card , dev , " AUX " , AC97_AUX ) ;
em28xx_cvol_new ( card , dev , " PCM " , AC97_PCM ) ;
em28xx_cvol_new ( card , dev , " Master " , AC97_MASTER ) ;
em28xx_cvol_new ( card , dev , " Line " , AC97_HEADPHONE ) ;
em28xx_cvol_new ( card , dev , " Mono " , AC97_MASTER_MONO ) ;
em28xx_cvol_new ( card , dev , " LFE " , AC97_CENTER_LFE_MASTER ) ;
em28xx_cvol_new ( card , dev , " Surround " , AC97_SURROUND_MASTER ) ;
2011-06-19 13:06:40 -03:00
}
2014-01-10 05:43:09 -03:00
if ( dev - > audio_ifnum )
alt = 1 ;
else
alt = 7 ;
intf = usb_ifnum_to_if ( dev - > udev , dev - > audio_ifnum ) ;
if ( intf - > num_altsetting < = alt ) {
em28xx_errdev ( " alt %d doesn't exist on interface %d \n " ,
dev - > audio_ifnum , alt ) ;
2014-01-10 06:59:09 -03:00
snd_card_free ( card ) ;
2014-01-10 05:43:09 -03:00
return - ENODEV ;
}
for ( i = 0 ; i < intf - > altsetting [ alt ] . desc . bNumEndpoints ; i + + ) {
e = & intf - > altsetting [ alt ] . endpoint [ i ] . desc ;
if ( ! usb_endpoint_dir_in ( e ) )
continue ;
if ( e - > bEndpointAddress = = EM28XX_EP_AUDIO ) {
ep = e ;
break ;
}
}
if ( ! ep ) {
em28xx_errdev ( " Couldn't find an audio endpoint " ) ;
2014-01-10 06:59:09 -03:00
snd_card_free ( card ) ;
2014-01-10 05:43:09 -03:00
return - ENODEV ;
}
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
ep_size = em28xx_audio_ep_packet_size ( dev - > udev , ep ) ;
interval = 1 < < ( ep - > bInterval - 1 ) ;
em28xx_info ( " Endpoint 0x%02x %s on intf %d alt %d interval = %d, size %d \n " ,
EM28XX_EP_AUDIO , usb_speed_string ( dev - > udev - > speed ) ,
dev - > audio_ifnum , alt ,
interval ,
ep_size ) ;
/* Calculate the number and size of URBs to better fit the audio samples */
/*
* Estimate the number of bytes per DMA transfer .
*
* This is given by the bit rate ( for now , only 48000 Hz ) multiplied
* by 2 channels and 2 bytes / sample divided by the number of microframe
* intervals and by the microframe rate ( 125 us )
*/
bytes_per_transfer = DIV_ROUND_UP ( 48000 * 2 * 2 , 125 * interval ) ;
/*
* Estimate the number of transfer URBs . Don ' t let it go past the
* maximum number of URBs that is known to be supported by the device .
*/
num_urb = DIV_ROUND_UP ( bytes_per_transfer , ep_size ) ;
if ( num_urb > EM28XX_MAX_AUDIO_BUFS )
num_urb = EM28XX_MAX_AUDIO_BUFS ;
/*
* Now that we know the number of bytes per transfer and the number of
* URBs , estimate the typical size of an URB , in order to adjust the
* minimal number of packets .
*/
urb_size = bytes_per_transfer / num_urb ;
/*
* Now , calculate the amount of audio packets to be filled on each
* URB . In order to preserve the old behaviour , use a minimal
* threshold for this value .
*/
npackets = EM28XX_MIN_AUDIO_PACKETS ;
if ( urb_size > ep_size * npackets )
npackets = DIV_ROUND_UP ( urb_size , ep_size ) ;
em28xx_info ( " Number of URBs: %d, with %d packets and %d size " ,
num_urb , npackets , urb_size ) ;
/* Allocate space to store the number of URBs to be used */
dev - > adev . transfer_buffer = kcalloc ( num_urb ,
sizeof ( * dev - > adev . transfer_buffer ) ,
GFP_ATOMIC ) ;
if ( ! dev - > adev . transfer_buffer ) {
snd_card_free ( card ) ;
return - ENOMEM ;
}
dev - > adev . urb = kcalloc ( num_urb , sizeof ( * dev - > adev . urb ) , GFP_ATOMIC ) ;
if ( ! dev - > adev . urb ) {
snd_card_free ( card ) ;
kfree ( dev - > adev . transfer_buffer ) ;
return - ENOMEM ;
}
/* Alloc memory for each URB and for each transfer buffer */
dev - > adev . num_urb = num_urb ;
for ( i = 0 ; i < num_urb ; i + + ) {
2013-12-28 21:16:26 -03:00
struct urb * urb ;
int j , k ;
void * buf ;
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
urb = usb_alloc_urb ( npackets , GFP_ATOMIC ) ;
2013-12-28 21:16:26 -03:00
if ( ! urb ) {
em28xx_errdev ( " usb_alloc_urb failed! \n " ) ;
em28xx_audio_free_urb ( dev ) ;
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
snd_card_free ( card ) ;
2013-12-28 21:16:26 -03:00
return - ENOMEM ;
}
dev - > adev . urb [ i ] = urb ;
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
buf = usb_alloc_coherent ( dev - > udev , npackets * ep_size , GFP_ATOMIC ,
2013-12-28 21:16:26 -03:00
& urb - > transfer_dma ) ;
if ( ! buf ) {
em28xx_errdev ( " usb_alloc_coherent failed! \n " ) ;
em28xx_audio_free_urb ( dev ) ;
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
snd_card_free ( card ) ;
2013-12-28 21:16:26 -03:00
return - ENOMEM ;
}
dev - > adev . transfer_buffer [ i ] = buf ;
urb - > dev = dev - > udev ;
urb - > context = dev ;
urb - > pipe = usb_rcvisocpipe ( dev - > udev , EM28XX_EP_AUDIO ) ;
urb - > transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP ;
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
urb - > transfer_buffer = buf ;
urb - > interval = interval ;
2013-12-28 21:16:26 -03:00
urb - > complete = em28xx_audio_isocirq ;
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
urb - > number_of_packets = npackets ;
urb - > transfer_buffer_length = ep_size * npackets ;
2014-01-10 05:43:09 -03:00
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
for ( j = k = 0 ; j < npackets ; j + + , k + = ep_size ) {
2013-12-28 21:16:26 -03:00
urb - > iso_frame_desc [ j ] . offset = k ;
[media] em28xx-audio: don't hardcode audio URB calculus
The current code hardcodes the number of audio URBs, the number
of packets per URB and the maximum URB size.
This is not a good idea, as it:
- wastes more bandwidth than necessary, by using a very
large number of packets;
- those constants are bound to an specific scenario, with
a bandwidth of 48 kHz;
- don't take the maximum endpoint size into account;
- with urb->interval = 1 on xHCI, those constraints cause a "funny"
setup: URBs with 64 packets inside, with only 24 bytes total. E. g.
a complete waste of space.
Change the code to do dynamic URB audio calculus and allocation.
For now, use the same constraints as used before this patch, to
avoid regressions.
A good scenario (tested) seems to use those defines, instead:
#define EM28XX_MAX_AUDIO_BUFS 8
#define EM28XX_MIN_AUDIO_PACKETS 2
But let's not do such change here, letting the optimization to
happen on latter patches, after more tests.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
2014-01-10 05:53:24 -03:00
urb - > iso_frame_desc [ j ] . length = ep_size ;
2013-12-28 21:16:26 -03:00
}
}
2008-01-05 09:57:31 -03:00
err = snd_card_register ( card ) ;
if ( err < 0 ) {
2014-01-10 06:59:09 -03:00
em28xx_audio_free_urb ( dev ) ;
2008-01-05 09:55:47 -03:00
snd_card_free ( card ) ;
2008-11-07 14:24:18 -03:00
return err ;
2008-01-05 09:55:47 -03:00
}
2008-01-05 09:57:31 -03:00
2013-12-26 12:41:03 -03:00
em28xx_info ( " Audio extension successfully initialized \n " ) ;
2008-01-05 09:55:47 -03:00
return 0 ;
}
static int em28xx_audio_fini ( struct em28xx * dev )
{
2008-01-05 09:56:24 -03:00
if ( dev = = NULL )
2008-01-05 09:55:47 -03:00
return 0 ;
2008-01-05 09:57:31 -03:00
2008-11-12 02:05:19 -03:00
if ( dev - > has_alsa_audio ! = 1 ) {
2008-06-10 12:34:35 -03:00
/* This device does not support the extension (in this case
2008-11-12 02:05:19 -03:00
the device is expecting the snd - usb - audio module or
doesn ' t have analog audio support at all ) */
2008-06-10 12:34:35 -03:00
return 0 ;
}
2013-12-28 21:16:26 -03:00
em28xx_audio_free_urb ( dev ) ;
2008-12-31 09:37:33 -03:00
if ( dev - > adev . sndcard ) {
snd_card_free ( dev - > adev . sndcard ) ;
dev - > adev . sndcard = NULL ;
2008-01-05 09:55:47 -03:00
}
2008-01-05 09:57:31 -03:00
2008-01-05 09:55:47 -03:00
return 0 ;
}
static struct em28xx_ops audio_ops = {
2008-01-05 09:57:31 -03:00
. id = EM28XX_AUDIO ,
2008-01-05 09:56:24 -03:00
. name = " Em28xx Audio Extension " ,
. init = em28xx_audio_init ,
. fini = em28xx_audio_fini ,
2008-01-05 09:55:47 -03:00
} ;
static int __init em28xx_alsa_register ( void )
{
return em28xx_register_extension ( & audio_ops ) ;
}
static void __exit em28xx_alsa_unregister ( void )
{
em28xx_unregister_extension ( & audio_ops ) ;
}
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Markus Rechberger <mrechberger@gmail.com> " ) ;
2011-06-17 15:15:12 -03:00
MODULE_AUTHOR ( " Mauro Carvalho Chehab <mchehab@redhat.com> " ) ;
2013-12-27 11:14:59 -03:00
MODULE_DESCRIPTION ( DRIVER_DESC " - audio interface " ) ;
MODULE_VERSION ( EM28XX_VERSION ) ;
2008-01-05 09:55:47 -03:00
module_init ( em28xx_alsa_register ) ;
module_exit ( em28xx_alsa_unregister ) ;