Exemplo n.º 1
0
static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
			 const struct auto_pin_cfg *cfg,
			 const char *base_name)
{
	unsigned int def_conf, conn;
	char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
	int idx, err;
	bool phantom_jack;

	if (!nid)
		return 0;
	def_conf = snd_hda_codec_get_pincfg(codec, nid);
	conn = get_defcfg_connect(def_conf);
	if (conn == AC_JACK_PORT_NONE)
		return 0;
	phantom_jack = (conn != AC_JACK_PORT_COMPLEX) ||
		       !is_jack_detectable(codec, nid);

	if (base_name) {
		strlcpy(name, base_name, sizeof(name));
		idx = 0;
	} else
		snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
	if (phantom_jack)
		/* Example final name: "Internal Mic Phantom Jack" */
		strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
	idx = get_unique_index(codec, name, idx);
	err = __snd_hda_jack_add_kctl(codec, nid, name, idx, phantom_jack);
	if (err < 0)
		return err;

	if (!phantom_jack)
		return snd_hda_jack_detect_enable(codec, nid);
	return 0;
}
Exemplo n.º 2
0
static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
			 const struct auto_pin_cfg *cfg,
			 char *lastname, int *lastidx)
{
	unsigned int def_conf, conn;
	char name[44];
	int idx, err;

	if (!nid)
		return 0;
	if (!is_jack_detectable(codec, nid))
		return 0;
	def_conf = snd_hda_codec_get_pincfg(codec, nid);
	conn = get_defcfg_connect(def_conf);
	if (conn != AC_JACK_PORT_COMPLEX)
		return 0;

	snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
	if (!strcmp(name, lastname) && idx == *lastidx)
		idx++;
	strncpy(lastname, name, 44);
	*lastidx = idx;
	err = snd_hda_jack_add_kctl(codec, nid, name, idx);
	if (err < 0)
		return err;
	return snd_hda_jack_detect_enable(codec, nid, 0);
}
Exemplo n.º 3
0
static void cs_automute(struct hda_codec *codec)
{
	struct cs_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->autocfg;
	unsigned int hp_present;
	hda_nid_t nid;
	int i;

	hp_present = 0;
	for (i = 0; i < cfg->hp_outs; i++) {
		nid = cfg->hp_pins[i];
		if (!is_jack_detectable(codec, nid))
			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_MBP53 ||
	    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);
	}
}
Exemplo n.º 4
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;
	if (!is_jack_detectable(codec, pin))
		return 0;
	val = snd_hda_codec_get_pincfg(codec, pin);
	return (snd_hda_get_input_pin_attr(val) != INPUT_PIN_ATTR_INT);
}
Exemplo n.º 5
0
static void init_output(struct hda_codec *codec)
{
	struct cs_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->autocfg;
	int i;

	/* mute first */
	for (i = 0; i < spec->multiout.num_dacs; i++)
		snd_hda_codec_write(codec, spec->multiout.dac_nids[i], 0,
				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
	if (spec->multiout.hp_nid)
		snd_hda_codec_write(codec, spec->multiout.hp_nid, 0,
				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
	for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) {
		if (!spec->multiout.extra_out_nid[i])
			break;
		snd_hda_codec_write(codec, spec->multiout.extra_out_nid[i], 0,
				    AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
	}

	/* set appropriate pin controls */
	for (i = 0; i < cfg->line_outs; i++)
		snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
	for (i = 0; i < cfg->hp_outs; i++) {
		hda_nid_t nid = cfg->hp_pins[i];
		snd_hda_codec_write(codec, nid, 0,
				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
		if (!cfg->speaker_outs)
			continue;
		if (is_jack_detectable(codec, nid)) {
			snd_hda_codec_write(codec, nid, 0,
					    AC_VERB_SET_UNSOLICITED_ENABLE,
					    AC_USRSP_EN | HP_EVENT);
			spec->hp_detect = 1;
		}
	}
	for (i = 0; i < cfg->speaker_outs; i++)
		snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
				    AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
	if (spec->hp_detect)
		cs_automute(codec);
}
Exemplo n.º 6
0
static void cs_automute(struct hda_codec *codec)
{
	struct cs_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->autocfg;
	unsigned int hp_present;
	unsigned int spdif_present;
	hda_nid_t nid;
	int i;

	spdif_present = 0;
	if (cfg->dig_outs) {
		nid = cfg->dig_out_pins[0];
		if (is_jack_detectable(codec, nid)) {
			/*
			TODO: SPDIF output redirect when SENSE_B is enabled.
			Shared (SENSE_A) jack (e.g HP/mini-TOSLINK)
			assumed.
			*/
			if (snd_hda_jack_detect(codec, nid)
				/* && spec->sense_b */)
				spdif_present = 1;
		}
	}

	hp_present = 0;
	for (i = 0; i < cfg->hp_outs; i++) {
		nid = cfg->hp_pins[i];
		if (!is_jack_detectable(codec, nid))
			continue;
		hp_present = snd_hda_jack_detect(codec, nid);
		if (hp_present)
			break;
	}

	/* mute speakers if spdif or hp jack is plugged in */
	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);
		/* detect on spdif is specific to CS421x */
		if (spec->vendor_nid == CS421X_VENDOR_NID) {
			snd_hda_codec_write(codec, nid, 0,
					AC_VERB_SET_PIN_WIDGET_CONTROL,
					spdif_present ? 0 : PIN_OUT);
		}
	}
	if (spec->board_config == CS420X_MBP53 ||
	    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);
	}

	/* specific to CS421x */
	if (spec->vendor_nid == CS421X_VENDOR_NID) {
		/* mute HPs if spdif jack (SENSE_B) is present */
		for (i = 0; i < cfg->hp_outs; i++) {
			nid = cfg->hp_pins[i];
			snd_hda_codec_write(codec, nid, 0,
				AC_VERB_SET_PIN_WIDGET_CONTROL,
				(spdif_present && spec->sense_b) ? 0 : PIN_HP);
		}

		/* SPDIF TX on/off */
		if (cfg->dig_outs) {
			nid = cfg->dig_out_pins[0];
			snd_hda_codec_write(codec, nid, 0,
				AC_VERB_SET_PIN_WIDGET_CONTROL,
				spdif_present ? PIN_OUT : 0);

		}
		/* Update board GPIOs if neccessary ... */
	}
}