Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
8c941de1
Commit
8c941de1
authored
Apr 07, 2009
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/usb-audio' into for-linus
parents
5f9c510e
a7d9c099
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
120 additions
and
135 deletions
+120
-135
sound/usb/usbaudio.c
sound/usb/usbaudio.c
+120
-135
No files found.
sound/usb/usbaudio.c
View file @
8c941de1
...
...
@@ -121,6 +121,7 @@ struct audioformat {
unsigned
char
attributes
;
/* corresponding attributes of cs endpoint */
unsigned
char
endpoint
;
/* endpoint */
unsigned
char
ep_attr
;
/* endpoint attributes */
unsigned
char
datainterval
;
/* log_2 of data packet interval */
unsigned
int
maxpacksize
;
/* max. packet size */
unsigned
int
rates
;
/* rate bitmasks */
unsigned
int
rate_min
,
rate_max
;
/* min/max rates */
...
...
@@ -170,7 +171,6 @@ struct snd_usb_substream {
unsigned
int
curframesize
;
/* current packet size in frames (for capture) */
unsigned
int
fill_max
:
1
;
/* fill max packet size always */
unsigned
int
fmt_type
;
/* USB audio format type (1-3) */
unsigned
int
packs_per_ms
;
/* packets per millisecond (for playback) */
unsigned
int
running
:
1
;
/* running status */
...
...
@@ -607,9 +607,7 @@ static int prepare_playback_urb(struct snd_usb_substream *subs,
break
;
}
}
/* finish at the frame boundary at/after the period boundary */
if
(
period_elapsed
&&
(
i
&
(
subs
->
packs_per_ms
-
1
))
==
subs
->
packs_per_ms
-
1
)
if
(
period_elapsed
)
/* finish at the period boundary */
break
;
}
if
(
subs
->
hwptr_done
+
offs
>
runtime
->
buffer_size
)
{
...
...
@@ -1067,7 +1065,6 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri
packs_per_ms
=
8
>>
subs
->
datainterval
;
else
packs_per_ms
=
1
;
subs
->
packs_per_ms
=
packs_per_ms
;
if
(
is_playback
)
{
urb_packs
=
max
(
nrpacks
,
1
);
...
...
@@ -1087,18 +1084,17 @@ static int init_substream_urbs(struct snd_usb_substream *subs, unsigned int peri
minsize
-=
minsize
>>
3
;
minsize
=
max
(
minsize
,
1u
);
total_packs
=
(
period_bytes
+
minsize
-
1
)
/
minsize
;
/* round up to multiple of packs_per_ms */
total_packs
=
(
total_packs
+
packs_per_ms
-
1
)
&
~
(
packs_per_ms
-
1
);
/* we need at least two URBs for queueing */
if
(
total_packs
<
2
*
packs_per_ms
)
{
total_packs
=
2
*
packs_per_ms
;
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
;
}
subs
->
nurbs
=
(
total_packs
+
urb_packs
-
1
)
/
urb_packs
;
...
...
@@ -1350,12 +1346,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
subs
->
datapipe
=
usb_sndisocpipe
(
dev
,
ep
);
else
subs
->
datapipe
=
usb_rcvisocpipe
(
dev
,
ep
);
if
(
snd_usb_get_speed
(
subs
->
dev
)
==
USB_SPEED_HIGH
&&
get_endpoint
(
alts
,
0
)
->
bInterval
>=
1
&&
get_endpoint
(
alts
,
0
)
->
bInterval
<=
4
)
subs
->
datainterval
=
get_endpoint
(
alts
,
0
)
->
bInterval
-
1
;
else
subs
->
datainterval
=
0
;
subs
->
datainterval
=
fmt
->
datainterval
;
subs
->
syncpipe
=
subs
->
syncinterval
=
0
;
subs
->
maxpacksize
=
fmt
->
maxpacksize
;
subs
->
fill_max
=
0
;
...
...
@@ -1568,11 +1559,15 @@ static struct snd_pcm_hardware snd_usb_hardware =
#define hwc_debug(fmt, args...)
/**/
#endif
static
int
hw_check_valid_format
(
struct
snd_pcm_hw_params
*
params
,
struct
audioformat
*
fp
)
static
int
hw_check_valid_format
(
struct
snd_usb_substream
*
subs
,
struct
snd_pcm_hw_params
*
params
,
struct
audioformat
*
fp
)
{
struct
snd_interval
*
it
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_RATE
);
struct
snd_interval
*
ct
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_CHANNELS
);
struct
snd_mask
*
fmts
=
hw_param_mask
(
params
,
SNDRV_PCM_HW_PARAM_FORMAT
);
struct
snd_interval
*
pt
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_PERIOD_TIME
);
unsigned
int
ptime
;
/* check the format */
if
(
!
snd_mask_test
(
fmts
,
fp
->
format
))
{
...
...
@@ -1593,6 +1588,14 @@ static int hw_check_valid_format(struct snd_pcm_hw_params *params, struct audiof
hwc_debug
(
" > check: rate_max %d < min %d
\n
"
,
fp
->
rate_max
,
it
->
min
);
return
0
;
}
/* check whether the period time is >= the data packet interval */
if
(
snd_usb_get_speed
(
subs
->
dev
)
==
USB_SPEED_HIGH
)
{
ptime
=
125
*
(
1
<<
fp
->
datainterval
);
if
(
ptime
>
pt
->
max
||
(
ptime
==
pt
->
max
&&
pt
->
openmax
))
{
hwc_debug
(
" > check: ptime %u > max %u
\n
"
,
ptime
,
pt
->
max
);
return
0
;
}
}
return
1
;
}
...
...
@@ -1611,7 +1614,7 @@ static int hw_rule_rate(struct snd_pcm_hw_params *params,
list_for_each
(
p
,
&
subs
->
fmt_list
)
{
struct
audioformat
*
fp
;
fp
=
list_entry
(
p
,
struct
audioformat
,
list
);
if
(
!
hw_check_valid_format
(
params
,
fp
))
if
(
!
hw_check_valid_format
(
subs
,
params
,
fp
))
continue
;
if
(
changed
++
)
{
if
(
rmin
>
fp
->
rate_min
)
...
...
@@ -1665,7 +1668,7 @@ static int hw_rule_channels(struct snd_pcm_hw_params *params,
list_for_each
(
p
,
&
subs
->
fmt_list
)
{
struct
audioformat
*
fp
;
fp
=
list_entry
(
p
,
struct
audioformat
,
list
);
if
(
!
hw_check_valid_format
(
params
,
fp
))
if
(
!
hw_check_valid_format
(
subs
,
params
,
fp
))
continue
;
if
(
changed
++
)
{
if
(
rmin
>
fp
->
channels
)
...
...
@@ -1718,7 +1721,7 @@ static int hw_rule_format(struct snd_pcm_hw_params *params,
list_for_each
(
p
,
&
subs
->
fmt_list
)
{
struct
audioformat
*
fp
;
fp
=
list_entry
(
p
,
struct
audioformat
,
list
);
if
(
!
hw_check_valid_format
(
params
,
fp
))
if
(
!
hw_check_valid_format
(
subs
,
params
,
fp
))
continue
;
fbits
|=
(
1ULL
<<
fp
->
format
);
}
...
...
@@ -1736,95 +1739,42 @@ static int hw_rule_format(struct snd_pcm_hw_params *params,
return
changed
;
}
#define MAX_MASK 64
/*
* check whether the registered audio formats need special hw-constraints
*/
static
int
check_hw_params_convention
(
struct
snd_usb_substream
*
subs
)
static
int
hw_rule_period_time
(
struct
snd_pcm_hw_params
*
params
,
struct
snd_pcm_hw_rule
*
rule
)
{
int
i
;
u32
*
channels
;
u32
*
rates
;
u32
cmaster
,
rmaster
;
u32
rate_min
=
0
,
rate_max
=
0
;
struct
list_head
*
p
;
int
err
=
1
;
channels
=
kcalloc
(
MAX_MASK
,
sizeof
(
u32
),
GFP_KERNEL
);
rates
=
kcalloc
(
MAX_MASK
,
sizeof
(
u32
),
GFP_KERNEL
);
if
(
!
channels
||
!
rates
)
{
err
=
-
ENOMEM
;
goto
__out
;
}
struct
snd_usb_substream
*
subs
=
rule
->
private
;
struct
audioformat
*
fp
;
struct
snd_interval
*
it
;
unsigned
char
min_datainterval
;
unsigned
int
pmin
;
int
changed
;
list_for_each
(
p
,
&
subs
->
fmt_list
)
{
struct
audioformat
*
f
;
f
=
list_entry
(
p
,
struct
audioformat
,
list
);
/* unconventional channels? */
if
(
f
->
channels
>
32
)
goto
__out
;
/* continuous rate min/max matches? */
if
(
f
->
rates
&
SNDRV_PCM_RATE_CONTINUOUS
)
{
if
(
rate_min
&&
f
->
rate_min
!=
rate_min
)
goto
__out
;
if
(
rate_max
&&
f
->
rate_max
!=
rate_max
)
goto
__out
;
rate_min
=
f
->
rate_min
;
rate_max
=
f
->
rate_max
;
}
/* combination of continuous rates and fixed rates? */
if
(
rates
[
f
->
format
]
&
SNDRV_PCM_RATE_CONTINUOUS
)
{
if
(
f
->
rates
!=
rates
[
f
->
format
])
goto
__out
;
}
if
(
f
->
rates
&
SNDRV_PCM_RATE_CONTINUOUS
)
{
if
(
rates
[
f
->
format
]
&&
rates
[
f
->
format
]
!=
f
->
rates
)
goto
__out
;
}
channels
[
f
->
format
]
|=
1
<<
(
f
->
channels
-
1
);
rates
[
f
->
format
]
|=
f
->
rates
;
/* needs knot? */
if
(
f
->
rates
&
SNDRV_PCM_RATE_KNOT
)
goto
__out
;
}
/* check whether channels and rates match for all formats */
cmaster
=
rmaster
=
0
;
for
(
i
=
0
;
i
<
MAX_MASK
;
i
++
)
{
if
(
cmaster
!=
channels
[
i
]
&&
cmaster
&&
channels
[
i
])
goto
__out
;
if
(
rmaster
!=
rates
[
i
]
&&
rmaster
&&
rates
[
i
])
goto
__out
;
if
(
channels
[
i
])
cmaster
=
channels
[
i
];
if
(
rates
[
i
])
rmaster
=
rates
[
i
];
}
/* check whether channels match for all distinct rates */
memset
(
channels
,
0
,
MAX_MASK
*
sizeof
(
u32
));
list_for_each
(
p
,
&
subs
->
fmt_list
)
{
struct
audioformat
*
f
;
f
=
list_entry
(
p
,
struct
audioformat
,
list
);
if
(
f
->
rates
&
SNDRV_PCM_RATE_CONTINUOUS
)
it
=
hw_param_interval
(
params
,
SNDRV_PCM_HW_PARAM_PERIOD_TIME
);
hwc_debug
(
"hw_rule_period_time: (%u,%u)
\n
"
,
it
->
min
,
it
->
max
);
min_datainterval
=
0xff
;
list_for_each_entry
(
fp
,
&
subs
->
fmt_list
,
list
)
{
if
(
!
hw_check_valid_format
(
subs
,
params
,
fp
))
continue
;
for
(
i
=
0
;
i
<
32
;
i
++
)
{
if
(
f
->
rates
&
(
1
<<
i
))
channels
[
i
]
|=
1
<<
(
f
->
channels
-
1
);
}
min_datainterval
=
min
(
min_datainterval
,
fp
->
datainterval
);
}
cmaster
=
0
;
for
(
i
=
0
;
i
<
32
;
i
++
)
{
if
(
cmaster
!=
channels
[
i
]
&&
cmaster
&&
channels
[
i
])
goto
__out
;
if
(
channels
[
i
])
cmaster
=
channels
[
i
];
if
(
min_datainterval
==
0xff
)
{
hwc_debug
(
" --> get emtpy
\n
"
);
it
->
empty
=
1
;
return
-
EINVAL
;
}
err
=
0
;
__out:
kfree
(
channels
);
kfree
(
rates
);
return
err
;
pmin
=
125
*
(
1
<<
min_datainterval
);
changed
=
0
;
if
(
it
->
min
<
pmin
)
{
it
->
min
=
pmin
;
it
->
openmin
=
0
;
changed
=
1
;
}
if
(
snd_interval_checkempty
(
it
))
{
it
->
empty
=
1
;
return
-
EINVAL
;
}
hwc_debug
(
" --> (%u,%u) (changed = %d)
\n
"
,
it
->
min
,
it
->
max
,
changed
);
return
changed
;
}
/*
...
...
@@ -1872,6 +1822,8 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
static
int
setup_hw_info
(
struct
snd_pcm_runtime
*
runtime
,
struct
snd_usb_substream
*
subs
)
{
struct
list_head
*
p
;
unsigned
int
pt
,
ptmin
;
int
param_period_time_if_needed
;
int
err
;
runtime
->
hw
.
formats
=
subs
->
formats
;
...
...
@@ -1881,6 +1833,7 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
runtime
->
hw
.
channels_min
=
256
;
runtime
->
hw
.
channels_max
=
0
;
runtime
->
hw
.
rates
=
0
;
ptmin
=
UINT_MAX
;
/* check min/max rates and channels */
list_for_each
(
p
,
&
subs
->
fmt_list
)
{
struct
audioformat
*
fp
;
...
...
@@ -1899,42 +1852,54 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre
runtime
->
hw
.
period_bytes_min
=
runtime
->
hw
.
period_bytes_max
=
fp
->
frame_size
;
}
pt
=
125
*
(
1
<<
fp
->
datainterval
);
ptmin
=
min
(
ptmin
,
pt
);
}
/* set the period time minimum 1ms */
/* FIXME: high-speed mode allows 125us minimum period, but many parts
* in the current code assume the 1ms period.
*/
param_period_time_if_needed
=
SNDRV_PCM_HW_PARAM_PERIOD_TIME
;
if
(
snd_usb_get_speed
(
subs
->
dev
)
!=
USB_SPEED_HIGH
)
/* full speed devices have fixed data packet interval */
ptmin
=
1000
;
if
(
ptmin
==
1000
)
/* if period time doesn't go below 1 ms, no rules needed */
param_period_time_if_needed
=
-
1
;
snd_pcm_hw_constraint_minmax
(
runtime
,
SNDRV_PCM_HW_PARAM_PERIOD_TIME
,
1000
,
/*(nrpacks * MAX_URBS) * 1000*/
UINT_MAX
);
err
=
check_hw_params_convention
(
subs
);
if
(
err
<
0
)
ptmin
,
UINT_MAX
);
if
((
err
=
snd_pcm_hw_rule_add
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_RATE
,
hw_rule_rate
,
subs
,
SNDRV_PCM_HW_PARAM_FORMAT
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
param_period_time_if_needed
,
-
1
))
<
0
)
return
err
;
else
if
(
err
)
{
hwc_debug
(
"setting extra hw constraints...
\n
"
);
if
((
err
=
snd_pcm_hw_rule_add
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_RATE
,
hw_rule_rate
,
subs
,
SNDRV_PCM_HW_PARAM_FORMAT
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
-
1
))
<
0
)
return
err
;
if
((
err
=
snd_pcm_hw_rule_add
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
hw_rule_channels
,
subs
,
SNDRV_PCM_HW_PARAM_FORMAT
,
SNDRV_PCM_HW_PARAM_RATE
,
-
1
))
<
0
)
return
err
;
if
((
err
=
snd_pcm_hw_rule_add
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_FORMAT
,
hw_rule_format
,
subs
,
SNDRV_PCM_HW_PARAM_RATE
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
-
1
))
<
0
)
return
err
;
if
((
err
=
snd_usb_pcm_check_knot
(
runtime
,
subs
))
<
0
)
if
((
err
=
snd_pcm_hw_rule_add
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
hw_rule_channels
,
subs
,
SNDRV_PCM_HW_PARAM_FORMAT
,
SNDRV_PCM_HW_PARAM_RATE
,
param_period_time_if_needed
,
-
1
))
<
0
)
return
err
;
if
((
err
=
snd_pcm_hw_rule_add
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_FORMAT
,
hw_rule_format
,
subs
,
SNDRV_PCM_HW_PARAM_RATE
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
param_period_time_if_needed
,
-
1
))
<
0
)
return
err
;
if
(
param_period_time_if_needed
>=
0
)
{
err
=
snd_pcm_hw_rule_add
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_PERIOD_TIME
,
hw_rule_period_time
,
subs
,
SNDRV_PCM_HW_PARAM_FORMAT
,
SNDRV_PCM_HW_PARAM_CHANNELS
,
SNDRV_PCM_HW_PARAM_RATE
,
-
1
);
if
(
err
<
0
)
return
err
;
}
if
((
err
=
snd_usb_pcm_check_knot
(
runtime
,
subs
))
<
0
)
return
err
;
return
0
;
}
...
...
@@ -2147,7 +2112,8 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
fp
=
list_entry
(
p
,
struct
audioformat
,
list
);
snd_iprintf
(
buffer
,
" Interface %d
\n
"
,
fp
->
iface
);
snd_iprintf
(
buffer
,
" Altset %d
\n
"
,
fp
->
altsetting
);
snd_iprintf
(
buffer
,
" Format: %#x
\n
"
,
fp
->
format
);
snd_iprintf
(
buffer
,
" Format: %#x (%d bits)
\n
"
,
fp
->
format
,
snd_pcm_format_width
(
fp
->
format
));
snd_iprintf
(
buffer
,
" Channels: %d
\n
"
,
fp
->
channels
);
snd_iprintf
(
buffer
,
" Endpoint: %d %s (%s)
\n
"
,
fp
->
endpoint
&
USB_ENDPOINT_NUMBER_MASK
,
...
...
@@ -2166,6 +2132,9 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
}
snd_iprintf
(
buffer
,
"
\n
"
);
}
if
(
snd_usb_get_speed
(
subs
->
dev
)
==
USB_SPEED_HIGH
)
snd_iprintf
(
buffer
,
" Data packet interval: %d us
\n
"
,
125
*
(
1
<<
fp
->
datainterval
));
// snd_iprintf(buffer, " Max Packet Size = %d\n", fp->maxpacksize);
// snd_iprintf(buffer, " EP Attribute = %#x\n", fp->attributes);
}
...
...
@@ -2659,6 +2628,17 @@ static int parse_audio_format(struct snd_usb_audio *chip, struct audioformat *fp
return
0
;
}
static
unsigned
char
parse_datainterval
(
struct
snd_usb_audio
*
chip
,
struct
usb_host_interface
*
alts
)
{
if
(
snd_usb_get_speed
(
chip
->
dev
)
==
USB_SPEED_HIGH
&&
get_endpoint
(
alts
,
0
)
->
bInterval
>=
1
&&
get_endpoint
(
alts
,
0
)
->
bInterval
<=
4
)
return
get_endpoint
(
alts
,
0
)
->
bInterval
-
1
;
else
return
0
;
}
static
int
audiophile_skip_setting_quirk
(
struct
snd_usb_audio
*
chip
,
int
iface
,
int
altno
);
static
int
parse_audio_endpoints
(
struct
snd_usb_audio
*
chip
,
int
iface_no
)
...
...
@@ -2764,6 +2744,7 @@ static int parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
fp
->
altset_idx
=
i
;
fp
->
endpoint
=
get_endpoint
(
alts
,
0
)
->
bEndpointAddress
;
fp
->
ep_attr
=
get_endpoint
(
alts
,
0
)
->
bmAttributes
;
fp
->
datainterval
=
parse_datainterval
(
chip
,
alts
);
fp
->
maxpacksize
=
le16_to_cpu
(
get_endpoint
(
alts
,
0
)
->
wMaxPacketSize
);
if
(
snd_usb_get_speed
(
dev
)
==
USB_SPEED_HIGH
)
fp
->
maxpacksize
=
(((
fp
->
maxpacksize
>>
11
)
&
3
)
+
1
)
...
...
@@ -2955,6 +2936,7 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
return
-
EINVAL
;
}
alts
=
&
iface
->
altsetting
[
fp
->
altset_idx
];
fp
->
datainterval
=
parse_datainterval
(
chip
,
alts
);
fp
->
maxpacksize
=
le16_to_cpu
(
get_endpoint
(
alts
,
0
)
->
wMaxPacketSize
);
usb_set_interface
(
chip
->
dev
,
fp
->
iface
,
0
);
init_usb_pitch
(
chip
->
dev
,
fp
->
iface
,
alts
,
fp
);
...
...
@@ -3049,6 +3031,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
fp
->
iface
=
altsd
->
bInterfaceNumber
;
fp
->
endpoint
=
get_endpoint
(
alts
,
0
)
->
bEndpointAddress
;
fp
->
ep_attr
=
get_endpoint
(
alts
,
0
)
->
bmAttributes
;
fp
->
datainterval
=
0
;
fp
->
maxpacksize
=
le16_to_cpu
(
get_endpoint
(
alts
,
0
)
->
wMaxPacketSize
);
switch
(
fp
->
maxpacksize
)
{
...
...
@@ -3116,6 +3099,7 @@ static int create_ua1000_quirk(struct snd_usb_audio *chip,
fp
->
iface
=
altsd
->
bInterfaceNumber
;
fp
->
endpoint
=
get_endpoint
(
alts
,
0
)
->
bEndpointAddress
;
fp
->
ep_attr
=
get_endpoint
(
alts
,
0
)
->
bmAttributes
;
fp
->
datainterval
=
parse_datainterval
(
chip
,
alts
);
fp
->
maxpacksize
=
le16_to_cpu
(
get_endpoint
(
alts
,
0
)
->
wMaxPacketSize
);
fp
->
rate_max
=
fp
->
rate_min
=
combine_triple
(
&
alts
->
extra
[
8
]);
...
...
@@ -3168,6 +3152,7 @@ static int create_ua101_quirk(struct snd_usb_audio *chip,
fp
->
iface
=
altsd
->
bInterfaceNumber
;
fp
->
endpoint
=
get_endpoint
(
alts
,
0
)
->
bEndpointAddress
;
fp
->
ep_attr
=
get_endpoint
(
alts
,
0
)
->
bmAttributes
;
fp
->
datainterval
=
parse_datainterval
(
chip
,
alts
);
fp
->
maxpacksize
=
le16_to_cpu
(
get_endpoint
(
alts
,
0
)
->
wMaxPacketSize
);
fp
->
rate_max
=
fp
->
rate_min
=
combine_triple
(
&
alts
->
extra
[
15
]);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment