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
nvhdmi_mcp_init(struct hda_codec * codec)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
nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec * codec,int channels)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
nvhdmi_8ch_7x_pcm_close(struct hda_pcm_stream * hinfo,struct hda_codec * codec,struct snd_pcm_substream * substream)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
nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream * hinfo,struct hda_codec * codec,unsigned int stream_tag,unsigned int format,struct snd_pcm_substream * substream)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
nvhdmi_mcp_build_pcms(struct hda_codec * codec)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
nvhdmi_mcp_build_controls(struct hda_codec * codec)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
nvhdmi_mcp_probe(struct hda_codec * codec,const struct hda_device_id * id)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