Commit 26037980 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'topic/hda' into for-linus

parents 9fe6206f fc091769
...@@ -114,6 +114,11 @@ ALC662/663/272 ...@@ -114,6 +114,11 @@ ALC662/663/272
samsung-nc10 Samsung NC10 mini notebook samsung-nc10 Samsung NC10 mini notebook
auto auto-config reading BIOS (default) auto auto-config reading BIOS (default)
ALC680
======
base Base model (ASUS NX90)
auto auto-config reading BIOS (default)
ALC882/883/885/888/889 ALC882/883/885/888/889
====================== ======================
3stack-dig 3-jack with SPDIF I/O 3stack-dig 3-jack with SPDIF I/O
...@@ -282,6 +287,7 @@ Conexant 5051 ...@@ -282,6 +287,7 @@ Conexant 5051
hp HP Spartan laptop hp HP Spartan laptop
hp-dv6736 HP dv6736 hp-dv6736 HP dv6736
hp-f700 HP Compaq Presario F700 hp-f700 HP Compaq Presario F700
ideapad Lenovo IdeaPad laptop
lenovo-x200 Lenovo X200 laptop lenovo-x200 Lenovo X200 laptop
toshiba Toshiba Satellite M300 toshiba Toshiba Satellite M300
......
...@@ -396,15 +396,18 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, ...@@ -396,15 +396,18 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
} }
for (n = prev_nid + 1; n <= val; n++) { for (n = prev_nid + 1; n <= val; n++) {
if (conns >= max_conns) { if (conns >= max_conns) {
snd_printk(KERN_ERR snd_printk(KERN_ERR "hda_codec: "
"Too many connections\n"); "Too many connections %d for NID 0x%x\n",
conns, nid);
return -EINVAL; return -EINVAL;
} }
conn_list[conns++] = n; conn_list[conns++] = n;
} }
} else { } else {
if (conns >= max_conns) { if (conns >= max_conns) {
snd_printk(KERN_ERR "Too many connections\n"); snd_printk(KERN_ERR "hda_codec: "
"Too many connections %d for NID 0x%x\n",
conns, nid);
return -EINVAL; return -EINVAL;
} }
conn_list[conns++] = val; conn_list[conns++] = val;
...@@ -1565,6 +1568,17 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec) ...@@ -1565,6 +1568,17 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp); EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp);
#endif /* SND_HDA_NEEDS_RESUME */ #endif /* SND_HDA_NEEDS_RESUME */
static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir,
unsigned int ofs)
{
u32 caps = query_amp_caps(codec, nid, dir);
/* get num steps */
caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
if (ofs < caps)
caps -= ofs;
return caps;
}
/** /**
* snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer
* *
...@@ -1579,23 +1593,17 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, ...@@ -1579,23 +1593,17 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
u8 chs = get_amp_channels(kcontrol); u8 chs = get_amp_channels(kcontrol);
int dir = get_amp_direction(kcontrol); int dir = get_amp_direction(kcontrol);
unsigned int ofs = get_amp_offset(kcontrol); unsigned int ofs = get_amp_offset(kcontrol);
u32 caps;
caps = query_amp_caps(codec, nid, dir); uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
/* num steps */ uinfo->count = chs == 3 ? 2 : 1;
caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; uinfo->value.integer.min = 0;
if (!caps) { uinfo->value.integer.max = get_amp_max_value(codec, nid, dir, ofs);
if (!uinfo->value.integer.max) {
printk(KERN_WARNING "hda_codec: " printk(KERN_WARNING "hda_codec: "
"num_steps = 0 for NID=0x%x (ctl = %s)\n", nid, "num_steps = 0 for NID=0x%x (ctl = %s)\n", nid,
kcontrol->id.name); kcontrol->id.name);
return -EINVAL; return -EINVAL;
} }
if (ofs < caps)
caps -= ofs;
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
uinfo->count = chs == 3 ? 2 : 1;
uinfo->value.integer.min = 0;
uinfo->value.integer.max = caps;
return 0; return 0;
} }
EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info); EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info);
...@@ -1620,8 +1628,14 @@ update_amp_value(struct hda_codec *codec, hda_nid_t nid, ...@@ -1620,8 +1628,14 @@ update_amp_value(struct hda_codec *codec, hda_nid_t nid,
int ch, int dir, int idx, unsigned int ofs, int ch, int dir, int idx, unsigned int ofs,
unsigned int val) unsigned int val)
{ {
unsigned int maxval;
if (val > 0) if (val > 0)
val += ofs; val += ofs;
/* ofs = 0: raw max value */
maxval = get_amp_max_value(codec, nid, dir, 0);
if (val > maxval)
val = maxval;
return snd_hda_codec_amp_update(codec, nid, ch, dir, idx, return snd_hda_codec_amp_update(codec, nid, ch, dir, idx,
HDA_AMP_VOLMASK, val); HDA_AMP_VOLMASK, val);
} }
...@@ -2999,26 +3013,31 @@ struct hda_rate_tbl { ...@@ -2999,26 +3013,31 @@ struct hda_rate_tbl {
unsigned int hda_fmt; unsigned int hda_fmt;
}; };
/* rate = base * mult / div */
#define HDA_RATE(base, mult, div) \
(AC_FMT_BASE_##base##K | (((mult) - 1) << AC_FMT_MULT_SHIFT) | \
(((div) - 1) << AC_FMT_DIV_SHIFT))
static struct hda_rate_tbl rate_bits[] = { static struct hda_rate_tbl rate_bits[] = {
/* rate in Hz, ALSA rate bitmask, HDA format value */ /* rate in Hz, ALSA rate bitmask, HDA format value */
/* autodetected value used in snd_hda_query_supported_pcm */ /* autodetected value used in snd_hda_query_supported_pcm */
{ 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */ { 8000, SNDRV_PCM_RATE_8000, HDA_RATE(48, 1, 6) },
{ 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */ { 11025, SNDRV_PCM_RATE_11025, HDA_RATE(44, 1, 4) },
{ 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */ { 16000, SNDRV_PCM_RATE_16000, HDA_RATE(48, 1, 3) },
{ 22050, SNDRV_PCM_RATE_22050, 0x4100 }, /* 1/2 x 44 */ { 22050, SNDRV_PCM_RATE_22050, HDA_RATE(44, 1, 2) },
{ 32000, SNDRV_PCM_RATE_32000, 0x0a00 }, /* 2/3 x 48 */ { 32000, SNDRV_PCM_RATE_32000, HDA_RATE(48, 2, 3) },
{ 44100, SNDRV_PCM_RATE_44100, 0x4000 }, /* 44 */ { 44100, SNDRV_PCM_RATE_44100, HDA_RATE(44, 1, 1) },
{ 48000, SNDRV_PCM_RATE_48000, 0x0000 }, /* 48 */ { 48000, SNDRV_PCM_RATE_48000, HDA_RATE(48, 1, 1) },
{ 88200, SNDRV_PCM_RATE_88200, 0x4800 }, /* 2 x 44 */ { 88200, SNDRV_PCM_RATE_88200, HDA_RATE(44, 2, 1) },
{ 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ { 96000, SNDRV_PCM_RATE_96000, HDA_RATE(48, 2, 1) },
{ 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ { 176400, SNDRV_PCM_RATE_176400, HDA_RATE(44, 4, 1) },
{ 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ { 192000, SNDRV_PCM_RATE_192000, HDA_RATE(48, 4, 1) },
#define AC_PAR_PCM_RATE_BITS 11 #define AC_PAR_PCM_RATE_BITS 11
/* up to bits 10, 384kHZ isn't supported properly */ /* up to bits 10, 384kHZ isn't supported properly */
/* not autodetected value */ /* not autodetected value */
{ 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */ { 9600, SNDRV_PCM_RATE_KNOT, HDA_RATE(48, 1, 5) },
{ 0 } /* terminator */ { 0 } /* terminator */
}; };
...@@ -3037,7 +3056,8 @@ static struct hda_rate_tbl rate_bits[] = { ...@@ -3037,7 +3056,8 @@ static struct hda_rate_tbl rate_bits[] = {
unsigned int snd_hda_calc_stream_format(unsigned int rate, unsigned int snd_hda_calc_stream_format(unsigned int rate,
unsigned int channels, unsigned int channels,
unsigned int format, unsigned int format,
unsigned int maxbps) unsigned int maxbps,
unsigned short spdif_ctls)
{ {
int i; int i;
unsigned int val = 0; unsigned int val = 0;
...@@ -3060,20 +3080,20 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, ...@@ -3060,20 +3080,20 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
switch (snd_pcm_format_width(format)) { switch (snd_pcm_format_width(format)) {
case 8: case 8:
val |= 0x00; val |= AC_FMT_BITS_8;
break; break;
case 16: case 16:
val |= 0x10; val |= AC_FMT_BITS_16;
break; break;
case 20: case 20:
case 24: case 24:
case 32: case 32:
if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE) if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
val |= 0x40; val |= AC_FMT_BITS_32;
else if (maxbps >= 24) else if (maxbps >= 24)
val |= 0x30; val |= AC_FMT_BITS_24;
else else
val |= 0x20; val |= AC_FMT_BITS_20;
break; break;
default: default:
snd_printdd("invalid format width %d\n", snd_printdd("invalid format width %d\n",
...@@ -3081,6 +3101,9 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, ...@@ -3081,6 +3101,9 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
return 0; return 0;
} }
if (spdif_ctls & AC_DIG1_NONAUDIO)
val |= AC_FMT_TYPE_NON_PCM;
return val; return val;
} }
EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format); EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format);
......
...@@ -224,6 +224,27 @@ enum { ...@@ -224,6 +224,27 @@ enum {
/* Input converter SDI select */ /* Input converter SDI select */
#define AC_SDI_SELECT (0xf<<0) #define AC_SDI_SELECT (0xf<<0)
/* stream format id */
#define AC_FMT_CHAN_SHIFT 0
#define AC_FMT_CHAN_MASK (0x0f << 0)
#define AC_FMT_BITS_SHIFT 4
#define AC_FMT_BITS_MASK (7 << 4)
#define AC_FMT_BITS_8 (0 << 4)
#define AC_FMT_BITS_16 (1 << 4)
#define AC_FMT_BITS_20 (2 << 4)
#define AC_FMT_BITS_24 (3 << 4)
#define AC_FMT_BITS_32 (4 << 4)
#define AC_FMT_DIV_SHIFT 8
#define AC_FMT_DIV_MASK (7 << 8)
#define AC_FMT_MULT_SHIFT 11
#define AC_FMT_MULT_MASK (7 << 11)
#define AC_FMT_BASE_SHIFT 14
#define AC_FMT_BASE_48K (0 << 14)
#define AC_FMT_BASE_44K (1 << 14)
#define AC_FMT_TYPE_SHIFT 15
#define AC_FMT_TYPE_PCM (0 << 15)
#define AC_FMT_TYPE_NON_PCM (1 << 15)
/* Unsolicited response control */ /* Unsolicited response control */
#define AC_UNSOL_TAG (0x3f<<0) #define AC_UNSOL_TAG (0x3f<<0)
#define AC_UNSOL_ENABLED (1<<7) #define AC_UNSOL_ENABLED (1<<7)
...@@ -364,6 +385,9 @@ enum { ...@@ -364,6 +385,9 @@ enum {
#define AC_DIG2_CC (0x7f<<0) #define AC_DIG2_CC (0x7f<<0)
/* Pin widget control - 8bit */ /* Pin widget control - 8bit */
#define AC_PINCTL_EPT (0x3<<0)
#define AC_PINCTL_EPT_NATIVE 0
#define AC_PINCTL_EPT_HBR 3
#define AC_PINCTL_VREFEN (0x7<<0) #define AC_PINCTL_VREFEN (0x7<<0)
#define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */ #define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */
#define AC_PINCTL_VREF_50 1 /* 50% */ #define AC_PINCTL_VREF_50 1 /* 50% */
...@@ -928,7 +952,8 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid); ...@@ -928,7 +952,8 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid);
unsigned int snd_hda_calc_stream_format(unsigned int rate, unsigned int snd_hda_calc_stream_format(unsigned int rate,
unsigned int channels, unsigned int channels,
unsigned int format, unsigned int format,
unsigned int maxbps); unsigned int maxbps,
unsigned short spdif_ctls);
int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
unsigned int format); unsigned int format);
......
...@@ -649,7 +649,9 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus, ...@@ -649,7 +649,9 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus,
*codecp = NULL; *codecp = NULL;
if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) { if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) {
list_for_each_entry(codec, &bus->codec_list, list) { list_for_each_entry(codec, &bus->codec_list, list) {
if (codec->addr == caddr) { if (codec->vendor_id == vendorid &&
codec->subsystem_id == subid &&
codec->addr == caddr) {
*codecp = codec; *codecp = codec;
break; break;
} }
......
...@@ -1653,7 +1653,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) ...@@ -1653,7 +1653,8 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
format_val = snd_hda_calc_stream_format(runtime->rate, format_val = snd_hda_calc_stream_format(runtime->rate,
runtime->channels, runtime->channels,
runtime->format, runtime->format,
hinfo->maxbps); hinfo->maxbps,
apcm->codec->spdif_ctls);
if (!format_val) { if (!format_val) {
snd_printk(KERN_ERR SFX snd_printk(KERN_ERR SFX
"invalid format_val, rate=%d, ch=%d, format=%d\n", "invalid format_val, rate=%d, ch=%d, format=%d\n",
...@@ -1960,7 +1961,7 @@ static void azx_irq_pending_work(struct work_struct *work) ...@@ -1960,7 +1961,7 @@ static void azx_irq_pending_work(struct work_struct *work)
spin_unlock_irq(&chip->reg_lock); spin_unlock_irq(&chip->reg_lock);
if (!pending) if (!pending)
return; return;
cond_resched(); msleep(1);
} }
} }
......
...@@ -3662,7 +3662,12 @@ static int patch_ad1984(struct hda_codec *codec) ...@@ -3662,7 +3662,12 @@ static int patch_ad1984(struct hda_codec *codec)
codec->patch_ops.build_pcms = ad1984_build_pcms; codec->patch_ops.build_pcms = ad1984_build_pcms;
break; break;
case AD1984_THINKPAD: case AD1984_THINKPAD:
spec->multiout.dig_out_nid = AD1884_SPDIF_OUT; if (codec->subsystem_id == 0x17aa20fb) {
/* Thinpad X300 does not have the ability to do SPDIF,
or attach to docking station to use SPDIF */
spec->multiout.dig_out_nid = 0;
} else
spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
spec->input_mux = &ad1984_thinkpad_capture_source; spec->input_mux = &ad1984_thinkpad_capture_source;
spec->mixers[0] = ad1984_thinkpad_mixers; spec->mixers[0] = ad1984_thinkpad_mixers;
spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs; spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
......
...@@ -131,6 +131,8 @@ struct conexant_spec { ...@@ -131,6 +131,8 @@ struct conexant_spec {
unsigned int dc_enable; unsigned int dc_enable;
unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */ unsigned int dc_input_bias; /* offset into cxt5066_olpc_dc_bias */
unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
unsigned int beep_amp;
}; };
static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
...@@ -515,6 +517,15 @@ static struct snd_kcontrol_new cxt_capture_mixers[] = { ...@@ -515,6 +517,15 @@ static struct snd_kcontrol_new cxt_capture_mixers[] = {
{} {}
}; };
#ifdef CONFIG_SND_HDA_INPUT_BEEP
/* additional beep mixers; the actual parameters are overwritten at build */
static struct snd_kcontrol_new cxt_beep_mixer[] = {
HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
{ } /* end */
};
#endif
static const char *slave_vols[] = { static const char *slave_vols[] = {
"Headphone Playback Volume", "Headphone Playback Volume",
"Speaker Playback Volume", "Speaker Playback Volume",
...@@ -580,16 +591,52 @@ static int conexant_build_controls(struct hda_codec *codec) ...@@ -580,16 +591,52 @@ static int conexant_build_controls(struct hda_codec *codec)
return err; return err;
} }
#ifdef CONFIG_SND_HDA_INPUT_BEEP
/* create beep controls if needed */
if (spec->beep_amp) {
struct snd_kcontrol_new *knew;
for (knew = cxt_beep_mixer; knew->name; knew++) {
struct snd_kcontrol *kctl;
kctl = snd_ctl_new1(knew, codec);
if (!kctl)
return -ENOMEM;
kctl->private_value = spec->beep_amp;
err = snd_hda_ctl_add(codec, 0, kctl);
if (err < 0)
return err;
}
}
#endif
return 0;
}
#ifdef CONFIG_SND_HDA_POWER_SAVE
static int conexant_suspend(struct hda_codec *codec, pm_message_t state)
{
snd_hda_shutup_pins(codec);
return 0; return 0;
} }
#endif
static struct hda_codec_ops conexant_patch_ops = { static struct hda_codec_ops conexant_patch_ops = {
.build_controls = conexant_build_controls, .build_controls = conexant_build_controls,
.build_pcms = conexant_build_pcms, .build_pcms = conexant_build_pcms,
.init = conexant_init, .init = conexant_init,
.free = conexant_free, .free = conexant_free,
#ifdef CONFIG_SND_HDA_POWER_SAVE
.suspend = conexant_suspend,
#endif
.reboot_notify = snd_hda_shutup_pins,
}; };
#ifdef CONFIG_SND_HDA_INPUT_BEEP
#define set_beep_amp(spec, nid, idx, dir) \
((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir))
#else
#define set_beep_amp(spec, nid, idx, dir) /* NOP */
#endif
/* /*
* EAPD control * EAPD control
* the private value = nid | (invert << 8) * the private value = nid | (invert << 8)
...@@ -1130,9 +1177,10 @@ static int patch_cxt5045(struct hda_codec *codec) ...@@ -1130,9 +1177,10 @@ static int patch_cxt5045(struct hda_codec *codec)
spec->num_init_verbs = 1; spec->num_init_verbs = 1;
spec->init_verbs[0] = cxt5045_init_verbs; spec->init_verbs[0] = cxt5045_init_verbs;
spec->spdif_route = 0; spec->spdif_route = 0;
spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes), spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes);
spec->channel_mode = cxt5045_modes, spec->channel_mode = cxt5045_modes;
set_beep_amp(spec, 0x16, 0, 1);
codec->patch_ops = conexant_patch_ops; codec->patch_ops = conexant_patch_ops;
...@@ -1211,6 +1259,9 @@ static int patch_cxt5045(struct hda_codec *codec) ...@@ -1211,6 +1259,9 @@ static int patch_cxt5045(struct hda_codec *codec)
break; break;
} }
if (spec->beep_amp)
snd_hda_attach_beep_device(codec, spec->beep_amp);
return 0; return 0;
} }
...@@ -1632,6 +1683,11 @@ static void cxt5051_update_speaker(struct hda_codec *codec) ...@@ -1632,6 +1683,11 @@ static void cxt5051_update_speaker(struct hda_codec *codec)
pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
pinctl); pinctl);
/* on ideapad there is an aditional speaker (subwoofer) to mute */
if (spec->ideapad)
snd_hda_codec_write(codec, 0x1b, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL,
pinctl);
} }
/* turn on/off EAPD (+ mute HP) as a master switch */ /* turn on/off EAPD (+ mute HP) as a master switch */
...@@ -1888,6 +1944,13 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid, ...@@ -1888,6 +1944,13 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
#endif #endif
} }
static struct hda_verb cxt5051_ideapad_init_verbs[] = {
/* Subwoofer */
{0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
{0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
{ } /* end */
};
/* initialize jack-sensing, too */ /* initialize jack-sensing, too */
static int cxt5051_init(struct hda_codec *codec) static int cxt5051_init(struct hda_codec *codec)
{ {
...@@ -1917,6 +1980,7 @@ enum { ...@@ -1917,6 +1980,7 @@ enum {
CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */ CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */
CXT5051_F700, /* HP Compaq Presario F700 */ CXT5051_F700, /* HP Compaq Presario F700 */
CXT5051_TOSHIBA, /* Toshiba M300 & co */ CXT5051_TOSHIBA, /* Toshiba M300 & co */
CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */
CXT5051_MODELS CXT5051_MODELS
}; };
...@@ -1927,6 +1991,7 @@ static const char *cxt5051_models[CXT5051_MODELS] = { ...@@ -1927,6 +1991,7 @@ static const char *cxt5051_models[CXT5051_MODELS] = {
[CXT5051_LENOVO_X200] = "lenovo-x200", [CXT5051_LENOVO_X200] = "lenovo-x200",
[CXT5051_F700] = "hp-700", [CXT5051_F700] = "hp-700",
[CXT5051_TOSHIBA] = "toshiba", [CXT5051_TOSHIBA] = "toshiba",
[CXT5051_IDEAPAD] = "ideapad",
}; };
static struct snd_pci_quirk cxt5051_cfg_tbl[] = { static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
...@@ -1938,6 +2003,7 @@ static struct snd_pci_quirk cxt5051_cfg_tbl[] = { ...@@ -1938,6 +2003,7 @@ static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
CXT5051_LAPTOP), CXT5051_LAPTOP),
SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD),
{} {}
}; };
...@@ -1972,6 +2038,8 @@ static int patch_cxt5051(struct hda_codec *codec) ...@@ -1972,6 +2038,8 @@ static int patch_cxt5051(struct hda_codec *codec)
spec->cur_adc = 0; spec->cur_adc = 0;
spec->cur_adc_idx = 0; spec->cur_adc_idx = 0;
set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; codec->patch_ops.unsol_event = cxt5051_hp_unsol_event;
board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
...@@ -1989,6 +2057,10 @@ static int patch_cxt5051(struct hda_codec *codec) ...@@ -1989,6 +2057,10 @@ static int patch_cxt5051(struct hda_codec *codec)
break; break;
case CXT5051_LENOVO_X200: case CXT5051_LENOVO_X200:
spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
/* Thinkpad X301 does not have S/PDIF wired and no ability
to use a docking station. */
if (codec->subsystem_id == 0x17aa211f)
spec->multiout.dig_out_nid = 0;
break; break;
case CXT5051_F700: case CXT5051_F700:
spec->init_verbs[0] = cxt5051_f700_init_verbs; spec->init_verbs[0] = cxt5051_f700_init_verbs;
...@@ -1999,8 +2071,16 @@ static int patch_cxt5051(struct hda_codec *codec) ...@@ -1999,8 +2071,16 @@ static int patch_cxt5051(struct hda_codec *codec)
spec->mixers[0] = cxt5051_toshiba_mixers; spec->mixers[0] = cxt5051_toshiba_mixers;
spec->auto_mic = AUTO_MIC_PORTB; spec->auto_mic = AUTO_MIC_PORTB;
break; break;
case CXT5051_IDEAPAD:
spec->init_verbs[spec->num_init_verbs++] =
cxt5051_ideapad_init_verbs;
spec->ideapad = 1;
break;
} }
if (spec->beep_amp)
snd_hda_attach_beep_device(codec, spec->beep_amp);
return 0; return 0;
} }
...@@ -2616,7 +2696,6 @@ static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { ...@@ -2616,7 +2696,6 @@ static struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
.put = cxt5066_mic_boost_mux_enum_put, .put = cxt5066_mic_boost_mux_enum_put,
.private_value = 0x23 | 0x100, .private_value = 0x23 | 0x100,
}, },
HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
{} {}
}; };
...@@ -2977,8 +3056,10 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { ...@@ -2977,8 +3056,10 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G series (AMD)", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
{} {}
}; };
...@@ -3014,6 +3095,8 @@ static int patch_cxt5066(struct hda_codec *codec) ...@@ -3014,6 +3095,8 @@ static int patch_cxt5066(struct hda_codec *codec)
spec->cur_adc = 0; spec->cur_adc = 0;
spec->cur_adc_idx = 0; spec->cur_adc_idx = 0;
set_beep_amp(spec, 0x13, 0, HDA_OUTPUT);
board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
cxt5066_models, cxt5066_cfg_tbl); cxt5066_models, cxt5066_cfg_tbl);
switch (board_config) { switch (board_config) {
...@@ -3062,7 +3145,6 @@ static int patch_cxt5066(struct hda_codec *codec) ...@@ -3062,7 +3145,6 @@ static int patch_cxt5066(struct hda_codec *codec)
spec->port_d_mode = 0; spec->port_d_mode = 0;
spec->dell_vostro = 1; spec->dell_vostro = 1;
spec->mic_boost = 3; /* default 30dB gain */ spec->mic_boost = 3; /* default 30dB gain */
snd_hda_attach_beep_device(codec, 0x13);
/* no S/PDIF out */ /* no S/PDIF out */
spec->multiout.dig_out_nid = 0; spec->multiout.dig_out_nid = 0;
...@@ -3104,6 +3186,9 @@ static int patch_cxt5066(struct hda_codec *codec) ...@@ -3104,6 +3186,9 @@ static int patch_cxt5066(struct hda_codec *codec)
break; break;
} }
if (spec->beep_amp)
snd_hda_attach_beep_device(codec, spec->beep_amp);
return 0; return 0;
} }
......
...@@ -698,11 +698,51 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res) ...@@ -698,11 +698,51 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
* Callbacks * Callbacks
*/ */
static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, /* HBR should be Non-PCM, 8 channels */
#define is_hbr_format(format) \
((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7)
static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
u32 stream_tag, int format) u32 stream_tag, int format)
{ {
struct hdmi_spec *spec = codec->spec;
int tag; int tag;
int fmt; int fmt;
int pinctl;
int new_pinctl = 0;
int i;
for (i = 0; i < spec->num_pins; i++) {
if (spec->pin_cvt[i] != nid)
continue;
if (!(snd_hda_query_pin_caps(codec, spec->pin[i]) & AC_PINCAP_HBR))
continue;
pinctl = snd_hda_codec_read(codec, spec->pin[i], 0,
AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
new_pinctl = pinctl & ~AC_PINCTL_EPT;
if (is_hbr_format(format))
new_pinctl |= AC_PINCTL_EPT_HBR;
else
new_pinctl |= AC_PINCTL_EPT_NATIVE;
snd_printdd("hdmi_setup_stream: "
"NID=0x%x, %spinctl=0x%x\n",
spec->pin[i],
pinctl == new_pinctl ? "" : "new-",
new_pinctl);
if (pinctl != new_pinctl)
snd_hda_codec_write(codec, spec->pin[i], 0,
AC_VERB_SET_PIN_WIDGET_CONTROL,
new_pinctl);
}
if (is_hbr_format(format) && !new_pinctl) {
snd_printdd("hdmi_setup_stream: HBR is not supported\n");
return -EINVAL;
}
tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4; tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0); fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
...@@ -722,6 +762,7 @@ static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, ...@@ -722,6 +762,7 @@ static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
if (fmt != format) if (fmt != format)
snd_hda_codec_write(codec, nid, 0, snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_STREAM_FORMAT, format); AC_VERB_SET_STREAM_FORMAT, format);
return 0;
} }
/* /*
......
...@@ -66,8 +66,7 @@ static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, ...@@ -66,8 +66,7 @@ static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
return 0;
} }
static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
......
...@@ -202,8 +202,7 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo, ...@@ -202,8 +202,7 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo,
hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
return 0;
} }
static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
......
This diff is collapsed.
...@@ -202,6 +202,7 @@ struct sigmatel_spec { ...@@ -202,6 +202,7 @@ struct sigmatel_spec {
unsigned int spdif_mute: 1; unsigned int spdif_mute: 1;
unsigned int check_volume_offset:1; unsigned int check_volume_offset:1;
unsigned int auto_mic:1; unsigned int auto_mic:1;
unsigned int linear_tone_beep:1;
/* gpio lines */ /* gpio lines */
unsigned int eapd_mask; unsigned int eapd_mask;
...@@ -3802,7 +3803,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out ...@@ -3802,7 +3803,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
return err; return err;
if (codec->beep) { if (codec->beep) {
/* IDT/STAC codecs have linear beep tone parameter */ /* IDT/STAC codecs have linear beep tone parameter */
codec->beep->linear_tone = 1; codec->beep->linear_tone = spec->linear_tone_beep;
/* if no beep switch is available, make its own one */ /* if no beep switch is available, make its own one */
caps = query_amp_caps(codec, nid, HDA_OUTPUT); caps = query_amp_caps(codec, nid, HDA_OUTPUT);
if (!(caps & AC_AMPCAP_MUTE)) { if (!(caps & AC_AMPCAP_MUTE)) {
...@@ -5005,6 +5006,7 @@ static int patch_stac9200(struct hda_codec *codec) ...@@ -5005,6 +5006,7 @@ static int patch_stac9200(struct hda_codec *codec)
codec->no_trigger_sense = 1; codec->no_trigger_sense = 1;
codec->spec = spec; codec->spec = spec;
spec->linear_tone_beep = 1;
spec->num_pins = ARRAY_SIZE(stac9200_pin_nids); spec->num_pins = ARRAY_SIZE(stac9200_pin_nids);
spec->pin_nids = stac9200_pin_nids; spec->pin_nids = stac9200_pin_nids;
spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
...@@ -5068,6 +5070,7 @@ static int patch_stac925x(struct hda_codec *codec) ...@@ -5068,6 +5070,7 @@ static int patch_stac925x(struct hda_codec *codec)
codec->no_trigger_sense = 1; codec->no_trigger_sense = 1;
codec->spec = spec; codec->spec = spec;
spec->linear_tone_beep = 1;
spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); spec->num_pins = ARRAY_SIZE(stac925x_pin_nids);
spec->pin_nids = stac925x_pin_nids; spec->pin_nids = stac925x_pin_nids;
...@@ -5153,6 +5156,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec) ...@@ -5153,6 +5156,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
codec->no_trigger_sense = 1; codec->no_trigger_sense = 1;
codec->spec = spec; codec->spec = spec;
spec->linear_tone_beep = 0;
codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; codec->slave_dig_outs = stac92hd73xx_slave_dig_outs;
spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids);
spec->pin_nids = stac92hd73xx_pin_nids; spec->pin_nids = stac92hd73xx_pin_nids;
...@@ -5300,6 +5304,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) ...@@ -5300,6 +5304,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
codec->no_trigger_sense = 1; codec->no_trigger_sense = 1;
codec->spec = spec; codec->spec = spec;
spec->linear_tone_beep = 1;
codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
spec->digbeep_nid = 0x21; spec->digbeep_nid = 0x21;
spec->mux_nids = stac92hd83xxx_mux_nids; spec->mux_nids = stac92hd83xxx_mux_nids;
...@@ -5522,6 +5527,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) ...@@ -5522,6 +5527,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
codec->no_trigger_sense = 1; codec->no_trigger_sense = 1;
codec->spec = spec; codec->spec = spec;
spec->linear_tone_beep = 0;
codec->patch_ops = stac92xx_patch_ops; codec->patch_ops = stac92xx_patch_ops;
spec->num_pins = STAC92HD71BXX_NUM_PINS; spec->num_pins = STAC92HD71BXX_NUM_PINS;
switch (codec->vendor_id) { switch (codec->vendor_id) {
...@@ -5779,6 +5785,7 @@ static int patch_stac922x(struct hda_codec *codec) ...@@ -5779,6 +5785,7 @@ static int patch_stac922x(struct hda_codec *codec)
codec->no_trigger_sense = 1; codec->no_trigger_sense = 1;
codec->spec = spec; codec->spec = spec;
spec->linear_tone_beep = 1;
spec->num_pins = ARRAY_SIZE(stac922x_pin_nids); spec->num_pins = ARRAY_SIZE(stac922x_pin_nids);
spec->pin_nids = stac922x_pin_nids; spec->pin_nids = stac922x_pin_nids;
spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS, spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
...@@ -5883,6 +5890,7 @@ static int patch_stac927x(struct hda_codec *codec) ...@@ -5883,6 +5890,7 @@ static int patch_stac927x(struct hda_codec *codec)
codec->no_trigger_sense = 1; codec->no_trigger_sense = 1;
codec->spec = spec; codec->spec = spec;
spec->linear_tone_beep = 1;
codec->slave_dig_outs = stac927x_slave_dig_outs; codec->slave_dig_outs = stac927x_slave_dig_outs;
spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); spec->num_pins = ARRAY_SIZE(stac927x_pin_nids);
spec->pin_nids = stac927x_pin_nids; spec->pin_nids = stac927x_pin_nids;
...@@ -6018,6 +6026,7 @@ static int patch_stac9205(struct hda_codec *codec) ...@@ -6018,6 +6026,7 @@ static int patch_stac9205(struct hda_codec *codec)
codec->no_trigger_sense = 1; codec->no_trigger_sense = 1;
codec->spec = spec; codec->spec = spec;
spec->linear_tone_beep = 1;
spec->num_pins = ARRAY_SIZE(stac9205_pin_nids); spec->num_pins = ARRAY_SIZE(stac9205_pin_nids);
spec->pin_nids = stac9205_pin_nids; spec->pin_nids = stac9205_pin_nids;
spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS, spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
...@@ -6174,6 +6183,7 @@ static int patch_stac9872(struct hda_codec *codec) ...@@ -6174,6 +6183,7 @@ static int patch_stac9872(struct hda_codec *codec)
return -ENOMEM; return -ENOMEM;
codec->no_trigger_sense = 1; codec->no_trigger_sense = 1;
codec->spec = spec; codec->spec = spec;
spec->linear_tone_beep = 1;
spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); spec->num_pins = ARRAY_SIZE(stac9872_pin_nids);
spec->pin_nids = stac9872_pin_nids; spec->pin_nids = stac9872_pin_nids;
......
...@@ -552,24 +552,30 @@ static void via_auto_init_hp_out(struct hda_codec *codec) ...@@ -552,24 +552,30 @@ static void via_auto_init_hp_out(struct hda_codec *codec)
} }
} }
static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
static void via_auto_init_analog_input(struct hda_codec *codec) static void via_auto_init_analog_input(struct hda_codec *codec)
{ {
struct via_spec *spec = codec->spec; struct via_spec *spec = codec->spec;
unsigned int ctl;
int i; int i;
for (i = 0; i < AUTO_PIN_LAST; i++) { for (i = 0; i < AUTO_PIN_LAST; i++) {
hda_nid_t nid = spec->autocfg.input_pins[i]; hda_nid_t nid = spec->autocfg.input_pins[i];
if (!nid)
continue;
if (spec->smart51_enabled && is_smart51_pins(spec, nid))
ctl = PIN_OUT;
else if (i <= AUTO_PIN_FRONT_MIC)
ctl = PIN_VREF50;
else
ctl = PIN_IN;
snd_hda_codec_write(codec, nid, 0, snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_PIN_WIDGET_CONTROL, AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
(i <= AUTO_PIN_FRONT_MIC ?
PIN_VREF50 : PIN_IN));
} }
} }
static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin);
static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
unsigned int *affected_parm) unsigned int *affected_parm)
{ {
...@@ -658,6 +664,8 @@ static void set_jack_power_state(struct hda_codec *codec) ...@@ -658,6 +664,8 @@ static void set_jack_power_state(struct hda_codec *codec)
/* PW0 (19h), SW1 (18h), AOW1 (11h) */ /* PW0 (19h), SW1 (18h), AOW1 (11h) */
parm = AC_PWRST_D3; parm = AC_PWRST_D3;
set_pin_power_state(codec, 0x19, &parm); set_pin_power_state(codec, 0x19, &parm);
if (spec->smart51_enabled)
parm = AC_PWRST_D0;
snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE,
parm); parm);
snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE,
...@@ -667,6 +675,8 @@ static void set_jack_power_state(struct hda_codec *codec) ...@@ -667,6 +675,8 @@ static void set_jack_power_state(struct hda_codec *codec)
if (is_8ch) { if (is_8ch) {
parm = AC_PWRST_D3; parm = AC_PWRST_D3;
set_pin_power_state(codec, 0x22, &parm); set_pin_power_state(codec, 0x22, &parm);
if (spec->smart51_enabled)
parm = AC_PWRST_D0;
snd_hda_codec_write(codec, 0x26, 0, snd_hda_codec_write(codec, 0x26, 0,
AC_VERB_SET_POWER_STATE, parm); AC_VERB_SET_POWER_STATE, parm);
snd_hda_codec_write(codec, 0x24, 0, snd_hda_codec_write(codec, 0x24, 0,
...@@ -3915,6 +3925,13 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, ...@@ -3915,6 +3925,13 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
} }
} }
/* for Smart 5.1, line/mic inputs double as output pins */
if (cfg->line_outs == 1) {
spec->multiout.num_dacs = 3;
spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11;
spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24;
}
return 0; return 0;
} }
...@@ -3932,7 +3949,8 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, ...@@ -3932,7 +3949,8 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
for (i = 0; i <= AUTO_SEQ_SIDE; i++) { for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
nid = cfg->line_out_pins[i]; nid = cfg->line_out_pins[i];
if (!nid) /* for Smart 5.1, there are always at least six channels */
if (!nid && i > AUTO_SEQ_CENLFE)
continue; continue;
nid_vol = nid_vols[i]; nid_vol = nid_vols[i];
......
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