1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Legacy Nvidia HDMI codec support 4 */ 5 6 #include <linux/init.h> 7 #include <linux/slab.h> 8 #include <linux/module.h> 9 #include <sound/core.h> 10 #include <sound/hdaudio.h> 11 #include <sound/hda_codec.h> 12 #include "hda_local.h" 13 #include "hdmi_local.h" 14 15 enum { MODEL_2CH, MODEL_8CH }; 16 17 #define Nv_VERB_SET_Channel_Allocation 0xF79 18 #define Nv_VERB_SET_Info_Frame_Checksum 0xF7A 19 #define Nv_VERB_SET_Audio_Protection_On 0xF98 20 #define Nv_VERB_SET_Audio_Protection_Off 0xF99 21 22 #define nvhdmi_master_con_nid_7x 0x04 23 #define nvhdmi_master_pin_nid_7x 0x05 24 25 static const hda_nid_t nvhdmi_con_nids_7x[4] = { 26 /*front, rear, clfe, rear_surr */ 27 0x6, 0x8, 0xa, 0xc, 28 }; 29 30 static const struct hda_verb nvhdmi_basic_init_7x_2ch[] = { 31 /* set audio protect on */ 32 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, 33 /* enable digital output on pin widget */ 34 { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, 35 {} /* terminator */ 36 }; 37 38 static const struct hda_verb nvhdmi_basic_init_7x_8ch[] = { 39 /* set audio protect on */ 40 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, 41 /* enable digital output on pin widget */ 42 { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, 43 { 0x7, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, 44 { 0x9, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, 45 { 0xb, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, 46 { 0xd, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, 47 {} /* terminator */ 48 }; 49 50 static int nvhdmi_mcp_init(struct hda_codec *codec) 51 { 52 struct hdmi_spec *spec = codec->spec; 53 54 if (spec->multiout.max_channels == 2) 55 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_2ch); 56 else 57 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_8ch); 58 return 0; 59 } 60 61 static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec, 62 int channels) 63 { 64 unsigned int chanmask; 65 int chan = channels ? (channels - 1) : 1; 66 67 switch (channels) { 68 default: 69 case 0: 70 case 2: 71 chanmask = 0x00; 72 break; 73 case 4: 74 chanmask = 0x08; 75 break; 76 case 6: 77 chanmask = 0x0b; 78 break; 79 case 8: 80 chanmask = 0x13; 81 break; 82 } 83 84 /* Set the audio infoframe channel allocation and checksum fields. The 85 * channel count is computed implicitly by the hardware. 86 */ 87 snd_hda_codec_write(codec, 0x1, 0, 88 Nv_VERB_SET_Channel_Allocation, chanmask); 89 90 snd_hda_codec_write(codec, 0x1, 0, 91 Nv_VERB_SET_Info_Frame_Checksum, 92 (0x71 - chan - chanmask)); 93 } 94 95 static int nvhdmi_8ch_7x_pcm_close(struct hda_pcm_stream *hinfo, 96 struct hda_codec *codec, 97 struct snd_pcm_substream *substream) 98 { 99 struct hdmi_spec *spec = codec->spec; 100 int i; 101 102 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 103 0, AC_VERB_SET_CHANNEL_STREAMID, 0); 104 for (i = 0; i < 4; i++) { 105 /* set the stream id */ 106 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0, 107 AC_VERB_SET_CHANNEL_STREAMID, 0); 108 /* set the stream format */ 109 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0, 110 AC_VERB_SET_STREAM_FORMAT, 0); 111 } 112 113 /* The audio hardware sends a channel count of 0x7 (8ch) when all the 114 * streams are disabled. 115 */ 116 nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8); 117 118 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 119 } 120 121 static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, 122 struct hda_codec *codec, 123 unsigned int stream_tag, 124 unsigned int format, 125 struct snd_pcm_substream *substream) 126 { 127 int chs; 128 unsigned int dataDCC2, channel_id; 129 int i; 130 struct hdmi_spec *spec = codec->spec; 131 struct hda_spdif_out *spdif; 132 struct hdmi_spec_per_cvt *per_cvt; 133 134 guard(mutex)(&codec->spdif_mutex); 135 per_cvt = get_cvt(spec, 0); 136 spdif = snd_hda_spdif_out_of_nid(codec, per_cvt->cvt_nid); 137 138 chs = substream->runtime->channels; 139 140 dataDCC2 = 0x2; 141 142 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 143 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE)) 144 snd_hda_codec_write(codec, 145 nvhdmi_master_con_nid_7x, 146 0, 147 AC_VERB_SET_DIGI_CONVERT_1, 148 spdif->ctls & ~AC_DIG1_ENABLE & 0xff); 149 150 /* set the stream id */ 151 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0, 152 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0); 153 154 /* set the stream format */ 155 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0, 156 AC_VERB_SET_STREAM_FORMAT, format); 157 158 /* turn on again (if needed) */ 159 /* enable and set the channel status audio/data flag */ 160 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE)) { 161 snd_hda_codec_write(codec, 162 nvhdmi_master_con_nid_7x, 163 0, 164 AC_VERB_SET_DIGI_CONVERT_1, 165 spdif->ctls & 0xff); 166 snd_hda_codec_write(codec, 167 nvhdmi_master_con_nid_7x, 168 0, 169 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); 170 } 171 172 for (i = 0; i < 4; i++) { 173 if (chs == 2) 174 channel_id = 0; 175 else 176 channel_id = i * 2; 177 178 /* turn off SPDIF once; 179 *otherwise the IEC958 bits won't be updated 180 */ 181 if (codec->spdif_status_reset && 182 (spdif->ctls & AC_DIG1_ENABLE)) 183 snd_hda_codec_write(codec, 184 nvhdmi_con_nids_7x[i], 185 0, 186 AC_VERB_SET_DIGI_CONVERT_1, 187 spdif->ctls & ~AC_DIG1_ENABLE & 0xff); 188 /* set the stream id */ 189 snd_hda_codec_write(codec, 190 nvhdmi_con_nids_7x[i], 191 0, 192 AC_VERB_SET_CHANNEL_STREAMID, 193 (stream_tag << 4) | channel_id); 194 /* set the stream format */ 195 snd_hda_codec_write(codec, 196 nvhdmi_con_nids_7x[i], 197 0, 198 AC_VERB_SET_STREAM_FORMAT, 199 format); 200 /* turn on again (if needed) */ 201 /* enable and set the channel status audio/data flag */ 202 if (codec->spdif_status_reset && 203 (spdif->ctls & AC_DIG1_ENABLE)) { 204 snd_hda_codec_write(codec, 205 nvhdmi_con_nids_7x[i], 206 0, 207 AC_VERB_SET_DIGI_CONVERT_1, 208 spdif->ctls & 0xff); 209 snd_hda_codec_write(codec, 210 nvhdmi_con_nids_7x[i], 211 0, 212 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); 213 } 214 } 215 216 nvhdmi_8ch_7x_set_info_frame_parameters(codec, chs); 217 218 return 0; 219 } 220 221 static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = { 222 .substreams = 1, 223 .channels_min = 2, 224 .channels_max = 8, 225 .nid = nvhdmi_master_con_nid_7x, 226 .rates = SUPPORTED_RATES, 227 .maxbps = SUPPORTED_MAXBPS, 228 .formats = SUPPORTED_FORMATS, 229 .ops = { 230 .open = snd_hda_hdmi_simple_pcm_open, 231 .close = nvhdmi_8ch_7x_pcm_close, 232 .prepare = nvhdmi_8ch_7x_pcm_prepare 233 }, 234 }; 235 236 static int nvhdmi_mcp_build_pcms(struct hda_codec *codec) 237 { 238 struct hdmi_spec *spec = codec->spec; 239 int err; 240 241 err = snd_hda_hdmi_simple_build_pcms(codec); 242 if (!err && spec->multiout.max_channels == 8) { 243 struct hda_pcm *info = get_pcm_rec(spec, 0); 244 245 info->own_chmap = true; 246 } 247 return err; 248 } 249 250 static int nvhdmi_mcp_build_controls(struct hda_codec *codec) 251 { 252 struct hdmi_spec *spec = codec->spec; 253 struct hda_pcm *info; 254 struct snd_pcm_chmap *chmap; 255 int err; 256 257 err = snd_hda_hdmi_simple_build_controls(codec); 258 if (err < 0) 259 return err; 260 261 if (spec->multiout.max_channels != 8) 262 return 0; 263 264 /* add channel maps */ 265 info = get_pcm_rec(spec, 0); 266 err = snd_pcm_add_chmap_ctls(info->pcm, 267 SNDRV_PCM_STREAM_PLAYBACK, 268 snd_pcm_alt_chmaps, 8, 0, &chmap); 269 if (err < 0) 270 return err; 271 switch (codec->preset->vendor_id) { 272 case 0x10de0002: 273 case 0x10de0003: 274 case 0x10de0005: 275 case 0x10de0006: 276 chmap->channel_mask = (1U << 2) | (1U << 8); 277 break; 278 case 0x10de0007: 279 chmap->channel_mask = (1U << 2) | (1U << 6) | (1U << 8); 280 } 281 return 0; 282 } 283 284 static const unsigned int channels_2_6_8[] = { 285 2, 6, 8 286 }; 287 288 static const unsigned int channels_2_8[] = { 289 2, 8 290 }; 291 292 static const struct snd_pcm_hw_constraint_list hw_constraints_2_6_8_channels = { 293 .count = ARRAY_SIZE(channels_2_6_8), 294 .list = channels_2_6_8, 295 .mask = 0, 296 }; 297 298 static const struct snd_pcm_hw_constraint_list hw_constraints_2_8_channels = { 299 .count = ARRAY_SIZE(channels_2_8), 300 .list = channels_2_8, 301 .mask = 0, 302 }; 303 304 static int nvhdmi_mcp_probe(struct hda_codec *codec, 305 const struct hda_device_id *id) 306 { 307 struct hdmi_spec *spec; 308 int err; 309 310 err = snd_hda_hdmi_simple_probe(codec, nvhdmi_master_con_nid_7x, 311 nvhdmi_master_pin_nid_7x); 312 if (err < 0) 313 return err; 314 315 /* override the PCM rates, etc, as the codec doesn't give full list */ 316 spec = codec->spec; 317 spec->pcm_playback.rates = SUPPORTED_RATES; 318 spec->pcm_playback.maxbps = SUPPORTED_MAXBPS; 319 spec->pcm_playback.formats = SUPPORTED_FORMATS; 320 spec->nv_dp_workaround = true; 321 322 if (id->driver_data == MODEL_2CH) 323 return 0; 324 325 spec->multiout.max_channels = 8; 326 spec->pcm_playback = nvhdmi_pcm_playback_8ch_7x; 327 328 switch (codec->preset->vendor_id) { 329 case 0x10de0002: 330 case 0x10de0003: 331 case 0x10de0005: 332 case 0x10de0006: 333 spec->hw_constraints_channels = &hw_constraints_2_8_channels; 334 break; 335 case 0x10de0007: 336 spec->hw_constraints_channels = &hw_constraints_2_6_8_channels; 337 break; 338 default: 339 break; 340 } 341 342 /* Initialize the audio infoframe channel mask and checksum to something 343 * valid 344 */ 345 nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8); 346 347 return 0; 348 } 349 350 static const struct hda_codec_ops nvhdmi_mcp_codec_ops = { 351 .probe = nvhdmi_mcp_probe, 352 .remove = snd_hda_hdmi_simple_remove, 353 .build_controls = nvhdmi_mcp_build_pcms, 354 .build_pcms = nvhdmi_mcp_build_controls, 355 .init = nvhdmi_mcp_init, 356 .unsol_event = snd_hda_hdmi_simple_unsol_event, 357 }; 358 359 static const struct hda_device_id snd_hda_id_nvhdmi_mcp[] = { 360 HDA_CODEC_ID_MODEL(0x10de0001, "MCP73 HDMI", MODEL_2CH), 361 HDA_CODEC_ID_MODEL(0x10de0002, "MCP77/78 HDMI", MODEL_8CH), 362 HDA_CODEC_ID_MODEL(0x10de0003, "MCP77/78 HDMI", MODEL_8CH), 363 HDA_CODEC_ID_MODEL(0x10de0004, "GPU 04 HDMI", MODEL_8CH), 364 HDA_CODEC_ID_MODEL(0x10de0005, "MCP77/78 HDMI", MODEL_8CH), 365 HDA_CODEC_ID_MODEL(0x10de0006, "MCP77/78 HDMI", MODEL_8CH), 366 HDA_CODEC_ID_MODEL(0x10de0007, "MCP79/7A HDMI", MODEL_8CH), 367 HDA_CODEC_ID_MODEL(0x10de0067, "MCP67 HDMI", MODEL_2CH), 368 HDA_CODEC_ID_MODEL(0x10de8001, "MCP73 HDMI", MODEL_2CH), 369 HDA_CODEC_ID_MODEL(0x10de8067, "MCP67/68 HDMI", MODEL_2CH), 370 {} /* terminator */ 371 }; 372 MODULE_DEVICE_TABLE(hdaudio, snd_hda_id_nvhdmi_mcp); 373 374 MODULE_LICENSE("GPL"); 375 MODULE_DESCRIPTION("Legacy Nvidia HDMI HD-audio codec"); 376 MODULE_IMPORT_NS("SND_HDA_CODEC_HDMI"); 377 378 static struct hda_codec_driver nvhdmi_mcp_driver = { 379 .id = snd_hda_id_nvhdmi_mcp, 380 .ops = &nvhdmi_mcp_codec_ops, 381 }; 382 383 module_hda_codec_driver(nvhdmi_mcp_driver); 384