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
8128c9f2
Commit
8128c9f2
authored
Oct 27, 2011
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/hda' into for-linus
parents
bb14eb0d
6b452142
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
88 additions
and
29 deletions
+88
-29
sound/pci/hda/hda_local.h
sound/pci/hda/hda_local.h
+2
-1
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_conexant.c
+49
-23
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_realtek.c
+37
-5
No files found.
sound/pci/hda/hda_local.h
View file @
8128c9f2
...
@@ -600,7 +600,8 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
...
@@ -600,7 +600,8 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
#define get_amp_nid_(pv) ((pv) & 0xffff)
#define get_amp_nid_(pv) ((pv) & 0xffff)
#define get_amp_nid(kc) get_amp_nid_((kc)->private_value)
#define get_amp_nid(kc) get_amp_nid_((kc)->private_value)
#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
#define get_amp_direction_(pv) (((pv) >> 18) & 0x1)
#define get_amp_direction(kc) get_amp_direction_((kc)->private_value)
#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
#define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f)
#define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f)
#define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1)
#define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1)
...
...
sound/pci/hda/patch_conexant.c
View file @
8128c9f2
...
@@ -136,6 +136,8 @@ struct conexant_spec {
...
@@ -136,6 +136,8 @@ struct conexant_spec {
unsigned
int
thinkpad
:
1
;
unsigned
int
thinkpad
:
1
;
unsigned
int
hp_laptop
:
1
;
unsigned
int
hp_laptop
:
1
;
unsigned
int
asus
:
1
;
unsigned
int
asus
:
1
;
unsigned
int
pin_eapd_ctrls
:
1
;
unsigned
int
single_adc_amp
:
1
;
unsigned
int
adc_switching
:
1
;
unsigned
int
adc_switching
:
1
;
...
@@ -3430,12 +3432,14 @@ static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
...
@@ -3430,12 +3432,14 @@ static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
static
void
do_automute
(
struct
hda_codec
*
codec
,
int
num_pins
,
static
void
do_automute
(
struct
hda_codec
*
codec
,
int
num_pins
,
hda_nid_t
*
pins
,
bool
on
)
hda_nid_t
*
pins
,
bool
on
)
{
{
struct
conexant_spec
*
spec
=
codec
->
spec
;
int
i
;
int
i
;
for
(
i
=
0
;
i
<
num_pins
;
i
++
)
for
(
i
=
0
;
i
<
num_pins
;
i
++
)
snd_hda_codec_write
(
codec
,
pins
[
i
],
0
,
snd_hda_codec_write
(
codec
,
pins
[
i
],
0
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
on
?
PIN_OUT
:
0
);
on
?
PIN_OUT
:
0
);
cx_auto_turn_eapd
(
codec
,
num_pins
,
pins
,
on
);
if
(
spec
->
pin_eapd_ctrls
)
cx_auto_turn_eapd
(
codec
,
num_pins
,
pins
,
on
);
}
}
static
int
detect_jacks
(
struct
hda_codec
*
codec
,
int
num_pins
,
hda_nid_t
*
pins
)
static
int
detect_jacks
(
struct
hda_codec
*
codec
,
int
num_pins
,
hda_nid_t
*
pins
)
...
@@ -3460,9 +3464,12 @@ static void cx_auto_update_speakers(struct hda_codec *codec)
...
@@ -3460,9 +3464,12 @@ static void cx_auto_update_speakers(struct hda_codec *codec)
int
on
=
1
;
int
on
=
1
;
/* turn on HP EAPD when HP jacks are present */
/* turn on HP EAPD when HP jacks are present */
if
(
spec
->
auto_mute
)
if
(
spec
->
pin_eapd_ctrls
)
{
on
=
spec
->
hp_present
;
if
(
spec
->
auto_mute
)
cx_auto_turn_eapd
(
codec
,
cfg
->
hp_outs
,
cfg
->
hp_pins
,
on
);
on
=
spec
->
hp_present
;
cx_auto_turn_eapd
(
codec
,
cfg
->
hp_outs
,
cfg
->
hp_pins
,
on
);
}
/* mute speakers in auto-mode if HP or LO jacks are plugged */
/* mute speakers in auto-mode if HP or LO jacks are plugged */
if
(
spec
->
auto_mute
)
if
(
spec
->
auto_mute
)
on
=
!
(
spec
->
hp_present
||
on
=
!
(
spec
->
hp_present
||
...
@@ -3889,20 +3896,10 @@ static void cx_auto_parse_beep(struct hda_codec *codec)
...
@@ -3889,20 +3896,10 @@ static void cx_auto_parse_beep(struct hda_codec *codec)
#define cx_auto_parse_beep(codec)
#define cx_auto_parse_beep(codec)
#endif
#endif
static
bool
found_in_nid_list
(
hda_nid_t
nid
,
const
hda_nid_t
*
list
,
int
nums
)
/* parse EAPDs */
{
int
i
;
for
(
i
=
0
;
i
<
nums
;
i
++
)
if
(
list
[
i
]
==
nid
)
return
true
;
return
false
;
}
/* parse extra-EAPD that aren't assigned to any pins */
static
void
cx_auto_parse_eapd
(
struct
hda_codec
*
codec
)
static
void
cx_auto_parse_eapd
(
struct
hda_codec
*
codec
)
{
{
struct
conexant_spec
*
spec
=
codec
->
spec
;
struct
conexant_spec
*
spec
=
codec
->
spec
;
struct
auto_pin_cfg
*
cfg
=
&
spec
->
autocfg
;
hda_nid_t
nid
,
end_nid
;
hda_nid_t
nid
,
end_nid
;
end_nid
=
codec
->
start_nid
+
codec
->
num_nodes
;
end_nid
=
codec
->
start_nid
+
codec
->
num_nodes
;
...
@@ -3911,14 +3908,18 @@ static void cx_auto_parse_eapd(struct hda_codec *codec)
...
@@ -3911,14 +3908,18 @@ static void cx_auto_parse_eapd(struct hda_codec *codec)
continue
;
continue
;
if
(
!
(
snd_hda_query_pin_caps
(
codec
,
nid
)
&
AC_PINCAP_EAPD
))
if
(
!
(
snd_hda_query_pin_caps
(
codec
,
nid
)
&
AC_PINCAP_EAPD
))
continue
;
continue
;
if
(
found_in_nid_list
(
nid
,
cfg
->
line_out_pins
,
cfg
->
line_outs
)
||
found_in_nid_list
(
nid
,
cfg
->
hp_pins
,
cfg
->
hp_outs
)
||
found_in_nid_list
(
nid
,
cfg
->
speaker_pins
,
cfg
->
speaker_outs
))
continue
;
spec
->
eapds
[
spec
->
num_eapds
++
]
=
nid
;
spec
->
eapds
[
spec
->
num_eapds
++
]
=
nid
;
if
(
spec
->
num_eapds
>=
ARRAY_SIZE
(
spec
->
eapds
))
if
(
spec
->
num_eapds
>=
ARRAY_SIZE
(
spec
->
eapds
))
break
;
break
;
}
}
/* NOTE: below is a wild guess; if we have more than two EAPDs,
* it's a new chip, where EAPDs are supposed to be associated to
* pins, and we can control EAPD per pin.
* OTOH, if only one or two EAPDs are found, it's an old chip,
* thus it might control over all pins.
*/
spec
->
pin_eapd_ctrls
=
spec
->
num_eapds
>
2
;
}
}
static
int
cx_auto_parse_auto_config
(
struct
hda_codec
*
codec
)
static
int
cx_auto_parse_auto_config
(
struct
hda_codec
*
codec
)
...
@@ -4024,8 +4025,9 @@ static void cx_auto_init_output(struct hda_codec *codec)
...
@@ -4024,8 +4025,9 @@ static void cx_auto_init_output(struct hda_codec *codec)
}
}
}
}
cx_auto_update_speakers
(
codec
);
cx_auto_update_speakers
(
codec
);
/* turn on/off extra EAPDs, too */
/* turn on all EAPDs if no individual EAPD control is available */
cx_auto_turn_eapd
(
codec
,
spec
->
num_eapds
,
spec
->
eapds
,
true
);
if
(
!
spec
->
pin_eapd_ctrls
)
cx_auto_turn_eapd
(
codec
,
spec
->
num_eapds
,
spec
->
eapds
,
true
);
}
}
static
void
cx_auto_init_input
(
struct
hda_codec
*
codec
)
static
void
cx_auto_init_input
(
struct
hda_codec
*
codec
)
...
@@ -4212,6 +4214,8 @@ static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
...
@@ -4212,6 +4214,8 @@ static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
int
idx
=
get_input_connection
(
codec
,
adc_nid
,
nid
);
int
idx
=
get_input_connection
(
codec
,
adc_nid
,
nid
);
if
(
idx
<
0
)
if
(
idx
<
0
)
continue
;
continue
;
if
(
spec
->
single_adc_amp
)
idx
=
0
;
return
cx_auto_add_volume_idx
(
codec
,
label
,
pfx
,
return
cx_auto_add_volume_idx
(
codec
,
label
,
pfx
,
cidx
,
adc_nid
,
HDA_INPUT
,
idx
);
cidx
,
adc_nid
,
HDA_INPUT
,
idx
);
}
}
...
@@ -4252,14 +4256,21 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
...
@@ -4252,14 +4256,21 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
struct
hda_input_mux
*
imux
=
&
spec
->
private_imux
;
struct
hda_input_mux
*
imux
=
&
spec
->
private_imux
;
const
char
*
prev_label
;
const
char
*
prev_label
;
int
input_conn
[
HDA_MAX_NUM_INPUTS
];
int
input_conn
[
HDA_MAX_NUM_INPUTS
];
int
i
,
err
,
cidx
;
int
i
,
j
,
err
,
cidx
;
int
multi_connection
;
int
multi_connection
;
if
(
!
imux
->
num_items
)
return
0
;
multi_connection
=
0
;
multi_connection
=
0
;
for
(
i
=
0
;
i
<
imux
->
num_items
;
i
++
)
{
for
(
i
=
0
;
i
<
imux
->
num_items
;
i
++
)
{
cidx
=
get_input_connection
(
codec
,
spec
->
imux_info
[
i
].
adc
,
cidx
=
get_input_connection
(
codec
,
spec
->
imux_info
[
i
].
adc
,
spec
->
imux_info
[
i
].
pin
);
spec
->
imux_info
[
i
].
pin
);
input_conn
[
i
]
=
(
spec
->
imux_info
[
i
].
adc
<<
8
)
|
cidx
;
if
(
cidx
<
0
)
continue
;
input_conn
[
i
]
=
spec
->
imux_info
[
i
].
adc
;
if
(
!
spec
->
single_adc_amp
)
input_conn
[
i
]
|=
cidx
<<
8
;
if
(
i
>
0
&&
input_conn
[
i
]
!=
input_conn
[
0
])
if
(
i
>
0
&&
input_conn
[
i
]
!=
input_conn
[
0
])
multi_connection
=
1
;
multi_connection
=
1
;
}
}
...
@@ -4288,6 +4299,15 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
...
@@ -4288,6 +4299,15 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
err
=
cx_auto_add_capture_volume
(
codec
,
nid
,
err
=
cx_auto_add_capture_volume
(
codec
,
nid
,
"Capture"
,
""
,
cidx
);
"Capture"
,
""
,
cidx
);
}
else
{
}
else
{
bool
dup_found
=
false
;
for
(
j
=
0
;
j
<
i
;
j
++
)
{
if
(
input_conn
[
j
]
==
input_conn
[
i
])
{
dup_found
=
true
;
break
;
}
}
if
(
dup_found
)
continue
;
err
=
cx_auto_add_capture_volume
(
codec
,
nid
,
err
=
cx_auto_add_capture_volume
(
codec
,
nid
,
label
,
" Capture"
,
cidx
);
label
,
" Capture"
,
cidx
);
}
}
...
@@ -4412,6 +4432,12 @@ static int patch_conexant_auto(struct hda_codec *codec)
...
@@ -4412,6 +4432,12 @@ static int patch_conexant_auto(struct hda_codec *codec)
codec
->
spec
=
spec
;
codec
->
spec
=
spec
;
codec
->
pin_amp_workaround
=
1
;
codec
->
pin_amp_workaround
=
1
;
switch
(
codec
->
vendor_id
)
{
case
0x14f15045
:
spec
->
single_adc_amp
=
1
;
break
;
}
apply_pin_fixup
(
codec
,
cxt_fixups
,
cxt_pincfg_tbl
);
apply_pin_fixup
(
codec
,
cxt_fixups
,
cxt_pincfg_tbl
);
err
=
cx_auto_search_adcs
(
codec
);
err
=
cx_auto_search_adcs
(
codec
);
...
...
sound/pci/hda/patch_realtek.c
View file @
8128c9f2
...
@@ -116,6 +116,8 @@ struct alc_spec {
...
@@ -116,6 +116,8 @@ struct alc_spec {
const
hda_nid_t
*
capsrc_nids
;
const
hda_nid_t
*
capsrc_nids
;
hda_nid_t
dig_in_nid
;
/* digital-in NID; optional */
hda_nid_t
dig_in_nid
;
/* digital-in NID; optional */
hda_nid_t
mixer_nid
;
/* analog-mixer NID */
hda_nid_t
mixer_nid
;
/* analog-mixer NID */
DECLARE_BITMAP
(
vol_ctls
,
0x20
<<
1
);
DECLARE_BITMAP
(
sw_ctls
,
0x20
<<
1
);
/* capture setup for dynamic dual-adc switch */
/* capture setup for dynamic dual-adc switch */
hda_nid_t
cur_adc
;
hda_nid_t
cur_adc
;
...
@@ -3006,14 +3008,32 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
...
@@ -3006,14 +3008,32 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
return
0
;
return
0
;
}
}
static
inline
unsigned
int
get_ctl_pos
(
unsigned
int
data
)
{
hda_nid_t
nid
=
get_amp_nid_
(
data
);
unsigned
int
dir
=
get_amp_direction_
(
data
);
return
(
nid
<<
1
)
|
dir
;
}
#define is_ctl_used(bits, data) \
test_bit(get_ctl_pos(data), bits)
#define mark_ctl_usage(bits, data) \
set_bit(get_ctl_pos(data), bits)
static
int
alc_auto_add_vol_ctl
(
struct
hda_codec
*
codec
,
static
int
alc_auto_add_vol_ctl
(
struct
hda_codec
*
codec
,
const
char
*
pfx
,
int
cidx
,
const
char
*
pfx
,
int
cidx
,
hda_nid_t
nid
,
unsigned
int
chs
)
hda_nid_t
nid
,
unsigned
int
chs
)
{
{
struct
alc_spec
*
spec
=
codec
->
spec
;
unsigned
int
val
;
if
(
!
nid
)
if
(
!
nid
)
return
0
;
return
0
;
val
=
HDA_COMPOSE_AMP_VAL
(
nid
,
chs
,
0
,
HDA_OUTPUT
);
if
(
is_ctl_used
(
spec
->
vol_ctls
,
val
)
&&
chs
!=
2
)
/* exclude LFE */
return
0
;
mark_ctl_usage
(
spec
->
vol_ctls
,
val
);
return
__add_pb_vol_ctrl
(
codec
->
spec
,
ALC_CTL_WIDGET_VOL
,
pfx
,
cidx
,
return
__add_pb_vol_ctrl
(
codec
->
spec
,
ALC_CTL_WIDGET_VOL
,
pfx
,
cidx
,
HDA_COMPOSE_AMP_VAL
(
nid
,
chs
,
0
,
HDA_OUTPUT
)
);
val
);
}
}
#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
...
@@ -3026,6 +3046,7 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
...
@@ -3026,6 +3046,7 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
const
char
*
pfx
,
int
cidx
,
const
char
*
pfx
,
int
cidx
,
hda_nid_t
nid
,
unsigned
int
chs
)
hda_nid_t
nid
,
unsigned
int
chs
)
{
{
struct
alc_spec
*
spec
=
codec
->
spec
;
int
wid_type
;
int
wid_type
;
int
type
;
int
type
;
unsigned
long
val
;
unsigned
long
val
;
...
@@ -3042,6 +3063,9 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
...
@@ -3042,6 +3063,9 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
type
=
ALC_CTL_BIND_MUTE
;
type
=
ALC_CTL_BIND_MUTE
;
val
=
HDA_COMPOSE_AMP_VAL
(
nid
,
chs
,
2
,
HDA_INPUT
);
val
=
HDA_COMPOSE_AMP_VAL
(
nid
,
chs
,
2
,
HDA_INPUT
);
}
}
if
(
is_ctl_used
(
spec
->
sw_ctls
,
val
)
&&
chs
!=
2
)
/* exclude LFE */
return
0
;
mark_ctl_usage
(
spec
->
sw_ctls
,
val
);
return
__add_pb_sw_ctrl
(
codec
->
spec
,
type
,
pfx
,
cidx
,
val
);
return
__add_pb_sw_ctrl
(
codec
->
spec
,
type
,
pfx
,
cidx
,
val
);
}
}
...
@@ -3136,12 +3160,16 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
...
@@ -3136,12 +3160,16 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
int
err
;
int
err
;
if
(
!
dac
)
{
if
(
!
dac
)
{
unsigned
int
val
;
/* the corresponding DAC is already occupied */
/* the corresponding DAC is already occupied */
if
(
!
(
get_wcaps
(
codec
,
pin
)
&
AC_WCAP_OUT_AMP
))
if
(
!
(
get_wcaps
(
codec
,
pin
)
&
AC_WCAP_OUT_AMP
))
return
0
;
/* no way */
return
0
;
/* no way */
/* create a switch only */
/* create a switch only */
return
add_pb_sw_ctrl
(
spec
,
ALC_CTL_WIDGET_MUTE
,
pfx
,
val
=
HDA_COMPOSE_AMP_VAL
(
pin
,
3
,
0
,
HDA_OUTPUT
);
HDA_COMPOSE_AMP_VAL
(
pin
,
3
,
0
,
HDA_OUTPUT
));
if
(
is_ctl_used
(
spec
->
sw_ctls
,
val
))
return
0
;
/* already created */
mark_ctl_usage
(
spec
->
sw_ctls
,
val
);
return
add_pb_sw_ctrl
(
spec
,
ALC_CTL_WIDGET_MUTE
,
pfx
,
val
);
}
}
sw
=
alc_look_for_out_mute_nid
(
codec
,
pin
,
dac
);
sw
=
alc_look_for_out_mute_nid
(
codec
,
pin
,
dac
);
...
@@ -3186,8 +3214,12 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
...
@@ -3186,8 +3214,12 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins,
if
(
!
num_pins
||
!
pins
[
0
])
if
(
!
num_pins
||
!
pins
[
0
])
return
0
;
return
0
;
if
(
num_pins
==
1
)
if
(
num_pins
==
1
)
{
return
alc_auto_create_extra_out
(
codec
,
*
pins
,
*
dacs
,
pfx
);
hda_nid_t
dac
=
*
dacs
;
if
(
!
dac
)
dac
=
spec
->
multiout
.
dac_nids
[
0
];
return
alc_auto_create_extra_out
(
codec
,
*
pins
,
dac
,
pfx
);
}
if
(
dacs
[
num_pins
-
1
])
{
if
(
dacs
[
num_pins
-
1
])
{
/* OK, we have a multi-output system with individual volumes */
/* OK, we have a multi-output system with individual volumes */
...
...
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