173cd0490STakashi Iwai // SPDX-License-Identifier: GPL-2.0-or-later 273cd0490STakashi Iwai /* 373cd0490STakashi Iwai * Legacy Nvidia HDMI codec support 473cd0490STakashi Iwai */ 573cd0490STakashi Iwai 673cd0490STakashi Iwai #include <linux/init.h> 773cd0490STakashi Iwai #include <linux/slab.h> 873cd0490STakashi Iwai #include <linux/module.h> 973cd0490STakashi Iwai #include <sound/core.h> 1073cd0490STakashi Iwai #include <sound/hdaudio.h> 1173cd0490STakashi Iwai #include <sound/hda_codec.h> 1273cd0490STakashi Iwai #include "hda_local.h" 1373cd0490STakashi Iwai #include "hdmi_local.h" 1473cd0490STakashi Iwai 15*ad781b55STakashi Iwai enum { MODEL_2CH, MODEL_8CH }; 16*ad781b55STakashi Iwai 1773cd0490STakashi Iwai #define Nv_VERB_SET_Channel_Allocation 0xF79 1873cd0490STakashi Iwai #define Nv_VERB_SET_Info_Frame_Checksum 0xF7A 1973cd0490STakashi Iwai #define Nv_VERB_SET_Audio_Protection_On 0xF98 2073cd0490STakashi Iwai #define Nv_VERB_SET_Audio_Protection_Off 0xF99 2173cd0490STakashi Iwai 2273cd0490STakashi Iwai #define nvhdmi_master_con_nid_7x 0x04 2373cd0490STakashi Iwai #define nvhdmi_master_pin_nid_7x 0x05 2473cd0490STakashi Iwai 2573cd0490STakashi Iwai static const hda_nid_t nvhdmi_con_nids_7x[4] = { 2673cd0490STakashi Iwai /*front, rear, clfe, rear_surr */ 2773cd0490STakashi Iwai 0x6, 0x8, 0xa, 0xc, 2873cd0490STakashi Iwai }; 2973cd0490STakashi Iwai 3073cd0490STakashi Iwai static const struct hda_verb nvhdmi_basic_init_7x_2ch[] = { 3173cd0490STakashi Iwai /* set audio protect on */ 3273cd0490STakashi Iwai { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, 3373cd0490STakashi Iwai /* enable digital output on pin widget */ 3473cd0490STakashi Iwai { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, 3573cd0490STakashi Iwai {} /* terminator */ 3673cd0490STakashi Iwai }; 3773cd0490STakashi Iwai 3873cd0490STakashi Iwai static const struct hda_verb nvhdmi_basic_init_7x_8ch[] = { 3973cd0490STakashi Iwai /* set audio protect on */ 4073cd0490STakashi Iwai { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, 4173cd0490STakashi Iwai /* enable digital output on pin widget */ 4273cd0490STakashi Iwai { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, 4373cd0490STakashi Iwai { 0x7, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, 4473cd0490STakashi Iwai { 0x9, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, 4573cd0490STakashi Iwai { 0xb, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, 4673cd0490STakashi Iwai { 0xd, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, 4773cd0490STakashi Iwai {} /* terminator */ 4873cd0490STakashi Iwai }; 4973cd0490STakashi Iwai 50*ad781b55STakashi Iwai static int nvhdmi_mcp_init(struct hda_codec *codec) 5173cd0490STakashi Iwai { 52*ad781b55STakashi Iwai struct hdmi_spec *spec = codec->spec; 5373cd0490STakashi Iwai 54*ad781b55STakashi Iwai if (spec->multiout.max_channels == 2) 55*ad781b55STakashi Iwai snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_2ch); 56*ad781b55STakashi Iwai else 5773cd0490STakashi Iwai snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_8ch); 5873cd0490STakashi Iwai return 0; 5973cd0490STakashi Iwai } 6073cd0490STakashi Iwai 6173cd0490STakashi Iwai static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec, 6273cd0490STakashi Iwai int channels) 6373cd0490STakashi Iwai { 6473cd0490STakashi Iwai unsigned int chanmask; 6573cd0490STakashi Iwai int chan = channels ? (channels - 1) : 1; 6673cd0490STakashi Iwai 6773cd0490STakashi Iwai switch (channels) { 6873cd0490STakashi Iwai default: 6973cd0490STakashi Iwai case 0: 7073cd0490STakashi Iwai case 2: 7173cd0490STakashi Iwai chanmask = 0x00; 7273cd0490STakashi Iwai break; 7373cd0490STakashi Iwai case 4: 7473cd0490STakashi Iwai chanmask = 0x08; 7573cd0490STakashi Iwai break; 7673cd0490STakashi Iwai case 6: 7773cd0490STakashi Iwai chanmask = 0x0b; 7873cd0490STakashi Iwai break; 7973cd0490STakashi Iwai case 8: 8073cd0490STakashi Iwai chanmask = 0x13; 8173cd0490STakashi Iwai break; 8273cd0490STakashi Iwai } 8373cd0490STakashi Iwai 8473cd0490STakashi Iwai /* Set the audio infoframe channel allocation and checksum fields. The 8573cd0490STakashi Iwai * channel count is computed implicitly by the hardware. 8673cd0490STakashi Iwai */ 8773cd0490STakashi Iwai snd_hda_codec_write(codec, 0x1, 0, 8873cd0490STakashi Iwai Nv_VERB_SET_Channel_Allocation, chanmask); 8973cd0490STakashi Iwai 9073cd0490STakashi Iwai snd_hda_codec_write(codec, 0x1, 0, 9173cd0490STakashi Iwai Nv_VERB_SET_Info_Frame_Checksum, 9273cd0490STakashi Iwai (0x71 - chan - chanmask)); 9373cd0490STakashi Iwai } 9473cd0490STakashi Iwai 9573cd0490STakashi Iwai static int nvhdmi_8ch_7x_pcm_close(struct hda_pcm_stream *hinfo, 9673cd0490STakashi Iwai struct hda_codec *codec, 9773cd0490STakashi Iwai struct snd_pcm_substream *substream) 9873cd0490STakashi Iwai { 9973cd0490STakashi Iwai struct hdmi_spec *spec = codec->spec; 10073cd0490STakashi Iwai int i; 10173cd0490STakashi Iwai 10273cd0490STakashi Iwai snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 10373cd0490STakashi Iwai 0, AC_VERB_SET_CHANNEL_STREAMID, 0); 10473cd0490STakashi Iwai for (i = 0; i < 4; i++) { 10573cd0490STakashi Iwai /* set the stream id */ 10673cd0490STakashi Iwai snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0, 10773cd0490STakashi Iwai AC_VERB_SET_CHANNEL_STREAMID, 0); 10873cd0490STakashi Iwai /* set the stream format */ 10973cd0490STakashi Iwai snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0, 11073cd0490STakashi Iwai AC_VERB_SET_STREAM_FORMAT, 0); 11173cd0490STakashi Iwai } 11273cd0490STakashi Iwai 11373cd0490STakashi Iwai /* The audio hardware sends a channel count of 0x7 (8ch) when all the 11473cd0490STakashi Iwai * streams are disabled. 11573cd0490STakashi Iwai */ 11673cd0490STakashi Iwai nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8); 11773cd0490STakashi Iwai 11873cd0490STakashi Iwai return snd_hda_multi_out_dig_close(codec, &spec->multiout); 11973cd0490STakashi Iwai } 12073cd0490STakashi Iwai 12173cd0490STakashi Iwai static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, 12273cd0490STakashi Iwai struct hda_codec *codec, 12373cd0490STakashi Iwai unsigned int stream_tag, 12473cd0490STakashi Iwai unsigned int format, 12573cd0490STakashi Iwai struct snd_pcm_substream *substream) 12673cd0490STakashi Iwai { 12773cd0490STakashi Iwai int chs; 12873cd0490STakashi Iwai unsigned int dataDCC2, channel_id; 12973cd0490STakashi Iwai int i; 13073cd0490STakashi Iwai struct hdmi_spec *spec = codec->spec; 13173cd0490STakashi Iwai struct hda_spdif_out *spdif; 13273cd0490STakashi Iwai struct hdmi_spec_per_cvt *per_cvt; 13373cd0490STakashi Iwai 13473cd0490STakashi Iwai mutex_lock(&codec->spdif_mutex); 13573cd0490STakashi Iwai per_cvt = get_cvt(spec, 0); 13673cd0490STakashi Iwai spdif = snd_hda_spdif_out_of_nid(codec, per_cvt->cvt_nid); 13773cd0490STakashi Iwai 13873cd0490STakashi Iwai chs = substream->runtime->channels; 13973cd0490STakashi Iwai 14073cd0490STakashi Iwai dataDCC2 = 0x2; 14173cd0490STakashi Iwai 14273cd0490STakashi Iwai /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 14373cd0490STakashi Iwai if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE)) 14473cd0490STakashi Iwai snd_hda_codec_write(codec, 14573cd0490STakashi Iwai nvhdmi_master_con_nid_7x, 14673cd0490STakashi Iwai 0, 14773cd0490STakashi Iwai AC_VERB_SET_DIGI_CONVERT_1, 14873cd0490STakashi Iwai spdif->ctls & ~AC_DIG1_ENABLE & 0xff); 14973cd0490STakashi Iwai 15073cd0490STakashi Iwai /* set the stream id */ 15173cd0490STakashi Iwai snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0, 15273cd0490STakashi Iwai AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0); 15373cd0490STakashi Iwai 15473cd0490STakashi Iwai /* set the stream format */ 15573cd0490STakashi Iwai snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0, 15673cd0490STakashi Iwai AC_VERB_SET_STREAM_FORMAT, format); 15773cd0490STakashi Iwai 15873cd0490STakashi Iwai /* turn on again (if needed) */ 15973cd0490STakashi Iwai /* enable and set the channel status audio/data flag */ 16073cd0490STakashi Iwai if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE)) { 16173cd0490STakashi Iwai snd_hda_codec_write(codec, 16273cd0490STakashi Iwai nvhdmi_master_con_nid_7x, 16373cd0490STakashi Iwai 0, 16473cd0490STakashi Iwai AC_VERB_SET_DIGI_CONVERT_1, 16573cd0490STakashi Iwai spdif->ctls & 0xff); 16673cd0490STakashi Iwai snd_hda_codec_write(codec, 16773cd0490STakashi Iwai nvhdmi_master_con_nid_7x, 16873cd0490STakashi Iwai 0, 16973cd0490STakashi Iwai AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); 17073cd0490STakashi Iwai } 17173cd0490STakashi Iwai 17273cd0490STakashi Iwai for (i = 0; i < 4; i++) { 17373cd0490STakashi Iwai if (chs == 2) 17473cd0490STakashi Iwai channel_id = 0; 17573cd0490STakashi Iwai else 17673cd0490STakashi Iwai channel_id = i * 2; 17773cd0490STakashi Iwai 17873cd0490STakashi Iwai /* turn off SPDIF once; 17973cd0490STakashi Iwai *otherwise the IEC958 bits won't be updated 18073cd0490STakashi Iwai */ 18173cd0490STakashi Iwai if (codec->spdif_status_reset && 18273cd0490STakashi Iwai (spdif->ctls & AC_DIG1_ENABLE)) 18373cd0490STakashi Iwai snd_hda_codec_write(codec, 18473cd0490STakashi Iwai nvhdmi_con_nids_7x[i], 18573cd0490STakashi Iwai 0, 18673cd0490STakashi Iwai AC_VERB_SET_DIGI_CONVERT_1, 18773cd0490STakashi Iwai spdif->ctls & ~AC_DIG1_ENABLE & 0xff); 18873cd0490STakashi Iwai /* set the stream id */ 18973cd0490STakashi Iwai snd_hda_codec_write(codec, 19073cd0490STakashi Iwai nvhdmi_con_nids_7x[i], 19173cd0490STakashi Iwai 0, 19273cd0490STakashi Iwai AC_VERB_SET_CHANNEL_STREAMID, 19373cd0490STakashi Iwai (stream_tag << 4) | channel_id); 19473cd0490STakashi Iwai /* set the stream format */ 19573cd0490STakashi Iwai snd_hda_codec_write(codec, 19673cd0490STakashi Iwai nvhdmi_con_nids_7x[i], 19773cd0490STakashi Iwai 0, 19873cd0490STakashi Iwai AC_VERB_SET_STREAM_FORMAT, 19973cd0490STakashi Iwai format); 20073cd0490STakashi Iwai /* turn on again (if needed) */ 20173cd0490STakashi Iwai /* enable and set the channel status audio/data flag */ 20273cd0490STakashi Iwai if (codec->spdif_status_reset && 20373cd0490STakashi Iwai (spdif->ctls & AC_DIG1_ENABLE)) { 20473cd0490STakashi Iwai snd_hda_codec_write(codec, 20573cd0490STakashi Iwai nvhdmi_con_nids_7x[i], 20673cd0490STakashi Iwai 0, 20773cd0490STakashi Iwai AC_VERB_SET_DIGI_CONVERT_1, 20873cd0490STakashi Iwai spdif->ctls & 0xff); 20973cd0490STakashi Iwai snd_hda_codec_write(codec, 21073cd0490STakashi Iwai nvhdmi_con_nids_7x[i], 21173cd0490STakashi Iwai 0, 21273cd0490STakashi Iwai AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); 21373cd0490STakashi Iwai } 21473cd0490STakashi Iwai } 21573cd0490STakashi Iwai 21673cd0490STakashi Iwai nvhdmi_8ch_7x_set_info_frame_parameters(codec, chs); 21773cd0490STakashi Iwai 21873cd0490STakashi Iwai mutex_unlock(&codec->spdif_mutex); 21973cd0490STakashi Iwai return 0; 22073cd0490STakashi Iwai } 22173cd0490STakashi Iwai 22273cd0490STakashi Iwai static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = { 22373cd0490STakashi Iwai .substreams = 1, 22473cd0490STakashi Iwai .channels_min = 2, 22573cd0490STakashi Iwai .channels_max = 8, 22673cd0490STakashi Iwai .nid = nvhdmi_master_con_nid_7x, 22773cd0490STakashi Iwai .rates = SUPPORTED_RATES, 22873cd0490STakashi Iwai .maxbps = SUPPORTED_MAXBPS, 22973cd0490STakashi Iwai .formats = SUPPORTED_FORMATS, 23073cd0490STakashi Iwai .ops = { 23173cd0490STakashi Iwai .open = snd_hda_hdmi_simple_pcm_open, 23273cd0490STakashi Iwai .close = nvhdmi_8ch_7x_pcm_close, 23373cd0490STakashi Iwai .prepare = nvhdmi_8ch_7x_pcm_prepare 23473cd0490STakashi Iwai }, 23573cd0490STakashi Iwai }; 23673cd0490STakashi Iwai 237*ad781b55STakashi Iwai static int nvhdmi_mcp_build_pcms(struct hda_codec *codec) 23873cd0490STakashi Iwai { 23973cd0490STakashi Iwai struct hdmi_spec *spec = codec->spec; 24073cd0490STakashi Iwai int err; 24173cd0490STakashi Iwai 24273cd0490STakashi Iwai err = snd_hda_hdmi_simple_build_pcms(codec); 243*ad781b55STakashi Iwai if (!err && spec->multiout.max_channels == 8) { 24473cd0490STakashi Iwai struct hda_pcm *info = get_pcm_rec(spec, 0); 24573cd0490STakashi Iwai 24673cd0490STakashi Iwai info->own_chmap = true; 24773cd0490STakashi Iwai } 24873cd0490STakashi Iwai return err; 24973cd0490STakashi Iwai } 25073cd0490STakashi Iwai 251*ad781b55STakashi Iwai static int nvhdmi_mcp_build_controls(struct hda_codec *codec) 25273cd0490STakashi Iwai { 25373cd0490STakashi Iwai struct hdmi_spec *spec = codec->spec; 25473cd0490STakashi Iwai struct hda_pcm *info; 25573cd0490STakashi Iwai struct snd_pcm_chmap *chmap; 25673cd0490STakashi Iwai int err; 25773cd0490STakashi Iwai 25873cd0490STakashi Iwai err = snd_hda_hdmi_simple_build_controls(codec); 25973cd0490STakashi Iwai if (err < 0) 26073cd0490STakashi Iwai return err; 26173cd0490STakashi Iwai 262*ad781b55STakashi Iwai if (spec->multiout.max_channels != 8) 263*ad781b55STakashi Iwai return 0; 264*ad781b55STakashi Iwai 26573cd0490STakashi Iwai /* add channel maps */ 26673cd0490STakashi Iwai info = get_pcm_rec(spec, 0); 26773cd0490STakashi Iwai err = snd_pcm_add_chmap_ctls(info->pcm, 26873cd0490STakashi Iwai SNDRV_PCM_STREAM_PLAYBACK, 26973cd0490STakashi Iwai snd_pcm_alt_chmaps, 8, 0, &chmap); 27073cd0490STakashi Iwai if (err < 0) 27173cd0490STakashi Iwai return err; 27273cd0490STakashi Iwai switch (codec->preset->vendor_id) { 27373cd0490STakashi Iwai case 0x10de0002: 27473cd0490STakashi Iwai case 0x10de0003: 27573cd0490STakashi Iwai case 0x10de0005: 27673cd0490STakashi Iwai case 0x10de0006: 27773cd0490STakashi Iwai chmap->channel_mask = (1U << 2) | (1U << 8); 27873cd0490STakashi Iwai break; 27973cd0490STakashi Iwai case 0x10de0007: 28073cd0490STakashi Iwai chmap->channel_mask = (1U << 2) | (1U << 6) | (1U << 8); 28173cd0490STakashi Iwai } 28273cd0490STakashi Iwai return 0; 28373cd0490STakashi Iwai } 28473cd0490STakashi Iwai 28573cd0490STakashi Iwai static const unsigned int channels_2_6_8[] = { 28673cd0490STakashi Iwai 2, 6, 8 28773cd0490STakashi Iwai }; 28873cd0490STakashi Iwai 28973cd0490STakashi Iwai static const unsigned int channels_2_8[] = { 29073cd0490STakashi Iwai 2, 8 29173cd0490STakashi Iwai }; 29273cd0490STakashi Iwai 29373cd0490STakashi Iwai static const struct snd_pcm_hw_constraint_list hw_constraints_2_6_8_channels = { 29473cd0490STakashi Iwai .count = ARRAY_SIZE(channels_2_6_8), 29573cd0490STakashi Iwai .list = channels_2_6_8, 29673cd0490STakashi Iwai .mask = 0, 29773cd0490STakashi Iwai }; 29873cd0490STakashi Iwai 29973cd0490STakashi Iwai static const struct snd_pcm_hw_constraint_list hw_constraints_2_8_channels = { 30073cd0490STakashi Iwai .count = ARRAY_SIZE(channels_2_8), 30173cd0490STakashi Iwai .list = channels_2_8, 30273cd0490STakashi Iwai .mask = 0, 30373cd0490STakashi Iwai }; 30473cd0490STakashi Iwai 305*ad781b55STakashi Iwai static int nvhdmi_mcp_probe(struct hda_codec *codec, 306*ad781b55STakashi Iwai const struct hda_device_id *id) 30773cd0490STakashi Iwai { 30873cd0490STakashi Iwai struct hdmi_spec *spec; 30973cd0490STakashi Iwai int err; 31073cd0490STakashi Iwai 311*ad781b55STakashi Iwai err = snd_hda_hdmi_simple_probe(codec, nvhdmi_master_con_nid_7x, 312*ad781b55STakashi Iwai nvhdmi_master_pin_nid_7x); 31373cd0490STakashi Iwai if (err < 0) 31473cd0490STakashi Iwai return err; 315*ad781b55STakashi Iwai 316*ad781b55STakashi Iwai /* override the PCM rates, etc, as the codec doesn't give full list */ 31773cd0490STakashi Iwai spec = codec->spec; 318*ad781b55STakashi Iwai spec->pcm_playback.rates = SUPPORTED_RATES; 319*ad781b55STakashi Iwai spec->pcm_playback.maxbps = SUPPORTED_MAXBPS; 320*ad781b55STakashi Iwai spec->pcm_playback.formats = SUPPORTED_FORMATS; 321*ad781b55STakashi Iwai spec->nv_dp_workaround = true; 322*ad781b55STakashi Iwai 323*ad781b55STakashi Iwai if (id->driver_data == MODEL_2CH) 324*ad781b55STakashi Iwai return 0; 325*ad781b55STakashi Iwai 32673cd0490STakashi Iwai spec->multiout.max_channels = 8; 32773cd0490STakashi Iwai spec->pcm_playback = nvhdmi_pcm_playback_8ch_7x; 32873cd0490STakashi Iwai 32973cd0490STakashi Iwai switch (codec->preset->vendor_id) { 33073cd0490STakashi Iwai case 0x10de0002: 33173cd0490STakashi Iwai case 0x10de0003: 33273cd0490STakashi Iwai case 0x10de0005: 33373cd0490STakashi Iwai case 0x10de0006: 33473cd0490STakashi Iwai spec->hw_constraints_channels = &hw_constraints_2_8_channels; 33573cd0490STakashi Iwai break; 33673cd0490STakashi Iwai case 0x10de0007: 33773cd0490STakashi Iwai spec->hw_constraints_channels = &hw_constraints_2_6_8_channels; 33873cd0490STakashi Iwai break; 33973cd0490STakashi Iwai default: 34073cd0490STakashi Iwai break; 34173cd0490STakashi Iwai } 34273cd0490STakashi Iwai 34373cd0490STakashi Iwai /* Initialize the audio infoframe channel mask and checksum to something 34473cd0490STakashi Iwai * valid 34573cd0490STakashi Iwai */ 34673cd0490STakashi Iwai nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8); 34773cd0490STakashi Iwai 34873cd0490STakashi Iwai return 0; 34973cd0490STakashi Iwai } 35073cd0490STakashi Iwai 351*ad781b55STakashi Iwai static const struct hda_codec_ops nvhdmi_mcp_codec_ops = { 352*ad781b55STakashi Iwai .probe = nvhdmi_mcp_probe, 353*ad781b55STakashi Iwai .remove = snd_hda_hdmi_simple_remove, 354*ad781b55STakashi Iwai .build_controls = nvhdmi_mcp_build_pcms, 355*ad781b55STakashi Iwai .build_pcms = nvhdmi_mcp_build_controls, 356*ad781b55STakashi Iwai .init = nvhdmi_mcp_init, 357*ad781b55STakashi Iwai .unsol_event = snd_hda_hdmi_simple_unsol_event, 358*ad781b55STakashi Iwai }; 359*ad781b55STakashi Iwai 36073cd0490STakashi Iwai static const struct hda_device_id snd_hda_id_nvhdmi_mcp[] = { 361*ad781b55STakashi Iwai HDA_CODEC_ID_MODEL(0x10de0001, "MCP73 HDMI", MODEL_2CH), 362*ad781b55STakashi Iwai HDA_CODEC_ID_MODEL(0x10de0002, "MCP77/78 HDMI", MODEL_8CH), 363*ad781b55STakashi Iwai HDA_CODEC_ID_MODEL(0x10de0003, "MCP77/78 HDMI", MODEL_8CH), 364*ad781b55STakashi Iwai HDA_CODEC_ID_MODEL(0x10de0004, "GPU 04 HDMI", MODEL_8CH), 365*ad781b55STakashi Iwai HDA_CODEC_ID_MODEL(0x10de0005, "MCP77/78 HDMI", MODEL_8CH), 366*ad781b55STakashi Iwai HDA_CODEC_ID_MODEL(0x10de0006, "MCP77/78 HDMI", MODEL_8CH), 367*ad781b55STakashi Iwai HDA_CODEC_ID_MODEL(0x10de0007, "MCP79/7A HDMI", MODEL_8CH), 368*ad781b55STakashi Iwai HDA_CODEC_ID_MODEL(0x10de0067, "MCP67 HDMI", MODEL_2CH), 369*ad781b55STakashi Iwai HDA_CODEC_ID_MODEL(0x10de8001, "MCP73 HDMI", MODEL_2CH), 370*ad781b55STakashi Iwai HDA_CODEC_ID_MODEL(0x10de8067, "MCP67/68 HDMI", MODEL_2CH), 37173cd0490STakashi Iwai {} /* terminator */ 37273cd0490STakashi Iwai }; 37373cd0490STakashi Iwai MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_nvhdmi_mcp); 37473cd0490STakashi Iwai 37573cd0490STakashi Iwai MODULE_LICENSE("GPL"); 37673cd0490STakashi Iwai MODULE_DESCRIPTION("Legacy Nvidia HDMI HD-audio codec"); 37773cd0490STakashi Iwai MODULE_IMPORT_NS("SND_HDA_CODEC_HDMI"); 37873cd0490STakashi Iwai 37973cd0490STakashi Iwai static struct hda_codec_driver nvhdmi_mcp_driver = { 38073cd0490STakashi Iwai .id = snd_hda_id_nvhdmi_mcp, 381*ad781b55STakashi Iwai .ops = &nvhdmi_mcp_codec_ops, 38273cd0490STakashi Iwai }; 38373cd0490STakashi Iwai 38473cd0490STakashi Iwai module_hda_codec_driver(nvhdmi_mcp_driver); 385