@ -1015,6 +1015,60 @@ int snd_interval_list(struct snd_interval *i, unsigned int count,
EXPORT_SYMBOL ( snd_interval_list ) ;
/**
* snd_interval_ranges - refine the interval value from the list of ranges
* @ i : the interval value to refine
* @ count : the number of elements in the list of ranges
* @ ranges : the ranges list
* @ mask : the bit - mask to evaluate
*
* Refines the interval value from the list of ranges .
* When mask is non - zero , only the elements corresponding to bit 1 are
* evaluated .
*
* Return : Positive if the value is changed , zero if it ' s not changed , or a
* negative error code .
*/
int snd_interval_ranges ( struct snd_interval * i , unsigned int count ,
const struct snd_interval * ranges , unsigned int mask )
{
unsigned int k ;
struct snd_interval range_union ;
struct snd_interval range ;
if ( ! count ) {
snd_interval_none ( i ) ;
return - EINVAL ;
}
snd_interval_any ( & range_union ) ;
range_union . min = UINT_MAX ;
range_union . max = 0 ;
for ( k = 0 ; k < count ; k + + ) {
if ( mask & & ! ( mask & ( 1 < < k ) ) )
continue ;
snd_interval_copy ( & range , & ranges [ k ] ) ;
if ( snd_interval_refine ( & range , i ) < 0 )
continue ;
if ( snd_interval_empty ( & range ) )
continue ;
if ( range . min < range_union . min ) {
range_union . min = range . min ;
range_union . openmin = 1 ;
}
if ( range . min = = range_union . min & & ! range . openmin )
range_union . openmin = 0 ;
if ( range . max > range_union . max ) {
range_union . max = range . max ;
range_union . openmax = 1 ;
}
if ( range . max = = range_union . max & & ! range . openmax )
range_union . openmax = 0 ;
}
return snd_interval_refine ( i , & range_union ) ;
}
EXPORT_SYMBOL ( snd_interval_ranges ) ;
static int snd_interval_step ( struct snd_interval * i , unsigned int step )
{
unsigned int n ;
@ -1221,6 +1275,37 @@ int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
EXPORT_SYMBOL ( snd_pcm_hw_constraint_list ) ;
static int snd_pcm_hw_rule_ranges ( struct snd_pcm_hw_params * params ,
struct snd_pcm_hw_rule * rule )
{
struct snd_pcm_hw_constraint_ranges * r = rule - > private ;
return snd_interval_ranges ( hw_param_interval ( params , rule - > var ) ,
r - > count , r - > ranges , r - > mask ) ;
}
/**
* snd_pcm_hw_constraint_ranges - apply list of range constraints to a parameter
* @ runtime : PCM runtime instance
* @ cond : condition bits
* @ var : hw_params variable to apply the list of range constraints
* @ r : ranges
*
* Apply the list of range constraints to an interval parameter .
*
* Return : Zero if successful , or a negative error code on failure .
*/
int snd_pcm_hw_constraint_ranges ( struct snd_pcm_runtime * runtime ,
unsigned int cond ,
snd_pcm_hw_param_t var ,
const struct snd_pcm_hw_constraint_ranges * r )
{
return snd_pcm_hw_rule_add ( runtime , cond , var ,
snd_pcm_hw_rule_ranges , ( void * ) r ,
var , - 1 ) ;
}
EXPORT_SYMBOL ( snd_pcm_hw_constraint_ranges ) ;
static int snd_pcm_hw_rule_ratnums ( struct snd_pcm_hw_params * params ,
struct snd_pcm_hw_rule * rule )
{