Skip to content

Commit

Permalink
Merge branch 'topic/hda-gen-parser' into for-next
Browse files Browse the repository at this point in the history
This is a merge of really big changes: the generic parser is heavily
enhanced for handling all cases, based on the former Realtek codec
driver code.  And all codec drivers except for a few ones (CA0132,
HDMI and modem) have been converted to use the new generic driver.

Conflicts:
	sound/pci/hda/patch_realtek.c
  • Loading branch information
Takashi Iwai committed Jan 23, 2013
2 parents e152f18 + 657e1b9 commit 2cf215b
Show file tree
Hide file tree
Showing 20 changed files with 10,745 additions and 16,670 deletions.
11 changes: 8 additions & 3 deletions sound/pci/hda/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ config SND_HDA_PATCH_LOADER
config SND_HDA_CODEC_REALTEK
bool "Build Realtek HD-audio codec support"
default y
select SND_HDA_GENERIC
help
Say Y here to include Realtek HD-audio codec support in
snd-hda-intel driver, such as ALC880.
Expand All @@ -98,6 +99,7 @@ config SND_HDA_CODEC_REALTEK
config SND_HDA_CODEC_ANALOG
bool "Build Analog Device HD-audio codec support"
default y
select SND_HDA_GENERIC
help
Say Y here to include Analog Device HD-audio codec support in
snd-hda-intel driver, such as AD1986A.
Expand All @@ -110,6 +112,7 @@ config SND_HDA_CODEC_ANALOG
config SND_HDA_CODEC_SIGMATEL
bool "Build IDT/Sigmatel HD-audio codec support"
default y
select SND_HDA_GENERIC
help
Say Y here to include IDT (Sigmatel) HD-audio codec support in
snd-hda-intel driver, such as STAC9200.
Expand All @@ -122,6 +125,7 @@ config SND_HDA_CODEC_SIGMATEL
config SND_HDA_CODEC_VIA
bool "Build VIA HD-audio codec support"
default y
select SND_HDA_GENERIC
help
Say Y here to include VIA HD-audio codec support in
snd-hda-intel driver, such as VT1708.
Expand All @@ -147,8 +151,8 @@ config SND_HDA_CODEC_HDMI

config SND_HDA_CODEC_CIRRUS
bool "Build Cirrus Logic codec support"
depends on SND_HDA_INTEL
default y
select SND_HDA_GENERIC
help
Say Y here to include Cirrus Logic codec support in
snd-hda-intel driver, such as CS4206.
Expand All @@ -161,6 +165,7 @@ config SND_HDA_CODEC_CIRRUS
config SND_HDA_CODEC_CONEXANT
bool "Build Conexant HD-audio codec support"
default y
select SND_HDA_GENERIC
help
Say Y here to include Conexant HD-audio codec support in
snd-hda-intel driver, such as CX20549.
Expand All @@ -172,8 +177,8 @@ config SND_HDA_CODEC_CONEXANT

config SND_HDA_CODEC_CA0110
bool "Build Creative CA0110-IBG codec support"
depends on SND_HDA_INTEL
default y
select SND_HDA_GENERIC
help
Say Y here to include Creative CA0110-IBG codec support in
snd-hda-intel driver, found on some Creative X-Fi cards.
Expand All @@ -185,7 +190,6 @@ config SND_HDA_CODEC_CA0110

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
Expand All @@ -199,6 +203,7 @@ config SND_HDA_CODEC_CA0132
config SND_HDA_CODEC_CMEDIA
bool "Build C-Media HD-audio codec support"
default y
select SND_HDA_GENERIC
help
Say Y here to include C-Media HD-audio codec support in
snd-hda-intel driver, such as CMI9880.
Expand Down
115 changes: 82 additions & 33 deletions sound/pci/hda/hda_auto_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,28 @@ static void reorder_outputs(unsigned int nums, hda_nid_t *pins)
}
}

/* check whether the given pin has a proper pin I/O capability bit */
static bool check_pincap_validity(struct hda_codec *codec, hda_nid_t pin,
unsigned int dev)
{
unsigned int pincap = snd_hda_query_pin_caps(codec, pin);

/* some old hardware don't return the proper pincaps */
if (!pincap)
return true;

switch (dev) {
case AC_JACK_LINE_OUT:
case AC_JACK_SPEAKER:
case AC_JACK_HP_OUT:
case AC_JACK_SPDIF_OUT:
case AC_JACK_DIG_OTHER_OUT:
return !!(pincap & AC_PINCAP_OUT);
default:
return !!(pincap & AC_PINCAP_IN);
}
}

/*
* Parse all pin widgets and store the useful pin nids to cfg
*
Expand Down Expand Up @@ -126,6 +148,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,
struct auto_out_pin hp_out[ARRAY_SIZE(cfg->hp_pins)];
int i;

if (!snd_hda_get_int_hint(codec, "parser_flags", &i))
cond_flags = i;

memset(cfg, 0, sizeof(*cfg));

memset(line_out, 0, sizeof(line_out));
Expand Down Expand Up @@ -156,10 +181,14 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec,

/* workaround for buggy BIOS setups */
if (dev == AC_JACK_LINE_OUT) {
if (conn == AC_JACK_PORT_FIXED)
if (conn == AC_JACK_PORT_FIXED ||
conn == AC_JACK_PORT_BOTH)
dev = AC_JACK_SPEAKER;
}

if (!check_pincap_validity(codec, nid, dev))
continue;

