Пример #1
0
static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
				hda_nid_t hp)
{
	if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD)
		snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE,
			    !codec->inv_eapd ? 0x00 : 0x02);
	if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD)
		snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE,
			    !codec->inv_eapd ? 0x00 : 0x02);
}
Пример #2
0
/* parse EAPDs */
static void cx_auto_parse_eapd(struct hda_codec *codec)
{
	struct conexant_spec *spec = codec->spec;
	hda_nid_t nid, end_nid;

	end_nid = codec->start_nid + codec->num_nodes;
	for (nid = codec->start_nid; nid < end_nid; nid++) {
		if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
			continue;
		if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
			continue;
		spec->eapds[spec->num_eapds++] = nid;
		if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
			break;
	}

	/* NOTE: below is a wild guess; if we have more than two EAPDs,
	 * it's a new chip, where EAPDs are supposed to be associated to
	 * pins, and we can control EAPD per pin.
	 * OTOH, if only one or two EAPDs are found, it's an old chip,
	 * thus it might control over all pins.
	 */
	if (spec->num_eapds > 2)
		spec->dynamic_eapd = 1;
}
Пример #3
0
static void init_input(struct hda_codec *codec)
{
	struct cs_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->autocfg;
	unsigned int coef;
	int i;

	for (i = 0; i < cfg->num_inputs; i++) {
		unsigned int ctl;
		hda_nid_t pin = cfg->inputs[i].pin;
		if (!spec->adc_nid[i])
			continue;
		/* set appropriate pin control and mute first */
		ctl = PIN_IN;
		if (cfg->inputs[i].type == AUTO_PIN_MIC) {
			unsigned int caps = snd_hda_query_pin_caps(codec, pin);
			caps >>= AC_PINCAP_VREF_SHIFT;
			if (caps & AC_PINCAP_VREF_80)
				ctl = PIN_VREF80;
		}
		snd_hda_codec_write(codec, pin, 0,
				    AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
		snd_hda_codec_write(codec, spec->adc_nid[i], 0,
				    AC_VERB_SET_AMP_GAIN_MUTE,
				    AMP_IN_MUTE(spec->adc_idx[i]));
		if (spec->mic_detect && spec->automic_idx == i)
			snd_hda_codec_write(codec, pin, 0,
					    AC_VERB_SET_UNSOLICITED_ENABLE,
					    AC_USRSP_EN | MIC_EVENT);
	}
Пример #4
0
static void cs_automute(struct hda_codec *codec)
{
	struct cs_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->autocfg;
	unsigned int caps, hp_present;
	hda_nid_t nid;
	int i;

	hp_present = 0;
	for (i = 0; i < cfg->hp_outs; i++) {
		nid = cfg->hp_pins[i];
		caps = snd_hda_query_pin_caps(codec, nid);
		if (!(caps & AC_PINCAP_PRES_DETECT))
			continue;
		hp_present = snd_hda_jack_detect(codec, nid);
		if (hp_present)
			break;
	}
	for (i = 0; i < cfg->speaker_outs; i++) {
		nid = cfg->speaker_pins[i];
		snd_hda_codec_write(codec, nid, 0,
				    AC_VERB_SET_PIN_WIDGET_CONTROL,
				    hp_present ? 0 : PIN_OUT);
	}
	if (spec->board_config == CS420X_MBP55 ||
	    spec->board_config == CS420X_IMAC27) {
		unsigned int gpio = hp_present ? 0x02 : 0x08;
		snd_hda_codec_write(codec, 0x01, 0,
				    AC_VERB_SET_GPIO_DATA, gpio);
	}
}
Пример #5
0
static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
			      hda_nid_t *pins, bool on)
{
	int i;
	for (i = 0; i < num_pins; i++) {
		if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD)
			snd_hda_codec_write(codec, pins[i], 0,
					    AC_VERB_SET_EAPD_BTLENABLE,
					    on ? 0x02 : 0);
	}
}
Пример #6
0
static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
{
	struct cs_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->autocfg;
	hda_nid_t pin = cfg->input_pins[idx];
	unsigned int val = snd_hda_query_pin_caps(codec, pin);
	if (!(val & AC_PINCAP_PRES_DETECT))
		return 0;
	val = snd_hda_codec_get_pincfg(codec, pin);
	return (get_defcfg_connect(val) == AC_JACK_PORT_COMPLEX);
}
Пример #7
0
static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
{
	struct cs_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->autocfg;
	hda_nid_t pin = cfg->inputs[idx].pin;
	unsigned int val = snd_hda_query_pin_caps(codec, pin);
	if (!(val & AC_PINCAP_PRES_DETECT))
		return 0;
	val = snd_hda_codec_get_pincfg(codec, pin);
	return (snd_hda_get_input_pin_attr(val) != INPUT_PIN_ATTR_INT);
}
Пример #8
0
/* execute pin sense measurement */
static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
{
	u32 pincap;

	if (!codec->no_trigger_sense) {
		pincap = snd_hda_query_pin_caps(codec, nid);
		if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
			snd_hda_codec_read(codec, nid, 0,
					AC_VERB_SET_PIN_SENSE, 0);
	}
	return snd_hda_codec_read(codec, nid, 0,
				  AC_VERB_GET_PIN_SENSE, 0);
}
Пример #9
0
bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid)
{
    if (codec->no_jack_detect)
        return false;
    if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT))
        return false;
    if (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) &
            AC_DEFCFG_MISC_NO_PRESENCE)
        return false;
    if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
        return false;
    return true;
}
Пример #10
0
/* execute pin sense measurement */
static u32 read_pin_sense(struct hda_codec *codec, hda_nid_t nid)
{
	u32 pincap;
	u32 val;

	if (!codec->no_trigger_sense) {
		pincap = snd_hda_query_pin_caps(codec, nid);
		if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
			snd_hda_codec_read(codec, nid, 0,
					AC_VERB_SET_PIN_SENSE, 0);
	}
	val = snd_hda_codec_read(codec, nid, 0,
				  AC_VERB_GET_PIN_SENSE, 0);
	if (codec->inv_jack_detect)
		val ^= AC_PINSENSE_PRESENCE;
	return val;
}
Пример #11
0
/* check whether the given pin has a proper pin I/O capability bit */
static bool check_pincap_validity(struct hda_codec *codec, hda_nid_t pin,
				  unsigned int dev)
{
	unsigned int pincap = snd_hda_query_pin_caps(codec, pin);

	/* some old hardware don't return the proper pincaps */
	if (!pincap)
		return true;

	switch (dev) {
	case AC_JACK_LINE_OUT:
	case AC_JACK_SPEAKER:
	case AC_JACK_HP_OUT:
	case AC_JACK_SPDIF_OUT:
	case AC_JACK_DIG_OTHER_OUT:
		return !!(pincap & AC_PINCAP_OUT);
	default:
		return !!(pincap & AC_PINCAP_IN);
	}
}
Пример #12
0
static void cs_automic(struct hda_codec *codec)
{
	struct cs_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->autocfg;
	hda_nid_t nid;
	unsigned int caps, present;
	
	nid = cfg->input_pins[spec->automic_idx];
	caps = snd_hda_query_pin_caps(codec, nid);
	if (caps & AC_PINCAP_TRIG_REQ)
		snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
	present = snd_hda_codec_read(codec, nid, 0,
				     AC_VERB_GET_PIN_SENSE, 0);
	if (present & AC_PINSENSE_PRESENCE)
		change_cur_input(codec, spec->automic_idx, 0);
	else {
		unsigned int imic = (spec->automic_idx == AUTO_PIN_MIC) ?
			AUTO_PIN_FRONT_MIC : AUTO_PIN_MIC;
		change_cur_input(codec, imic, 0);
	}
}