Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 148438
b: refs/heads/master
c: 7c922de
h: refs/heads/master
v: v3
  • Loading branch information
Nickolas Lloyd authored and Takashi Iwai committed Jun 1, 2009
1 parent d9894ff commit fd15dca
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 80 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: a3d6ab9723060e8d67e28a8d9142e6d08953d07b
refs/heads/master: 7c922de709b90badc19705e4f998e6d5b44c419b
219 changes: 140 additions & 79 deletions trunk/sound/pci/hda/patch_sigmatel.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,62 +670,6 @@ static unsigned int stac92xx_vref_get(struct hda_codec *codec, hda_nid_t nid)
return vref;
}

static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int new_vref;
unsigned int error;

if (ucontrol->value.enumerated.item[0] == 0)
new_vref = AC_PINCTL_VREF_80;
else if (ucontrol->value.enumerated.item[0] == 1)
new_vref = AC_PINCTL_VREF_GRD;
else
new_vref = AC_PINCTL_VREF_HIZ;

if (new_vref != stac92xx_vref_get(codec, kcontrol->private_value)) {
error = stac92xx_vref_set(codec,
kcontrol->private_value, new_vref);
return error;
}

return 0;
}

static int stac92xx_dc_bias_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int vref = stac92xx_vref_get(codec, kcontrol->private_value);
if (vref == AC_PINCTL_VREF_80)
ucontrol->value.enumerated.item[0] = 0;
else if (vref == AC_PINCTL_VREF_GRD)
ucontrol->value.enumerated.item[0] = 1;
else if (vref == AC_PINCTL_VREF_HIZ)
ucontrol->value.enumerated.item[0] = 2;

return 0;
}

static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
static char *texts[] = {
"Mic In", "Line In", "Line Out"
};

uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->value.enumerated.items = 3;
uinfo->count = 1;
if (uinfo->value.enumerated.item >= 3)
uinfo->value.enumerated.item = 2;
strcpy(uinfo->value.enumerated.name,
texts[uinfo->value.enumerated.item]);

return 0;
}

static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
Expand Down Expand Up @@ -2652,7 +2596,8 @@ static int stac92xx_build_pcms(struct hda_codec *codec)
return 0;
}

static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid)
static unsigned int stac92xx_get_default_vref(struct hda_codec *codec,
hda_nid_t nid)
{
unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
Expand Down Expand Up @@ -2706,25 +2651,118 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
return 1;
}

#define stac92xx_io_switch_info snd_ctl_boolean_mono_info
static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
int i;
static char *texts[] = {
"Mic In", "Line In", "Line Out"
};

struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct sigmatel_spec *spec = codec->spec;
hda_nid_t nid = kcontrol->private_value;

if (nid == spec->mic_switch || nid == spec->line_switch)
i = 3;
else
i = 2;

uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->value.enumerated.items = i;
uinfo->count = 1;
if (uinfo->value.enumerated.item >= i)
uinfo->value.enumerated.item = i-1;
strcpy(uinfo->value.enumerated.name,
texts[uinfo->value.enumerated.item]);

return 0;
}

static int stac92xx_dc_bias_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
hda_nid_t nid = kcontrol->private_value;
unsigned int vref = stac92xx_vref_get(codec, nid);

if (vref == stac92xx_get_default_vref(codec, nid))
ucontrol->value.enumerated.item[0] = 0;
else if (vref == AC_PINCTL_VREF_GRD)
ucontrol->value.enumerated.item[0] = 1;
else if (vref == AC_PINCTL_VREF_HIZ)
ucontrol->value.enumerated.item[0] = 2;

return 0;
}

static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
unsigned int new_vref = 0;
unsigned int error;
hda_nid_t nid = kcontrol->private_value;

if (ucontrol->value.enumerated.item[0] == 0)
new_vref = stac92xx_get_default_vref(codec, nid);
else if (ucontrol->value.enumerated.item[0] == 1)
new_vref = AC_PINCTL_VREF_GRD;
else if (ucontrol->value.enumerated.item[0] == 2)
new_vref = AC_PINCTL_VREF_HIZ;
else
return 0;

if (new_vref != stac92xx_vref_get(codec, nid)) {
error = stac92xx_vref_set(codec, nid, new_vref);
return error;
}

return 0;
}

static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
static char *texts[2];
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct sigmatel_spec *spec = codec->spec;

if (kcontrol->private_value == spec->line_switch)
texts[0] = "Line In";
else
texts[0] = "Mic In";
texts[1] = "Line Out";
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
uinfo->value.enumerated.items = 2;
uinfo->count = 1;

