/* 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);
}
static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
{
	snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0,
			    AC_VERB_SET_COEF_INDEX, idx);
	return snd_hda_codec_read(codec, CS420X_VENDOR_NID, 0,
				  AC_VERB_GET_PROC_COEF, 0);
}
Exemple #3
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;
}
Exemple #4
0
static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
{
	struct cs_spec *spec = codec->spec;
	snd_hda_codec_write(codec, spec->vendor_nid, 0,
			    AC_VERB_SET_COEF_INDEX, idx);
	return snd_hda_codec_read(codec, spec->vendor_nid, 0,
				  AC_VERB_GET_PROC_COEF, 0);
}
/* mute internal speaker if HP is plugged */
static void cxt5045_hp_automute(struct hda_codec *codec)
{
	struct conexant_spec *spec = codec->spec;
	unsigned int bits;

	spec->hp_present = snd_hda_codec_read(codec, 0x11, 0,
				     AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;

	bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0;
	snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits);
	snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits);
}
Exemple #6
0
static unsigned int hdmi_get_eld_data(struct hda_codec *codec, hda_nid_t nid,
					int byte_index)
{
	unsigned int val;

	val = snd_hda_codec_read(codec, nid, 0,
					AC_VERB_GET_HDMI_ELDD, byte_index);
#ifdef BE_PARANOID
	printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val);
#endif
	return val;
}
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);
	}
}
static int cxt_spdif_ctrl_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 & 0xffff;
	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
	long *valp = ucontrol->value.integer.value;
	unsigned int val = snd_hda_codec_read(codec, nid, 0,
					      AC_VERB_GET_DIGI_CONVERT, 0x00);

	*valp = (val & mask) != 0;
	return 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, present, 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;
		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);
		hp_present |= (present & AC_PINSENSE_PRESENCE) != 0;
		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);
	}
}
/* Chip access helper function */
static int chipio_send(struct hda_codec *codec,
		       unsigned int reg,
		       unsigned int data)
{
	unsigned int res;
	int retry = 50;

	/* send bits of data specified by reg */
	do {
		res = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
					 reg, data);
		if (res == VENDOR_STATUS_CHIPIO_OK)
			return 0;
	} while (--retry);
	return -EIO;
}
static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid,
					int byte_index)
{
	unsigned int val;

	val = snd_hda_codec_read(codec, nid, 0,
					AC_VERB_GET_HDMI_ELDD, byte_index);

#ifdef BE_PARANOID
	printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val);
