Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 132990
b: refs/heads/master
c: 29fdbec
h: refs/heads/master
v: v3
  • Loading branch information
Takashi Iwai committed Jan 20, 2009
1 parent 40669d8 commit d190829
Show file tree
Hide file tree
Showing 6 changed files with 255 additions and 113 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 08989930f91e4802b94e03eb54e5385bac112811
refs/heads/master: 29fdbec2dcb1ce364812778271056aa9516ff3ed
3 changes: 2 additions & 1 deletion trunk/Documentation/sound/alsa/HD-Audio-Models.txt
Original file line number Diff line number Diff line change
Expand Up @@ -352,4 +352,5 @@ STAC92HD83*

STAC9872
========
N/A
vaio Setup for VAIO FE550G/SZ110
vaio-ar Setup for VAIO AR
61 changes: 38 additions & 23 deletions trunk/sound/pci/hda/hda_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,7 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
u16 nid = get_amp_nid(kcontrol);
u8 chs = get_amp_channels(kcontrol);
int dir = get_amp_direction(kcontrol);
unsigned int ofs = get_amp_offset(kcontrol);
u32 caps;

caps = query_amp_caps(codec, nid, dir);
Expand All @@ -1130,6 +1131,8 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
kcontrol->id.name);
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;
Expand All @@ -1138,6 +1141,32 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
}
EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info);


static inline unsigned int
read_amp_value(struct hda_codec *codec, hda_nid_t nid,
int ch, int dir, int idx, unsigned int ofs)
{
unsigned int val;
val = snd_hda_codec_amp_read(codec, nid, ch, dir, idx);
val &= HDA_AMP_VOLMASK;
if (val >= ofs)
val -= ofs;
else
val = 0;
return val;
}

static inline int
update_amp_value(struct hda_codec *codec, hda_nid_t nid,
int ch, int dir, int idx, unsigned int ofs,
unsigned int val)
{
if (val > 0)
val += ofs;
return snd_hda_codec_amp_update(codec, nid, ch, dir, idx,
HDA_AMP_VOLMASK, val);
}

int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
Expand All @@ -1146,14 +1175,13 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
int chs = get_amp_channels(kcontrol);
int dir = get_amp_direction(kcontrol);
int idx = get_amp_index(kcontrol);
unsigned int ofs = get_amp_offset(kcontrol);
long *valp = ucontrol->value.integer.value;

if (chs & 1)
*valp++ = snd_hda_codec_amp_read(codec, nid, 0, dir, idx)
& HDA_AMP_VOLMASK;
*valp++ = read_amp_value(codec, nid, 0, dir, idx, ofs);
if (chs & 2)
*valp = snd_hda_codec_amp_read(codec, nid, 1, dir, idx)
& HDA_AMP_VOLMASK;
*valp = read_amp_value(codec, nid, 1, dir, idx, ofs);
return 0;
}
EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_get);
Expand All @@ -1166,18 +1194,17 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
int chs = get_amp_channels(kcontrol);
int dir = get_amp_direction(kcontrol);
int idx = get_amp_index(kcontrol);
unsigned int ofs = get_amp_offset(kcontrol);
long *valp = ucontrol->value.integer.value;
int change = 0;

snd_hda_power_up(codec);
if (chs & 1) {
change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
0x7f, *valp);
change = update_amp_value(codec, nid, 0, dir, idx, ofs, *valp);
valp++;
}
if (chs & 2)
change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
0x7f, *valp);
change |= update_amp_value(codec, nid, 1, dir, idx, ofs, *valp);
snd_hda_power_down(codec);
return change;
}
Expand All @@ -1189,6 +1216,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
hda_nid_t nid = get_amp_nid(kcontrol);
int dir = get_amp_direction(kcontrol);
unsigned int ofs = get_amp_offset(kcontrol);
u32 caps, val1, val2;

if (size < 4 * sizeof(unsigned int))
Expand All @@ -1197,6 +1225,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
val2 = (val2 + 1) * 25;
val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
val1 += ofs;
val1 = ((int)val1) * ((int)val2);
if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
return -EFAULT;
Expand Down Expand Up @@ -2613,7 +2642,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
int dev;

if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
continue; /* no substreams assigned */
return 0; /* no substreams assigned */

if (!cpcm->pcm) {
dev = get_empty_pcm_device(codec->bus, cpcm->pcm_type);
Expand Down Expand Up @@ -3390,20 +3419,10 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
cfg->input_pins[AUTO_PIN_AUX] = nid;
break;
case AC_JACK_SPDIF_OUT:
case AC_JACK_DIG_OTHER_OUT:
cfg->dig_out_pin = nid;
if (loc == AC_JACK_LOC_HDMI)
cfg->dig_out_type = HDA_PCM_TYPE_HDMI;
else
cfg->dig_out_type = HDA_PCM_TYPE_SPDIF;
break;
case AC_JACK_SPDIF_IN:
case AC_JACK_DIG_OTHER_IN:
cfg->dig_in_pin = nid;
if (loc == AC_JACK_LOC_HDMI)
cfg->dig_in_type = HDA_PCM_TYPE_HDMI;
else
cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
break;
}
}
Expand Down Expand Up @@ -3509,8 +3528,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
cfg->hp_pins[1], cfg->hp_pins[2],
cfg->hp_pins[3], cfg->hp_pins[4]);
snd_printd(" mono: mono_out=0x%x\n", cfg->mono_out_pin);
if (cfg->dig_out_pin)
snd_printd(" dig-out=0x%x\n", cfg->dig_out_pin);
snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x,"
" cd=0x%x, aux=0x%x\n",
cfg->input_pins[AUTO_PIN_MIC],
Expand All @@ -3519,8 +3536,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
cfg->input_pins[AUTO_PIN_FRONT_LINE],
cfg->input_pins[AUTO_PIN_CD],
cfg->input_pins[AUTO_PIN_AUX]);
if (cfg->dig_out_pin)
snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin);

return 0;
}
Expand Down
7 changes: 4 additions & 3 deletions trunk/sound/pci/hda/hda_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
/*
* for mixer controls
*/
#define HDA_COMPOSE_AMP_VAL_OFS(nid,chs,idx,dir,ofs) \
((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19) | ((ofs)<<23))
#define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \
((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19))
HDA_COMPOSE_AMP_VAL_OFS(nid, chs, idx, dir, 0)
/* mono volume with index (index=0,1,...) (channel=1,2) */
#define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
Expand Down Expand Up @@ -355,8 +357,6 @@ struct auto_pin_cfg {
hda_nid_t dig_out_pin;
hda_nid_t dig_in_pin;
hda_nid_t mono_out_pin;
int dig_out_type; /* HDA_PCM_TYPE_XXX */
int dig_in_type; /* HDA_PCM_TYPE_XXX */
};

#define get_defcfg_connect(cfg) \
Expand Down Expand Up @@ -458,6 +458,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
#define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f)

/*
* CEA Short Audio Descriptor data
Expand Down
49 changes: 11 additions & 38 deletions trunk/sound/pci/hda/patch_realtek.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,6 @@ struct alc_spec {
* dig_out_nid and hp_nid are optional
*/
hda_nid_t alt_dac_nid;
int dig_out_type;