if (uinfo->value.enumerated.item >= 2)
uinfo->value.enumerated.item = 1;
strcpy(uinfo->value.enumerated.name,
texts[uinfo->value.enumerated.item]);

return 0;
}

static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct sigmatel_spec *spec = codec->spec;
int io_idx = kcontrol-> private_value & 0xff;
hda_nid_t nid = kcontrol->private_value;
int io_idx = (nid == spec->mic_switch) ? 1 : 0;

ucontrol->value.integer.value[0] = spec->io_switch[io_idx];
ucontrol->value.enumerated.item[0] = spec->io_switch[io_idx];
return 0;
}

static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct sigmatel_spec *spec = codec->spec;
hda_nid_t nid = kcontrol->private_value >> 8;
int io_idx = kcontrol-> private_value & 0xff;
unsigned short val = !!ucontrol->value.integer.value[0];
hda_nid_t nid = kcontrol->private_value;
int io_idx = (nid == spec->mic_switch) ? 1 : 0;
unsigned short val = !!ucontrol->value.enumerated.item[0];

spec->io_switch[io_idx] = val;

Expand All @@ -2733,7 +2771,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
else {
unsigned int pinctl = AC_PINCTL_IN_EN;
if (io_idx) /* set VREF for mic */
pinctl |= stac92xx_get_vref(codec, nid);
pinctl |= stac92xx_get_default_vref(codec, nid);
stac92xx_auto_set_pinctl(codec, nid, pinctl);
}

Expand Down Expand Up @@ -2891,6 +2929,34 @@ static struct snd_kcontrol_new stac_input_src_temp = {
.put = stac92xx_mux_enum_put,
};

static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec,
hda_nid_t nid, int idx)
{
int def_conf = snd_hda_codec_get_pincfg(codec, nid);
int control = 0;
struct sigmatel_spec *spec = codec->spec;
char name[22];

if (!((get_defcfg_connect(def_conf)) & AC_JACK_PORT_FIXED)) {
if (stac92xx_get_default_vref(codec, nid) == AC_PINCTL_VREF_GRD
&& nid == spec->line_switch)
control = STAC_CTL_WIDGET_IO_SWITCH;
else if (snd_hda_query_pin_caps(codec, nid)
& (AC_PINCAP_VREF_GRD << AC_PINCAP_VREF_SHIFT))
control = STAC_CTL_WIDGET_DC_BIAS;
else if (nid == spec->mic_switch)
control = STAC_CTL_WIDGET_IO_SWITCH;
}

if (control) {
strcpy(name, auto_pin_cfg_labels[idx]);
return stac92xx_add_control(codec->spec, control,
strcat(name, " Jack Mode"), nid);
}

return 0;
}

static int stac92xx_add_input_source(struct sigmatel_spec *spec)
{
struct snd_kcontrol_new *knew;
Expand Down Expand Up @@ -3253,7 +3319,9 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
const struct auto_pin_cfg *cfg)
{
struct sigmatel_spec *spec = codec->spec;
hda_nid_t nid;
int err;
int idx;

err = create_multi_out_ctls(codec, cfg->line_outs, cfg->line_out_pins,
spec->multiout.dac_nids,
Expand All @@ -3270,20 +3338,13 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
return err;
}

if (spec->line_switch) {
err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH,
"Line In as Output Switch",
spec->line_switch << 8);
if (err < 0)
return err;
}

if (spec->mic_switch) {
err = stac92xx_add_control(spec, STAC_CTL_WIDGET_DC_BIAS,
"Mic Jack Mode",
spec->mic_switch);
if (err < 0)
return err;
for (idx = AUTO_PIN_MIC; idx <= AUTO_PIN_FRONT_LINE; idx++) {
nid = cfg->input_pins[idx];
if (nid) {
err = stac92xx_add_jack_mode_control(codec, nid, idx);
if (err < 0)
return err;
}
}

return 0;
Expand Down Expand Up @@ -4193,7 +4254,7 @@ static int stac92xx_init(struct hda_codec *codec)
unsigned int pinctl, conf;
if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {
/* for mic pins, force to initialize */
pinctl = stac92xx_get_vref(codec, nid);
pinctl = stac92xx_get_default_vref(codec, nid);
pinctl |= AC_PINCTL_IN_EN;
stac92xx_auto_set_pinctl(codec, nid, pinctl);
} else {
Expand Down

0 comments on commit fd15dca

Please sign in to comment.