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
nexedi
linux
Commits
081a8c45
Commit
081a8c45
authored
Oct 02, 2009
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'fix/hda' into topic/hda
parents
71623855
7085ec12
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
311 additions
and
93 deletions
+311
-93
Documentation/sound/alsa/HD-Audio-Models.txt
Documentation/sound/alsa/HD-Audio-Models.txt
+1
-0
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_analog.c
+139
-0
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_realtek.c
+157
-87
sound/pci/hda/patch_sigmatel.c
sound/pci/hda/patch_sigmatel.c
+14
-6
No files found.
Documentation/sound/alsa/HD-Audio-Models.txt
View file @
081a8c45
...
@@ -209,6 +209,7 @@ AD1884A / AD1883 / AD1984A / AD1984B
...
@@ -209,6 +209,7 @@ AD1884A / AD1883 / AD1984A / AD1984B
laptop laptop with HP jack sensing
laptop laptop with HP jack sensing
mobile mobile devices with HP jack sensing
mobile mobile devices with HP jack sensing
thinkpad Lenovo Thinkpad X300
thinkpad Lenovo Thinkpad X300
touchsmart HP Touchsmart
AD1884
AD1884
======
======
...
...
sound/pci/hda/patch_analog.c
View file @
081a8c45
...
@@ -4031,6 +4031,127 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec)
...
@@ -4031,6 +4031,127 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec)
return
0
;
return
0
;
}
}
/*
* HP Touchsmart
* port-A (0x11) - front hp-out
* port-B (0x14) - unused
* port-C (0x15) - unused
* port-D (0x12) - rear line out
* port-E (0x1c) - front mic-in
* port-F (0x16) - Internal speakers
* digital-mic (0x17) - Internal mic
*/
static
struct
hda_verb
ad1984a_touchsmart_verbs
[]
=
{
/* DACs; unmute as default */
{
0x03
,
AC_VERB_SET_AMP_GAIN_MUTE
,
0x27
},
/* 0dB */
{
0x04
,
AC_VERB_SET_AMP_GAIN_MUTE
,
0x27
},
/* 0dB */
/* Port-A (HP) mixer - route only from analog mixer */
{
0x07
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_IN_MUTE
(
0
)},
{
0x07
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_IN_UNMUTE
(
1
)},
/* Port-A pin */
{
0x11
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
PIN_HP
},
/* Port-A (HP) pin - always unmuted */
{
0x11
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_OUT_UNMUTE
},
/* Port-E (int speaker) mixer - route only from analog mixer */
{
0x25
,
AC_VERB_SET_AMP_GAIN_MUTE
,
0x03
},
/* Port-E pin */
{
0x1c
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
PIN_IN
},
{
0x1c
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_OUT_UNMUTE
},
{
0x1c
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
PIN_VREF80
},
/* Port-F (int speaker) mixer - route only from analog mixer */
{
0x0b
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_IN_MUTE
(
0
)},
{
0x0b
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_IN_UNMUTE
(
1
)},
/* Port-F pin */
{
0x16
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
PIN_HP
},
{
0x16
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_OUT_MUTE
},
/* Analog mixer; mute as default */
{
0x20
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_IN_MUTE
(
0
)},
{
0x20
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_IN_MUTE
(
1
)},
{
0x20
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_IN_MUTE
(
2
)},
{
0x20
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_IN_MUTE
(
3
)},
{
0x20
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_IN_MUTE
(
4
)},
{
0x20
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_IN_MUTE
(
5
)},
/* Analog Mix output amp */
{
0x21
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_OUT_MUTE
},
/* capture sources */
/* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */
/* set via unsol */
{
0x0c
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_OUT_MUTE
},
{
0x0d
,
AC_VERB_SET_CONNECT_SEL
,
0x0
},
{
0x0d
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_OUT_MUTE
},
/* unsolicited event for pin-sense */
{
0x11
,
AC_VERB_SET_UNSOLICITED_ENABLE
,
AC_USRSP_EN
|
AD1884A_HP_EVENT
},
{
0x1c
,
AC_VERB_SET_UNSOLICITED_ENABLE
,
AC_USRSP_EN
|
AD1884A_MIC_EVENT
},
/* allow to touch GPIO1 (for mute control) */
{
0x01
,
AC_VERB_SET_GPIO_MASK
,
0x02
},
{
0x01
,
AC_VERB_SET_GPIO_DIRECTION
,
0x02
},
{
0x01
,
AC_VERB_SET_GPIO_DATA
,
0x02
},
/* first muted */
/* internal mic - dmic */
{
0x17
,
AC_VERB_SET_PIN_WIDGET_CONTROL
,
PIN_IN
},
/* set magic COEFs for dmic */
{
0x01
,
AC_VERB_SET_COEF_INDEX
,
0x13f7
},
{
0x01
,
AC_VERB_SET_PROC_COEF
,
0x08
},
{
}
/* end */
};
static
struct
snd_kcontrol_new
ad1984a_touchsmart_mixers
[]
=
{
HDA_CODEC_VOLUME
(
"Master Playback Volume"
,
0x21
,
0x0
,
HDA_OUTPUT
),
/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_MIXER
,
.
name
=
"Master Playback Switch"
,
.
info
=
snd_hda_mixer_amp_switch_info
,
.
get
=
snd_hda_mixer_amp_switch_get
,
.
put
=
ad1884a_mobile_master_sw_put
,
.
private_value
=
HDA_COMPOSE_AMP_VAL
(
0x21
,
3
,
0
,
HDA_OUTPUT
),
},
HDA_CODEC_VOLUME
(
"PCM Playback Volume"
,
0x20
,
0x5
,
HDA_INPUT
),
HDA_CODEC_MUTE
(
"PCM Playback Switch"
,
0x20
,
0x5
,
HDA_INPUT
),
HDA_CODEC_VOLUME
(
"Capture Volume"
,
0x0c
,
0x0
,
HDA_OUTPUT
),
HDA_CODEC_MUTE
(
"Capture Switch"
,
0x0c
,
0x0
,
HDA_OUTPUT
),
HDA_CODEC_VOLUME
(
"Mic Boost"
,
0x25
,
0x0
,
HDA_OUTPUT
),
HDA_CODEC_VOLUME
(
"Internal Mic Boost"
,
0x17
,
0x0
,
HDA_INPUT
),
{
}
/* end */
};
/* switch to external mic if plugged */
static
void
ad1984a_touchsmart_automic
(
struct
hda_codec
*
codec
)
{
if
(
snd_hda_codec_read
(
codec
,
0x1c
,
0
,
AC_VERB_GET_PIN_SENSE
,
0
)
&
0x80000000
)
{
snd_hda_codec_write
(
codec
,
0x0c
,
0
,
AC_VERB_SET_CONNECT_SEL
,
0x4
);
}
else
{
snd_hda_codec_write
(
codec
,
0x0c
,
0
,
AC_VERB_SET_CONNECT_SEL
,
0x5
);
}
}
/* unsolicited event for HP jack sensing */
static
void
ad1984a_touchsmart_unsol_event
(
struct
hda_codec
*
codec
,
unsigned
int
res
)
{
switch
(
res
>>
26
)
{
case
AD1884A_HP_EVENT
:
ad1884a_hp_automute
(
codec
);
break
;
case
AD1884A_MIC_EVENT
:
ad1984a_touchsmart_automic
(
codec
);
break
;
}
}
/* initialize jack-sensing, too */
static
int
ad1984a_touchsmart_init
(
struct
hda_codec
*
codec
)
{
ad198x_init
(
codec
);
ad1884a_hp_automute
(
codec
);
ad1984a_touchsmart_automic
(
codec
);
return
0
;
}
/*
/*
*/
*/
...
@@ -4039,6 +4160,7 @@ enum {
...
@@ -4039,6 +4160,7 @@ enum {
AD1884A_LAPTOP
,
AD1884A_LAPTOP
,
AD1884A_MOBILE
,
AD1884A_MOBILE
,
AD1884A_THINKPAD
,
AD1884A_THINKPAD
,
AD1984A_TOUCHSMART
,
AD1884A_MODELS
AD1884A_MODELS
};
};
...
@@ -4047,6 +4169,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
...
@@ -4047,6 +4169,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
[
AD1884A_LAPTOP
]
=
"laptop"
,
[
AD1884A_LAPTOP
]
=
"laptop"
,
[
AD1884A_MOBILE
]
=
"mobile"
,
[
AD1884A_MOBILE
]
=
"mobile"
,
[
AD1884A_THINKPAD
]
=
"thinkpad"
,
[
AD1884A_THINKPAD
]
=
"thinkpad"
,
[
AD1984A_TOUCHSMART
]
=
"touchsmart"
,
};
};
static
struct
snd_pci_quirk
ad1884a_cfg_tbl
[]
=
{
static
struct
snd_pci_quirk
ad1884a_cfg_tbl
[]
=
{
...
@@ -4059,6 +4182,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
...
@@ -4059,6 +4182,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
SND_PCI_QUIRK_MASK
(
0x103c
,
0xff00
,
0x3600
,
"HP laptop"
,
AD1884A_LAPTOP
),
SND_PCI_QUIRK_MASK
(
0x103c
,
0xff00
,
0x3600
,
"HP laptop"
,
AD1884A_LAPTOP
),
SND_PCI_QUIRK_MASK
(
0x103c
,
0xfff0
,
0x7010
,
"HP laptop"
,
AD1884A_MOBILE
),
SND_PCI_QUIRK_MASK
(
0x103c
,
0xfff0
,
0x7010
,
"HP laptop"
,
AD1884A_MOBILE
),
SND_PCI_QUIRK
(
0x17aa
,
0x20ac
,
"Thinkpad X300"
,
AD1884A_THINKPAD
),
SND_PCI_QUIRK
(
0x17aa
,
0x20ac
,
"Thinkpad X300"
,
AD1884A_THINKPAD
),
SND_PCI_QUIRK
(
0x103c
,
0x2a82
,
"Touchsmart"
,
AD1984A_TOUCHSMART
),
{}
{}
};
};
...
@@ -4142,6 +4266,21 @@ static int patch_ad1884a(struct hda_codec *codec)
...
@@ -4142,6 +4266,21 @@ static int patch_ad1884a(struct hda_codec *codec)
codec
->
patch_ops
.
unsol_event
=
ad1984a_thinkpad_unsol_event
;
codec
->
patch_ops
.
unsol_event
=
ad1984a_thinkpad_unsol_event
;
codec
->
patch_ops
.
init
=
ad1984a_thinkpad_init
;
codec
->
patch_ops
.
init
=
ad1984a_thinkpad_init
;
break
;
break
;
case
AD1984A_TOUCHSMART
:
spec
->
mixers
[
0
]
=
ad1984a_touchsmart_mixers
;
spec
->
init_verbs
[
0
]
=
ad1984a_touchsmart_verbs
;
spec
->
multiout
.
dig_out_nid
=
0
;
codec
->
patch_ops
.
unsol_event
=
ad1984a_touchsmart_unsol_event
;
codec
->
patch_ops
.
init
=
ad1984a_touchsmart_init
;
/* set the upper-limit for mixer amp to 0dB for avoiding the
* possible damage by overloading
*/
snd_hda_override_amp_caps
(
codec
,
0x20
,
HDA_INPUT
,
(
0x17
<<
AC_AMPCAP_OFFSET_SHIFT
)
|
(
0x17
<<
AC_AMPCAP_NUM_STEPS_SHIFT
)
|
(
0x05
<<
AC_AMPCAP_STEP_SIZE_SHIFT
)
|
(
1
<<
AC_AMPCAP_MUTE_SHIFT
));
break
;
}
}
return
0
;
return
0
;
...
...
sound/pci/hda/patch_realtek.c
View file @
081a8c45
...
@@ -12660,7 +12660,7 @@ static struct alc_config_preset alc268_presets[] = {
...
@@ -12660,7 +12660,7 @@ static struct alc_config_preset alc268_presets[] = {
.
init_hook
=
alc268_toshiba_automute
,
.
init_hook
=
alc268_toshiba_automute
,
},
},
[
ALC268_ACER
]
=
{
[
ALC268_ACER
]
=
{
.
mixers
=
{
alc268_acer_mixer
,
alc268_capture_
nosrc
_mixer
,
.
mixers
=
{
alc268_acer_mixer
,
alc268_capture_
alt
_mixer
,
alc268_beep_mixer
},
alc268_beep_mixer
},
.
init_verbs
=
{
alc268_base_init_verbs
,
alc268_eapd_verbs
,
.
init_verbs
=
{
alc268_base_init_verbs
,
alc268_eapd_verbs
,
alc268_acer_verbs
},
alc268_acer_verbs
},
...
@@ -16852,6 +16852,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
...
@@ -16852,6 +16852,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
SND_PCI_QUIRK
(
0x105b
,
0x0cd6
,
"Foxconn"
,
ALC662_ECS
),
SND_PCI_QUIRK
(
0x105b
,
0x0cd6
,
"Foxconn"
,
ALC662_ECS
),
SND_PCI_QUIRK
(
0x105b
,
0x0d47
,
"Foxconn 45CMX/45GMX/45CMX-K"
,
SND_PCI_QUIRK
(
0x105b
,
0x0d47
,
"Foxconn 45CMX/45GMX/45CMX-K"
,
ALC662_3ST_6ch_DIG
),
ALC662_3ST_6ch_DIG
),
SND_PCI_QUIRK
(
0x1179
,
0xff6e
,
"Toshiba NB200"
,
ALC663_ASUS_MODE4
),
SND_PCI_QUIRK
(
0x144d
,
0xca00
,
"Samsung NC10"
,
ALC272_SAMSUNG_NC10
),
SND_PCI_QUIRK
(
0x144d
,
0xca00
,
"Samsung NC10"
,
ALC272_SAMSUNG_NC10
),
SND_PCI_QUIRK
(
0x1458
,
0xa002
,
"Gigabyte 945GCM-S2L"
,
SND_PCI_QUIRK
(
0x1458
,
0xa002
,
"Gigabyte 945GCM-S2L"
,
ALC662_3ST_6ch_DIG
),
ALC662_3ST_6ch_DIG
),
...
@@ -17145,70 +17146,145 @@ static struct alc_config_preset alc662_presets[] = {
...
@@ -17145,70 +17146,145 @@ static struct alc_config_preset alc662_presets[] = {
* BIOS auto configuration
* BIOS auto configuration
*/
*/
/* add playback controls from the parsed DAC table */
/* convert from MIX nid to DAC */
static
int
alc662_auto_create_multi_out_ctls
(
struct
alc_spec
*
spec
,
static
inline
hda_nid_t
alc662_mix_to_dac
(
hda_nid_t
nid
)
{
if
(
nid
==
0x0f
)
return
0x02
;
else
if
(
nid
>=
0x0c
&&
nid
<=
0x0e
)
return
nid
-
0x0c
+
0x02
;
else
return
0
;
}
/* get MIX nid connected to the given pin targeted to DAC */
static
hda_nid_t
alc662_dac_to_mix
(
struct
hda_codec
*
codec
,
hda_nid_t
pin
,
hda_nid_t
dac
)
{
hda_nid_t
mix
[
4
];
int
i
,
num
;
num
=
snd_hda_get_connections
(
codec
,
pin
,
mix
,
ARRAY_SIZE
(
mix
));
for
(
i
=
0
;
i
<
num
;
i
++
)
{
if
(
alc662_mix_to_dac
(
mix
[
i
])
==
dac
)
return
mix
[
i
];
}
return
0
;
}
/* look for an empty DAC slot */
static
hda_nid_t
alc662_look_for_dac
(
struct
hda_codec
*
codec
,
hda_nid_t
pin
)
{
struct
alc_spec
*
spec
=
codec
->
spec
;
hda_nid_t
srcs
[
5
];
int
i
,
j
,
num
;
num
=
snd_hda_get_connections
(
codec
,
pin
,
srcs
,
ARRAY_SIZE
(
srcs
));
if
(
num
<
0
)
return
0
;
for
(
i
=
0
;
i
<
num
;
i
++
)
{
hda_nid_t
nid
=
alc662_mix_to_dac
(
srcs
[
i
]);
if
(
!
nid
)
continue
;
for
(
j
=
0
;
j
<
spec
->
multiout
.
num_dacs
;
j
++
)
if
(
spec
->
multiout
.
dac_nids
[
j
]
==
nid
)
break
;
if
(
j
>=
spec
->
multiout
.
num_dacs
)
return
nid
;
}
return
0
;
}
/* fill in the dac_nids table from the parsed pin configuration */
static
int
alc662_auto_fill_dac_nids
(
struct
hda_codec
*
codec
,
const
struct
auto_pin_cfg
*
cfg
)
const
struct
auto_pin_cfg
*
cfg
)
{
struct
alc_spec
*
spec
=
codec
->
spec
;
int
i
;
hda_nid_t
dac
;
spec
->
multiout
.
dac_nids
=
spec
->
private_dac_nids
;
for
(
i
=
0
;
i
<
cfg
->
line_outs
;
i
++
)
{
dac
=
alc662_look_for_dac
(
codec
,
cfg
->
line_out_pins
[
i
]);
if
(
!
dac
)
continue
;
spec
->
multiout
.
dac_nids
[
spec
->
multiout
.
num_dacs
++
]
=
dac
;
}
return
0
;
}
static
int
alc662_add_vol_ctl
(
struct
alc_spec
*
spec
,
const
char
*
pfx
,
hda_nid_t
nid
,
unsigned
int
chs
)
{
{
char
name
[
32
];
char
name
[
32
];
sprintf
(
name
,
"%s Playback Volume"
,
pfx
);
return
add_control
(
spec
,
ALC_CTL_WIDGET_VOL
,
name
,
HDA_COMPOSE_AMP_VAL
(
nid
,
chs
,
0
,
HDA_OUTPUT
));
}
static
int
alc662_add_sw_ctl
(
struct
alc_spec
*
spec
,
const
char
*
pfx
,
hda_nid_t
nid
,
unsigned
int
chs
)
{
char
name
[
32
];
sprintf
(
name
,
"%s Playback Switch"
,
pfx
);
return
add_control
(
spec
,
ALC_CTL_WIDGET_MUTE
,
name
,
HDA_COMPOSE_AMP_VAL
(
nid
,
chs
,
0
,
HDA_INPUT
));
}
#define alc662_add_stereo_vol(spec, pfx, nid) \
alc662_add_vol_ctl(spec, pfx, nid, 3)
#define alc662_add_stereo_sw(spec, pfx, nid) \
alc662_add_sw_ctl(spec, pfx, nid, 3)
/* add playback controls from the parsed DAC table */
static
int
alc662_auto_create_multi_out_ctls
(
struct
hda_codec
*
codec
,
const
struct
auto_pin_cfg
*
cfg
)
{
struct
alc_spec
*
spec
=
codec
->
spec
;
static
const
char
*
chname
[
4
]
=
{
static
const
char
*
chname
[
4
]
=
{
"Front"
,
"Surround"
,
NULL
/*CLFE*/
,
"Side"
"Front"
,
"Surround"
,
NULL
/*CLFE*/
,
"Side"
};
};
hda_nid_t
nid
;
hda_nid_t
nid
,
mix
;
int
i
,
err
;
int
i
,
err
;
for
(
i
=
0
;
i
<
cfg
->
line_outs
;
i
++
)
{
for
(
i
=
0
;
i
<
cfg
->
line_outs
;
i
++
)
{
if
(
!
spec
->
multiout
.
dac_nids
[
i
])
nid
=
spec
->
multiout
.
dac_nids
[
i
];
if
(
!
nid
)
continue
;
mix
=
alc662_dac_to_mix
(
codec
,
cfg
->
line_out_pins
[
i
],
nid
);
if
(
!
mix
)
continue
;
continue
;
nid
=
alc880_idx_to_dac
(
i
);
if
(
i
==
2
)
{
if
(
i
==
2
)
{
/* Center/LFE */
/* Center/LFE */
err
=
add_control
(
spec
,
ALC_CTL_WIDGET_VOL
,
err
=
alc662_add_vol_ctl
(
spec
,
"Center"
,
nid
,
1
);
"Center Playback Volume"
,
HDA_COMPOSE_AMP_VAL
(
nid
,
1
,
0
,
HDA_OUTPUT
));
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
err
=
add_control
(
spec
,
ALC_CTL_WIDGET_VOL
,
err
=
alc662_add_vol_ctl
(
spec
,
"LFE"
,
nid
,
2
);
"LFE Playback Volume"
,
HDA_COMPOSE_AMP_VAL
(
nid
,
2
,
0
,
HDA_OUTPUT
));
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
err
=
add_control
(
spec
,
ALC_CTL_WIDGET_MUTE
,
err
=
alc662_add_sw_ctl
(
spec
,
"Center"
,
mix
,
1
);
"Center Playback Switch"
,
HDA_COMPOSE_AMP_VAL
(
0x0e
,
1
,
0
,
HDA_INPUT
));
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
err
=
add_control
(
spec
,
ALC_CTL_WIDGET_MUTE
,
err
=
alc662_add_sw_ctl
(
spec
,
"LFE"
,
mix
,
2
);
"LFE Playback Switch"
,
HDA_COMPOSE_AMP_VAL
(
0x0e
,
2
,
0
,
HDA_INPUT
));
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
}
else
{
}
else
{
const
char
*
pfx
;
const
char
*
pfx
;
if
(
cfg
->
line_outs
==
1
&&
if
(
cfg
->
line_outs
==
1
&&
cfg
->
line_out_type
==
AUTO_PIN_SPEAKER_OUT
)
{
cfg
->
line_out_type
==
AUTO_PIN_SPEAKER_OUT
)
{
if
(
!
cfg
->
hp_pin
s
)
if
(
cfg
->
hp_out
s
)
pfx
=
"Speaker"
;
pfx
=
"Speaker"
;
else
else
pfx
=
"PCM"
;
pfx
=
"PCM"
;
}
else
}
else
pfx
=
chname
[
i
];
pfx
=
chname
[
i
];
sprintf
(
name
,
"%s Playback Volume"
,
pfx
);
err
=
alc662_add_vol_ctl
(
spec
,
pfx
,
nid
,
3
);
err
=
add_control
(
spec
,
ALC_CTL_WIDGET_VOL
,
name
,
HDA_COMPOSE_AMP_VAL
(
nid
,
3
,
0
,
HDA_OUTPUT
));
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
if
(
cfg
->
line_outs
==
1
&&
if
(
cfg
->
line_outs
==
1
&&
cfg
->
line_out_type
==
AUTO_PIN_SPEAKER_OUT
)
cfg
->
line_out_type
==
AUTO_PIN_SPEAKER_OUT
)
pfx
=
"Speaker"
;
pfx
=
"Speaker"
;
sprintf
(
name
,
"%s Playback Switch"
,
pfx
);
err
=
alc662_add_sw_ctl
(
spec
,
pfx
,
mix
,
3
);
err
=
add_control
(
spec
,
ALC_CTL_WIDGET_MUTE
,
name
,
HDA_COMPOSE_AMP_VAL
(
alc880_idx_to_mixer
(
i
),
3
,
0
,
HDA_INPUT
));
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
}
}
...
@@ -17217,54 +17293,38 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
...
@@ -17217,54 +17293,38 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
}
}
/* add playback controls for speaker and HP outputs */
/* add playback controls for speaker and HP outputs */
static
int
alc662_auto_create_extra_out
(
struct
alc_spec
*
spec
,
hda_nid_t
pin
,
/* return DAC nid if any new DAC is assigned */
static
int
alc662_auto_create_extra_out
(
struct
hda_codec
*
codec
,
hda_nid_t
pin
,
const
char
*
pfx
)
const
char
*
pfx
)
{
{
hda_nid_t
nid
;
struct
alc_spec
*
spec
=
codec
->
spec
;
hda_nid_t
nid
,
mix
;
int
err
;
int
err
;
char
name
[
32
];
if
(
!
pin
)
if
(
!
pin
)
return
0
;
return
0
;
nid
=
alc662_look_for_dac
(
codec
,
pin
);
if
(
pin
==
0x17
)
{
if
(
!
nid
)
{
/* ALC663 has a mono output pin on 0x17 */
char
name
[
32
];
/* the corresponding DAC is already occupied */
if
(
!
(
get_wcaps
(
codec
,
pin
)
&
AC_WCAP_OUT_AMP
))
return
0
;
/* no way */
/* create a switch only */
sprintf
(
name
,
"%s Playback Switch"
,
pfx
);
sprintf
(
name
,
"%s Playback Switch"
,
pfx
);
err
=
add_control
(
spec
,
ALC_CTL_WIDGET_MUTE
,
name
,
return
add_control
(
spec
,
ALC_CTL_WIDGET_MUTE
,
name
,
HDA_COMPOSE_AMP_VAL
(
pin
,
2
,
0
,
HDA_OUTPUT
));
HDA_COMPOSE_AMP_VAL
(
pin
,
3
,
0
,
HDA_OUTPUT
));
return
err
;
}
}
if
(
alc880_is_fixed_pin
(
pin
))
{
mix
=
alc662_dac_to_mix
(
codec
,
pin
,
nid
);
nid
=
alc880_idx_to_dac
(
alc880_fixed_pin_idx
(
pin
));
if
(
!
mix
)
/* printk(KERN_DEBUG "DAC nid=%x\n",nid); */
return
0
;
/* specify the DAC as the extra output */
err
=
alc662_add_vol_ctl
(
spec
,
pfx
,
nid
,
3
);
if
(
!
spec
->
multiout
.
hp_nid
)
spec
->
multiout
.
hp_nid
=
nid
;
else
spec
->
multiout
.
extra_out_nid
[
0
]
=
nid
;
/* control HP volume/switch on the output mixer amp */
nid
=
alc880_idx_to_dac
(
alc880_fixed_pin_idx
(
pin
));
sprintf
(
name
,
"%s Playback Volume"
,
pfx
);
err
=
add_control
(
spec
,
ALC_CTL_WIDGET_VOL
,
name
,
HDA_COMPOSE_AMP_VAL
(
nid
,
3
,
0
,
HDA_OUTPUT
));
if
(
err
<
0
)
return
err
;
sprintf
(
name
,
"%s Playback Switch"
,
pfx
);
err
=
add_control
(
spec
,
ALC_CTL_BIND_MUTE
,
name
,
HDA_COMPOSE_AMP_VAL
(
nid
,
3
,
2
,
HDA_INPUT
));
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
}
else
if
(
alc880_is_multi_pin
(
pin
))
{
err
=
alc662_add_sw_ctl
(
spec
,
pfx
,
mix
,
3
);
/* set manual connection */
/* we have only a switch on HP-out PIN */
sprintf
(
name
,
"%s Playback Switch"
,
pfx
);
err
=
add_control
(
spec
,
ALC_CTL_WIDGET_MUTE
,
name
,
HDA_COMPOSE_AMP_VAL
(
pin
,
3
,
0
,
HDA_OUTPUT
));
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
}
return
nid
;
return
0
;
}
}
/* create playback/capture controls for input pins */
/* create playback/capture controls for input pins */
...
@@ -17273,30 +17333,35 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
...
@@ -17273,30 +17333,35 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
static
void
alc662_auto_set_output_and_unmute
(
struct
hda_codec
*
codec
,
static
void
alc662_auto_set_output_and_unmute
(
struct
hda_codec
*
codec
,
hda_nid_t
nid
,
int
pin_type
,
hda_nid_t
nid
,
int
pin_type
,
int
dac_idx
)
hda_nid_t
dac
)
{
{
int
i
,
num
;
hda_nid_t
srcs
[
4
];
alc_set_pin_output
(
codec
,
nid
,
pin_type
);
alc_set_pin_output
(
codec
,
nid
,
pin_type
);
/* need the manual connection? */
/* need the manual connection? */
if
(
alc880_is_multi_pin
(
nid
))
{
num
=
snd_hda_get_connections
(
codec
,
nid
,
srcs
,
ARRAY_SIZE
(
srcs
));
struct
alc_spec
*
spec
=
codec
->
spec
;
if
(
num
<=
1
)
int
idx
=
alc880_multi_pin_idx
(
nid
);
return
;
snd_hda_codec_write
(
codec
,
alc880_idx_to_selector
(
idx
),
0
,
for
(
i
=
0
;
i
<
num
;
i
++
)
{
AC_VERB_SET_CONNECT_SEL
,
if
(
alc662_mix_to_dac
(
srcs
[
i
])
!=
dac
)
alc880_dac_to_idx
(
spec
->
multiout
.
dac_nids
[
dac_idx
]));
continue
;
snd_hda_codec_write
(
codec
,
nid
,
0
,
AC_VERB_SET_CONNECT_SEL
,
i
);
return
;
}
}
}
}
static
void
alc662_auto_init_multi_out
(
struct
hda_codec
*
codec
)
static
void
alc662_auto_init_multi_out
(
struct
hda_codec
*
codec
)
{
{
struct
alc_spec
*
spec
=
codec
->
spec
;
struct
alc_spec
*
spec
=
codec
->
spec
;
int
pin_type
=
get_pin_type
(
spec
->
autocfg
.
line_out_type
);
int
i
;
int
i
;
for
(
i
=
0
;
i
<=
HDA_SIDE
;
i
++
)
{
for
(
i
=
0
;
i
<=
HDA_SIDE
;
i
++
)
{
hda_nid_t
nid
=
spec
->
autocfg
.
line_out_pins
[
i
];
hda_nid_t
nid
=
spec
->
autocfg
.
line_out_pins
[
i
];
int
pin_type
=
get_pin_type
(
spec
->
autocfg
.
line_out_type
);
if
(
nid
)
if
(
nid
)
alc662_auto_set_output_and_unmute
(
codec
,
nid
,
pin_type
,
alc662_auto_set_output_and_unmute
(
codec
,
nid
,
pin_type
,
i
);
spec
->
multiout
.
dac_nids
[
i
]
);
}
}
}
}
...
@@ -17306,12 +17371,13 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec)
...
@@ -17306,12 +17371,13 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec)
hda_nid_t
pin
;
hda_nid_t
pin
;
pin
=
spec
->
autocfg
.
hp_pins
[
0
];
pin
=
spec
->
autocfg
.
hp_pins
[
0
];
if
(
pin
)
/* connect to front */
if
(
pin
)
/* use dac 0 */
alc662_auto_set_output_and_unmute
(
codec
,
pin
,
PIN_HP
,
alc662_auto_set_output_and_unmute
(
codec
,
pin
,
PIN_HP
,
0
);
spec
->
multiout
.
hp_nid
);
pin
=
spec
->
autocfg
.
speaker_pins
[
0
];
pin
=
spec
->
autocfg
.
speaker_pins
[
0
];
if
(
pin
)
if
(
pin
)
alc662_auto_set_output_and_unmute
(
codec
,
pin
,
PIN_OUT
,
0
);
alc662_auto_set_output_and_unmute
(
codec
,
pin
,
PIN_OUT
,
spec
->
multiout
.
extra_out_nid
[
0
]);
}
}
#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
...
@@ -17349,21 +17415,25 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
...
@@ -17349,21 +17415,25 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
if
(
!
spec
->
autocfg
.
line_outs
)
if
(
!
spec
->
autocfg
.
line_outs
)
return
0
;
/* can't find valid BIOS pin config */
return
0
;
/* can't find valid BIOS pin config */
err
=
alc
880_auto_fill_dac_nids
(
sp
ec
,
&
spec
->
autocfg
);
err
=
alc
662_auto_fill_dac_nids
(
cod
ec
,
&
spec
->
autocfg
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
err
=
alc662_auto_create_multi_out_ctls
(
sp
ec
,
&
spec
->
autocfg
);
err
=
alc662_auto_create_multi_out_ctls
(
cod
ec
,
&
spec
->
autocfg
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
err
=
alc662_auto_create_extra_out
(
sp
ec
,
err
=
alc662_auto_create_extra_out
(
cod
ec
,
spec
->
autocfg
.
speaker_pins
[
0
],
spec
->
autocfg
.
speaker_pins
[
0
],
"Speaker"
);
"Speaker"
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
err
=
alc662_auto_create_extra_out
(
spec
,
spec
->
autocfg
.
hp_pins
[
0
],
if
(
err
)
spec
->
multiout
.
extra_out_nid
[
0
]
=
err
;
err
=
alc662_auto_create_extra_out
(
codec
,
spec
->
autocfg
.
hp_pins
[
0
],
"Headphone"
);
"Headphone"
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
if
(
err
)
spec
->
multiout
.
hp_nid
=
err
;
err
=
alc662_auto_create_input_ctls
(
codec
,
&
spec
->
autocfg
);
err
=
alc662_auto_create_input_ctls
(
codec
,
&
spec
->
autocfg
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
...
...
sound/pci/hda/patch_sigmatel.c
View file @
081a8c45
...
@@ -182,8 +182,8 @@ struct sigmatel_jack {
...
@@ -182,8 +182,8 @@ struct sigmatel_jack {
struct
sigmatel_mic_route
{
struct
sigmatel_mic_route
{
hda_nid_t
pin
;
hda_nid_t
pin
;
un
signed
char
mux_idx
;
signed
char
mux_idx
;
un
signed
char
dmux_idx
;
signed
char
dmux_idx
;
};
};
struct
sigmatel_spec
{
struct
sigmatel_spec
{
...
@@ -3469,18 +3469,26 @@ static int set_mic_route(struct hda_codec *codec,
...
@@ -3469,18 +3469,26 @@ static int set_mic_route(struct hda_codec *codec,
break
;
break
;
if
(
i
<=
AUTO_PIN_FRONT_MIC
)
{
if
(
i
<=
AUTO_PIN_FRONT_MIC
)
{
/* analog pin */
/* analog pin */
mic
->
dmux_idx
=
0
;
i
=
get_connection_index
(
codec
,
spec
->
mux_nids
[
0
],
pin
);
i
=
get_connection_index
(
codec
,
spec
->
mux_nids
[
0
],
pin
);
if
(
i
<
0
)
if
(
i
<
0
)
return
-
1
;
return
-
1
;
mic
->
mux_idx
=
i
;
mic
->
mux_idx
=
i
;
mic
->
dmux_idx
=
-
1
;
if
(
spec
->
dmux_nids
)
mic
->
dmux_idx
=
get_connection_index
(
codec
,
spec
->
dmux_nids
[
0
],
spec
->
mux_nids
[
0
]);
}
else
if
(
spec
->
dmux_nids
)
{
}
else
if
(
spec
->
dmux_nids
)
{
/* digital pin */
/* digital pin */
mic
->
mux_idx
=
0
;
i
=
get_connection_index
(
codec
,
spec
->
dmux_nids
[
0
],
pin
);
i
=
get_connection_index
(
codec
,
spec
->
dmux_nids
[
0
],
pin
);
if
(
i
<
0
)
if
(
i
<
0
)
return
-
1
;
return
-
1
;
mic
->
dmux_idx
=
i
;
mic
->
dmux_idx
=
i
;
mic
->
mux_idx
=
-
1
;
if
(
spec
->
mux_nids
)
mic
->
mux_idx
=
get_connection_index
(
codec
,
spec
->
mux_nids
[
0
],
spec
->
dmux_nids
[
0
]);
}
}
return
0
;
return
0
;
}
}
...
@@ -4557,11 +4565,11 @@ static void stac92xx_mic_detect(struct hda_codec *codec)
...
@@ -4557,11 +4565,11 @@ static void stac92xx_mic_detect(struct hda_codec *codec)
mic
=
&
spec
->
ext_mic
;
mic
=
&
spec
->
ext_mic
;
else
else
mic
=
&
spec
->
int_mic
;
mic
=
&
spec
->
int_mic
;
if
(
mic
->
dmux_idx
)
if
(
mic
->
dmux_idx
>=
0
)
snd_hda_codec_write_cache
(
codec
,
spec
->
dmux_nids
[
0
],
0
,
snd_hda_codec_write_cache
(
codec
,
spec
->
dmux_nids
[
0
],
0
,
AC_VERB_SET_CONNECT_SEL
,
AC_VERB_SET_CONNECT_SEL
,
mic
->
dmux_idx
);
mic
->
dmux_idx
);
else
if
(
mic
->
mux_idx
>=
0
)
snd_hda_codec_write_cache
(
codec
,
spec
->
mux_nids
[
0
],
0
,
snd_hda_codec_write_cache
(
codec
,
spec
->
mux_nids
[
0
],
0
,
AC_VERB_SET_CONNECT_SEL
,
AC_VERB_SET_CONNECT_SEL
,
mic
->
mux_idx
);
mic
->
mux_idx
);
...
...
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