#endif

	if ((val & AC_ELDD_ELD_VALID) == 0) {
		snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n",
								byte_index);
		val = 0;
	}

	return val & AC_ELDD_ELD_DATA;
}
/* toggle input of built-in and mic jack appropriately */
static void cxt5045_hp_automic(struct hda_codec *codec)
{
    static struct hda_verb mic_jack_on[] = {
        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
        {}
    };
    static struct hda_verb mic_jack_off[] = {
        {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
        {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
        {}
    };
    unsigned int present;

    present = snd_hda_codec_read(codec, 0x12, 0,
                                 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
    if (present)
        snd_hda_sequence_write(codec, mic_jack_on);
    else
        snd_hda_sequence_write(codec, mic_jack_off);
}
static int cxt_gpio_data_put(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 & 0xffff;
	unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
	long val = *ucontrol->value.integer.value;
	unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
						    AC_VERB_GET_GPIO_DATA,
						    0x00);
	unsigned int old_data = gpio_data;

	/* Set/unset the masked GPIO bit(s) as needed */
	if (val == 0)
		gpio_data &= ~mask;
	else
		gpio_data |= mask;
	if (gpio_data == old_data && !codec->in_resume)
		return 0;
	snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
	return 1;
}
Exemple #14
0
static int patch_cmi9880(struct hda_codec *codec)
{
    struct cmi_spec *spec;

    spec = kzalloc(sizeof(*spec), GFP_KERNEL);
    if (spec == NULL)
        return -ENOMEM;

    codec->spec = spec;
    spec->board_config = snd_hda_check_board_config(codec, CMI_MODELS,
                            cmi9880_models,
                            cmi9880_cfg_tbl);
    if (spec->board_config < 0) {
        snd_printdd(KERN_INFO "hda_codec: Unknown model for CMI9880\n");
        spec->board_config = CMI_AUTO; /* try everything */
    }

    /* copy default DAC NIDs */
    memcpy(spec->dac_nids, cmi9880_dac_nids, sizeof(spec->dac_nids));
    spec->num_dacs = 4;

    switch (spec->board_config) {
    case CMI_MINIMAL:
    case CMI_MIN_FP:
        spec->channel_modes = cmi9880_channel_modes;
        if (spec->board_config == CMI_MINIMAL)
            spec->num_channel_modes = 2;
        else {
            spec->front_panel = 1;
            spec->num_channel_modes = 3;
        }
        spec->multiout.max_channels = cmi9880_channel_modes[0].channels;
        spec->input_mux = &cmi9880_basic_mux;
        break;
    case CMI_FULL:
    case CMI_FULL_DIG:
        spec->front_panel = 1;
        spec->multiout.max_channels = 8;
        spec->input_mux = &cmi9880_basic_mux;
        if (spec->board_config == CMI_FULL_DIG) {
            spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
            spec->dig_in_nid = CMI_DIG_IN_NID;
        }
        break;
    case CMI_ALLOUT:
        spec->front_panel = 1;
        spec->multiout.max_channels = 8;
        spec->no_line_in = 1;
        spec->input_mux = &cmi9880_no_line_mux;
        spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
        break;
    case CMI_AUTO:
        {
        unsigned int port_e, port_f, port_g, port_h;
        unsigned int port_spdifi, port_spdifo;
        struct auto_pin_cfg cfg;

        /* collect pin default configuration */
        port_e = snd_hda_codec_read(codec, 0x0f, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
        port_f = snd_hda_codec_read(codec, 0x10, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
        spec->front_panel = 1;
        if (get_defcfg_connect(port_e) == AC_JACK_PORT_NONE ||
            get_defcfg_connect(port_f) == AC_JACK_PORT_NONE) {
            port_g = snd_hda_codec_read(codec, 0x1f, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
            port_h = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
            spec->channel_modes = cmi9880_channel_modes;
            /* no front panel */
            if (get_defcfg_connect(port_g) == AC_JACK_PORT_NONE ||
                get_defcfg_connect(port_h) == AC_JACK_PORT_NONE) {
                /* no optional rear panel */
                spec->board_config = CMI_MINIMAL;
                spec->front_panel = 0;
                spec->num_channel_modes = 2;
            } else {
                spec->board_config = CMI_MIN_FP;
                spec->num_channel_modes = 3;
            }
            spec->input_mux = &cmi9880_basic_mux;
            spec->multiout.max_channels = cmi9880_channel_modes[0].channels;
        } else {
            spec->input_mux = &cmi9880_basic_mux;
            port_spdifi = snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
            port_spdifo = snd_hda_codec_read(codec, 0x12, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
            if (get_defcfg_connect(port_spdifo) != AC_JACK_PORT_NONE)
                spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
            if (get_defcfg_connect(port_spdifi) != AC_JACK_PORT_NONE)
                spec->dig_in_nid = CMI_DIG_IN_NID;
            spec->multiout.max_channels = 8;
        }
        snd_hda_parse_pin_def_config(codec, &cfg, NULL);
        if (cfg.line_outs) {
            spec->multiout.max_channels = cfg.line_outs * 2;
            cmi9880_fill_multi_dac_nids(codec, &cfg);
            cmi9880_fill_multi_init(codec, &cfg);
        } else
            snd_printd("patch_cmedia: cannot detect association in defcfg\n");
        break;
        }
    }

    spec->multiout.num_dacs = spec->num_dacs;
    spec->multiout.dac_nids = spec->dac_nids;

    spec->adc_nids = cmi9880_adc_nids;

    codec->patch_ops = cmi9880_patch_ops;

    return 0;
}
int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
{
	return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
						 AC_DIPSIZE_ELD_BUF);
}
static int hdmi_present_sense(struct hda_codec *codec, hda_nid_t nid)
{
	return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0);
}