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
a540e133
Commit
a540e133
authored
Feb 12, 2010
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote branch 'alsa/devel' into topic/misc
parents
cebe41d4
c3a3e040
Changes
3
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
273 additions
and
165 deletions
+273
-165
sound/drivers/dummy.c
sound/drivers/dummy.c
+180
-110
sound/usb/usbmixer.c
sound/usb/usbmixer.c
+76
-49
sound/usb/usbmixer_maps.c
sound/usb/usbmixer_maps.c
+17
-6
No files found.
sound/drivers/dummy.c
View file @
a540e133
This diff is collapsed.
Click to expand it.
sound/usb/usbmixer.c
View file @
a540e133
...
...
@@ -123,6 +123,7 @@ struct usb_mixer_elem_info {
int
channels
;
int
val_type
;
int
min
,
max
,
res
;
int
dBmin
,
dBmax
;
int
cached
;
int
cache_val
[
MAX_CHANNELS
];
u8
initialized
;
...
...
@@ -209,42 +210,50 @@ enum {
*/
#include "usbmixer_maps.c"
/* get the mapped name if the unit matches */
static
int
check_mapped_name
(
struct
mixer_build
*
state
,
int
unitid
,
int
control
,
char
*
buf
,
int
buflen
)
static
const
struct
usbmix_name_map
*
find_map
(
struct
mixer_build
*
state
,
int
unitid
,
int
control
)
{
const
struct
usbmix_name_map
*
p
;
const
struct
usbmix_name_map
*
p
=
state
->
map
;
if
(
!
state
->
ma
p
)
return
0
;
if
(
!
p
)
return
NULL
;
for
(
p
=
state
->
map
;
p
->
id
;
p
++
)
{
if
(
p
->
id
==
unitid
&&
p
->
name
&&
(
!
control
||
!
p
->
control
||
control
==
p
->
control
))
{
buflen
--
;
return
strlcpy
(
buf
,
p
->
name
,
buflen
);
}
if
(
p
->
id
==
unitid
&&
(
!
control
||
!
p
->
control
||
control
==
p
->
control
))
return
p
;
}
return
NULL
;
}
/* get the mapped name if the unit matches */
static
int
check_mapped_name
(
const
struct
usbmix_name_map
*
p
,
char
*
buf
,
int
buflen
)
{
if
(
!
p
||
!
p
->
name
)
return
0
;
buflen
--
;
return
strlcpy
(
buf
,
p
->
name
,
buflen
);
}
/* check whether the control should be ignored */
static
int
check_ignored_ctl
(
struct
mixer_build
*
state
,
int
unitid
,
int
control
)
static
inline
int
check_ignored_ctl
(
const
struct
usbmix_name_map
*
p
)
{
const
struct
usbmix_name_map
*
p
;
if
(
!
state
->
map
)
if
(
!
p
||
p
->
name
||
p
->
dB
)
return
0
;
for
(
p
=
state
->
map
;
p
->
id
;
p
++
)
{
if
(
p
->
id
==
unitid
&&
!
p
->
name
&&
(
!
control
||
!
p
->
control
||
control
==
p
->
control
))
{
/*
printk(KERN_DEBUG "ignored control %d:%d\n",
unitid, control);
*/
return
1
;
}
/* dB mapping */
static
inline
void
check_mapped_dB
(
const
struct
usbmix_name_map
*
p
,
struct
usb_mixer_elem_info
*
cval
)
{
if
(
p
&&
p
->
dB
)
{
cval
->
dBmin
=
p
->
dB
->
min
;
cval
->
dBmax
=
p
->
dB
->
max
;
}
}
return
0
;
}
/* get the mapped selector source name */
...
...
@@ -481,20 +490,8 @@ static int mixer_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
if
(
size
<
sizeof
(
scale
))
return
-
ENOMEM
;
/* USB descriptions contain the dB scale in 1/256 dB unit
* while ALSA TLV contains in 1/100 dB unit
*/
scale
[
2
]
=
(
convert_signed_value
(
cval
,
cval
->
min
)
*
100
)
/
256
;
scale
[
3
]
=
(
convert_signed_value
(
cval
,
cval
->
max
)
*
100
)
/
256
;
if
(
scale
[
3
]
<=
scale
[
2
])
{
/* something is wrong; assume it's either from/to 0dB */
if
(
scale
[
2
]
<
0
)
scale
[
3
]
=
0
;
else
if
(
scale
[
2
]
>
0
)
scale
[
2
]
=
0
;
else
/* totally crap, return an error */
return
-
EINVAL
;
}
scale
[
2
]
=
cval
->
dBmin
;
scale
[
3
]
=
cval
->
dBmax
;
if
(
copy_to_user
(
_tlv
,
scale
,
sizeof
(
scale
)))
return
-
EFAULT
;
return
0
;
...
...
@@ -735,6 +732,7 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
cval
->
min
=
default_min
;
cval
->
max
=
cval
->
min
+
1
;
cval
->
res
=
1
;
cval
->
dBmin
=
cval
->
dBmax
=
0
;
if
(
cval
->
val_type
==
USB_MIXER_BOOLEAN
||
cval
->
val_type
==
USB_MIXER_INV_BOOLEAN
)
{
...
...
@@ -802,6 +800,24 @@ static int get_min_max(struct usb_mixer_elem_info *cval, int default_min)
cval
->
initialized
=
1
;
}
/* USB descriptions contain the dB scale in 1/256 dB unit
* while ALSA TLV contains in 1/100 dB unit
*/
cval
->
dBmin
=
(
convert_signed_value
(
cval
,
cval
->
min
)
*
100
)
/
256
;
cval
->
dBmax
=
(
convert_signed_value
(
cval
,
cval
->
max
)
*
100
)
/
256
;
if
(
cval
->
dBmin
>
cval
->
dBmax
)
{
/* something is wrong; assume it's either from/to 0dB */
if
(
cval
->
dBmin
<
0
)
cval
->
dBmax
=
0
;
else
if
(
cval
->
dBmin
>
0
)
cval
->
dBmin
=
0
;
if
(
cval
->
dBmin
>
cval
->
dBmax
)
{
/* totally crap, return an error */
return
-
EINVAL
;
}
}
return
0
;
}
...
...
@@ -927,6 +943,7 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
int
nameid
=
desc
[
desc
[
0
]
-
1
];
struct
snd_kcontrol
*
kctl
;
struct
usb_mixer_elem_info
*
cval
;
const
struct
usbmix_name_map
*
map
;
control
++
;
/* change from zero-based to 1-based value */
...
...
@@ -935,7 +952,8 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
return
;
}
if
(
check_ignored_ctl
(
state
,
unitid
,
control
))
map
=
find_map
(
state
,
unitid
,
control
);
if
(
check_ignored_ctl
(
map
))
return
;
cval
=
kzalloc
(
sizeof
(
*
cval
),
GFP_KERNEL
);
...
...
@@ -969,10 +987,11 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
}
kctl
->
private_free
=
usb_mixer_elem_free
;
len
=
check_mapped_name
(
state
,
unitid
,
control
,
kctl
->
id
.
name
,
sizeof
(
kctl
->
id
.
name
));
len
=
check_mapped_name
(
map
,
kctl
->
id
.
name
,
sizeof
(
kctl
->
id
.
name
));
mapped_name
=
len
!=
0
;
if
(
!
len
&&
nameid
)
len
=
snd_usb_copy_string_desc
(
state
,
nameid
,
kctl
->
id
.
name
,
sizeof
(
kctl
->
id
.
name
));
len
=
snd_usb_copy_string_desc
(
state
,
nameid
,
kctl
->
id
.
name
,
sizeof
(
kctl
->
id
.
name
));
switch
(
control
)
{
case
USB_FEATURE_MUTE
:
...
...
@@ -1010,6 +1029,7 @@ static void build_feature_ctl(struct mixer_build *state, unsigned char *desc,
kctl
->
vd
[
0
].
access
|=
SNDRV_CTL_ELEM_ACCESS_TLV_READ
|
SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK
;
check_mapped_dB
(
map
,
cval
);
}
break
;
...
...
@@ -1137,8 +1157,10 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
unsigned
int
num_outs
=
desc
[
5
+
input_pins
];
unsigned
int
i
,
len
;
struct
snd_kcontrol
*
kctl
;
const
struct
usbmix_name_map
*
map
;
if
(
check_ignored_ctl
(
state
,
unitid
,
0
))
map
=
find_map
(
state
,
unitid
,
0
);
if
(
check_ignored_ctl
(
map
))
return
;
cval
=
kzalloc
(
sizeof
(
*
cval
),
GFP_KERNEL
);
...
...
@@ -1167,7 +1189,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, unsigned char *desc,
}
kctl
->
private_free
=
usb_mixer_elem_free
;
len
=
check_mapped_name
(
state
,
unitid
,
0
,
kctl
->
id
.
name
,
sizeof
(
kctl
->
id
.
name
));
len
=
check_mapped_name
(
map
,
kctl
->
id
.
name
,
sizeof
(
kctl
->
id
.
name
));
if
(
!
len
)
len
=
get_term_name
(
state
,
iterm
,
kctl
->
id
.
name
,
sizeof
(
kctl
->
id
.
name
),
0
);
if
(
!
len
)
...
...
@@ -1382,6 +1404,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
int
i
,
err
,
nameid
,
type
,
len
;
struct
procunit_info
*
info
;
struct
procunit_value_info
*
valinfo
;
const
struct
usbmix_name_map
*
map
;
static
struct
procunit_value_info
default_value_info
[]
=
{
{
0x01
,
"Switch"
,
USB_MIXER_BOOLEAN
},
{
0
}
...
...
@@ -1411,7 +1434,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
/* FIXME: bitmap might be longer than 8bit */
if
(
!
(
dsc
[
12
+
num_ins
]
&
(
1
<<
(
valinfo
->
control
-
1
))))
continue
;
if
(
check_ignored_ctl
(
state
,
unitid
,
valinfo
->
control
))
map
=
find_map
(
state
,
unitid
,
valinfo
->
control
);
if
(
check_ignored_ctl
(
map
))
continue
;
cval
=
kzalloc
(
sizeof
(
*
cval
),
GFP_KERNEL
);
if
(
!
cval
)
{
...
...
@@ -1452,8 +1476,9 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, unsigned
}
kctl
->
private_free
=
usb_mixer_elem_free
;
if
(
check_mapped_name
(
state
,
unitid
,
cval
->
control
,
kctl
->
id
.
name
,
sizeof
(
kctl
->
id
.
name
)))
;
if
(
check_mapped_name
(
map
,
kctl
->
id
.
name
,
sizeof
(
kctl
->
id
.
name
)))
/* nothing */
;
else
if
(
info
->
name
)
strlcpy
(
kctl
->
id
.
name
,
info
->
name
,
sizeof
(
kctl
->
id
.
name
));
else
{
...
...
@@ -1592,6 +1617,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
int
err
;
struct
usb_mixer_elem_info
*
cval
;
struct
snd_kcontrol
*
kctl
;
const
struct
usbmix_name_map
*
map
;
char
**
namelist
;
if
(
!
num_ins
||
desc
[
0
]
<
5
+
num_ins
)
{
...
...
@@ -1607,7 +1633,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
if
(
num_ins
==
1
)
/* only one ? nonsense! */
return
0
;
if
(
check_ignored_ctl
(
state
,
unitid
,
0
))
map
=
find_map
(
state
,
unitid
,
0
);
if
(
check_ignored_ctl
(
map
))
return
0
;
cval
=
kzalloc
(
sizeof
(
*
cval
),
GFP_KERNEL
);
...
...
@@ -1662,7 +1689,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, unsi
kctl
->
private_free
=
usb_mixer_selector_elem_free
;
nameid
=
desc
[
desc
[
0
]
-
1
];
len
=
check_mapped_name
(
state
,
unitid
,
0
,
kctl
->
id
.
name
,
sizeof
(
kctl
->
id
.
name
));
len
=
check_mapped_name
(
map
,
kctl
->
id
.
name
,
sizeof
(
kctl
->
id
.
name
));
if
(
len
)
;
else
if
(
nameid
)
...
...
sound/usb/usbmixer_maps.c
View file @
a540e133
...
...
@@ -19,11 +19,16 @@
*
*/
struct
usbmix_dB_map
{
u32
min
;
u32
max
;
};
struct
usbmix_name_map
{
int
id
;
const
char
*
name
;
int
control
;
struct
usbmix_dB_map
*
dB
;
};
struct
usbmix_selector_map
{
...
...
@@ -72,7 +77,7 @@ static struct usbmix_name_map extigy_map[] = {
{
8
,
"Line Playback"
},
/* FU */
/* 9: IT mic */
{
10
,
"Mic Playback"
},
/* FU */
{
11
,
"Capture
Input
Source"
},
/* SU */
{
11
,
"Capture Source"
},
/* SU */
{
12
,
"Capture"
},
/* FU */
/* 13: OT pcm capture */
/* 14: MU (w/o controls) */
...
...
@@ -102,6 +107,9 @@ static struct usbmix_name_map extigy_map[] = {
* e.g. no Master and fake PCM volume
* Pavel Mihaylov <bin@bash.info>
*/
static
struct
usbmix_dB_map
mp3plus_dB_1
=
{
-
4781
,
0
};
/* just guess */
static
struct
usbmix_dB_map
mp3plus_dB_2
=
{
-
1781
,
618
};
/* just guess */
static
struct
usbmix_name_map
mp3plus_map
[]
=
{
/* 1: IT pcm */
/* 2: IT mic */
...
...
@@ -110,16 +118,19 @@ static struct usbmix_name_map mp3plus_map[] = {
/* 5: OT digital out */
/* 6: OT speaker */
/* 7: OT pcm capture */
{
8
,
"Capture
Input
Source"
},
/* FU, default PCM Capture Source */
{
8
,
"Capture Source"
},
/* FU, default PCM Capture Source */
/* (Mic, Input 1 = Line input, Input 2 = Optical input) */
{
9
,
"Master Playback"
},
/* FU, default Speaker 1 */
/* { 10, "Mic Capture", 1 }, */
/* FU, Mic Capture */
/* { 10, "Mic Capture", 2 }, */
/* FU, Mic Capture */
{
10
,
/* "Mic Capture", */
NULL
,
2
,
.
dB
=
&
mp3plus_dB_2
},
/* FU, Mic Capture */
{
10
,
"Mic Boost"
,
7
},
/* FU, default Auto Gain Input */
{
11
,
"Line Capture"
},
/* FU, default PCM Capture */
{
11
,
"Line Capture"
,
.
dB
=
&
mp3plus_dB_2
},
/* FU, default PCM Capture */
{
12
,
"Digital In Playback"
},
/* FU, default PCM 1 */
/* { 13, "Mic Playback" }, */
/* FU, default Mic Playback */
{
14
,
"Line Playback"
},
/* FU, default Speaker */
{
13
,
/* "Mic Playback", */
.
dB
=
&
mp3plus_dB_1
},
/* FU, default Mic Playback */
{
14
,
"Line Playback"
,
.
dB
=
&
mp3plus_dB_1
},
/* FU, default Speaker */
/* 15: MU */
{
0
}
/* terminator */
};
...
...
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