Loading sound/pci/hda/hda_codec.h +5 −0 Original line number Diff line number Diff line Loading @@ -255,9 +255,13 @@ enum { * in HD-audio specification */ #define AC_PINCAP_HDMI (1<<7) /* HDMI pin */ #define AC_PINCAP_DP (1<<24) /* DisplayPort pin, can * coexist with AC_PINCAP_HDMI */ #define AC_PINCAP_VREF (0x37<<8) #define AC_PINCAP_VREF_SHIFT 8 #define AC_PINCAP_EAPD (1<<16) /* EAPD capable */ #define AC_PINCAP_HBR (1<<27) /* High Bit Rate */ /* Vref status (used in pin cap) */ #define AC_PINCAP_VREF_HIZ (1<<0) /* Hi-Z */ #define AC_PINCAP_VREF_50 (1<<1) /* 50% */ Loading Loading @@ -635,6 +639,7 @@ struct hda_bus { unsigned int rirb_error:1; /* error in codec communication */ unsigned int response_reset:1; /* controller was reset */ unsigned int in_reset:1; /* during reset operation */ unsigned int power_keep_link_on:1; /* don't power off HDA link */ }; /* Loading sound/pci/hda/hda_intel.c +2 −1 Original line number Diff line number Diff line Loading @@ -2082,7 +2082,8 @@ static void azx_power_notify(struct hda_bus *bus) } if (power_on) azx_init_chip(chip); else if (chip->running && power_save_controller) else if (chip->running && power_save_controller && !bus->power_keep_link_on) azx_stop_chip(chip); } #endif /* CONFIG_SND_HDA_POWER_SAVE */ Loading sound/pci/hda/hda_proc.c +6 −1 Original line number Diff line number Diff line Loading @@ -240,9 +240,14 @@ static void print_pin_caps(struct snd_info_buffer *buffer, /* Realtek uses this bit as a different meaning */ if ((codec->vendor_id >> 16) == 0x10ec) snd_iprintf(buffer, " R/L"); else else { if (caps & AC_PINCAP_HBR) snd_iprintf(buffer, " HBR"); snd_iprintf(buffer, " HDMI"); } } if (caps & AC_PINCAP_DP) snd_iprintf(buffer, " DP"); if (caps & AC_PINCAP_TRIG_REQ) snd_iprintf(buffer, " Trigger"); if (caps & AC_PINCAP_IMP_SENSE) Loading sound/pci/hda/patch_intelhdmi.c +86 −28 Original line number Diff line number Diff line Loading @@ -145,6 +145,42 @@ struct cea_channel_speaker_allocation { int spk_mask; }; /* * ALSA sequence is: * * surround40 surround41 surround50 surround51 surround71 * ch0 front left = = = = * ch1 front right = = = = * ch2 rear left = = = = * ch3 rear right = = = = * ch4 LFE center center center * ch5 LFE LFE * ch6 side left * ch7 side right * * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR} */ static int hdmi_channel_mapping[0x32][8] = { /* stereo */ [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 }, /* 2.1 */ [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 }, /* Dolby Surround */ [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 }, /* surround40 */ [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 }, /* 4ch */ [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 }, /* surround41 */ [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 }, /* surround50 */ [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 }, /* surround51 */ [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 }, /* 7.1 */ [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 }, }; /* * This is an ordered list! * Loading @@ -152,32 +188,36 @@ struct cea_channel_speaker_allocation { * hdmi_setup_channel_allocation(). */ static struct cea_channel_speaker_allocation channel_allocations[] = { /* channel: 8 7 6 5 4 3 2 1 */ /* channel: 7 6 5 4 3 2 1 0 */ { .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } }, /* 2.1 */ { .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } }, /* Dolby Surround */ { .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } }, /* surround40 */ { .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } }, /* surround41 */ { .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } }, /* surround50 */ { .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } }, /* surround51 */ { .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } }, /* 6.1 */ { .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } }, /* surround71 */ { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, { .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } }, { .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } }, { .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } }, { .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } }, { .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } }, { .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } }, { .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } }, { .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } }, /* 5.1 */ { .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } }, { .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } }, { .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } }, { .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } }, /* 6.1 */ { .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } }, { .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } }, { .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } }, { .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } }, /* 7.1 */ { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, { .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } }, { .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } }, { .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } }, Loading Loading @@ -210,7 +250,6 @@ static struct cea_channel_speaker_allocation channel_allocations[] = { { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, }; /* * HDA/HDMI auto parsing */ Loading Loading @@ -344,7 +383,7 @@ static int intel_hdmi_parse_codec(struct hda_codec *codec) break; case AC_WID_PIN: caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); if (!(caps & AC_PINCAP_HDMI)) if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP))) continue; if (intel_hdmi_add_pin(codec, nid) < 0) return -EINVAL; Loading @@ -352,6 +391,17 @@ static int intel_hdmi_parse_codec(struct hda_codec *codec) } } /* * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event * can be lost and presence sense verb will become inaccurate if the * HDA link is powered off at hot plug or hw initialization time. */ #ifdef CONFIG_SND_HDA_POWER_SAVE if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) & AC_PWRST_EPSS)) codec->bus->power_keep_link_on = 1; #endif return 0; } Loading Loading @@ -436,14 +486,15 @@ static void hdmi_set_channel_count(struct hda_codec *codec, AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); } static void hdmi_debug_channel_mapping(struct hda_codec *codec, hda_nid_t nid) static void hdmi_debug_channel_mapping(struct hda_codec *codec, hda_nid_t pin_nid) { #ifdef CONFIG_SND_DEBUG_VERBOSE int i; int slot; for (i = 0; i < 8; i++) { slot = snd_hda_codec_read(codec, nid, 0, slot = snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_CHAN_SLOT, i); printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n", slot >> 4, slot & 0xf); Loading Loading @@ -619,25 +670,32 @@ static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid, return ai->CA; } static void hdmi_setup_channel_mapping(struct hda_codec *codec, hda_nid_t nid, static void hdmi_setup_channel_mapping(struct hda_codec *codec, hda_nid_t pin_nid, struct hdmi_audio_infoframe *ai) { int i; int ca = ai->CA; int err; if (!ai->CA) return; /* * TODO: adjust channel mapping if necessary * ALSA sequence is front/surr/clfe/side? */ if (hdmi_channel_mapping[ca][1] == 0) { for (i = 0; i < channel_allocations[ca].channels; i++) hdmi_channel_mapping[ca][i] = i | (i << 4); for (; i < 8; i++) hdmi_channel_mapping[ca][i] = 0xf | (i << 4); } for (i = 0; i < 8; i++) snd_hda_codec_write(codec, nid, 0, for (i = 0; i < 8; i++) { err = snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_CHAN_SLOT, (i << 4) | i); hdmi_channel_mapping[ca][i]); if (err) { snd_printdd(KERN_INFO "HDMI: channel mapping failed\n"); break; } } hdmi_debug_channel_mapping(codec, nid); hdmi_debug_channel_mapping(codec, pin_nid); } static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid, Loading Loading @@ -676,7 +734,6 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, }; hdmi_setup_channel_allocation(codec, nid, &ai); hdmi_setup_channel_mapping(codec, nid, &ai); for (i = 0; i < spec->num_pins; i++) { if (spec->pin_cvt[i] != nid) Loading @@ -686,6 +743,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, pin_nid = spec->pin[i]; if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) { hdmi_setup_channel_mapping(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); Loading sound/pci/hda/patch_sigmatel.c +76 −27 Original line number Diff line number Diff line Loading @@ -209,6 +209,7 @@ struct sigmatel_spec { unsigned int gpio_data; unsigned int gpio_mute; unsigned int gpio_led; unsigned int gpio_led_polarity; /* stream */ unsigned int stream_delay; Loading Loading @@ -1538,6 +1539,13 @@ static unsigned int alienware_m17x_pin_configs[13] = { 0x904601b0, }; static unsigned int intel_dg45id_pin_configs[14] = { 0x02214230, 0x02A19240, 0x01013214, 0x01014210, 0x01A19250, 0x01011212, 0x01016211, 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x014510A0, 0x074510B0, 0x40f000f0 }; static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, Loading @@ -1545,6 +1553,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { [STAC_DELL_M6_BOTH] = dell_m6_pin_configs, [STAC_DELL_EQ] = dell_m6_pin_configs, [STAC_ALIENWARE_M17X] = alienware_m17x_pin_configs, [STAC_92HD73XX_INTEL] = intel_dg45id_pin_configs, }; static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { Loading Loading @@ -4724,13 +4733,61 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) } } static int hp_bseries_system(u32 subsystem_id) /* * This method searches for the mute LED GPIO configuration * provided as OEM string in SMBIOS. The format of that string * is HP_Mute_LED_P_G or HP_Mute_LED_P * where P can be 0 or 1 and defines mute LED GPIO control state (low/high) * that corresponds to the NOT muted state of the master volume * and G is the index of the GPIO to use as the mute LED control (0..9) * If _G portion is missing it is assigned based on the codec ID * * So, HP B-series like systems may have HP_Mute_LED_0 (current models) * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings */ static int find_mute_led_gpio(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; const struct dmi_device *dev = NULL; if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { if (sscanf(dev->name, "HP_Mute_LED_%d_%d", &spec->gpio_led_polarity, &spec->gpio_led) == 2) { spec->gpio_led = 1 << spec->gpio_led; return 1; } if (sscanf(dev->name, "HP_Mute_LED_%d", &spec->gpio_led_polarity) == 1) { switch (codec->vendor_id) { case 0x111d7608: /* GPIO 0 */ spec->gpio_led = 0x01; return 1; case 0x111d7600: case 0x111d7601: case 0x111d7602: case 0x111d7603: /* GPIO 3 */ spec->gpio_led = 0x08; return 1; } } } } return 0; } static int hp_blike_system(u32 subsystem_id) { switch (subsystem_id) { case 0x103c307e: case 0x103c307f: case 0x103c3080: case 0x103c3081: case 0x103c1520: case 0x103c1521: case 0x103c1523: case 0x103c1524: case 0x103c1525: case 0x103c1722: case 0x103c1723: case 0x103c1724: Loading @@ -4739,6 +4796,14 @@ static int hp_bseries_system(u32 subsystem_id) case 0x103c1727: case 0x103c1728: case 0x103c1729: case 0x103c172a: case 0x103c172b: case 0x103c307e: case 0x103c307f: case 0x103c3080: case 0x103c3081: case 0x103c7007: case 0x103c7008: return 1; } return 0; Loading Loading @@ -4833,7 +4898,7 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec, else spec->gpio_data |= spec->gpio_led; /* white */ if (hp_bseries_system(codec->subsystem_id)) { if (!spec->gpio_led_polarity) { /* LED state is inverted on these systems */ spec->gpio_data ^= spec->gpio_led; } Loading Loading @@ -5526,7 +5591,7 @@ again: break; } if (hp_bseries_system(codec->subsystem_id)) { if (hp_blike_system(codec->subsystem_id)) { pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f); if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER || Loading @@ -5544,26 +5609,10 @@ again: } } if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { const struct dmi_device *dev = NULL; while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { if (strcmp(dev->name, "HP_Mute_LED_1")) { switch (codec->vendor_id) { case 0x111d7608: spec->gpio_led = 0x01; break; case 0x111d7600: case 0x111d7601: case 0x111d7602: case 0x111d7603: spec->gpio_led = 0x08; break; } break; } } } if (find_mute_led_gpio(codec)) snd_printd("mute LED gpio %d polarity %d\n", spec->gpio_led, spec->gpio_led_polarity); #ifdef CONFIG_SND_HDA_POWER_SAVE if (spec->gpio_led) { Loading Loading
sound/pci/hda/hda_codec.h +5 −0 Original line number Diff line number Diff line Loading @@ -255,9 +255,13 @@ enum { * in HD-audio specification */ #define AC_PINCAP_HDMI (1<<7) /* HDMI pin */ #define AC_PINCAP_DP (1<<24) /* DisplayPort pin, can * coexist with AC_PINCAP_HDMI */ #define AC_PINCAP_VREF (0x37<<8) #define AC_PINCAP_VREF_SHIFT 8 #define AC_PINCAP_EAPD (1<<16) /* EAPD capable */ #define AC_PINCAP_HBR (1<<27) /* High Bit Rate */ /* Vref status (used in pin cap) */ #define AC_PINCAP_VREF_HIZ (1<<0) /* Hi-Z */ #define AC_PINCAP_VREF_50 (1<<1) /* 50% */ Loading Loading @@ -635,6 +639,7 @@ struct hda_bus { unsigned int rirb_error:1; /* error in codec communication */ unsigned int response_reset:1; /* controller was reset */ unsigned int in_reset:1; /* during reset operation */ unsigned int power_keep_link_on:1; /* don't power off HDA link */ }; /* Loading
sound/pci/hda/hda_intel.c +2 −1 Original line number Diff line number Diff line Loading @@ -2082,7 +2082,8 @@ static void azx_power_notify(struct hda_bus *bus) } if (power_on) azx_init_chip(chip); else if (chip->running && power_save_controller) else if (chip->running && power_save_controller && !bus->power_keep_link_on) azx_stop_chip(chip); } #endif /* CONFIG_SND_HDA_POWER_SAVE */ Loading
sound/pci/hda/hda_proc.c +6 −1 Original line number Diff line number Diff line Loading @@ -240,9 +240,14 @@ static void print_pin_caps(struct snd_info_buffer *buffer, /* Realtek uses this bit as a different meaning */ if ((codec->vendor_id >> 16) == 0x10ec) snd_iprintf(buffer, " R/L"); else else { if (caps & AC_PINCAP_HBR) snd_iprintf(buffer, " HBR"); snd_iprintf(buffer, " HDMI"); } } if (caps & AC_PINCAP_DP) snd_iprintf(buffer, " DP"); if (caps & AC_PINCAP_TRIG_REQ) snd_iprintf(buffer, " Trigger"); if (caps & AC_PINCAP_IMP_SENSE) Loading
sound/pci/hda/patch_intelhdmi.c +86 −28 Original line number Diff line number Diff line Loading @@ -145,6 +145,42 @@ struct cea_channel_speaker_allocation { int spk_mask; }; /* * ALSA sequence is: * * surround40 surround41 surround50 surround51 surround71 * ch0 front left = = = = * ch1 front right = = = = * ch2 rear left = = = = * ch3 rear right = = = = * ch4 LFE center center center * ch5 LFE LFE * ch6 side left * ch7 side right * * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR} */ static int hdmi_channel_mapping[0x32][8] = { /* stereo */ [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 }, /* 2.1 */ [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 }, /* Dolby Surround */ [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 }, /* surround40 */ [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 }, /* 4ch */ [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 }, /* surround41 */ [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 }, /* surround50 */ [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 }, /* surround51 */ [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 }, /* 7.1 */ [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 }, }; /* * This is an ordered list! * Loading @@ -152,32 +188,36 @@ struct cea_channel_speaker_allocation { * hdmi_setup_channel_allocation(). */ static struct cea_channel_speaker_allocation channel_allocations[] = { /* channel: 8 7 6 5 4 3 2 1 */ /* channel: 7 6 5 4 3 2 1 0 */ { .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } }, /* 2.1 */ { .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } }, /* Dolby Surround */ { .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } }, /* surround40 */ { .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } }, /* surround41 */ { .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } }, /* surround50 */ { .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } }, /* surround51 */ { .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } }, /* 6.1 */ { .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } }, /* surround71 */ { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, { .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } }, { .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } }, { .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } }, { .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } }, { .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } }, { .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } }, { .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } }, { .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } }, /* 5.1 */ { .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } }, { .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } }, { .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } }, { .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } }, /* 6.1 */ { .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } }, { .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } }, { .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } }, { .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } }, /* 7.1 */ { .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, { .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } }, { .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } }, { .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } }, Loading Loading @@ -210,7 +250,6 @@ static struct cea_channel_speaker_allocation channel_allocations[] = { { .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, }; /* * HDA/HDMI auto parsing */ Loading Loading @@ -344,7 +383,7 @@ static int intel_hdmi_parse_codec(struct hda_codec *codec) break; case AC_WID_PIN: caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); if (!(caps & AC_PINCAP_HDMI)) if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP))) continue; if (intel_hdmi_add_pin(codec, nid) < 0) return -EINVAL; Loading @@ -352,6 +391,17 @@ static int intel_hdmi_parse_codec(struct hda_codec *codec) } } /* * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event * can be lost and presence sense verb will become inaccurate if the * HDA link is powered off at hot plug or hw initialization time. */ #ifdef CONFIG_SND_HDA_POWER_SAVE if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) & AC_PWRST_EPSS)) codec->bus->power_keep_link_on = 1; #endif return 0; } Loading Loading @@ -436,14 +486,15 @@ static void hdmi_set_channel_count(struct hda_codec *codec, AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); } static void hdmi_debug_channel_mapping(struct hda_codec *codec, hda_nid_t nid) static void hdmi_debug_channel_mapping(struct hda_codec *codec, hda_nid_t pin_nid) { #ifdef CONFIG_SND_DEBUG_VERBOSE int i; int slot; for (i = 0; i < 8; i++) { slot = snd_hda_codec_read(codec, nid, 0, slot = snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_CHAN_SLOT, i); printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n", slot >> 4, slot & 0xf); Loading Loading @@ -619,25 +670,32 @@ static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid, return ai->CA; } static void hdmi_setup_channel_mapping(struct hda_codec *codec, hda_nid_t nid, static void hdmi_setup_channel_mapping(struct hda_codec *codec, hda_nid_t pin_nid, struct hdmi_audio_infoframe *ai) { int i; int ca = ai->CA; int err; if (!ai->CA) return; /* * TODO: adjust channel mapping if necessary * ALSA sequence is front/surr/clfe/side? */ if (hdmi_channel_mapping[ca][1] == 0) { for (i = 0; i < channel_allocations[ca].channels; i++) hdmi_channel_mapping[ca][i] = i | (i << 4); for (; i < 8; i++) hdmi_channel_mapping[ca][i] = 0xf | (i << 4); } for (i = 0; i < 8; i++) snd_hda_codec_write(codec, nid, 0, for (i = 0; i < 8; i++) { err = snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_CHAN_SLOT, (i << 4) | i); hdmi_channel_mapping[ca][i]); if (err) { snd_printdd(KERN_INFO "HDMI: channel mapping failed\n"); break; } } hdmi_debug_channel_mapping(codec, nid); hdmi_debug_channel_mapping(codec, pin_nid); } static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid, Loading Loading @@ -676,7 +734,6 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, }; hdmi_setup_channel_allocation(codec, nid, &ai); hdmi_setup_channel_mapping(codec, nid, &ai); for (i = 0; i < spec->num_pins; i++) { if (spec->pin_cvt[i] != nid) Loading @@ -686,6 +743,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, pin_nid = spec->pin[i]; if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) { hdmi_setup_channel_mapping(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); Loading
sound/pci/hda/patch_sigmatel.c +76 −27 Original line number Diff line number Diff line Loading @@ -209,6 +209,7 @@ struct sigmatel_spec { unsigned int gpio_data; unsigned int gpio_mute; unsigned int gpio_led; unsigned int gpio_led_polarity; /* stream */ unsigned int stream_delay; Loading Loading @@ -1538,6 +1539,13 @@ static unsigned int alienware_m17x_pin_configs[13] = { 0x904601b0, }; static unsigned int intel_dg45id_pin_configs[14] = { 0x02214230, 0x02A19240, 0x01013214, 0x01014210, 0x01A19250, 0x01011212, 0x01016211, 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x014510A0, 0x074510B0, 0x40f000f0 }; static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, Loading @@ -1545,6 +1553,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { [STAC_DELL_M6_BOTH] = dell_m6_pin_configs, [STAC_DELL_EQ] = dell_m6_pin_configs, [STAC_ALIENWARE_M17X] = alienware_m17x_pin_configs, [STAC_92HD73XX_INTEL] = intel_dg45id_pin_configs, }; static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { Loading Loading @@ -4724,13 +4733,61 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) } } static int hp_bseries_system(u32 subsystem_id) /* * This method searches for the mute LED GPIO configuration * provided as OEM string in SMBIOS. The format of that string * is HP_Mute_LED_P_G or HP_Mute_LED_P * where P can be 0 or 1 and defines mute LED GPIO control state (low/high) * that corresponds to the NOT muted state of the master volume * and G is the index of the GPIO to use as the mute LED control (0..9) * If _G portion is missing it is assigned based on the codec ID * * So, HP B-series like systems may have HP_Mute_LED_0 (current models) * or HP_Mute_LED_0_3 (future models) OEM SMBIOS strings */ static int find_mute_led_gpio(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; const struct dmi_device *dev = NULL; if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { if (sscanf(dev->name, "HP_Mute_LED_%d_%d", &spec->gpio_led_polarity, &spec->gpio_led) == 2) { spec->gpio_led = 1 << spec->gpio_led; return 1; } if (sscanf(dev->name, "HP_Mute_LED_%d", &spec->gpio_led_polarity) == 1) { switch (codec->vendor_id) { case 0x111d7608: /* GPIO 0 */ spec->gpio_led = 0x01; return 1; case 0x111d7600: case 0x111d7601: case 0x111d7602: case 0x111d7603: /* GPIO 3 */ spec->gpio_led = 0x08; return 1; } } } } return 0; } static int hp_blike_system(u32 subsystem_id) { switch (subsystem_id) { case 0x103c307e: case 0x103c307f: case 0x103c3080: case 0x103c3081: case 0x103c1520: case 0x103c1521: case 0x103c1523: case 0x103c1524: case 0x103c1525: case 0x103c1722: case 0x103c1723: case 0x103c1724: Loading @@ -4739,6 +4796,14 @@ static int hp_bseries_system(u32 subsystem_id) case 0x103c1727: case 0x103c1728: case 0x103c1729: case 0x103c172a: case 0x103c172b: case 0x103c307e: case 0x103c307f: case 0x103c3080: case 0x103c3081: case 0x103c7007: case 0x103c7008: return 1; } return 0; Loading Loading @@ -4833,7 +4898,7 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec, else spec->gpio_data |= spec->gpio_led; /* white */ if (hp_bseries_system(codec->subsystem_id)) { if (!spec->gpio_led_polarity) { /* LED state is inverted on these systems */ spec->gpio_data ^= spec->gpio_led; } Loading Loading @@ -5526,7 +5591,7 @@ again: break; } if (hp_bseries_system(codec->subsystem_id)) { if (hp_blike_system(codec->subsystem_id)) { pin_cfg = snd_hda_codec_get_pincfg(codec, 0x0f); if (get_defcfg_device(pin_cfg) == AC_JACK_LINE_OUT || get_defcfg_device(pin_cfg) == AC_JACK_SPEAKER || Loading @@ -5544,26 +5609,10 @@ again: } } if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { const struct dmi_device *dev = NULL; while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { if (strcmp(dev->name, "HP_Mute_LED_1")) { switch (codec->vendor_id) { case 0x111d7608: spec->gpio_led = 0x01; break; case 0x111d7600: case 0x111d7601: case 0x111d7602: case 0x111d7603: spec->gpio_led = 0x08; break; } break; } } } if (find_mute_led_gpio(codec)) snd_printd("mute LED gpio %d polarity %d\n", spec->gpio_led, spec->gpio_led_polarity); #ifdef CONFIG_SND_HDA_POWER_SAVE if (spec->gpio_led) { Loading