/* capture */
unsigned int num_adc_nids;
Expand Down Expand Up @@ -306,9 +305,6 @@ struct alc_spec {
unsigned int jack_present: 1;
unsigned int master_sw: 1;

/* other flags */
unsigned int no_analog :1; /* digital I/O only */

/* for virtual master */
hda_nid_t vmaster_nid;
#ifdef CONFIG_SND_HDA_POWER_SAVE
Expand Down Expand Up @@ -2022,13 +2018,11 @@ static int alc_build_controls(struct hda_codec *codec)
spec->multiout.dig_out_nid);
if (err < 0)
return err;
if (!spec->no_analog) {
err = snd_hda_create_spdif_share_sw(codec,
&spec->multiout);
if (err < 0)
return err;
spec->multiout.share_spdif = 1;
}
err = snd_hda_create_spdif_share_sw(codec,
&spec->multiout);
if (err < 0)
return err;
spec->multiout.share_spdif = 1;
}
if (spec->dig_in_nid) {
err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
Expand All @@ -2037,8 +2031,7 @@ static int alc_build_controls(struct hda_codec *codec)
}

/* if we have no master control, let's create it */
if (!spec->no_analog &&
!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
unsigned int vmaster_tlv[4];
snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
HDA_OUTPUT, vmaster_tlv);
Expand All @@ -2047,8 +2040,7 @@ static int alc_build_controls(struct hda_codec *codec)
if (err < 0)
return err;
}
if (!spec->no_analog &&
!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
err = snd_hda_add_vmaster(codec, "Master Playback Switch",
NULL, alc_slave_sws);
if (err < 0)
Expand Down Expand Up @@ -3067,9 +3059,6 @@ static int alc_build_pcms(struct hda_codec *codec)
codec->num_pcms = 1;
codec->pcm_info = info;

if (spec->no_analog)
goto skip_analog;

info->name = spec->stream_name_analog;
if (spec->stream_analog_playback) {
if (snd_BUG_ON(!spec->multiout.dac_nids))
Expand All @@ -3093,16 +3082,12 @@ static int alc_build_pcms(struct hda_codec *codec)
}
}

skip_analog:
/* SPDIF for stream index #1 */
if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
codec->num_pcms = 2;
info = spec->pcm_rec + 1;
info->name = spec->stream_name_digital;
if (spec->dig_out_type)
info->pcm_type = spec->dig_out_type;
else
info->pcm_type = HDA_PCM_TYPE_SPDIF;
info->pcm_type = HDA_PCM_TYPE_SPDIF;
if (spec->multiout.dig_out_nid &&
spec->stream_digital_playback) {
info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
Expand All @@ -3117,9 +3102,6 @@ static int alc_build_pcms(struct hda_codec *codec)
codec->spdif_status_reset = 1;
}

if (spec->no_analog)
return 0;

/* If the use of more than one ADC is requested for the current
* model, configure a second analog capture-only PCM.
*/
Expand Down Expand Up @@ -10482,14 +10464,8 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
alc262_ignore);
if (err < 0)
return err;
if (!spec->autocfg.line_outs) {
if (spec->autocfg.dig_out_pin || spec->autocfg.dig_in_pin) {
spec->multiout.max_channels = 2;
spec->no_analog = 1;
goto dig_only;
}
if (!spec->autocfg.line_outs)
return 0; /* can't find valid BIOS pin config */
}
err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
if (err < 0)
return err;
Expand All @@ -10499,11 +10475,8 @@ static int alc262_parse_auto_config(struct hda_codec *codec)

spec->multiout.max_channels = spec->multiout.num_dacs * 2;

dig_only:
if (spec->autocfg.dig_out_pin) {
if (spec->autocfg.dig_out_pin)
spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
spec->dig_out_type = spec->autocfg.dig_out_type;
}
if (spec->autocfg.dig_in_pin)
spec->dig_in_nid = ALC262_DIGIN_NID;

Expand Down Expand Up @@ -10898,7 +10871,7 @@ static int patch_alc262(struct hda_codec *codec)
spec->capsrc_nids = alc262_capsrc_nids;
}
}
if (!spec->cap_mixer && !spec->no_analog)
if (!spec->cap_mixer)
set_capture_mixer(spec);

spec->vmaster_nid = 0x0c;
Expand Down
Loading

0 comments on commit d190829

Please sign in to comment.