Commit 76531d41 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'topic/hda' into for-linus

parents 7d339ae9 a353fbb1
This file explains the codec-specific mixer controls.
Realtek codecs
--------------
* Channel Mode
This is an enum control to change the surround-channel setup,
appears only when the surround channels are available.
It gives the number of channels to be used, "2ch", "4ch", "6ch",
and "8ch". According to the configuration, this also controls the
jack-retasking of multi-I/O jacks.
* Auto-Mute Mode
This is an enum control to change the auto-mute behavior of the
headphone and line-out jacks. If built-in speakers and headphone
and/or line-out jacks are available on a machine, this controls
appears.
When there are only either headphones or line-out jacks, it gives
"Disabled" and "Enabled" state. When enabled, the speaker is muted
automatically when a jack is plugged.
When both headphone and line-out jacks are present, it gives
"Disabled", "Speaker Only" and "Line-Out+Speaker". When
speaker-only is chosen, plugging into a headphone or a line-out jack
mutes the speakers, but not line-outs. When line-out+speaker is
selected, plugging to a headphone jack mutes both speakers and
line-outs.
IDT/Sigmatel codecs
-------------------
* Analog Loopback
This control enables/disables the analog-loopback circuit. This
appears only when "loopback" is set to true in a codec hint
(see HD-Audio.txt). Note that on some codecs the analog-loopback
and the normal PCM playback are exclusive, i.e. when this is on, you
won't hear any PCM stream.
* Swap Center/LFE
Swaps the center and LFE channel order. Normally, the left
corresponds to the center and the right to the LFE. When this is
ON, the left to the LFE and the right to the center.
* Headphone as Line Out
When this control is ON, treat the headphone jacks as line-out
jacks. That is, the headphone won't auto-mute the other line-outs,
and no HP-amp is set to the pins.
* Mic Jack Mode, Line Jack Mode, etc
These enum controls the direction and the bias of the input jack
pins. Depending on the jack type, it can set as "Mic In" and "Line
In", for determining the input bias, or it can be set to "Line Out"
when the pin is a multi-I/O jack for surround channels.
VIA codecs
----------
* Smart 5.1
An enum control to re-task the multi-I/O jacks for surround outputs.
When it's ON, the corresponding input jacks (usually a line-in and a
mic-in) are switched as the surround and the CLFE output jacks.
* Independent HP
When this enum control is enabled, the headphone output is routed
from an individual stream (the third PCM such as hw:0,2) instead of
the primary stream. In the case the headphone DAC is shared with a
side or a CLFE-channel DAC, the DAC is switched to the headphone
automatically.
* Loopback Mixing
An enum control to determine whether the analog-loopback route is
enabled or not. When it's enabled, the analog-loopback is mixed to
the front-channel. Also, the same route is used for the headphone
and speaker outputs. As a side-effect, when this mode is set, the
individual volume controls will be no longer available for
headphones and speakers because there is only one DAC connected to a
mixer widget.
* Dynamic Power-Control
This control determines whether the dynamic power-control per jack
detection is enabled or not. When enabled, the widgets power state
(D0/D3) are changed dynamically depending on the jack plugging
state for saving power consumptions. However, if your system
doesn't provide a proper jack-detection, this won't work; in such a
case, turn this control OFF.
* Jack Detect
This control is provided only for VT1708 codec which gives no proper
unsolicited event per jack plug. When this is on, the driver polls
the jack detection so that the headphone auto-mute can work, while
turning this off would reduce the power consumption.
Conexant codecs
---------------
* Auto-Mute Mode
See Reatek codecs.
...@@ -14,6 +14,19 @@ menuconfig SND_HDA_INTEL ...@@ -14,6 +14,19 @@ menuconfig SND_HDA_INTEL
if SND_HDA_INTEL if SND_HDA_INTEL
config SND_HDA_PREALLOC_SIZE
int "Pre-allocated buffer size for HD-audio driver"
range 0 32768
default 64
help
Specifies the default pre-allocated buffer-size in kB for the
HD-audio driver. A larger buffer (e.g. 2048) is preferred
for systems using PulseAudio. The default 64 is chosen just
for compatibility reasons.
Note that the pre-allocation size can be changed dynamically
via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too.
config SND_HDA_HWDEP config SND_HDA_HWDEP
bool "Build hwdep interface for HD-audio driver" bool "Build hwdep interface for HD-audio driver"
select SND_HWDEP select SND_HWDEP
...@@ -83,6 +96,19 @@ config SND_HDA_CODEC_REALTEK ...@@ -83,6 +96,19 @@ config SND_HDA_CODEC_REALTEK
snd-hda-codec-realtek. snd-hda-codec-realtek.
This module is automatically loaded at probing. This module is automatically loaded at probing.
config SND_HDA_ENABLE_REALTEK_QUIRKS
bool "Build static quirks for Realtek codecs"
depends on SND_HDA_CODEC_REALTEK
default y
help
Say Y here to build the static quirks codes for Realtek codecs.
If you need the "model" preset that the default BIOS auto-parser
can't handle, turn this option on.
If your device works with model=auto option, basically you don't
need the quirk code. By turning this off, you can reduce the
module size quite a lot.
config SND_HDA_CODEC_ANALOG config SND_HDA_CODEC_ANALOG
bool "Build Analog Device HD-audio codec support" bool "Build Analog Device HD-audio codec support"
default y default y
...@@ -171,6 +197,19 @@ config SND_HDA_CODEC_CA0110 ...@@ -171,6 +197,19 @@ config SND_HDA_CODEC_CA0110
snd-hda-codec-ca0110. snd-hda-codec-ca0110.
This module is automatically loaded at probing. This module is automatically loaded at probing.
config SND_HDA_CODEC_CA0132
bool "Build Creative CA0132 codec support"
depends on SND_HDA_INTEL
default y
help
Say Y here to include Creative CA0132 codec support in
snd-hda-intel driver.
When the HD-audio driver is built as a module, the codec
support code is also built as another module,
snd-hda-codec-ca0132.
This module is automatically loaded at probing.
config SND_HDA_CODEC_CMEDIA config SND_HDA_CODEC_CMEDIA
bool "Build C-Media HD-audio codec support" bool "Build C-Media HD-audio codec support"
default y default y
......
...@@ -13,6 +13,7 @@ snd-hda-codec-idt-objs := patch_sigmatel.o ...@@ -13,6 +13,7 @@ snd-hda-codec-idt-objs := patch_sigmatel.o
snd-hda-codec-si3054-objs := patch_si3054.o snd-hda-codec-si3054-objs := patch_si3054.o
snd-hda-codec-cirrus-objs := patch_cirrus.o snd-hda-codec-cirrus-objs := patch_cirrus.o
snd-hda-codec-ca0110-objs := patch_ca0110.o snd-hda-codec-ca0110-objs := patch_ca0110.o
snd-hda-codec-ca0132-objs := patch_ca0132.o
snd-hda-codec-conexant-objs := patch_conexant.o snd-hda-codec-conexant-objs := patch_conexant.o
snd-hda-codec-via-objs := patch_via.o snd-hda-codec-via-objs := patch_via.o
snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o
...@@ -42,6 +43,9 @@ endif ...@@ -42,6 +43,9 @@ endif
ifdef CONFIG_SND_HDA_CODEC_CA0110 ifdef CONFIG_SND_HDA_CODEC_CA0110
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o
endif endif
ifdef CONFIG_SND_HDA_CODEC_CA0132
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0132.o
endif
ifdef CONFIG_SND_HDA_CODEC_CONEXANT ifdef CONFIG_SND_HDA_CODEC_CONEXANT
obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o
endif endif
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* ALC680 quirk models
* included by patch_realtek.c
*/
/* ALC680 models */
enum {
ALC680_AUTO,
ALC680_BASE,
ALC680_MODEL_LAST,
};
#define ALC680_DIGIN_NID ALC880_DIGIN_NID
#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
#define alc680_modes alc260_modes
static const hda_nid_t alc680_dac_nids[3] = {
/* Lout1, Lout2, hp */
0x02, 0x03, 0x04
};
static const hda_nid_t alc680_adc_nids[3] = {
/* ADC0-2 */
/* DMIC, MIC, Line-in*/
0x07, 0x08, 0x09
};
/*
* Analog capture ADC cgange
*/
static hda_nid_t alc680_get_cur_adc(struct hda_codec *codec)
{
static hda_nid_t pins[] = {0x18, 0x19};
static hda_nid_t adcs[] = {0x08, 0x09};
int i;
for (i = 0; i < ARRAY_SIZE(pins); i++) {
if (!is_jack_detectable(codec, pins[i]))
continue;
if (snd_hda_jack_detect(codec, pins[i]))
return adcs[i];
}
return 0x07;
}
static void alc680_rec_autoswitch(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
hda_nid_t nid = alc680_get_cur_adc(codec);
if (spec->cur_adc && nid != spec->cur_adc) {
__snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
spec->cur_adc = nid;
snd_hda_codec_setup_stream(codec, nid,
spec->cur_adc_stream_tag, 0,
spec->cur_adc_format);
}
}
static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
unsigned int format,
struct snd_pcm_substream *substream)
{
struct alc_spec *spec = codec->spec;
hda_nid_t nid = alc680_get_cur_adc(codec);
spec->cur_adc = nid;
spec->cur_adc_stream_tag = stream_tag;
spec->cur_adc_format = format;
snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
return 0;
}
static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
struct alc_spec *spec = codec->spec;
snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
spec->cur_adc = 0;
return 0;
}
static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
.substreams = 1, /* can be overridden */
.channels_min = 2,
.channels_max = 2,
/* NID is set in alc_build_pcms */
.ops = {
.prepare = alc680_capture_pcm_prepare,
.cleanup = alc680_capture_pcm_cleanup
},
};
static const struct snd_kcontrol_new alc680_base_mixer[] = {
/* output mixer control */
HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
{ }
};
static const struct hda_bind_ctls alc680_bind_cap_vol = {
.ops = &snd_hda_bind_vol,
.values = {
HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
0
},
};
static const struct hda_bind_ctls alc680_bind_cap_switch = {
.ops = &snd_hda_bind_sw,
.values = {
HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
0
},
};
static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
{ } /* end */
};
/*
* generic initialization of ADC, input mixers and output mixers
*/
static const struct hda_verb alc680_init_verbs[] = {
{0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
{0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
{0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
{0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
{0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
{0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
{0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
{0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
{0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
{ }
};
/* toggle speaker-output according to the hp-jack state */
static void alc680_base_setup(struct hda_codec *codec)
{
struct alc_spec *spec = codec->spec;
spec->autocfg.hp_pins[0] = 0x16;
spec->autocfg.speaker_pins[0] = 0x14;
spec->autocfg.speaker_pins[1] = 0x15;
spec->autocfg.num_inputs = 2;
spec->autocfg.inputs[0].pin = 0x18;
spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
spec->autocfg.inputs[1].pin = 0x19;
spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
spec->automute = 1;
spec->automute_mode = ALC_AUTOMUTE_AMP;
}
static void alc680_unsol_event(struct hda_codec *codec,
unsigned int res)
{
if ((res >> 26) == ALC_HP_EVENT)
alc_hp_automute(codec);
if ((res >> 26) == ALC_MIC_EVENT)
alc680_rec_autoswitch(codec);
}
static void alc680_inithook(struct hda_codec *codec)
{
alc_hp_automute(codec);
alc680_rec_autoswitch(codec);
}
/*
* configuration and preset
*/
static const char * const alc680_models[ALC680_MODEL_LAST] = {
[ALC680_BASE] = "base",
[ALC680_AUTO] = "auto",
};
static const struct snd_pci_quirk alc680_cfg_tbl[] = {
SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
{}
};
static const struct alc_config_preset alc680_presets[] = {
[ALC680_BASE] = {
.mixers = { alc680_base_mixer },
.cap_mixer = alc680_master_capture_mixer,
.init_verbs = { alc680_init_verbs },
.num_dacs = ARRAY_SIZE(alc680_dac_nids),
.dac_nids = alc680_dac_nids,
.dig_out_nid = ALC680_DIGOUT_NID,
.num_channel_mode = ARRAY_SIZE(alc680_modes),
.channel_mode = alc680_modes,
.unsol_event = alc680_unsol_event,
.setup = alc680_base_setup,
.init_hook = alc680_inithook,
},
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -212,7 +212,9 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, ...@@ -212,7 +212,9 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
/* /*
* SPDIF I/O * SPDIF I/O
*/ */
int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); int snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
hda_nid_t associated_nid,
hda_nid_t cvt_nid);
int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
/* /*
...@@ -563,7 +565,6 @@ int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key) ...@@ -563,7 +565,6 @@ int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
* power-management * power-management
*/ */
#ifdef CONFIG_SND_HDA_POWER_SAVE
void snd_hda_schedule_power_save(struct hda_codec *codec); void snd_hda_schedule_power_save(struct hda_codec *codec);
struct hda_amp_list { struct hda_amp_list {
...@@ -580,7 +581,6 @@ struct hda_loopback_check { ...@@ -580,7 +581,6 @@ struct hda_loopback_check {
int snd_hda_check_amp_list_power(struct hda_codec *codec, int snd_hda_check_amp_list_power(struct hda_codec *codec,
struct hda_loopback_check *check, struct hda_loopback_check *check,
hda_nid_t nid); hda_nid_t nid);
#endif /* CONFIG_SND_HDA_POWER_SAVE */
/* /*
* AMP control callbacks * AMP control callbacks
...@@ -639,8 +639,8 @@ struct hdmi_eld { ...@@ -639,8 +639,8 @@ struct hdmi_eld {
int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t); int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t);
void snd_hdmi_show_eld(struct hdmi_eld *eld); void snd_hdmi_show_eld(struct hdmi_eld *eld);
void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld,
struct hda_pcm_stream *codec_pars); struct hda_pcm_stream *hinfo);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld, int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
......
...@@ -636,7 +636,7 @@ static void print_codec_info(struct snd_info_entry *entry, ...@@ -636,7 +636,7 @@ static void print_codec_info(struct snd_info_entry *entry,
wid_caps |= AC_WCAP_CONN_LIST; wid_caps |= AC_WCAP_CONN_LIST;
if (wid_caps & AC_WCAP_CONN_LIST) if (wid_caps & AC_WCAP_CONN_LIST)
conn_len = snd_hda_get_connections(codec, nid, conn, conn_len = snd_hda_get_raw_connections(codec, nid, conn,
HDA_MAX_CONNECTIONS); HDA_MAX_CONNECTIONS);
if (wid_caps & AC_WCAP_IN_AMP) { if (wid_caps & AC_WCAP_IN_AMP) {
......
This diff is collapsed.
...@@ -240,7 +240,8 @@ static int ca0110_build_controls(struct hda_codec *codec) ...@@ -240,7 +240,8 @@ static int ca0110_build_controls(struct hda_codec *codec)
} }
if (spec->dig_out) { if (spec->dig_out) {
err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out); err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out,
spec->dig_out);
if (err < 0) if (err < 0)
return err; return err;
err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment