|
@@ -32,6 +32,7 @@
|
|
|
#include <sound/jack.h>
|
|
|
#include "hda_codec.h"
|
|
|
#include "hda_local.h"
|
|
|
+#include "hda_auto_parser.h"
|
|
|
#include "hda_beep.h"
|
|
|
#include "hda_jack.h"
|
|
|
|
|
@@ -66,8 +67,6 @@ struct alc_customize_define {
|
|
|
unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
|
|
|
};
|
|
|
|
|
|
-struct alc_fixup;
|
|
|
-
|
|
|
struct alc_multi_io {
|
|
|
hda_nid_t pin; /* multi-io widget pin NID */
|
|
|
hda_nid_t dac; /* DAC to be connected */
|
|
@@ -82,19 +81,33 @@ enum {
|
|
|
|
|
|
#define MAX_VOL_NIDS 0x40
|
|
|
|
|
|
+/* make compatible with old code */
|
|
|
+#define alc_apply_pincfgs snd_hda_apply_pincfgs
|
|
|
+#define alc_apply_fixup snd_hda_apply_fixup
|
|
|
+#define alc_pick_fixup snd_hda_pick_fixup
|
|
|
+#define alc_fixup hda_fixup
|
|
|
+#define alc_pincfg hda_pintbl
|
|
|
+#define alc_model_fixup hda_model_fixup
|
|
|
+
|
|
|
+#define ALC_FIXUP_PINS HDA_FIXUP_PINS
|
|
|
+#define ALC_FIXUP_VERBS HDA_FIXUP_VERBS
|
|
|
+#define ALC_FIXUP_FUNC HDA_FIXUP_FUNC
|
|
|
+
|
|
|
+#define ALC_FIXUP_ACT_PRE_PROBE HDA_FIXUP_ACT_PRE_PROBE
|
|
|
+#define ALC_FIXUP_ACT_PROBE HDA_FIXUP_ACT_PROBE
|
|
|
+#define ALC_FIXUP_ACT_INIT HDA_FIXUP_ACT_INIT
|
|
|
+#define ALC_FIXUP_ACT_BUILD HDA_FIXUP_ACT_BUILD
|
|
|
+
|
|
|
+
|
|
|
struct alc_spec {
|
|
|
+ struct hda_gen_spec gen;
|
|
|
+
|
|
|
/* codec parameterization */
|
|
|
const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
|
|
|
unsigned int num_mixers;
|
|
|
const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
|
|
|
unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
|
|
|
|
|
|
- const struct hda_verb *init_verbs[10]; /* initialization verbs
|
|
|
- * don't forget NULL
|
|
|
- * termination!
|
|
|
- */
|
|
|
- unsigned int num_init_verbs;
|
|
|
-
|
|
|
char stream_name_analog[32]; /* analog PCM stream */
|
|
|
const struct hda_pcm_stream *stream_analog_playback;
|
|
|
const struct hda_pcm_stream *stream_analog_capture;
|
|
@@ -210,11 +223,6 @@ struct alc_spec {
|
|
|
unsigned int pll_coef_idx, pll_coef_bit;
|
|
|
unsigned int coef0;
|
|
|
|
|
|
- /* fix-up list */
|
|
|
- int fixup_id;
|
|
|
- const struct alc_fixup *fixup_list;
|
|
|
- const char *fixup_name;
|
|
|
-
|
|
|
/* multi-io */
|
|
|
int multi_ios;
|
|
|
struct alc_multi_io multi_io[4];
|
|
@@ -396,13 +404,6 @@ static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
|
|
|
spec->mixers[spec->num_mixers++] = mix;
|
|
|
}
|
|
|
|
|
|
-static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
|
|
|
-{
|
|
|
- if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
|
|
|
- return;
|
|
|
- spec->init_verbs[spec->num_init_verbs++] = verb;
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* GPIO setup tables, used in initialization
|
|
|
*/
|
|
@@ -1185,6 +1186,16 @@ static void alc_auto_check_switches(struct hda_codec *codec)
|
|
|
*/
|
|
|
#define ALC_FIXUP_SKU_IGNORE (2)
|
|
|
|
|
|
+static void alc_fixup_sku_ignore(struct hda_codec *codec,
|
|
|
+ const struct hda_fixup *fix, int action)
|
|
|
+{
|
|
|
+ struct alc_spec *spec = codec->spec;
|
|
|
+ if (action == HDA_FIXUP_ACT_PRE_PROBE) {
|
|
|
+ spec->cdefine.fixup = 1;
|
|
|
+ spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static int alc_auto_parse_customize_define(struct hda_codec *codec)
|
|
|
{
|
|
|
unsigned int ass, tmp, i;
|
|
@@ -1387,178 +1398,6 @@ static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Fix-up pin default configurations and add default verbs
|
|
|
- */
|
|
|
-
|
|
|
-struct alc_pincfg {
|
|
|
- hda_nid_t nid;
|
|
|
- u32 val;
|
|
|
-};
|
|
|
-
|
|
|
-struct alc_model_fixup {
|
|
|
- const int id;
|
|
|
- const char *name;
|
|
|
-};
|
|
|
-
|
|
|
-struct alc_fixup {
|
|
|
- int type;
|
|
|
- bool chained;
|
|
|
- int chain_id;
|
|
|
- union {
|
|
|
- unsigned int sku;
|
|
|
- const struct alc_pincfg *pins;
|
|
|
- const struct hda_verb *verbs;
|
|
|
- void (*func)(struct hda_codec *codec,
|
|
|
- const struct alc_fixup *fix,
|
|
|
- int action);
|
|
|
- } v;
|
|
|
-};
|
|
|
-
|
|
|
-enum {
|
|
|
- ALC_FIXUP_INVALID,
|
|
|
- ALC_FIXUP_SKU,
|
|
|
- ALC_FIXUP_PINS,
|
|
|
- ALC_FIXUP_VERBS,
|
|
|
- ALC_FIXUP_FUNC,
|
|
|
-};
|
|
|
-
|
|
|
-enum {
|
|
|
- ALC_FIXUP_ACT_PRE_PROBE,
|
|
|
- ALC_FIXUP_ACT_PROBE,
|
|
|
- ALC_FIXUP_ACT_INIT,
|
|
|
- ALC_FIXUP_ACT_BUILD,
|
|
|
-};
|
|
|
-
|
|
|
-static void alc_apply_pincfgs(struct hda_codec *codec,
|
|
|
- const struct alc_pincfg *cfg)
|
|
|
-{
|
|
|
- for (; cfg->nid; cfg++)
|
|
|
- snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
|
|
|
-}
|
|
|
-
|
|
|
-static void alc_apply_fixup(struct hda_codec *codec, int action)
|
|
|
-{
|
|
|
- struct alc_spec *spec = codec->spec;
|
|
|
- int id = spec->fixup_id;
|
|
|
-#ifdef CONFIG_SND_DEBUG_VERBOSE
|
|
|
- const char *modelname = spec->fixup_name;
|
|
|
-#endif
|
|
|
- int depth = 0;
|
|
|
-
|
|
|
- if (!spec->fixup_list)
|
|
|
- return;
|
|
|
-
|
|
|
- while (id >= 0) {
|
|
|
- const struct alc_fixup *fix = spec->fixup_list + id;
|
|
|
- const struct alc_pincfg *cfg;
|
|
|
-
|
|
|
- switch (fix->type) {
|
|
|
- case ALC_FIXUP_SKU:
|
|
|
- if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
|
|
|
- break;
|
|
|
- snd_printdd(KERN_INFO "hda_codec: %s: "
|
|
|
- "Apply sku override for %s\n",
|
|
|
- codec->chip_name, modelname);
|
|
|
- spec->cdefine.sku_cfg = fix->v.sku;
|
|
|
- spec->cdefine.fixup = 1;
|
|
|
- break;
|
|
|
- case ALC_FIXUP_PINS:
|
|
|
- cfg = fix->v.pins;
|
|
|
- if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
|
|
|
- break;
|
|
|
- snd_printdd(KERN_INFO "hda_codec: %s: "
|
|
|
- "Apply pincfg for %s\n",
|
|
|
- codec->chip_name, modelname);
|
|
|
- alc_apply_pincfgs(codec, cfg);
|
|
|
- break;
|
|
|
- case ALC_FIXUP_VERBS:
|
|
|
- if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
|
|
|
- break;
|
|
|
- snd_printdd(KERN_INFO "hda_codec: %s: "
|
|
|
- "Apply fix-verbs for %s\n",
|
|
|
- codec->chip_name, modelname);
|
|
|
- add_verb(codec->spec, fix->v.verbs);
|
|
|
- break;
|
|
|
- case ALC_FIXUP_FUNC:
|
|
|
- if (!fix->v.func)
|
|
|
- break;
|
|
|
- snd_printdd(KERN_INFO "hda_codec: %s: "
|
|
|
- "Apply fix-func for %s\n",
|
|
|
- codec->chip_name, modelname);
|
|
|
- fix->v.func(codec, fix, action);
|
|
|
- break;
|
|
|
- default:
|
|
|
- snd_printk(KERN_ERR "hda_codec: %s: "
|
|
|
- "Invalid fixup type %d\n",
|
|
|
- codec->chip_name, fix->type);
|
|
|
- break;
|
|
|
- }
|
|
|
- if (!fix->chained)
|
|
|
- break;
|
|
|
- if (++depth > 10)
|
|
|
- break;
|
|
|
- id = fix->chain_id;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static void alc_pick_fixup(struct hda_codec *codec,
|
|
|
- const struct alc_model_fixup *models,
|
|
|
- const struct snd_pci_quirk *quirk,
|
|
|
- const struct alc_fixup *fixlist)
|
|
|
-{
|
|
|
- struct alc_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;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (codec->modelname && models) {
|
|
|
- while (models->name) {
|
|
|
- if (!strcmp(codec->modelname, models->name)) {
|
|
|
- id = models->id;
|
|
|
- name = models->name;
|
|
|
- break;
|
|
|
- }
|
|
|
- models++;
|
|
|
- }
|
|
|
- }
|
|
|
- if (id < 0) {
|
|
|
- q = snd_pci_quirk_lookup(codec->bus->pci, quirk);
|
|
|
- if (q) {
|
|
|
- id = q->value;
|
|
|
-#ifdef CONFIG_SND_DEBUG_VERBOSE
|
|
|
- name = q->name;
|
|
|
-#endif
|
|
|
- }
|
|
|
- }
|
|
|
- if (id < 0) {
|
|
|
- for (q = quirk; q->subvendor; q++) {
|
|
|
- unsigned int vendorid =
|
|
|
- q->subdevice | (q->subvendor << 16);
|
|
|
- if (vendorid == codec->subsystem_id) {
|
|
|
- id = q->value;
|
|
|
-#ifdef CONFIG_SND_DEBUG_VERBOSE
|
|
|
- name = q->name;
|
|
|
-#endif
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- spec->fixup_id = id;
|
|
|
- if (id >= 0) {
|
|
|
- spec->fixup_list = fixlist;
|
|
|
- spec->fixup_name = name;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/*
|
|
|
* COEF access helper functions
|
|
|
*/
|
|
@@ -2050,7 +1889,6 @@ static void alc_auto_init_std(struct hda_codec *codec);
|
|
|
static int alc_init(struct hda_codec *codec)
|
|
|
{
|
|
|
struct alc_spec *spec = codec->spec;
|
|
|
- unsigned int i;
|
|
|
|
|
|
if (spec->init_hook)
|
|
|
spec->init_hook(codec);
|
|
@@ -2058,8 +1896,6 @@ static int alc_init(struct hda_codec *codec)
|
|
|
alc_fix_pll(codec);
|
|
|
alc_auto_init_amp(codec, spec->init_amp);
|
|
|
|
|
|
- for (i = 0; i < spec->num_init_verbs; i++)
|
|
|
- snd_hda_sequence_write(codec, spec->init_verbs[i]);
|
|
|
alc_init_special_input_src(codec);
|
|
|
alc_auto_init_std(codec);
|
|
|
|
|
@@ -4885,7 +4721,7 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
|
|
|
spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
|
|
|
snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
|
|
|
spec->unsol_event = alc_sku_unsol_event;
|
|
|
- add_verb(codec->spec, alc_gpio1_init_verbs);
|
|
|
+ snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -5216,8 +5052,8 @@ static const struct alc_fixup alc882_fixups[] = {
|
|
|
}
|
|
|
},
|
|
|
[ALC882_FIXUP_ACER_ASPIRE_7736] = {
|
|
|
- .type = ALC_FIXUP_SKU,
|
|
|
- .v.sku = ALC_FIXUP_SKU_IGNORE,
|
|
|
+ .type = ALC_FIXUP_FUNC,
|
|
|
+ .v.func = alc_fixup_sku_ignore,
|
|
|
},
|
|
|
[ALC882_FIXUP_ASUS_W90V] = {
|
|
|
.type = ALC_FIXUP_PINS,
|
|
@@ -5693,7 +5529,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
|
|
|
if (err > 0) {
|
|
|
if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) {
|
|
|
add_mixer(spec, alc268_beep_mixer);
|
|
|
- add_verb(spec, alc268_beep_init_verbs);
|
|
|
+ snd_hda_gen_add_verbs(&spec->gen, alc268_beep_init_verbs);
|
|
|
}
|
|
|
}
|
|
|
return err;
|
|
@@ -5995,8 +5831,8 @@ static const struct alc_fixup alc269_fixups[] = {
|
|
|
}
|
|
|
},
|
|
|
[ALC269_FIXUP_SKU_IGNORE] = {
|
|
|
- .type = ALC_FIXUP_SKU,
|
|
|
- .v.sku = ALC_FIXUP_SKU_IGNORE,
|
|
|
+ .type = ALC_FIXUP_FUNC,
|
|
|
+ .v.func = alc_fixup_sku_ignore,
|
|
|
},
|
|
|
[ALC269_FIXUP_ASUS_G73JW] = {
|
|
|
.type = ALC_FIXUP_PINS,
|
|
@@ -6491,7 +6327,7 @@ static int patch_alc861vd(struct hda_codec *codec)
|
|
|
|
|
|
if (codec->vendor_id == 0x10ec0660) {
|
|
|
/* always turn on EAPD */
|
|
|
- add_verb(spec, alc660vd_eapd_verbs);
|
|
|
+ snd_hda_gen_add_verbs(&spec->gen, alc660vd_eapd_verbs);
|
|
|
}
|
|
|
|
|
|
if (!spec->no_analog) {
|
|
@@ -6604,8 +6440,8 @@ static const struct alc_fixup alc662_fixups[] = {
|
|
|
}
|
|
|
},
|
|
|
[ALC662_FIXUP_SKU_IGNORE] = {
|
|
|
- .type = ALC_FIXUP_SKU,
|
|
|
- .v.sku = ALC_FIXUP_SKU_IGNORE,
|
|
|
+ .type = ALC_FIXUP_FUNC,
|
|
|
+ .v.func = alc_fixup_sku_ignore,
|
|
|
},
|
|
|
[ALC662_FIXUP_HP_RP5800] = {
|
|
|
.type = ALC_FIXUP_PINS,
|