[alsa-devel] [PATCH 00/10] Intel HDMI fixes v2
Takashi,
Here are the updated Intel HDMI fixes.
Thanks, Fengguang
Reported-by: David Härdeman david@hardeman.nu Signed-off-by: Wu Fengguang fengguang.wu@intel.com --- sound/pci/hda/patch_intelhdmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-11-02 15:14:30.000000000 +0800 +++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-11-02 15:14:39.000000000 +0800 @@ -509,12 +509,12 @@ static void hdmi_fill_audio_infoframe(st hdmi_debug_dip_size(codec, pin_nid); hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
- for (i = 0; i < sizeof(ai); i++) + for (i = 0; i < sizeof(*ai); i++) sum += params[i]; ai->checksum = - sum;
hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0); - for (i = 0; i < sizeof(ai); i++) + for (i = 0; i < sizeof(*ai); i++) hdmi_write_dip_byte(codec, pin_nid, params[i]); }
Signed-off-by: Wu Fengguang fengguang.wu@intel.com --- sound/pci/hda/patch_intelhdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-11-02 15:14:39.000000000 +0800 +++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-11-02 15:14:46.000000000 +0800 @@ -433,7 +433,7 @@ static void hdmi_debug_channel_mapping(s slot = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_CHAN_SLOT, i); printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n", - slot >> 4, slot & 0x7); + slot >> 4, slot & 0xf); } #endif }
Signed-off-by: Wu Fengguang fengguang.wu@intel.com --- sound/pci/hda/hda_eld.c | 8 +++++++- sound/pci/hda/hda_local.h | 4 +++- sound/pci/hda/patch_intelhdmi.c | 8 +++----- 3 files changed, 13 insertions(+), 7 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-11-02 15:17:26.000000000 +0800 +++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-11-02 15:18:47.000000000 +0800 @@ -62,8 +62,6 @@ struct intel_hdmi_spec { /* * HDMI sink attached to each pin */ - bool sink_present[INTEL_HDMI_PINS]; - bool sink_eldv[INTEL_HDMI_PINS]; struct hdmi_eld sink_eld[INTEL_HDMI_PINS];
/* @@ -645,7 +643,7 @@ static void hdmi_setup_audio_infoframe(s for (i = 0; i < spec->num_pins; i++) { if (spec->pin_cvt[i] != nid) continue; - if (spec->sink_present[i] != true) + if (!spec->sink_eld[i].monitor_present) continue;
pin_nid = spec->pin[i]; @@ -675,8 +673,8 @@ static void hdmi_intrinsic_event(struct if (index < 0) return;
- spec->sink_present[index] = pind; - spec->sink_eldv[index] = eldv; + spec->sink_eld[index].monitor_present = pind; + spec->sink_eld[index].eld_valid = eldv;
if (pind && eldv) { hdmi_parse_eld(codec, index); --- sound-2.6.orig/sound/pci/hda/hda_eld.c 2009-11-02 15:14:30.000000000 +0800 +++ sound-2.6/sound/pci/hda/hda_eld.c 2009-11-02 15:24:04.000000000 +0800 @@ -477,6 +477,8 @@ static void hdmi_print_eld_info(struct s [4 ... 7] = "reserved" };
+ snd_iprintf(buffer, "monitor_present\t\t%d\n", e->monitor_present); + snd_iprintf(buffer, "eld_valid\t\t%d\n", e->eld_valid); snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); snd_iprintf(buffer, "connection_type\t\t%s\n", eld_connection_type_names[e->conn_type]); @@ -518,7 +520,11 @@ static void hdmi_write_eld_info(struct s * monitor_name manufacture_id product_id * eld_version edid_version */ - if (!strcmp(name, "connection_type")) + if (!strcmp(name, "monitor_present")) + e->monitor_present = val; + else if (!strcmp(name, "eld_valid")) + e->eld_valid = val; + else if (!strcmp(name, "connection_type")) e->conn_type = val; else if (!strcmp(name, "port_id")) e->port_id = val; --- sound-2.6.orig/sound/pci/hda/hda_local.h 2009-11-02 15:14:30.000000000 +0800 +++ sound-2.6/sound/pci/hda/hda_local.h 2009-11-02 15:21:11.000000000 +0800 @@ -516,9 +516,11 @@ struct cea_sad { * ELD: EDID Like Data */ struct hdmi_eld { + bool monitor_present; + bool eld_valid; int eld_size; int baseline_len; - int eld_ver; /* (eld_ver == 0) indicates invalid ELD */ + int eld_ver; int cea_edid_ver; char monitor_name[ELD_MAX_MNL + 1]; int manufacture_id;
This helps merge duplicate code.
v2: add snd_hda_jack_detect() and comments recommended by Takashi.
Signed-off-by: Wu Fengguang fengguang.wu@intel.com --- sound/pci/hda/hda_codec.c | 34 +++++ sound/pci/hda/hda_eld.c | 7 - sound/pci/hda/hda_local.h | 2 sound/pci/hda/patch_cirrus.c | 19 -- sound/pci/hda/patch_realtek.c | 206 +++++++------------------------- 5 files changed, 91 insertions(+), 177 deletions(-)
--- sound-2.6.orig/sound/pci/hda/hda_codec.c 2009-11-18 10:00:11.000000000 +0800 +++ sound-2.6/sound/pci/hda/hda_codec.c 2009-11-18 12:29:42.000000000 +0800 @@ -1229,6 +1229,40 @@ u32 snd_hda_query_pin_caps(struct hda_co } EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps);
+/** + * snd_hda_pin_sense - execute pin sense measurement + * @codec: the CODEC to sense + * @nid: the pin NID to sense + * + * Execute necessary pin sense measurement and return its Presence Detect, + * Impedance, ELD Valid etc. status bits. + */ +u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid) +{ + u32 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); +} +EXPORT_SYMBOL_HDA(snd_hda_pin_sense); + +/** + * snd_hda_jack_detect - query pin Presence Detect status + * @codec: the CODEC to sense + * @nid: the pin NID to sense + * + * Query and return the pin's Presence Detect status. + */ +int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) +{ + u32 sense = snd_hda_pin_sense(codec, nid); + return !!(sense & AC_PINSENSE_PRESENCE); +} +EXPORT_SYMBOL_HDA(snd_hda_jack_detect); + /* * read the current volume to info * if the cache exists, read the cache value. --- sound-2.6.orig/sound/pci/hda/hda_local.h 2009-11-18 10:00:15.000000000 +0800 +++ sound-2.6/sound/pci/hda/hda_local.h 2009-11-18 10:02:28.000000000 +0800 @@ -424,6 +424,8 @@ u32 query_amp_caps(struct hda_codec *cod int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, unsigned int caps); u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid); +u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); +int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid);
int snd_hda_ctl_add(struct hda_codec *codec, struct snd_kcontrol *kctl); void snd_hda_ctls_clear(struct hda_codec *codec); --- sound-2.6.orig/sound/pci/hda/patch_realtek.c 2009-11-18 10:00:11.000000000 +0800 +++ sound-2.6/sound/pci/hda/patch_realtek.c 2009-11-18 10:27:08.000000000 +0800 @@ -961,16 +961,10 @@ static void alc_fix_pll_init(struct hda_ static void alc_automute_pin(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int present, pincap; unsigned int nid = spec->autocfg.hp_pins[0]; int i;
- 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); - present = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; + spec->jack_present = snd_hda_jack_detect(codec, nid); for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { nid = spec->autocfg.speaker_pins[i]; if (!nid) @@ -1010,9 +1004,7 @@ static void alc_mic_automute(struct hda_
cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
- present = snd_hda_codec_read(codec, spec->ext_mic.pin, 0, - AC_VERB_GET_PIN_SENSE, 0); - present &= AC_PINSENSE_PRESENCE; + present = snd_hda_jack_detect(codec, spec->ext_mic.pin); if (present) { alive = &spec->ext_mic; dead = &spec->int_mic; @@ -1511,7 +1503,7 @@ static struct hda_verb alc888_fujitsu_xa static void alc_automute_amp(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int val, mute, pincap; + unsigned int mute; hda_nid_t nid; int i;
@@ -1520,13 +1512,7 @@ static void alc_automute_amp(struct hda_ nid = spec->autocfg.hp_pins[i]; if (!nid) break; - 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 (val & AC_PINSENSE_PRESENCE) { + if (snd_hda_jack_detect(codec, nid)) { spec->jack_present = 1; break; } @@ -2777,8 +2763,7 @@ static void alc880_uniwill_mic_automute( unsigned int present; unsigned char bits;
- present = snd_hda_codec_read(codec, 0x18, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + present = snd_hda_jack_detect(codec, 0x18); bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); } @@ -5089,11 +5074,8 @@ static struct hda_verb alc260_hp_unsol_v static void alc260_hp_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int present;
- present = snd_hda_codec_read(codec, 0x10, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; + spec->jack_present = snd_hda_jack_detect(codec, 0x10); alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); }
@@ -5158,11 +5140,8 @@ static struct hda_verb alc260_hp_3013_un static void alc260_hp_3013_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int present;
- present = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; + spec->jack_present = snd_hda_jack_detect(codec, 0x15); alc260_hp_master_update(codec, 0x15, 0x10, 0x11); }
@@ -5175,12 +5154,8 @@ static void alc260_hp_3013_unsol_event(s
static void alc260_hp_3012_automute(struct hda_codec *codec) { - unsigned int present, bits; - - present = snd_hda_codec_read(codec, 0x10, 0, - AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE; + unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT;
- bits = present ? 0 : PIN_OUT; snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, bits); snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, @@ -5750,8 +5725,7 @@ static void alc260_replacer_672v_automut unsigned int present;
/* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ - present = snd_hda_codec_read(codec, 0x0f, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + present = snd_hda_jack_detect(codec, 0x0f); if (present) { snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1); @@ -8183,12 +8157,8 @@ static void alc883_mitac_setup(struct hd /* static void alc883_mitac_mic_automute(struct hda_codec *codec) { - unsigned int present; - unsigned char bits; + unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
- present = snd_hda_codec_read(codec, 0x18, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); } */ @@ -8410,10 +8380,8 @@ static struct hda_channel_mode alc888_3s /* toggle front-jack and RCA according to the hp-jack state */ static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) { - unsigned int present; + unsigned int present = snd_hda_jack_detect(codec, 0x1b);
- present = snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, @@ -8423,10 +8391,8 @@ static void alc888_lenovo_ms7195_front_a /* toggle RCA according to the front-jack state */ static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) { - unsigned int present; + unsigned int present = snd_hda_jack_detect(codec, 0x14);
- present = snd_hda_codec_read(codec, 0x14, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); } @@ -8519,24 +8485,16 @@ static void alc883_haier_w66_setup(struc
static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) { - unsigned int present; - unsigned char bits; + int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0;
- present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; - bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits); }
static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) { - unsigned int present; - unsigned char bits; + int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0;
- present = snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, @@ -8687,8 +8645,7 @@ static void alc889A_mb31_automute(struct /* Mute only in 2ch or 4ch mode */ if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0) == 0x00) { - present = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE; + present = snd_hda_jack_detect(codec, 0x15); snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, @@ -10030,10 +9987,8 @@ static void alc262_hp_master_update(stru static void alc262_hp_bpc_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int presence; - presence = snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE); + + spec->jack_present = snd_hda_jack_detect(codec, 0x1b); alc262_hp_master_update(codec); }
@@ -10047,10 +10002,8 @@ static void alc262_hp_bpc_unsol_event(st static void alc262_hp_wildwest_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int presence; - presence = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = !!(presence & AC_PINSENSE_PRESENCE); + + spec->jack_present = snd_hda_jack_detect(codec, 0x15); alc262_hp_master_update(codec); }
@@ -10284,13 +10237,8 @@ static void alc262_hippo_automute(struct { struct alc_spec *spec = codec->spec; hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; - unsigned int present;
- /* need to execute and sync at first */ - snd_hda_codec_read(codec, hp_nid, 0, AC_VERB_SET_PIN_SENSE, 0); - present = snd_hda_codec_read(codec, hp_nid, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = (present & 0x80000000) != 0; + spec->jack_present = snd_hda_jack_detect(codec, hp_nid); alc262_hippo_master_update(codec); }
@@ -10616,21 +10564,8 @@ static void alc262_fujitsu_automute(stru unsigned int mute;
if (force || !spec->sense_updated) { - unsigned int present; - /* need to execute and sync at first */ - snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); - /* check laptop HP jack */ - present = snd_hda_codec_read(codec, 0x14, 0, - AC_VERB_GET_PIN_SENSE, 0); - /* need to execute and sync at first */ - snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); - /* check docking HP jack */ - present |= snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0); - if (present & AC_PINSENSE_PRESENCE) - spec->jack_present = 1; - else - spec->jack_present = 0; + spec->jack_present = snd_hda_jack_detect(codec, 0x14) || + snd_hda_jack_detect(codec, 0x1b); spec->sense_updated = 1; } /* unmute internal speaker only if both HPs are unplugged and @@ -10675,12 +10610,7 @@ static void alc262_lenovo_3000_automute( unsigned int mute;
if (force || !spec->sense_updated) { - unsigned int present_int_hp; - /* need to execute and sync at first */ - snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); - present_int_hp = snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = (present_int_hp & 0x80000000) != 0; + spec->jack_present = snd_hda_jack_detect(codec, 0x1b); spec->sense_updated = 1; } if (spec->jack_present) { @@ -10872,12 +10802,7 @@ static void alc262_ultra_automute(struct mute = 0; /* auto-mute only when HP is used as HP */ if (!spec->cur_mux[0]) { - unsigned int present; - /* need to execute and sync at first */ - snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); - present = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; + spec->jack_present = snd_hda_jack_detect(codec, 0x15); if (spec->jack_present) mute = HDA_AMP_MUTE; } @@ -11915,10 +11840,7 @@ static void alc268_acer_automute(struct unsigned int mute;
if (force || !spec->sense_updated) { - unsigned int present; - present = snd_hda_codec_read(codec, 0x14, 0, - AC_VERB_GET_PIN_SENSE, 0); - spec->jack_present = (present & 0x80000000) != 0; + spec->jack_present = snd_hda_jack_detect(codec, 0x14); spec->sense_updated = 1; } if (spec->jack_present) @@ -12037,8 +11959,7 @@ static void alc268_aspire_one_speaker_au unsigned int present; unsigned char bits;
- present = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + present = snd_hda_jack_detect(codec, 0x15); bits = present ? AMP_IN_MUTE(0) : 0; snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, AMP_IN_MUTE(0), bits); @@ -13020,8 +12941,7 @@ static void alc269_quanta_fl1_speaker_au unsigned int present; unsigned char bits;
- present = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + present = snd_hda_jack_detect(codec, 0x15); bits = present ? AMP_IN_MUTE(0) : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, AMP_IN_MUTE(0), bits); @@ -13046,12 +12966,10 @@ static void alc269_lifebook_speaker_auto unsigned char bits;
/* Check laptop headphone socket */ - present = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + present = snd_hda_jack_detect(codec, 0x15);
/* Check port replicator headphone socket */ - present |= snd_hda_codec_read(codec, 0x1a, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + present |= snd_hda_jack_detect(codec, 0x1a);
bits = present ? AMP_IN_MUTE(0) : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, @@ -13075,11 +12993,8 @@ static void alc269_lifebook_mic_autoswit unsigned int present_laptop; unsigned int present_dock;
- present_laptop = snd_hda_codec_read(codec, 0x18, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - - present_dock = snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + present_laptop = snd_hda_jack_detect(codec, 0x18); + present_dock = snd_hda_jack_detect(codec, 0x1b);
/* Laptop mic port overrides dock mic port, design decision */ if (present_dock) @@ -13164,8 +13079,7 @@ static void alc269_speaker_automute(stru unsigned int present; unsigned char bits;
- present = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + present = snd_hda_jack_detect(codec, 0x15); bits = present ? AMP_IN_MUTE(0) : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, AMP_IN_MUTE(0), bits); @@ -14143,10 +14057,8 @@ static struct hda_verb alc861_toshiba_in /* toggle speaker-output according to the hp-jack state */ static void alc861_toshiba_automute(struct hda_codec *codec) { - unsigned int present; + unsigned int present = snd_hda_jack_detect(codec, 0x0f);
- present = snd_hda_codec_read(codec, 0x0f, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, @@ -15051,9 +14963,9 @@ static void alc861vd_lenovo_mic_automute unsigned int present; unsigned char bits;
- present = snd_hda_codec_read(codec, 0x18, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + present = snd_hda_jack_detect(codec, 0x18); bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); } @@ -16364,9 +16276,9 @@ static void alc662_lenovo_101e_ispeaker_ unsigned int present; unsigned char bits;
- present = snd_hda_codec_read(codec, 0x14, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + present = snd_hda_jack_detect(codec, 0x14); bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits); } @@ -16376,9 +16288,9 @@ static void alc662_lenovo_101e_all_autom unsigned int present; unsigned char bits;
- present = snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + present = snd_hda_jack_detect(codec, 0x1b); bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits); snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, @@ -16437,9 +16349,7 @@ static void alc663_m51va_speaker_automut unsigned int present; unsigned char bits;
- present = snd_hda_codec_read(codec, 0x21, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; + present = snd_hda_jack_detect(codec, 0x21); bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, AMP_IN_MUTE(0), bits); @@ -16452,9 +16362,7 @@ static void alc663_21jd_two_speaker_auto unsigned int present; unsigned char bits;
- present = snd_hda_codec_read(codec, 0x21, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; + present = snd_hda_jack_detect(codec, 0x21); bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, AMP_IN_MUTE(0), bits); @@ -16471,9 +16379,7 @@ static void alc663_15jd_two_speaker_auto unsigned int present; unsigned char bits;
- present = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; + present = snd_hda_jack_detect(codec, 0x15); bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, AMP_IN_MUTE(0), bits); @@ -16490,9 +16396,7 @@ static void alc662_f5z_speaker_automute( unsigned int present; unsigned char bits;
- present = snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; + present = snd_hda_jack_detect(codec, 0x1b); bits = present ? 0 : PIN_OUT; snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, bits); @@ -16502,12 +16406,8 @@ static void alc663_two_hp_m1_speaker_aut { unsigned int present1, present2;
- present1 = snd_hda_codec_read(codec, 0x21, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; - present2 = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; + present1 = snd_hda_jack_detect(codec, 0x21); + present2 = snd_hda_jack_detect(codec, 0x15);
if (present1 || present2) { snd_hda_codec_write_cache(codec, 0x14, 0, @@ -16522,12 +16422,8 @@ static void alc663_two_hp_m2_speaker_aut { unsigned int present1, present2;
- present1 = snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; - present2 = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; + present1 = snd_hda_jack_detect(codec, 0x1b); + present2 = snd_hda_jack_detect(codec, 0x15);
if (present1 || present2) { snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, @@ -16687,9 +16583,7 @@ static void alc663_g71v_hp_automute(stru unsigned int present; unsigned char bits;
- present = snd_hda_codec_read(codec, 0x21, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; + present = snd_hda_jack_detect(codec, 0x21); bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits); @@ -16702,9 +16596,7 @@ static void alc663_g71v_front_automute(s unsigned int present; unsigned char bits;
- present = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; + present = snd_hda_jack_detect(codec, 0x15); bits = present ? HDA_AMP_MUTE : 0; snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, HDA_AMP_MUTE, bits); --- sound-2.6.orig/sound/pci/hda/patch_cirrus.c 2009-11-18 10:00:11.000000000 +0800 +++ sound-2.6/sound/pci/hda/patch_cirrus.c 2009-11-18 12:27:34.000000000 +0800 @@ -807,7 +807,7 @@ static void cs_automute(struct hda_codec { struct cs_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; - unsigned int caps, present, hp_present; + unsigned int caps, hp_present; hda_nid_t nid; int i;
@@ -817,12 +817,7 @@ static void cs_automute(struct hda_codec 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; + hp_present = snd_hda_jack_detect(codec, nid); if (hp_present) break; } @@ -844,15 +839,11 @@ static void cs_automic(struct hda_codec struct cs_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; hda_nid_t nid; - unsigned int caps, present; + unsigned int 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) + present = snd_hda_jack_detect(codec, nid); + if (present) change_cur_input(codec, spec->automic_idx, 0); else { unsigned int imic = (spec->automic_idx == AUTO_PIN_MIC) ? --- sound-2.6.orig/sound/pci/hda/hda_eld.c 2009-11-18 10:00:15.000000000 +0800 +++ sound-2.6/sound/pci/hda/hda_eld.c 2009-11-18 10:00:15.000000000 +0800 @@ -309,17 +309,12 @@ out_fail: return -EINVAL; }
-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); -} - static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid) { int eldv; int present;
- present = hdmi_present_sense(codec, nid); + present = snd_hda_pin_sense(codec, nid); eldv = (present & AC_PINSENSE_ELDV); present = (present & AC_PINSENSE_PRESENCE);
This avoids lost of presence info on module reloading. The presence info used to be only updated at the (rare) hotplug events.
Proposed by David, thanks!
CC: David Härdeman david@hardeman.nu Signed-off-by: Wu Fengguang fengguang.wu@intel.com --- sound/pci/hda/patch_intelhdmi.c | 33 ++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-11-02 15:44:26.000000000 +0800 +++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-11-02 15:47:43.000000000 +0800 @@ -259,6 +259,25 @@ static int intel_hdmi_read_pin_conn(stru return 0; }
+static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid, + struct hdmi_eld *eld) +{ + if (!snd_hdmi_get_eld(eld, codec, pin_nid)) + snd_hdmi_show_eld(eld); +} + +static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, + struct hdmi_eld *eld) +{ + int present = snd_hda_pin_sense(codec, pin_nid); + + eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); + eld->eld_valid = !!(present & AC_PINSENSE_ELDV); + + if (present & AC_PINSENSE_ELDV) + hdmi_get_show_eld(codec, pin_nid, eld); +} + static int intel_hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) { struct intel_hdmi_spec *spec = codec->spec; @@ -269,6 +288,8 @@ static int intel_hdmi_add_pin(struct hda return -EINVAL; }
+ hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]); + spec->pin[spec->num_pins] = pin_nid; spec->num_pins++;
@@ -436,15 +457,6 @@ static void hdmi_debug_channel_mapping(s #endif }
-static void hdmi_parse_eld(struct hda_codec *codec, int index) -{ - struct intel_hdmi_spec *spec = codec->spec; - struct hdmi_eld *eld = &spec->sink_eld[index]; - - if (!snd_hdmi_get_eld(eld, codec, spec->pin[index])) - snd_hdmi_show_eld(eld); -} -
/* * Audio InfoFrame routines @@ -677,7 +690,7 @@ static void hdmi_intrinsic_event(struct spec->sink_eld[index].eld_valid = eldv;
if (pind && eldv) { - hdmi_parse_eld(codec, index); + hdmi_get_show_eld(codec, spec->pin[index], &spec->sink_eld[index]); /* TODO: do real things about ELD */ } }
At Wed, 18 Nov 2009 12:38:03 +0800, Wu Fengguang wrote:
This avoids lost of presence info on module reloading. The presence info used to be only updated at the (rare) hotplug events.
Proposed by David, thanks!
CC: David Härdeman david@hardeman.nu Signed-off-by: Wu Fengguang fengguang.wu@intel.com
I think we should handle this also at resume. Typically, the codec resume callback calls the unsolicited event explicitly.
But, the resume callback can be used for resuming from the power-saving mode, too. Thus it should be optimized and less verbose, e.g. cache the ELD bytes, compare the new data with the cached data, and skip the procedure if it's the same content.
Anyway, all patches have been applied, so let's fix this on the current tree.
thanks,
Takashi
sound/pci/hda/patch_intelhdmi.c | 33 ++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-11-02 15:44:26.000000000 +0800 +++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-11-02 15:47:43.000000000 +0800 @@ -259,6 +259,25 @@ static int intel_hdmi_read_pin_conn(stru return 0; }
+static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
struct hdmi_eld *eld)
+{
- if (!snd_hdmi_get_eld(eld, codec, pin_nid))
snd_hdmi_show_eld(eld);
+}
+static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
struct hdmi_eld *eld)
+{
- int present = snd_hda_pin_sense(codec, pin_nid);
- eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
- eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
- if (present & AC_PINSENSE_ELDV)
hdmi_get_show_eld(codec, pin_nid, eld);
+}
static int intel_hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) { struct intel_hdmi_spec *spec = codec->spec; @@ -269,6 +288,8 @@ static int intel_hdmi_add_pin(struct hda return -EINVAL; }
- hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
- spec->pin[spec->num_pins] = pin_nid; spec->num_pins++;
@@ -436,15 +457,6 @@ static void hdmi_debug_channel_mapping(s #endif }
-static void hdmi_parse_eld(struct hda_codec *codec, int index) -{
- struct intel_hdmi_spec *spec = codec->spec;
- struct hdmi_eld *eld = &spec->sink_eld[index];
- if (!snd_hdmi_get_eld(eld, codec, spec->pin[index]))
snd_hdmi_show_eld(eld);
-}
/*
- Audio InfoFrame routines
@@ -677,7 +690,7 @@ static void hdmi_intrinsic_event(struct spec->sink_eld[index].eld_valid = eldv;
if (pind && eldv) {
hdmi_parse_eld(codec, index);
/* TODO: do real things about ELD */ }hdmi_get_show_eld(codec, spec->pin[index], &spec->sink_eld[index]);
}
On Wed, Nov 18, 2009 at 05:04:20PM +0800, Takashi Iwai wrote:
At Wed, 18 Nov 2009 12:38:03 +0800, Wu Fengguang wrote:
This avoids lost of presence info on module reloading. The presence info used to be only updated at the (rare) hotplug events.
Proposed by David, thanks!
CC: David Härdeman david@hardeman.nu Signed-off-by: Wu Fengguang fengguang.wu@intel.com
I think we should handle this also at resume. Typically, the codec resume callback calls the unsolicited event explicitly.
But, the resume callback can be used for resuming from the power-saving mode, too. Thus it should be optimized and less verbose, e.g. cache the ELD bytes, compare the new data with the cached data, and skip the procedure if it's the same content.
Anyway, all patches have been applied, so let's fix this on the current tree.
OK, thanks for the tips. Actually I have not tested suspend/resume yet, I will do it next week. Currently I have some pending items (that's why I have to put off the keep-power-on patch).
Thanks, Fengguang
And make it right when called for more than one times.
Signed-off-by: Wu Fengguang fengguang.wu@intel.com --- sound/pci/hda/patch_intelhdmi.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-11-02 16:11:22.000000000 +0800 +++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-11-02 16:27:42.000000000 +0800 @@ -508,24 +508,35 @@ static void hdmi_clear_dip_buffers(struc #endif }
+static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai) +{ + u8 *bytes = (u8 *)ai; + u8 sum = 0; + int i; + + ai->checksum = 0; + + for (i = 0; i < sizeof(*ai); i++) + sum += bytes[i]; + + ai->checksum = - sum; +} + static void hdmi_fill_audio_infoframe(struct hda_codec *codec, hda_nid_t pin_nid, struct hdmi_audio_infoframe *ai) { - u8 *params = (u8 *)ai; - u8 sum = 0; + u8 *bytes = (u8 *)ai; int i;
hdmi_debug_dip_size(codec, pin_nid); hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
- for (i = 0; i < sizeof(*ai); i++) - sum += params[i]; - ai->checksum = - sum; + hdmi_checksum_audio_infoframe(ai);
hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0); for (i = 0; i < sizeof(*ai); i++) - hdmi_write_dip_byte(codec, pin_nid, params[i]); + hdmi_write_dip_byte(codec, pin_nid, bytes[i]); }
/*
Remember the active infoframe, so as to avoid stop/restart infoframe transmission when switching between audio clips of the same format.
Proposed by Shang and David.
CC: Shane W shane-alsa@csy.ca CC: David Härdeman david@hardeman.nu Signed-off-by: Wu Fengguang fengguang.wu@intel.com --- sound/pci/hda/patch_intelhdmi.c | 38 ++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 12 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-11-05 13:52:12.000000000 +0800 +++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-11-05 13:56:58.000000000 +0800 @@ -646,6 +646,27 @@ static void hdmi_setup_channel_mapping(s hdmi_debug_channel_mapping(codec, nid); }
+static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid, + struct hdmi_audio_infoframe *ai) +{ + u8 *bytes = (u8 *)ai; + u8 val; + int i; + + if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0) + != AC_DIPXMIT_BEST) + return false; + + hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0); + for (i = 0; i < sizeof(*ai); i++) { + val = snd_hda_codec_read(codec, pin_nid, 0, + AC_VERB_GET_HDMI_DIP_DATA, 0); + if (val != bytes[i]) + return false; + } + + return true; +}
static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, struct snd_pcm_substream *substream) @@ -670,8 +691,11 @@ static void hdmi_setup_audio_infoframe(s continue;
pin_nid = spec->pin[i]; - hdmi_fill_audio_infoframe(codec, pin_nid, &ai); - hdmi_start_infoframe_trans(codec, pin_nid); + if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) { + hdmi_stop_infoframe_trans(codec, pin_nid); + hdmi_fill_audio_infoframe(codec, pin_nid, &ai); + hdmi_start_infoframe_trans(codec, pin_nid); + } } }
@@ -767,16 +791,6 @@ static int intel_hdmi_playback_pcm_clean struct hda_codec *codec, struct snd_pcm_substream *substream) { - struct intel_hdmi_spec *spec = codec->spec; - int i; - - for (i = 0; i < spec->num_pins; i++) { - if (spec->pin_cvt[i] != hinfo->nid) - continue; - - hdmi_stop_infoframe_trans(codec, spec->pin[i]); - } - snd_hda_codec_cleanup_stream(codec, hinfo->nid); return 0; }
We tracked down the first-0.5s-hdmi-audio-samples-lost problem to the AC_VERB_SET_CHANNEL_STREAMID command. It is suspected that many HDMI sinks need some time to adapt to the new state.
The workaround is to avoid changing stream id/format whenever possible. Proposed by David.
Signed-off-by: David Härdeman david@hardeman.nu Signed-off-by: Wu Fengguang fengguang.wu@intel.com --- sound/pci/hda/patch_intelhdmi.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-11-05 13:56:58.000000000 +0800 +++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-11-05 13:58:05.000000000 +0800 @@ -772,6 +772,31 @@ static void intel_hdmi_unsol_event(struc * Callbacks */
+static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, + u32 stream_tag, int format) +{ + int tag; + int fmt; + + tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4; + fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0); + + snd_printdd("hdmi_setup_stream: " + "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n", + nid, + tag == stream_tag ? "" : "new-", + stream_tag, + fmt == format ? "" : "new-", + format); + + if (tag != stream_tag) + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_CHANNEL_STREAMID, stream_tag << 4); + if (fmt != format) + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_STREAM_FORMAT, format); +} + static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, struct hda_codec *codec, unsigned int stream_tag, @@ -783,7 +808,7 @@ static int intel_hdmi_playback_pcm_prepa
hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
- snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format); + hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); return 0; }
@@ -791,7 +816,6 @@ static int intel_hdmi_playback_pcm_clean struct hda_codec *codec, struct snd_pcm_substream *substream) { - snd_hda_codec_cleanup_stream(codec, hinfo->nid); return 0; }
Don't change channel count if not necessary.
Signed-off-by: Wu Fengguang fengguang.wu@intel.com --- sound/pci/hda/patch_intelhdmi.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-11-05 16:48:43.000000000 +0800 +++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-11-05 16:49:22.000000000 +0800 @@ -422,24 +422,18 @@ static void hdmi_stop_infoframe_trans(st AC_DIPXMIT_DISABLE); }
-#ifdef CONFIG_SND_DEBUG_VERBOSE static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid) { return 1 + snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CVT_CHAN_COUNT, 0); } -#endif
static void hdmi_set_channel_count(struct hda_codec *codec, hda_nid_t nid, int chs) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); - -#ifdef CONFIG_SND_DEBUG_VERBOSE if (chs != hdmi_get_channel_count(codec, nid)) - snd_printd(KERN_INFO "HDMI channel count: expect %d, get %d\n", - chs, hdmi_get_channel_count(codec, nid)); -#endif + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); }
static void hdmi_debug_channel_mapping(struct hda_codec *codec, hda_nid_t nid)
Signed-off-by: Wu Fengguang fengguang.wu@intel.com --- sound/pci/hda/hda_codec.h | 4 ++++ sound/pci/hda/hda_proc.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+)
--- sound-2.6.orig/sound/pci/hda/hda_codec.h 2009-11-15 19:28:28.000000000 +0800 +++ sound-2.6/sound/pci/hda/hda_codec.h 2009-11-15 19:28:57.000000000 +0800 @@ -286,6 +286,10 @@ enum { #define AC_PWRST_D1SUP (1<<1) #define AC_PWRST_D2SUP (1<<2) #define AC_PWRST_D3SUP (1<<3) +#define AC_PWRST_D3COLDSUP (1<<4) +#define AC_PWRST_S3D3COLDSUP (1<<29) +#define AC_PWRST_CLKSTOP (1<<30) +#define AC_PWRST_EPSS (1U<<31)
/* Power state values */ #define AC_PWRST_SETTING (0xf<<0) --- sound-2.6.orig/sound/pci/hda/hda_proc.c 2009-11-15 19:28:28.000000000 +0800 +++ sound-2.6/sound/pci/hda/hda_proc.c 2009-11-15 19:31:44.000000000 +0800 @@ -26,6 +26,21 @@ #include "hda_codec.h" #include "hda_local.h"
+static char *bits_names(unsigned int bits, char *names[], int size) +{ + int i, n; + static char buf[128]; + + for (i = 0, n = 0; i < size; i++) { + if (bits & (1U<<i) && names[i]) + n += snprintf(buf + n, sizeof(buf) - n, " %s", + names[i]); + } + buf[n] = '\0'; + + return buf; +} + static const char *get_wid_type_name(unsigned int wid_value) { static char *names[16] = { @@ -363,8 +378,24 @@ static const char *get_pwr_state(u32 sta static void print_power_state(struct snd_info_buffer *buffer, struct hda_codec *codec, hda_nid_t nid) { + static char *names[] = { + [ilog2(AC_PWRST_D0SUP)] = "D0", + [ilog2(AC_PWRST_D1SUP)] = "D1", + [ilog2(AC_PWRST_D2SUP)] = "D2", + [ilog2(AC_PWRST_D3SUP)] = "D3", + [ilog2(AC_PWRST_D3COLDSUP)] = "D3cold", + [ilog2(AC_PWRST_S3D3COLDSUP)] = "S3D3cold", + [ilog2(AC_PWRST_CLKSTOP)] = "CLKSTOP", + [ilog2(AC_PWRST_EPSS)] = "EPSS", + }; + + int sup = snd_hda_param_read(codec, nid, AC_PAR_POWER_STATE); int pwr = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_POWER_STATE, 0); + if (sup) + snd_iprintf(buffer, " Power states: %s\n", + bits_names(sup, names, ARRAY_SIZE(names))); + snd_iprintf(buffer, " Power: setting=%s, actual=%s\n", get_pwr_state(pwr & AC_PWRST_SETTING), get_pwr_state((pwr & AC_PWRST_ACTUAL) >>
At Wed, 18 Nov 2009 12:58:24 +0800, Wu Fengguang wrote:
On Wed, Nov 18, 2009 at 12:37:58PM +0800, Wu, Fengguang wrote:
Takashi,
Here are the updated Intel HDMI fixes.
- removed the keep-power-on patch (need more investigation)
- added snd_hda_jack_detect()
- added comments to snd_hda_jack_detect()/snd_hda_pin_sense()
Thanks for quick fixes. Now applied all patches.
Takashi
participants (2)
-
Takashi Iwai
-
Wu Fengguang