2010-03-04 21:46:13 +03:00
/*
* 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 . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
*/
2011-09-14 14:46:57 +04:00
# include <linux/gfp.h>
# include <linux/init.h>
2012-01-09 14:37:20 +04:00
# include <linux/ratelimit.h>
2011-09-14 14:46:57 +04:00
# include <linux/usb.h>
# include <linux/usb/audio.h>
2012-04-12 15:51:11 +04:00
# include <linux/slab.h>
2011-09-14 14:46:57 +04:00
# include <sound/core.h>
# include <sound/pcm.h>
2012-04-12 15:51:11 +04:00
# include <sound/pcm_params.h>
2011-09-14 14:46:57 +04:00
# include "usbaudio.h"
# include "helper.h"
# include "card.h"
# include "endpoint.h"
# include "pcm.h"
2012-09-04 12:23:07 +04:00
# include "quirks.h"
2011-09-14 14:46:57 +04:00
2012-04-12 15:51:11 +04:00
# define EP_FLAG_ACTIVATED 0
# define EP_FLAG_RUNNING 1
2012-04-12 15:51:15 +04:00
/*
* snd_usb_endpoint is a model that abstracts everything related to an
* USB endpoint and its streaming .
*
* There are functions to activate and deactivate the streaming URBs and
2012-04-24 21:31:24 +04:00
* optional callbacks to let the pcm logic handle the actual content of the
2012-04-12 15:51:15 +04:00
* packets for playback and record . Thus , the bus streaming and the audio
* handlers are fully decoupled .
*
2012-04-24 21:31:24 +04:00
* There are two different types of endpoints in audio applications .
2012-04-12 15:51:15 +04:00
*
* SND_USB_ENDPOINT_TYPE_DATA handles full audio data payload for both
* inbound and outbound traffic .
*
2012-04-24 21:31:24 +04:00
* SND_USB_ENDPOINT_TYPE_SYNC endpoints are for inbound traffic only and
* expect the payload to carry Q10 .14 / Q16 .16 formatted sync information
* ( 3 or 4 bytes ) .
2012-04-12 15:51:15 +04:00
*
2012-04-24 21:31:24 +04:00
* Each endpoint has to be configured prior to being used by calling
* snd_usb_endpoint_set_params ( ) .
2012-04-12 15:51:15 +04:00
*
* The model incorporates a reference counting , so that multiple users
* can call snd_usb_endpoint_start ( ) and snd_usb_endpoint_stop ( ) , and
* only the first user will effectively start the URBs , and only the last
2012-04-24 21:31:24 +04:00
* one to stop it will tear the URBs down again .
2012-04-12 15:51:15 +04:00
*/
2011-09-14 14:46:57 +04:00
/*
* convert a sampling rate into our full speed format ( fs / 1000 in Q16 .16 )
* this will overflow at approx 524 kHz
*/
static inline unsigned get_usb_full_speed_rate ( unsigned int rate )
{
return ( ( rate < < 13 ) + 62 ) / 125 ;
}
/*
* convert a sampling rate into USB high speed format ( fs / 8000 in Q16 .16 )
* this will overflow at approx 4 MHz
*/
static inline unsigned get_usb_high_speed_rate ( unsigned int rate )
{
return ( ( rate < < 10 ) + 62 ) / 125 ;
}
/*
* release a urb data
*/
static void release_urb_ctx ( struct snd_urb_ctx * u )
{
2012-04-12 15:51:13 +04:00
if ( u - > buffer_size )
usb_free_coherent ( u - > ep - > chip - > dev , u - > buffer_size ,
u - > urb - > transfer_buffer ,
u - > urb - > transfer_dma ) ;
usb_free_urb ( u - > urb ) ;
u - > urb = NULL ;
2011-09-14 14:46:57 +04:00
}
static const char * usb_error_string ( int err )
{
switch ( err ) {
case - ENODEV :
return " no device " ;
case - ENOENT :
return " endpoint not enabled " ;
case - EPIPE :
return " endpoint stalled " ;
case - ENOSPC :
return " not enough bandwidth " ;
case - ESHUTDOWN :
return " device disabled " ;
case - EHOSTUNREACH :
return " device suspended " ;
case - EINVAL :
case - EAGAIN :
case - EFBIG :
case - EMSGSIZE :
return " internal error " ;
default :
return " unknown error " ;
}
}
2012-04-12 15:51:15 +04:00
/**
* snd_usb_endpoint_implicit_feedback_sink : Report endpoint usage type
*
2012-04-24 21:31:24 +04:00
* @ ep : The snd_usb_endpoint
2012-04-12 15:51:15 +04:00
*
* Determine whether an endpoint is driven by an implicit feedback
* data endpoint source .
*/
2012-04-12 15:51:11 +04:00
int snd_usb_endpoint_implict_feedback_sink ( struct snd_usb_endpoint * ep )
{
return ep - > sync_master & &
ep - > sync_master - > type = = SND_USB_ENDPOINT_TYPE_DATA & &
ep - > type = = SND_USB_ENDPOINT_TYPE_DATA & &
usb_pipeout ( ep - > pipe ) ;
}
2012-04-12 15:51:15 +04:00
/*
* For streaming based on information derived from sync endpoints ,
* prepare_outbound_urb_sizes ( ) will call next_packet_size ( ) to
* determine the number of samples to be sent in the next packet .
*
* For implicit feedback , next_packet_size ( ) is unused .
*/
2012-08-30 20:52:30 +04:00
int snd_usb_endpoint_next_packet_size ( struct snd_usb_endpoint * ep )
2012-04-12 15:51:11 +04:00
{
unsigned long flags ;
int ret ;
if ( ep - > fill_max )
return ep - > maxframesize ;
spin_lock_irqsave ( & ep - > lock , flags ) ;
ep - > phase = ( ep - > phase & 0xffff )
+ ( ep - > freqm < < ep - > datainterval ) ;
ret = min ( ep - > phase > > 16 , ep - > maxframesize ) ;
spin_unlock_irqrestore ( & ep - > lock , flags ) ;
return ret ;
}
static void retire_outbound_urb ( struct snd_usb_endpoint * ep ,
struct snd_urb_ctx * urb_ctx )
{
if ( ep - > retire_data_urb )
ep - > retire_data_urb ( ep - > data_subs , urb_ctx - > urb ) ;
}
static void retire_inbound_urb ( struct snd_usb_endpoint * ep ,
struct snd_urb_ctx * urb_ctx )
{
struct urb * urb = urb_ctx - > urb ;
2012-09-04 12:23:07 +04:00
if ( unlikely ( ep - > skip_packets > 0 ) ) {
ep - > skip_packets - - ;
return ;
}
2012-04-12 15:51:11 +04:00
if ( ep - > sync_slave )
snd_usb_handle_sync_urb ( ep - > sync_slave , ep , urb ) ;
if ( ep - > retire_data_urb )
ep - > retire_data_urb ( ep - > data_subs , urb ) ;
}
/*
* Prepare a PLAYBACK urb for submission to the bus .
*/
static void prepare_outbound_urb ( struct snd_usb_endpoint * ep ,
struct snd_urb_ctx * ctx )
{
int i ;
struct urb * urb = ctx - > urb ;
unsigned char * cp = urb - > transfer_buffer ;
urb - > dev = ep - > chip - > dev ; /* we need to set this at each time */
switch ( ep - > type ) {
case SND_USB_ENDPOINT_TYPE_DATA :
if ( ep - > prepare_data_urb ) {
ep - > prepare_data_urb ( ep - > data_subs , urb ) ;
} else {
/* no data provider, so send silence */
unsigned int offs = 0 ;
for ( i = 0 ; i < ctx - > packets ; + + i ) {
2012-09-27 12:26:01 +04:00
int counts ;
if ( ctx - > packet_size [ i ] )
counts = ctx - > packet_size [ i ] ;
else
counts = snd_usb_endpoint_next_packet_size ( ep ) ;
2012-04-12 15:51:11 +04:00
urb - > iso_frame_desc [ i ] . offset = offs * ep - > stride ;
urb - > iso_frame_desc [ i ] . length = counts * ep - > stride ;
offs + = counts ;
}
urb - > number_of_packets = ctx - > packets ;
urb - > transfer_buffer_length = offs * ep - > stride ;
memset ( urb - > transfer_buffer , ep - > silence_value ,
offs * ep - > stride ) ;
}
break ;
case SND_USB_ENDPOINT_TYPE_SYNC :
if ( snd_usb_get_speed ( ep - > chip - > dev ) > = USB_SPEED_HIGH ) {
/*
* fill the length and offset of each urb descriptor .
* the fixed 12.13 frequency is passed as 16.16 through the pipe .
*/
urb - > iso_frame_desc [ 0 ] . length = 4 ;
urb - > iso_frame_desc [ 0 ] . offset = 0 ;
cp [ 0 ] = ep - > freqn ;
cp [ 1 ] = ep - > freqn > > 8 ;
cp [ 2 ] = ep - > freqn > > 16 ;
cp [ 3 ] = ep - > freqn > > 24 ;
} else {
/*
* fill the length and offset of each urb descriptor .
* the fixed 10.14 frequency is passed through the pipe .
*/
urb - > iso_frame_desc [ 0 ] . length = 3 ;
urb - > iso_frame_desc [ 0 ] . offset = 0 ;
cp [ 0 ] = ep - > freqn > > 2 ;
cp [ 1 ] = ep - > freqn > > 10 ;
cp [ 2 ] = ep - > freqn > > 18 ;
}
break ;
}
}
/*
* Prepare a CAPTURE or SYNC urb for submission to the bus .
*/
static inline void prepare_inbound_urb ( struct snd_usb_endpoint * ep ,
struct snd_urb_ctx * urb_ctx )
{
int i , offs ;
struct urb * urb = urb_ctx - > urb ;
urb - > dev = ep - > chip - > dev ; /* we need to set this at each time */
switch ( ep - > type ) {
case SND_USB_ENDPOINT_TYPE_DATA :
offs = 0 ;
for ( i = 0 ; i < urb_ctx - > packets ; i + + ) {
urb - > iso_frame_desc [ i ] . offset = offs ;
urb - > iso_frame_desc [ i ] . length = ep - > curpacksize ;
offs + = ep - > curpacksize ;
}
urb - > transfer_buffer_length = offs ;
urb - > number_of_packets = urb_ctx - > packets ;
break ;
case SND_USB_ENDPOINT_TYPE_SYNC :
urb - > iso_frame_desc [ 0 ] . length = min ( 4u , ep - > syncmaxsize ) ;
urb - > iso_frame_desc [ 0 ] . offset = 0 ;
break ;
}
}
2012-04-12 15:51:15 +04:00
/*
2012-04-24 21:31:24 +04:00
* Send output urbs that have been prepared previously . URBs are dequeued
2012-04-12 15:51:15 +04:00
* from ep - > ready_playback_urbs and in case there there aren ' t any available
* or there are no packets that have been prepared , this function does
* nothing .
*
2012-04-24 21:31:24 +04:00
* The reason why the functionality of sending and preparing URBs is separated
* is that host controllers don ' t guarantee the order in which they return
* inbound and outbound packets to their submitters .
2012-04-12 15:51:15 +04:00
*
* This function is only used for implicit feedback endpoints . For endpoints
2012-04-24 21:31:24 +04:00
* driven by dedicated sync endpoints , URBs are immediately re - submitted
* from their completion handler .
2012-04-12 15:51:15 +04:00
*/
2012-04-12 15:51:11 +04:00
static void queue_pending_output_urbs ( struct snd_usb_endpoint * ep )
{
while ( test_bit ( EP_FLAG_RUNNING , & ep - > flags ) ) {
unsigned long flags ;
2012-04-24 10:10:10 +04:00
struct snd_usb_packet_info * uninitialized_var ( packet ) ;
2012-04-12 15:51:11 +04:00
struct snd_urb_ctx * ctx = NULL ;
struct urb * urb ;
int err , i ;
spin_lock_irqsave ( & ep - > lock , flags ) ;
if ( ep - > next_packet_read_pos ! = ep - > next_packet_write_pos ) {
packet = ep - > next_packet + ep - > next_packet_read_pos ;
ep - > next_packet_read_pos + + ;
ep - > next_packet_read_pos % = MAX_URBS ;
/* take URB out of FIFO */
if ( ! list_empty ( & ep - > ready_playback_urbs ) )
ctx = list_first_entry ( & ep - > ready_playback_urbs ,
struct snd_urb_ctx , ready_list ) ;
}
spin_unlock_irqrestore ( & ep - > lock , flags ) ;
if ( ctx = = NULL )
return ;
list_del_init ( & ctx - > ready_list ) ;
urb = ctx - > urb ;
/* copy over the length information */
for ( i = 0 ; i < packet - > packets ; i + + )
ctx - > packet_size [ i ] = packet - > packet_size [ i ] ;
2012-04-12 15:51:15 +04:00
/* call the data handler to fill in playback data */
2012-04-12 15:51:11 +04:00
prepare_outbound_urb ( ep , ctx ) ;
err = usb_submit_urb ( ctx - > urb , GFP_ATOMIC ) ;
if ( err < 0 )
snd_printk ( KERN_ERR " Unable to submit urb #%d: %d (urb %p) \n " ,
ctx - > index , err , ctx - > urb ) ;
else
set_bit ( ctx - > index , & ep - > active_mask ) ;
}
}
/*
* complete callback for urbs
*/
static void snd_complete_urb ( struct urb * urb )
{
struct snd_urb_ctx * ctx = urb - > context ;
struct snd_usb_endpoint * ep = ctx - > ep ;
int err ;
if ( unlikely ( urb - > status = = - ENOENT | | /* unlinked */
urb - > status = = - ENODEV | | /* device removed */
urb - > status = = - ECONNRESET | | /* unlinked */
urb - > status = = - ESHUTDOWN | | /* device disabled */
ep - > chip - > shutdown ) ) /* device disconnected */
goto exit_clear ;
if ( usb_pipeout ( ep - > pipe ) ) {
retire_outbound_urb ( ep , ctx ) ;
/* can be stopped during retire callback */
if ( unlikely ( ! test_bit ( EP_FLAG_RUNNING , & ep - > flags ) ) )
goto exit_clear ;
if ( snd_usb_endpoint_implict_feedback_sink ( ep ) ) {
unsigned long flags ;
spin_lock_irqsave ( & ep - > lock , flags ) ;
list_add_tail ( & ctx - > ready_list , & ep - > ready_playback_urbs ) ;
spin_unlock_irqrestore ( & ep - > lock , flags ) ;
queue_pending_output_urbs ( ep ) ;
goto exit_clear ;
}
prepare_outbound_urb ( ep , ctx ) ;
} else {
retire_inbound_urb ( ep , ctx ) ;
/* can be stopped during retire callback */
if ( unlikely ( ! test_bit ( EP_FLAG_RUNNING , & ep - > flags ) ) )
goto exit_clear ;
prepare_inbound_urb ( ep , ctx ) ;
}
err = usb_submit_urb ( urb , GFP_ATOMIC ) ;
if ( err = = 0 )
return ;
snd_printk ( KERN_ERR " cannot submit urb (err = %d) \n " , err ) ;
//snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
exit_clear :
clear_bit ( ctx - > index , & ep - > active_mask ) ;
}
2012-04-12 15:51:15 +04:00
/**
2012-04-24 21:31:24 +04:00
* snd_usb_add_endpoint : Add an endpoint to an USB audio chip
2012-04-12 15:51:15 +04:00
*
* @ chip : The chip
* @ alts : The USB host interface
* @ ep_num : The number of the endpoint to use
* @ direction : SNDRV_PCM_STREAM_PLAYBACK or SNDRV_PCM_STREAM_CAPTURE
* @ type : SND_USB_ENDPOINT_TYPE_DATA or SND_USB_ENDPOINT_TYPE_SYNC
*
* If the requested endpoint has not been added to the given chip before ,
* a new instance is created . Otherwise , a pointer to the previoulsy
* created instance is returned . In case of any error , NULL is returned .
*
* New endpoints will be added to chip - > ep_list and must be freed by
* calling snd_usb_endpoint_free ( ) .
*/
2012-04-12 15:51:11 +04:00
struct snd_usb_endpoint * snd_usb_add_endpoint ( struct snd_usb_audio * chip ,
struct usb_host_interface * alts ,
int ep_num , int direction , int type )
{
struct list_head * p ;
struct snd_usb_endpoint * ep ;
2012-07-12 15:08:40 +04:00
int is_playback = direction = = SNDRV_PCM_STREAM_PLAYBACK ;
2012-04-12 15:51:11 +04:00
mutex_lock ( & chip - > mutex ) ;
list_for_each ( p , & chip - > ep_list ) {
ep = list_entry ( p , struct snd_usb_endpoint , list ) ;
if ( ep - > ep_num = = ep_num & &
ep - > iface = = alts - > desc . bInterfaceNumber & &
ep - > alt_idx = = alts - > desc . bAlternateSetting ) {
snd_printdd ( KERN_DEBUG " Re-using EP %x in iface %d,%d @%p \n " ,
ep_num , ep - > iface , ep - > alt_idx , ep ) ;
goto __exit_unlock ;
}
}
snd_printdd ( KERN_DEBUG " Creating new %s %s endpoint #%x \n " ,
is_playback ? " playback " : " capture " ,
type = = SND_USB_ENDPOINT_TYPE_DATA ? " data " : " sync " ,
ep_num ) ;
ep = kzalloc ( sizeof ( * ep ) , GFP_KERNEL ) ;
if ( ! ep )
goto __exit_unlock ;
ep - > chip = chip ;
spin_lock_init ( & ep - > lock ) ;
ep - > type = type ;
ep - > ep_num = ep_num ;
ep - > iface = alts - > desc . bInterfaceNumber ;
ep - > alt_idx = alts - > desc . bAlternateSetting ;
INIT_LIST_HEAD ( & ep - > ready_playback_urbs ) ;
ep_num & = USB_ENDPOINT_NUMBER_MASK ;
if ( is_playback )
ep - > pipe = usb_sndisocpipe ( chip - > dev , ep_num ) ;
else
ep - > pipe = usb_rcvisocpipe ( chip - > dev , ep_num ) ;
if ( type = = SND_USB_ENDPOINT_TYPE_SYNC ) {
if ( get_endpoint ( alts , 1 ) - > bLength > = USB_DT_ENDPOINT_AUDIO_SIZE & &
get_endpoint ( alts , 1 ) - > bRefresh > = 1 & &
get_endpoint ( alts , 1 ) - > bRefresh < = 9 )
ep - > syncinterval = get_endpoint ( alts , 1 ) - > bRefresh ;
else if ( snd_usb_get_speed ( chip - > dev ) = = USB_SPEED_FULL )
ep - > syncinterval = 1 ;
else if ( get_endpoint ( alts , 1 ) - > bInterval > = 1 & &
get_endpoint ( alts , 1 ) - > bInterval < = 16 )
ep - > syncinterval = get_endpoint ( alts , 1 ) - > bInterval - 1 ;
else
ep - > syncinterval = 3 ;
ep - > syncmaxsize = le16_to_cpu ( get_endpoint ( alts , 1 ) - > wMaxPacketSize ) ;
}
list_add_tail ( & ep - > list , & chip - > ep_list ) ;
__exit_unlock :
mutex_unlock ( & chip - > mutex ) ;
return ep ;
}
/*
* wait until all urbs are processed .
*/
static int wait_clear_urbs ( struct snd_usb_endpoint * ep )
{
unsigned long end_time = jiffies + msecs_to_jiffies ( 1000 ) ;
unsigned int i ;
int alive ;
do {
alive = 0 ;
for ( i = 0 ; i < ep - > nurbs ; i + + )
if ( test_bit ( i , & ep - > active_mask ) )
alive + + ;
if ( ! alive )
break ;
schedule_timeout_uninterruptible ( 1 ) ;
} while ( time_before ( jiffies , end_time ) ) ;
if ( alive )
snd_printk ( KERN_ERR " timeout: still %d active urbs on EP #%x \n " ,
alive , ep - > ep_num ) ;
return 0 ;
}
/*
* unlink active urbs .
*/
static int deactivate_urbs ( struct snd_usb_endpoint * ep , int force , int can_sleep )
{
unsigned int i ;
int async ;
if ( ! force & & ep - > chip - > shutdown ) /* to be sure... */
return - EBADFD ;
async = ! can_sleep & & ep - > chip - > async_unlink ;
clear_bit ( EP_FLAG_RUNNING , & ep - > flags ) ;
INIT_LIST_HEAD ( & ep - > ready_playback_urbs ) ;
ep - > next_packet_read_pos = 0 ;
ep - > next_packet_write_pos = 0 ;
if ( ! async & & in_interrupt ( ) )
return 0 ;
for ( i = 0 ; i < ep - > nurbs ; i + + ) {
if ( test_bit ( i , & ep - > active_mask ) ) {
if ( ! test_and_set_bit ( i , & ep - > unlink_mask ) ) {
struct urb * u = ep - > urb [ i ] . urb ;
if ( async )
usb_unlink_urb ( u ) ;
else
usb_kill_urb ( u ) ;
}
}
}
return 0 ;
}
/*
* release an endpoint ' s urbs
*/
static void release_urbs ( struct snd_usb_endpoint * ep , int force )
{
int i ;
/* route incoming urbs to nirvana */
ep - > retire_data_urb = NULL ;
ep - > prepare_data_urb = NULL ;
/* stop urbs */
deactivate_urbs ( ep , force , 1 ) ;
wait_clear_urbs ( ep ) ;
for ( i = 0 ; i < ep - > nurbs ; i + + )
release_urb_ctx ( & ep - > urb [ i ] ) ;
if ( ep - > syncbuf )
usb_free_coherent ( ep - > chip - > dev , SYNC_URBS * 4 ,
ep - > syncbuf , ep - > sync_dma ) ;
ep - > syncbuf = NULL ;
ep - > nurbs = 0 ;
}
2012-04-12 15:51:15 +04:00
/*
* configure a data endpoint
*/
2012-04-12 15:51:11 +04:00
static int data_ep_set_params ( struct snd_usb_endpoint * ep ,
2012-09-18 20:49:47 +04:00
snd_pcm_format_t pcm_format ,
unsigned int channels ,
unsigned int period_bytes ,
2012-04-12 15:51:11 +04:00
struct audioformat * fmt ,
struct snd_usb_endpoint * sync_ep )
{
unsigned int maxsize , i , urb_packs , total_packs , packs_per_ms ;
int is_playback = usb_pipeout ( ep - > pipe ) ;
2012-09-18 20:49:47 +04:00
int frame_bits = snd_pcm_format_physical_width ( pcm_format ) * channels ;
2012-04-12 15:51:11 +04:00
ep - > datainterval = fmt - > datainterval ;
ep - > stride = frame_bits > > 3 ;
2012-09-18 20:49:47 +04:00
ep - > silence_value = pcm_format = = SNDRV_PCM_FORMAT_U8 ? 0x80 : 0 ;
2012-04-12 15:51:11 +04:00
/* calculate max. frequency */
if ( ep - > maxpacksize ) {
/* whatever fits into a max. size packet */
maxsize = ep - > maxpacksize ;
ep - > freqmax = ( maxsize / ( frame_bits > > 3 ) )
< < ( 16 - ep - > datainterval ) ;
} else {
/* no max. packet size: just take 25% higher than nominal */
ep - > freqmax = ep - > freqn + ( ep - > freqn > > 2 ) ;
maxsize = ( ( ep - > freqmax + 0xffff ) * ( frame_bits > > 3 ) )
> > ( 16 - ep - > datainterval ) ;
}
if ( ep - > fill_max )
ep - > curpacksize = ep - > maxpacksize ;
else
ep - > curpacksize = maxsize ;
if ( snd_usb_get_speed ( ep - > chip - > dev ) ! = USB_SPEED_FULL )
packs_per_ms = 8 > > ep - > datainterval ;
else
packs_per_ms = 1 ;
if ( is_playback & & ! snd_usb_endpoint_implict_feedback_sink ( ep ) ) {
urb_packs = max ( ep - > chip - > nrpacks , 1 ) ;
urb_packs = min ( urb_packs , ( unsigned int ) MAX_PACKS ) ;
} else {
urb_packs = 1 ;
}
urb_packs * = packs_per_ms ;
if ( sync_ep & & ! snd_usb_endpoint_implict_feedback_sink ( ep ) )
urb_packs = min ( urb_packs , 1U < < sync_ep - > syncinterval ) ;
/* decide how many packets to be used */
if ( is_playback & & ! snd_usb_endpoint_implict_feedback_sink ( ep ) ) {
unsigned int minsize , maxpacks ;
/* determine how small a packet can be */
minsize = ( ep - > freqn > > ( 16 - ep - > datainterval ) )
* ( frame_bits > > 3 ) ;
/* with sync from device, assume it can be 12% lower */
if ( sync_ep )
minsize - = minsize > > 3 ;
minsize = max ( minsize , 1u ) ;
total_packs = ( period_bytes + minsize - 1 ) / minsize ;
/* we need at least two URBs for queueing */
if ( total_packs < 2 ) {
total_packs = 2 ;
} else {
/* and we don't want too long a queue either */
maxpacks = max ( MAX_QUEUE * packs_per_ms , urb_packs * 2 ) ;
total_packs = min ( total_packs , maxpacks ) ;
}
} else {
while ( urb_packs > 1 & & urb_packs * maxsize > = period_bytes )
urb_packs > > = 1 ;
total_packs = MAX_URBS * urb_packs ;
}
ep - > nurbs = ( total_packs + urb_packs - 1 ) / urb_packs ;
if ( ep - > nurbs > MAX_URBS ) {
/* too much... */
ep - > nurbs = MAX_URBS ;
total_packs = MAX_URBS * urb_packs ;
} else if ( ep - > nurbs < 2 ) {
/* too little - we need at least two packets
* to ensure contiguous playback / capture
*/
ep - > nurbs = 2 ;
}
/* allocate and initialize data urbs */
for ( i = 0 ; i < ep - > nurbs ; i + + ) {
struct snd_urb_ctx * u = & ep - > urb [ i ] ;
u - > index = i ;
u - > ep = ep ;
u - > packets = ( i + 1 ) * total_packs / ep - > nurbs
- i * total_packs / ep - > nurbs ;
u - > buffer_size = maxsize * u - > packets ;
if ( fmt - > fmt_type = = UAC_FORMAT_TYPE_II )
u - > packets + + ; /* for transfer delimiter */
u - > urb = usb_alloc_urb ( u - > packets , GFP_KERNEL ) ;
if ( ! u - > urb )
goto out_of_memory ;
u - > urb - > transfer_buffer =
usb_alloc_coherent ( ep - > chip - > dev , u - > buffer_size ,
GFP_KERNEL , & u - > urb - > transfer_dma ) ;
if ( ! u - > urb - > transfer_buffer )
goto out_of_memory ;
u - > urb - > pipe = ep - > pipe ;
u - > urb - > transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP ;
u - > urb - > interval = 1 < < ep - > datainterval ;
u - > urb - > context = u ;
u - > urb - > complete = snd_complete_urb ;
INIT_LIST_HEAD ( & u - > ready_list ) ;
}
return 0 ;
out_of_memory :
release_urbs ( ep , 0 ) ;
return - ENOMEM ;
}
2012-04-12 15:51:15 +04:00
/*
* configure a sync endpoint
*/
2012-04-12 15:51:11 +04:00
static int sync_ep_set_params ( struct snd_usb_endpoint * ep ,
struct audioformat * fmt )
{
int i ;
ep - > syncbuf = usb_alloc_coherent ( ep - > chip - > dev , SYNC_URBS * 4 ,
GFP_KERNEL , & ep - > sync_dma ) ;
if ( ! ep - > syncbuf )
return - ENOMEM ;
for ( i = 0 ; i < SYNC_URBS ; i + + ) {
struct snd_urb_ctx * u = & ep - > urb [ i ] ;
u - > index = i ;
u - > ep = ep ;
u - > packets = 1 ;
u - > urb = usb_alloc_urb ( 1 , GFP_KERNEL ) ;
if ( ! u - > urb )
goto out_of_memory ;
u - > urb - > transfer_buffer = ep - > syncbuf + i * 4 ;
u - > urb - > transfer_dma = ep - > sync_dma + i * 4 ;
u - > urb - > transfer_buffer_length = 4 ;
u - > urb - > pipe = ep - > pipe ;
u - > urb - > transfer_flags = URB_ISO_ASAP |
URB_NO_TRANSFER_DMA_MAP ;
u - > urb - > number_of_packets = 1 ;
u - > urb - > interval = 1 < < ep - > syncinterval ;
u - > urb - > context = u ;
u - > urb - > complete = snd_complete_urb ;
}
ep - > nurbs = SYNC_URBS ;
return 0 ;
out_of_memory :
release_urbs ( ep , 0 ) ;
return - ENOMEM ;
}
2012-04-12 15:51:15 +04:00
/**
2012-04-24 21:31:24 +04:00
* snd_usb_endpoint_set_params : configure an snd_usb_endpoint
2012-04-12 15:51:15 +04:00
*
2012-04-24 21:31:24 +04:00
* @ ep : the snd_usb_endpoint to configure
2012-09-18 20:49:47 +04:00
* @ pcm_format : the audio fomat .
* @ channels : the number of audio channels .
* @ period_bytes : the number of bytes in one alsa period .
* @ rate : the frame rate .
2012-04-24 21:31:24 +04:00
* @ fmt : the USB audio format information
* @ sync_ep : the sync endpoint to use , if any
2012-04-12 15:51:15 +04:00
*
2012-04-24 21:31:24 +04:00
* Determine the number of URBs to be used on this endpoint .
2012-04-12 15:51:15 +04:00
* An endpoint must be configured before it can be started .
* An endpoint that is already running can not be reconfigured .
*/
2012-04-12 15:51:11 +04:00
int snd_usb_endpoint_set_params ( struct snd_usb_endpoint * ep ,
2012-09-18 20:49:47 +04:00
snd_pcm_format_t pcm_format ,
unsigned int channels ,
unsigned int period_bytes ,
unsigned int rate ,
2012-04-12 15:51:11 +04:00
struct audioformat * fmt ,
struct snd_usb_endpoint * sync_ep )
{
int err ;
if ( ep - > use_count ! = 0 ) {
snd_printk ( KERN_WARNING " Unable to change format on ep #%x: already in use \n " ,
ep - > ep_num ) ;
return - EBUSY ;
}
/* release old buffers, if any */
release_urbs ( ep , 0 ) ;
ep - > datainterval = fmt - > datainterval ;
ep - > maxpacksize = fmt - > maxpacksize ;
2012-04-13 14:41:54 +04:00
ep - > fill_max = ! ! ( fmt - > attributes & UAC_EP_CS_ATTR_FILL_MAX ) ;
2012-04-12 15:51:11 +04:00
if ( snd_usb_get_speed ( ep - > chip - > dev ) = = USB_SPEED_FULL )
2012-09-18 20:49:47 +04:00
ep - > freqn = get_usb_full_speed_rate ( rate ) ;
2012-04-12 15:51:11 +04:00
else
2012-09-18 20:49:47 +04:00
ep - > freqn = get_usb_high_speed_rate ( rate ) ;
2012-04-12 15:51:11 +04:00
/* calculate the frequency in 16.16 format */
ep - > freqm = ep - > freqn ;
ep - > freqshift = INT_MIN ;
ep - > phase = 0 ;
switch ( ep - > type ) {
case SND_USB_ENDPOINT_TYPE_DATA :
2012-09-18 20:49:47 +04:00
err = data_ep_set_params ( ep , pcm_format , channels ,
period_bytes , fmt , sync_ep ) ;
2012-04-12 15:51:11 +04:00
break ;
case SND_USB_ENDPOINT_TYPE_SYNC :
2012-09-18 20:49:47 +04:00
err = sync_ep_set_params ( ep , fmt ) ;
2012-04-12 15:51:11 +04:00
break ;
default :
err = - EINVAL ;
}
snd_printdd ( KERN_DEBUG " Setting params for ep #%x (type %d, %d urbs), ret=%d \n " ,
ep - > ep_num , ep - > type , ep - > nurbs , err ) ;
return err ;
}
2012-04-12 15:51:15 +04:00
/**
* snd_usb_endpoint_start : start an snd_usb_endpoint
*
2012-08-29 15:17:05 +04:00
* @ ep : the endpoint to start
* @ can_sleep : flag indicating whether the operation is executed in
* non - atomic context
2012-04-12 15:51:15 +04:00
*
* A call to this function will increment the use count of the endpoint .
2012-04-24 21:31:24 +04:00
* In case it is not already running , the URBs for this endpoint will be
2012-04-12 15:51:15 +04:00
* submitted . Otherwise , this function does nothing .
*
* Must be balanced to calls of snd_usb_endpoint_stop ( ) .
*
* Returns an error if the URB submission failed , 0 in all other cases .
*/
2012-08-29 15:17:05 +04:00
int snd_usb_endpoint_start ( struct snd_usb_endpoint * ep , int can_sleep )
2012-04-12 15:51:11 +04:00
{
int err ;
unsigned int i ;
if ( ep - > chip - > shutdown )
return - EBADFD ;
/* already running? */
if ( + + ep - > use_count ! = 1 )
return 0 ;
2012-08-29 15:17:05 +04:00
/* just to be sure */
deactivate_urbs ( ep , 0 , can_sleep ) ;
if ( can_sleep )
wait_clear_urbs ( ep ) ;
2012-04-12 15:51:11 +04:00
ep - > active_mask = 0 ;
ep - > unlink_mask = 0 ;
ep - > phase = 0 ;
2012-09-04 12:23:07 +04:00
snd_usb_endpoint_start_quirk ( ep ) ;
2012-04-12 15:51:11 +04:00
/*
* If this endpoint has a data endpoint as implicit feedback source ,
* don ' t start the urbs here . Instead , mark them all as available ,
2012-04-24 21:31:24 +04:00
* wait for the record urbs to return and queue the playback urbs
* from that context .
2012-04-12 15:51:11 +04:00
*/
set_bit ( EP_FLAG_RUNNING , & ep - > flags ) ;
if ( snd_usb_endpoint_implict_feedback_sink ( ep ) ) {
for ( i = 0 ; i < ep - > nurbs ; i + + ) {
struct snd_urb_ctx * ctx = ep - > urb + i ;
list_add_tail ( & ctx - > ready_list , & ep - > ready_playback_urbs ) ;
}
return 0 ;
}
for ( i = 0 ; i < ep - > nurbs ; i + + ) {
struct urb * urb = ep - > urb [ i ] . urb ;
if ( snd_BUG_ON ( ! urb ) )
goto __error ;
if ( usb_pipeout ( ep - > pipe ) ) {
prepare_outbound_urb ( ep , urb - > context ) ;
} else {
prepare_inbound_urb ( ep , urb - > context ) ;
}
err = usb_submit_urb ( urb , GFP_ATOMIC ) ;
if ( err < 0 ) {
snd_printk ( KERN_ERR " cannot submit urb %d, error %d: %s \n " ,
i , err , usb_error_string ( err ) ) ;
goto __error ;
}
set_bit ( i , & ep - > active_mask ) ;
}
return 0 ;
__error :
clear_bit ( EP_FLAG_RUNNING , & ep - > flags ) ;
ep - > use_count - - ;
deactivate_urbs ( ep , 0 , 0 ) ;
return - EPIPE ;
}
2012-04-12 15:51:15 +04:00
/**
* snd_usb_endpoint_stop : stop an snd_usb_endpoint
*
* @ ep : the endpoint to stop ( may be NULL )
*
* A call to this function will decrement the use count of the endpoint .
* In case the last user has requested the endpoint stop , the URBs will
2012-04-24 21:31:24 +04:00
* actually be deactivated .
2012-04-12 15:51:15 +04:00
*
* Must be balanced to calls of snd_usb_endpoint_start ( ) .
*/
2012-04-12 15:51:11 +04:00
void snd_usb_endpoint_stop ( struct snd_usb_endpoint * ep ,
int force , int can_sleep , int wait )
{
if ( ! ep )
return ;
if ( snd_BUG_ON ( ep - > use_count = = 0 ) )
return ;
if ( - - ep - > use_count = = 0 ) {
deactivate_urbs ( ep , force , can_sleep ) ;
ep - > data_subs = NULL ;
ep - > sync_slave = NULL ;
ep - > retire_data_urb = NULL ;
ep - > prepare_data_urb = NULL ;
if ( wait )
wait_clear_urbs ( ep ) ;
}
}
2012-04-12 15:51:15 +04:00
/**
* snd_usb_endpoint_deactivate : deactivate an snd_usb_endpoint
*
* @ ep : the endpoint to deactivate
*
* If the endpoint is not currently in use , this functions will select the
* alternate interface setting 0 for the interface of this endpoint .
*
* In case of any active users , this functions does nothing .
*
* Returns an error if usb_set_interface ( ) failed , 0 in all other
* cases .
*/
2012-04-12 15:51:11 +04:00
int snd_usb_endpoint_deactivate ( struct snd_usb_endpoint * ep )
{
if ( ! ep )
return - EINVAL ;
2012-07-12 15:08:40 +04:00
deactivate_urbs ( ep , 1 , 1 ) ;
wait_clear_urbs ( ep ) ;
2012-04-12 15:51:11 +04:00
if ( ep - > use_count ! = 0 )
return 0 ;
2012-07-12 15:08:40 +04:00
clear_bit ( EP_FLAG_ACTIVATED , & ep - > flags ) ;
2012-04-12 15:51:11 +04:00
2012-07-12 15:08:40 +04:00
return 0 ;
2012-04-12 15:51:11 +04:00
}
2012-04-24 21:31:24 +04:00
/**
* snd_usb_endpoint_free : Free the resources of an snd_usb_endpoint
2012-04-12 15:51:15 +04:00
*
* @ ep : the list header of the endpoint to free
*
* This function does not care for the endpoint ' s use count but will tear
* down all the streaming URBs immediately and free all resources .
*/
2012-04-12 15:51:11 +04:00
void snd_usb_endpoint_free ( struct list_head * head )
{
struct snd_usb_endpoint * ep ;
ep = list_entry ( head , struct snd_usb_endpoint , list ) ;
release_urbs ( ep , 1 ) ;
kfree ( ep ) ;
}
2012-04-12 15:51:15 +04:00
/**
* snd_usb_handle_sync_urb : parse an USB sync packet
*
* @ ep : the endpoint to handle the packet
* @ sender : the sending endpoint
* @ urb : the received packet
*
* This function is called from the context of an endpoint that received
* the packet and is used to let another endpoint object handle the payload .
2012-04-12 15:51:11 +04:00
*/
void snd_usb_handle_sync_urb ( struct snd_usb_endpoint * ep ,
struct snd_usb_endpoint * sender ,
const struct urb * urb )
{
int shift ;
unsigned int f ;
unsigned long flags ;
snd_BUG_ON ( ep = = sender ) ;
2012-04-12 15:51:15 +04:00
/*
* In case the endpoint is operating in implicit feedback mode , prepare
2012-04-24 21:31:24 +04:00
* a new outbound URB that has the same layout as the received packet
* and add it to the list of pending urbs . queue_pending_output_urbs ( )
* will take care of them later .
2012-04-12 15:51:15 +04:00
*/
2012-04-12 15:51:11 +04:00
if ( snd_usb_endpoint_implict_feedback_sink ( ep ) & &
ep - > use_count ! = 0 ) {
/* implicit feedback case */
int i , bytes = 0 ;
struct snd_urb_ctx * in_ctx ;
struct snd_usb_packet_info * out_packet ;
in_ctx = urb - > context ;
/* Count overall packet size */
for ( i = 0 ; i < in_ctx - > packets ; i + + )
if ( urb - > iso_frame_desc [ i ] . status = = 0 )
bytes + = urb - > iso_frame_desc [ i ] . actual_length ;
/*
* skip empty packets . At least M - Audio ' s Fast Track Ultra stops
* streaming once it received a 0 - byte OUT URB
*/
if ( bytes = = 0 )
return ;
spin_lock_irqsave ( & ep - > lock , flags ) ;
out_packet = ep - > next_packet + ep - > next_packet_write_pos ;
/*
* Iterate through the inbound packet and prepare the lengths
* for the output packet . The OUT packet we are about to send
2012-04-24 21:31:24 +04:00
* will have the same amount of payload bytes than the IN
* packet we just received .
2012-04-12 15:51:11 +04:00
*/
out_packet - > packets = in_ctx - > packets ;
for ( i = 0 ; i < in_ctx - > packets ; i + + ) {
if ( urb - > iso_frame_desc [ i ] . status = = 0 )
out_packet - > packet_size [ i ] =
urb - > iso_frame_desc [ i ] . actual_length / ep - > stride ;
else
out_packet - > packet_size [ i ] = 0 ;
}
ep - > next_packet_write_pos + + ;
ep - > next_packet_write_pos % = MAX_URBS ;
spin_unlock_irqrestore ( & ep - > lock , flags ) ;
queue_pending_output_urbs ( ep ) ;
return ;
}
2012-04-12 15:51:15 +04:00
/*
* process after playback sync complete
*
* Full speed devices report feedback values in 10.14 format as samples
* per frame , high speed devices in 16.16 format as samples per
* microframe .
*
* Because the Audio Class 1 spec was written before USB 2.0 , many high
* speed devices use a wrong interpretation , some others use an
* entirely different format .
*
* Therefore , we cannot predict what format any particular device uses
* and must detect it automatically .
*/
2012-04-12 15:51:11 +04:00
if ( urb - > iso_frame_desc [ 0 ] . status ! = 0 | |
urb - > iso_frame_desc [ 0 ] . actual_length < 3 )
return ;
f = le32_to_cpup ( urb - > transfer_buffer ) ;
if ( urb - > iso_frame_desc [ 0 ] . actual_length = = 3 )
f & = 0x00ffffff ;
else
f & = 0x0fffffff ;
if ( f = = 0 )
return ;
if ( unlikely ( ep - > freqshift = = INT_MIN ) ) {
/*
* The first time we see a feedback value , determine its format
* by shifting it left or right until it matches the nominal
* frequency value . This assumes that the feedback does not
* differ from the nominal value more than + 50 % or - 25 % .
*/
shift = 0 ;
while ( f < ep - > freqn - ep - > freqn / 4 ) {
f < < = 1 ;
shift + + ;
}
while ( f > ep - > freqn + ep - > freqn / 2 ) {
f > > = 1 ;
shift - - ;
}
ep - > freqshift = shift ;
} else if ( ep - > freqshift > = 0 )
f < < = ep - > freqshift ;
else
f > > = - ep - > freqshift ;
if ( likely ( f > = ep - > freqn - ep - > freqn / 8 & & f < = ep - > freqmax ) ) {
/*
* If the frequency looks valid , set it .
* This value is referred to in prepare_playback_urb ( ) .
*/
spin_lock_irqsave ( & ep - > lock , flags ) ;
ep - > freqm = f ;
spin_unlock_irqrestore ( & ep - > lock , flags ) ;
} else {
/*
* Out of range ; maybe the shift value is wrong .
* Reset it so that we autodetect again the next time .
*/
ep - > freqshift = INT_MIN ;
}
}