switch (dev) {
case AC_JACK_LINE_OUT:
seq = get_defcfg_sequence(def_conf);
Expand Down Expand Up @@ -363,7 +392,7 @@ static const char *hda_get_input_pin_label(struct hda_codec *codec,
{
unsigned int def_conf;
static const char * const mic_names[] = {
"Internal Mic", "Dock Mic", "Mic", "Front Mic", "Rear Mic",
"Internal Mic", "Dock Mic", "Mic", "Rear Mic", "Front Mic"
};
int attr;

Expand Down Expand Up @@ -394,6 +423,8 @@ static const char *hda_get_input_pin_label(struct hda_codec *codec,
return "SPDIF In";
case AC_JACK_DIG_OTHER_IN:
return "Digital In";
case AC_JACK_HP_OUT:
return "Headphone Mic";
default:
return "Misc";
}
Expand Down Expand Up @@ -552,6 +583,9 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid,
return 1;
}

#define is_hdmi_cfg(conf) \
(get_defcfg_location(conf) == AC_JACK_LOC_HDMI)

/**
* snd_hda_get_pin_label - Get a label for the given I/O pin
*
Expand All @@ -572,6 +606,7 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid);
const char *name = NULL;
int i;
bool hdmi;

if (indexp)
*indexp = 0;
Expand All @@ -590,16 +625,18 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
label, maxlen, indexp);
case AC_JACK_SPDIF_OUT:
case AC_JACK_DIG_OTHER_OUT:
if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI)
name = "HDMI";
else
name = "SPDIF";
if (cfg && indexp) {
i = find_idx_in_nid_list(nid, cfg->dig_out_pins,
cfg->dig_outs);
if (i >= 0)
*indexp = i;
}
hdmi = is_hdmi_cfg(def_conf);
name = hdmi ? "HDMI" : "SPDIF";
if (cfg && indexp)
for (i = 0; i < cfg->dig_outs; i++) {
hda_nid_t pin = cfg->dig_out_pins[i];
unsigned int c;
if (pin == nid)
break;
c = snd_hda_codec_get_pincfg(codec, pin);
if (hdmi == is_hdmi_cfg(c))
(*indexp)++;
}
break;
default:
if (cfg) {
Expand All @@ -622,28 +659,27 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
}
EXPORT_SYMBOL_HDA(snd_hda_get_pin_label);

int snd_hda_gen_add_verbs(struct hda_gen_spec *spec,
const struct hda_verb *list)
int snd_hda_add_verbs(struct hda_codec *codec,
const struct hda_verb *list)
{
const struct hda_verb **v;
v = snd_array_new(&spec->verbs);
v = snd_array_new(&codec->verbs);
if (!v)
return -ENOMEM;
*v = list;
return 0;
}
EXPORT_SYMBOL_HDA(snd_hda_gen_add_verbs);
EXPORT_SYMBOL_HDA(snd_hda_add_verbs);

void snd_hda_gen_apply_verbs(struct hda_codec *codec)
void snd_hda_apply_verbs(struct hda_codec *codec)
{
struct hda_gen_spec *spec = codec->spec;
int i;
for (i = 0; i < spec->verbs.used; i++) {
struct hda_verb **v = snd_array_elem(&spec->verbs, i);
for (i = 0; i < codec->verbs.used; i++) {
struct hda_verb **v = snd_array_elem(&codec->verbs, i);
snd_hda_sequence_write(codec, *v);
}
}
EXPORT_SYMBOL_HDA(snd_hda_gen_apply_verbs);
EXPORT_SYMBOL_HDA(snd_hda_apply_verbs);

void snd_hda_apply_pincfgs(struct hda_codec *codec,
const struct hda_pintbl *cfg)
Expand All @@ -653,20 +689,26 @@ void snd_hda_apply_pincfgs(struct hda_codec *codec,
}
EXPORT_SYMBOL_HDA(snd_hda_apply_pincfgs);

static void set_pin_targets(struct hda_codec *codec,
const struct hda_pintbl *cfg)
{
for (; cfg->nid; cfg++)
snd_hda_set_pin_ctl_cache(codec, cfg->nid, cfg->val);
}

void snd_hda_apply_fixup(struct hda_codec *codec, int action)
{
struct hda_gen_spec *spec = codec->spec;
int id = spec->fixup_id;
int id = codec->fixup_id;
#ifdef CONFIG_SND_DEBUG_VERBOSE
const char *modelname = spec->fixup_name;
const char *modelname = codec->fixup_name;
#endif
int depth = 0;

if (!spec->fixup_list)
if (!codec->fixup_list)
return;

while (id >= 0) {
const struct hda_fixup *fix = spec->fixup_list + id;
const struct hda_fixup *fix = codec->fixup_list + id;

switch (fix->type) {
case HDA_FIXUP_PINS:
Expand All @@ -683,7 +725,7 @@ void snd_hda_apply_fixup(struct hda_codec *codec, int action)
snd_printdd(KERN_INFO SFX
"%s: Apply fix-verbs for %s\n",
codec->chip_name, modelname);
snd_hda_gen_add_verbs(codec->spec, fix->v.verbs);
snd_hda_add_verbs(codec, fix->v.verbs);
break;
case HDA_FIXUP_FUNC:
if (!fix->v.func)
Expand All @@ -693,6 +735,14 @@ void snd_hda_apply_fixup(struct hda_codec *codec, int action)
codec->chip_name, modelname);
fix->v.func(codec, fix, action);
break;
case HDA_FIXUP_PINCTLS:
if (action != HDA_FIXUP_ACT_PROBE || !fix->v.pins)
break;
snd_printdd(KERN_INFO SFX
"%s: Apply pinctl for %s\n",
codec->chip_name, modelname);
set_pin_targets(codec, fix->v.pins);
break;
default:
snd_printk(KERN_ERR SFX
"%s: Invalid fixup type %d\n",
Expand All @@ -713,15 +763,14 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
const struct snd_pci_quirk *quirk,
const struct hda_fixup *fixlist)
{
struct hda_gen_spec *spec = codec->spec;
const struct snd_pci_quirk *q;
int id = -1;
const char *name = NULL;

/* when model=nofixup is given, don't pick up any fixups */
if (codec->modelname && !strcmp(codec->modelname, "nofixup")) {
spec->fixup_list = NULL;
spec->fixup_id = -1;
codec->fixup_list = NULL;
codec->fixup_id = -1;
return;
}

Expand Down Expand Up @@ -759,10 +808,10 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
}
}

spec->fixup_id = id;
codec->fixup_id = id;
if (id >= 0) {
spec->fixup_list = fixlist;
spec->fixup_name = name;
codec->fixup_list = fixlist;
codec->fixup_name = name;
}
}
EXPORT_SYMBOL_HDA(snd_hda_pick_fixup);
Loading

0 comments on commit 2cf215b

Please sign in to comment.