|
@@ -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];
|
|
@@ -319,13 +327,16 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
|
|
|
|
|
|
/* for shared I/O, change the pin-control accordingly */
|
|
|
if (spec->shared_mic_hp) {
|
|
|
+ unsigned int val;
|
|
|
+ hda_nid_t pin = spec->autocfg.inputs[1].pin;
|
|
|
/* NOTE: this assumes that there are only two inputs, the
|
|
|
* first is the real internal mic and the second is HP jack.
|
|
|
*/
|
|
|
- snd_hda_codec_write(codec, spec->autocfg.inputs[1].pin, 0,
|
|
|
- AC_VERB_SET_PIN_WIDGET_CONTROL,
|
|
|
- spec->cur_mux[adc_idx] ?
|
|
|
- PIN_VREF80 : PIN_HP);
|
|
|
+ if (spec->cur_mux[adc_idx])
|
|
|
+ val = snd_hda_get_default_vref(codec, pin) | PIN_IN;
|
|
|
+ else
|
|
|
+ val = PIN_HP;
|
|
|
+ snd_hda_set_pin_ctl(codec, pin, val);
|
|
|
spec->automute_speaker = !spec->cur_mux[adc_idx];
|
|
|
call_update_outputs(codec);
|
|
|
}
|
|
@@ -338,7 +349,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
|
|
|
nid = get_capsrc(spec, adc_idx);
|
|
|
|
|
|
/* no selection? */
|
|
|
- num_conns = snd_hda_get_conn_list(codec, nid, NULL);
|
|
|
+ num_conns = snd_hda_get_num_conns(codec, nid);
|
|
|
if (num_conns <= 1)
|
|
|
return 1;
|
|
|
|
|
@@ -376,25 +387,9 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
|
|
|
int auto_pin_type)
|
|
|
{
|
|
|
unsigned int val = PIN_IN;
|
|
|
-
|
|
|
- if (auto_pin_type == AUTO_PIN_MIC) {
|
|
|
- unsigned int pincap;
|
|
|
- unsigned int oldval;
|
|
|
- oldval = snd_hda_codec_read(codec, nid, 0,
|
|
|
- AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
|
|
- pincap = snd_hda_query_pin_caps(codec, nid);
|
|
|
- pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
|
|
|
- /* if the default pin setup is vref50, we give it priority */
|
|
|
- if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
|
|
|
- val = PIN_VREF80;
|
|
|
- else if (pincap & AC_PINCAP_VREF_50)
|
|
|
- val = PIN_VREF50;
|
|
|
- else if (pincap & AC_PINCAP_VREF_100)
|
|
|
- val = PIN_VREF100;
|
|
|
- else if (pincap & AC_PINCAP_VREF_GRD)
|
|
|
- val = PIN_VREFGRD;
|
|
|
- }
|
|
|
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
|
|
|
+ if (auto_pin_type == AUTO_PIN_MIC)
|
|
|
+ val |= snd_hda_get_default_vref(codec, nid);
|
|
|
+ snd_hda_set_pin_ctl(codec, nid, val);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -409,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
|
|
|
*/
|
|
@@ -517,9 +505,7 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
|
|
|
} else
|
|
|
val = 0;
|
|
|
val |= pin_bits;
|
|
|
- snd_hda_codec_write(codec, nid, 0,
|
|
|
- AC_VERB_SET_PIN_WIDGET_CONTROL,
|
|
|
- val);
|
|
|
+ snd_hda_set_pin_ctl(codec, nid, val);
|
|
|
break;
|
|
|
case ALC_AUTOMUTE_AMP:
|
|
|
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
|
|
@@ -1200,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;
|
|
@@ -1402,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
|
|
|
*/
|
|
@@ -1621,8 +1445,7 @@ static void alc_auto_init_digital(struct hda_codec *codec)
|
|
|
pin = spec->autocfg.dig_out_pins[i];
|
|
|
if (!pin)
|
|
|
continue;
|
|
|
- snd_hda_codec_write(codec, pin, 0,
|
|
|
- AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
|
|
|
+ snd_hda_set_pin_ctl(codec, pin, PIN_OUT);
|
|
|
if (!i)
|
|
|
dac = spec->multiout.dig_out_nid;
|
|
|
else
|
|
@@ -1635,9 +1458,7 @@ static void alc_auto_init_digital(struct hda_codec *codec)
|
|
|
}
|
|
|
pin = spec->autocfg.dig_in_pin;
|
|
|
if (pin)
|
|
|
- snd_hda_codec_write(codec, pin, 0,
|
|
|
- AC_VERB_SET_PIN_WIDGET_CONTROL,
|
|
|
- PIN_IN);
|
|
|
+ snd_hda_set_pin_ctl(codec, pin, PIN_IN);
|
|
|
}
|
|
|
|
|
|
/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
|
|
@@ -2068,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);
|
|
@@ -2076,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);
|
|
|
|
|
@@ -2725,7 +2543,6 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec)
|
|
|
nid = codec->start_nid;
|
|
|
for (i = 0; i < codec->num_nodes; i++, nid++) {
|
|
|
hda_nid_t src;
|
|
|
- const hda_nid_t *list;
|
|
|
unsigned int caps = get_wcaps(codec, nid);
|
|
|
int type = get_wcaps_type(caps);
|
|
|
|
|
@@ -2743,13 +2560,14 @@ static int alc_auto_fill_adc_caps(struct hda_codec *codec)
|
|
|
cap_nids[nums] = src;
|
|
|
break;
|
|
|
}
|
|
|
- n = snd_hda_get_conn_list(codec, src, &list);
|
|
|
+ n = snd_hda_get_num_conns(codec, src);
|
|
|
if (n > 1) {
|
|
|
cap_nids[nums] = src;
|
|
|
break;
|
|
|
} else if (n != 1)
|
|
|
break;
|
|
|
- src = *list;
|
|
|
+ if (snd_hda_get_connections(codec, src, &src, 1) != 1)
|
|
|
+ break;
|
|
|
}
|
|
|
if (++nums >= max_nums)
|
|
|
break;
|
|
@@ -2856,8 +2674,7 @@ static int alc_auto_create_shared_input(struct hda_codec *codec)
|
|
|
static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
|
|
|
unsigned int pin_type)
|
|
|
{
|
|
|
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
|
|
|
- pin_type);
|
|
|
+ snd_hda_set_pin_ctl(codec, nid, pin_type);
|
|
|
/* unmute pin */
|
|
|
if (nid_has_mute(codec, nid, HDA_OUTPUT))
|
|
|
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
|
|
@@ -2891,7 +2708,7 @@ static void alc_auto_init_analog_input(struct hda_codec *codec)
|
|
|
|
|
|
/* mute all loopback inputs */
|
|
|
if (spec->mixer_nid) {
|
|
|
- int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL);
|
|
|
+ int nums = snd_hda_get_num_conns(codec, spec->mixer_nid);
|
|
|
for (i = 0; i < nums; i++)
|
|
|
snd_hda_codec_write(codec, spec->mixer_nid, 0,
|
|
|
AC_VERB_SET_AMP_GAIN_MUTE,
|
|
@@ -3521,7 +3338,7 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec,
|
|
|
if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) {
|
|
|
type = ALC_CTL_WIDGET_MUTE;
|
|
|
val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
|
|
|
- } else if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
|
|
|
+ } else if (snd_hda_get_num_conns(codec, nid) == 1) {
|
|
|
type = ALC_CTL_WIDGET_MUTE;
|
|
|
val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
|
|
|
} else {
|
|
@@ -3998,9 +3815,7 @@ static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
|
|
|
snd_hda_codec_read(codec, nid, 0,
|
|
|
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
|
|
if (output) {
|
|
|
- snd_hda_codec_update_cache(codec, nid, 0,
|
|
|
- AC_VERB_SET_PIN_WIDGET_CONTROL,
|
|
|
- PIN_OUT);
|
|
|
+ snd_hda_set_pin_ctl_cache(codec, nid, PIN_OUT);
|
|
|
if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
|
|
|
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
|
|
|
HDA_AMP_MUTE, 0);
|
|
@@ -4009,9 +3824,8 @@ static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
|
|
|
if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
|
|
|
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
|
|
|
HDA_AMP_MUTE, HDA_AMP_MUTE);
|
|
|
- snd_hda_codec_update_cache(codec, nid, 0,
|
|
|
- AC_VERB_SET_PIN_WIDGET_CONTROL,
|
|
|
- spec->multi_io[idx].ctl_in);
|
|
|
+ snd_hda_set_pin_ctl_cache(codec, nid,
|
|
|
+ spec->multi_io[idx].ctl_in);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -4084,7 +3898,7 @@ static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
|
|
|
nums = 0;
|
|
|
for (n = 0; n < spec->num_adc_nids; n++) {
|
|
|
hda_nid_t cap = spec->private_capsrc_nids[n];
|
|
|
- int num_conns = snd_hda_get_conn_list(codec, cap, NULL);
|
|
|
+ int num_conns = snd_hda_get_num_conns(codec, cap);
|
|
|
for (i = 0; i < imux->num_items; i++) {
|
|
|
hda_nid_t pin = spec->imux_pins[i];
|
|
|
if (pin) {
|
|
@@ -4213,7 +4027,7 @@ static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
|
|
|
if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
|
|
|
snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
|
|
|
HDA_AMP_MUTE, 0);
|
|
|
- } else if (snd_hda_get_conn_list(codec, cap, NULL) > 1) {
|
|
|
+ } else if (snd_hda_get_num_conns(codec, cap) > 1) {
|
|
|
snd_hda_codec_write_cache(codec, cap, 0,
|
|
|
AC_VERB_SET_CONNECT_SEL, idx);
|
|
|
}
|
|
@@ -4427,6 +4241,25 @@ static int alc_parse_auto_config(struct hda_codec *codec,
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
+/* common preparation job for alc_spec */
|
|
|
+static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid)
|
|
|
+{
|
|
|
+ struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
|
|
+ int err;
|
|
|
+
|
|
|
+ if (!spec)
|
|
|
+ return -ENOMEM;
|
|
|
+ codec->spec = spec;
|
|
|
+ spec->mixer_nid = mixer_nid;
|
|
|
+
|
|
|
+ err = alc_codec_rename_from_preset(codec);
|
|
|
+ if (err < 0) {
|
|
|
+ kfree(spec);
|
|
|
+ return err;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int alc880_parse_auto_config(struct hda_codec *codec)
|
|
|
{
|
|
|
static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
|
|
@@ -4808,13 +4641,11 @@ static int patch_alc880(struct hda_codec *codec)
|
|
|
struct alc_spec *spec;
|
|
|
int err;
|
|
|
|
|
|
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
|
|
- if (spec == NULL)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- codec->spec = spec;
|
|
|
+ err = alc_alloc_spec(codec, 0x0b);
|
|
|
+ if (err < 0)
|
|
|
+ return err;
|
|
|
|
|
|
- spec->mixer_nid = 0x0b;
|
|
|
+ spec = codec->spec;
|
|
|
spec->need_dac_fix = 1;
|
|
|
|
|
|
alc_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl,
|
|
@@ -4890,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);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -5001,13 +4832,11 @@ static int patch_alc260(struct hda_codec *codec)
|
|
|
struct alc_spec *spec;
|
|
|
int err;
|
|
|
|
|
|
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
|
|
- if (spec == NULL)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- codec->spec = spec;
|
|
|
+ err = alc_alloc_spec(codec, 0x07);
|
|
|
+ if (err < 0)
|
|
|
+ return err;
|
|
|
|
|
|
- spec->mixer_nid = 0x07;
|
|
|
+ spec = codec->spec;
|
|
|
|
|
|
alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
|
|
|
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
|
|
@@ -5171,8 +5000,7 @@ static void alc889_fixup_mbp_vref(struct hda_codec *codec,
|
|
|
val = snd_hda_codec_read(codec, nids[i], 0,
|
|
|
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
|
|
val |= AC_PINCTL_VREF_80;
|
|
|
- snd_hda_codec_write(codec, nids[i], 0,
|
|
|
- AC_VERB_SET_PIN_WIDGET_CONTROL, val);
|
|
|
+ snd_hda_set_pin_ctl(codec, nids[i], val);
|
|
|
spec->keep_vref_in_automute = 1;
|
|
|
break;
|
|
|
}
|
|
@@ -5193,8 +5021,7 @@ static void alc889_fixup_imac91_vref(struct hda_codec *codec,
|
|
|
val = snd_hda_codec_read(codec, nids[i], 0,
|
|
|
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
|
|
|
val |= AC_PINCTL_VREF_50;
|
|
|
- snd_hda_codec_write(codec, nids[i], 0,
|
|
|
- AC_VERB_SET_PIN_WIDGET_CONTROL, val);
|
|
|
+ snd_hda_set_pin_ctl(codec, nids[i], val);
|
|
|
}
|
|
|
spec->keep_vref_in_automute = 1;
|
|
|
}
|
|
@@ -5225,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,
|
|
@@ -5476,13 +5303,11 @@ static int patch_alc882(struct hda_codec *codec)
|
|
|
struct alc_spec *spec;
|
|
|
int err;
|
|
|
|
|
|
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
|
|
- if (spec == NULL)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- codec->spec = spec;
|
|
|
+ err = alc_alloc_spec(codec, 0x0b);
|
|
|
+ if (err < 0)
|
|
|
+ return err;
|
|
|
|
|
|
- spec->mixer_nid = 0x0b;
|
|
|
+ spec = codec->spec;
|
|
|
|
|
|
switch (codec->vendor_id) {
|
|
|
case 0x10ec0882:
|
|
@@ -5494,10 +5319,6 @@ static int patch_alc882(struct hda_codec *codec)
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- err = alc_codec_rename_from_preset(codec);
|
|
|
- if (err < 0)
|
|
|
- goto error;
|
|
|
-
|
|
|
alc_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl,
|
|
|
alc882_fixups);
|
|
|
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
|
|
@@ -5621,13 +5442,11 @@ static int patch_alc262(struct hda_codec *codec)
|
|
|
struct alc_spec *spec;
|
|
|
int err;
|
|
|
|
|
|
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
|
|
- if (spec == NULL)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- codec->spec = spec;
|
|
|
+ err = alc_alloc_spec(codec, 0x0b);
|
|
|
+ if (err < 0)
|
|
|
+ return err;
|
|
|
|
|
|
- spec->mixer_nid = 0x0b;
|
|
|
+ spec = codec->spec;
|
|
|
|
|
|
#if 0
|
|
|
/* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
|
|
@@ -5710,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;
|
|
@@ -5723,13 +5542,12 @@ static int patch_alc268(struct hda_codec *codec)
|
|
|
struct alc_spec *spec;
|
|
|
int i, has_beep, err;
|
|
|
|
|
|
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
|
|
- if (spec == NULL)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- codec->spec = spec;
|
|
|
-
|
|
|
/* ALC268 has no aa-loopback mixer */
|
|
|
+ err = alc_alloc_spec(codec, 0);
|
|
|
+ if (err < 0)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ spec = codec->spec;
|
|
|
|
|
|
/* automatic parse from the BIOS config */
|
|
|
err = alc268_parse_auto_config(codec);
|
|
@@ -5946,9 +5764,7 @@ static void alc269_fixup_mic2_mute_hook(void *private_data, int enabled)
|
|
|
{
|
|
|
struct hda_codec *codec = private_data;
|
|
|
unsigned int pinval = enabled ? 0x20 : 0x24;
|
|
|
- snd_hda_codec_update_cache(codec, 0x19, 0,
|
|
|
- AC_VERB_SET_PIN_WIDGET_CONTROL,
|
|
|
- pinval);
|
|
|
+ snd_hda_set_pin_ctl_cache(codec, 0x19, pinval);
|
|
|
}
|
|
|
|
|
|
static void alc269_fixup_mic2_mute(struct hda_codec *codec,
|
|
@@ -6015,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,
|
|
@@ -6242,19 +6058,13 @@ static void alc269_fill_coef(struct hda_codec *codec)
|
|
|
static int patch_alc269(struct hda_codec *codec)
|
|
|
{
|
|
|
struct alc_spec *spec;
|
|
|
- int err = 0;
|
|
|
-
|
|
|
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
|
|
- if (spec == NULL)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- codec->spec = spec;
|
|
|
-
|
|
|
- spec->mixer_nid = 0x0b;
|
|
|
+ int err;
|
|
|
|
|
|
- err = alc_codec_rename_from_preset(codec);
|
|
|
+ err = alc_alloc_spec(codec, 0x0b);
|
|
|
if (err < 0)
|
|
|
- goto error;
|
|
|
+ return err;
|
|
|
+
|
|
|
+ spec = codec->spec;
|
|
|
|
|
|
if (codec->vendor_id == 0x10ec0269) {
|
|
|
spec->codec_variant = ALC269_TYPE_ALC269VA;
|
|
@@ -6346,8 +6156,7 @@ static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec,
|
|
|
if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)))
|
|
|
val |= AC_PINCTL_IN_EN;
|
|
|
val |= AC_PINCTL_VREF_50;
|
|
|
- snd_hda_codec_write(codec, 0x0f, 0,
|
|
|
- AC_VERB_SET_PIN_WIDGET_CONTROL, val);
|
|
|
+ snd_hda_set_pin_ctl(codec, 0x0f, val);
|
|
|
spec->keep_vref_in_automute = 1;
|
|
|
}
|
|
|
|
|
@@ -6401,13 +6210,11 @@ static int patch_alc861(struct hda_codec *codec)
|
|
|
struct alc_spec *spec;
|
|
|
int err;
|
|
|
|
|
|
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
|
|
- if (spec == NULL)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- codec->spec = spec;
|
|
|
+ err = alc_alloc_spec(codec, 0x15);
|
|
|
+ if (err < 0)
|
|
|
+ return err;
|
|
|
|
|
|
- spec->mixer_nid = 0x15;
|
|
|
+ spec = codec->spec;
|
|
|
|
|
|
alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
|
|
|
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
|
|
@@ -6504,13 +6311,11 @@ static int patch_alc861vd(struct hda_codec *codec)
|
|
|
struct alc_spec *spec;
|
|
|
int err;
|
|
|
|
|
|
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
|
|
- if (spec == NULL)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- codec->spec = spec;
|
|
|
+ err = alc_alloc_spec(codec, 0x0b);
|
|
|
+ if (err < 0)
|
|
|
+ return err;
|
|
|
|
|
|
- spec->mixer_nid = 0x0b;
|
|
|
+ spec = codec->spec;
|
|
|
|
|
|
alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
|
|
|
alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
|
|
@@ -6522,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) {
|
|
@@ -6635,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,
|
|
@@ -6849,25 +6654,19 @@ static const struct alc_model_fixup alc662_fixup_models[] = {
|
|
|
static int patch_alc662(struct hda_codec *codec)
|
|
|
{
|
|
|
struct alc_spec *spec;
|
|
|
- int err = 0;
|
|
|
-
|
|
|
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
|
|
- if (!spec)
|
|
|
- return -ENOMEM;
|
|
|
+ int err;
|
|
|
|
|
|
- codec->spec = spec;
|
|
|
+ err = alc_alloc_spec(codec, 0x0b);
|
|
|
+ if (err < 0)
|
|
|
+ return err;
|
|
|
|
|
|
- spec->mixer_nid = 0x0b;
|
|
|
+ spec = codec->spec;
|
|
|
|
|
|
/* handle multiple HPs as is */
|
|
|
spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
|
|
|
|
|
|
alc_fix_pll_init(codec, 0x20, 0x04, 15);
|
|
|
|
|
|
- err = alc_codec_rename_from_preset(codec);
|
|
|
- if (err < 0)
|
|
|
- goto error;
|
|
|
-
|
|
|
if ((alc_get_coef0(codec) & (1 << 14)) &&
|
|
|
codec->bus->pci->subsystem_vendor == 0x1025 &&
|
|
|
spec->cdefine.platform_type == 1) {
|
|
@@ -6930,16 +6729,12 @@ static int alc680_parse_auto_config(struct hda_codec *codec)
|
|
|
*/
|
|
|
static int patch_alc680(struct hda_codec *codec)
|
|
|
{
|
|
|
- struct alc_spec *spec;
|
|
|
int err;
|
|
|
|
|
|
- spec = kzalloc(sizeof(*spec), GFP_KERNEL);
|
|
|
- if (spec == NULL)
|
|
|
- return -ENOMEM;
|
|
|
-
|
|
|
- codec->spec = spec;
|
|
|
-
|
|
|
/* ALC680 has no aa-loopback mixer */
|
|
|
+ err = alc_alloc_spec(codec, 0);
|
|
|
+ if (err < 0)
|
|
|
+ return err;
|
|
|
|
|
|
/* automatic parse from the BIOS config */
|
|
|
err = alc680_parse_auto_config(codec);
|