diff options
| -rw-r--r-- | sound/pci/hda/patch_hdmi.c | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 251773e45f61..715615a88a8d 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
| @@ -1280,6 +1280,39 @@ static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
| 1280 | stream_tag, format, substream); | 1280 | stream_tag, format, substream); |
| 1281 | } | 1281 | } |
| 1282 | 1282 | ||
| 1283 | static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec, | ||
| 1284 | int channels) | ||
| 1285 | { | ||
| 1286 | unsigned int chanmask; | ||
| 1287 | int chan = channels ? (channels - 1) : 1; | ||
| 1288 | |||
| 1289 | switch (channels) { | ||
| 1290 | default: | ||
| 1291 | case 0: | ||
| 1292 | case 2: | ||
| 1293 | chanmask = 0x00; | ||
| 1294 | break; | ||
| 1295 | case 4: | ||
| 1296 | chanmask = 0x08; | ||
| 1297 | break; | ||
| 1298 | case 6: | ||
| 1299 | chanmask = 0x0b; | ||
| 1300 | break; | ||
| 1301 | case 8: | ||
| 1302 | chanmask = 0x13; | ||
| 1303 | break; | ||
| 1304 | } | ||
| 1305 | |||
| 1306 | /* Set the audio infoframe channel allocation and checksum fields. The | ||
| 1307 | * channel count is computed implicitly by the hardware. */ | ||
| 1308 | snd_hda_codec_write(codec, 0x1, 0, | ||
| 1309 | Nv_VERB_SET_Channel_Allocation, chanmask); | ||
| 1310 | |||
| 1311 | snd_hda_codec_write(codec, 0x1, 0, | ||
| 1312 | Nv_VERB_SET_Info_Frame_Checksum, | ||
| 1313 | (0x71 - chan - chanmask)); | ||
| 1314 | } | ||
| 1315 | |||
| 1283 | static int nvhdmi_8ch_7x_pcm_close(struct hda_pcm_stream *hinfo, | 1316 | static int nvhdmi_8ch_7x_pcm_close(struct hda_pcm_stream *hinfo, |
| 1284 | struct hda_codec *codec, | 1317 | struct hda_codec *codec, |
| 1285 | struct snd_pcm_substream *substream) | 1318 | struct snd_pcm_substream *substream) |
| @@ -1298,6 +1331,10 @@ static int nvhdmi_8ch_7x_pcm_close(struct hda_pcm_stream *hinfo, | |||
| 1298 | AC_VERB_SET_STREAM_FORMAT, 0); | 1331 | AC_VERB_SET_STREAM_FORMAT, 0); |
| 1299 | } | 1332 | } |
| 1300 | 1333 | ||
| 1334 | /* The audio hardware sends a channel count of 0x7 (8ch) when all the | ||
| 1335 | * streams are disabled. */ | ||
| 1336 | nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8); | ||
| 1337 | |||
| 1301 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | 1338 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); |
| 1302 | } | 1339 | } |
| 1303 | 1340 | ||
| @@ -1308,37 +1345,16 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
| 1308 | struct snd_pcm_substream *substream) | 1345 | struct snd_pcm_substream *substream) |
| 1309 | { | 1346 | { |
| 1310 | int chs; | 1347 | int chs; |
| 1311 | unsigned int dataDCC1, dataDCC2, chan, chanmask, channel_id; | 1348 | unsigned int dataDCC1, dataDCC2, channel_id; |
| 1312 | int i; | 1349 | int i; |
| 1313 | 1350 | ||
| 1314 | mutex_lock(&codec->spdif_mutex); | 1351 | mutex_lock(&codec->spdif_mutex); |
| 1315 | 1352 | ||
| 1316 | chs = substream->runtime->channels; | 1353 | chs = substream->runtime->channels; |
| 1317 | chan = chs ? (chs - 1) : 1; | ||
| 1318 | 1354 | ||
| 1319 | switch (chs) { | ||
| 1320 | default: | ||
| 1321 | case 0: | ||
| 1322 | case 2: | ||
| 1323 | chanmask = 0x00; | ||
| 1324 | break; | ||
| 1325 | case 4: | ||
| 1326 | chanmask = 0x08; | ||
| 1327 | break; | ||
| 1328 | case 6: | ||
| 1329 | chanmask = 0x0b; | ||
| 1330 | break; | ||
| 1331 | case 8: | ||
| 1332 | chanmask = 0x13; | ||
| 1333 | break; | ||
| 1334 | } | ||
| 1335 | dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT; | 1355 | dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT; |
| 1336 | dataDCC2 = 0x2; | 1356 | dataDCC2 = 0x2; |
| 1337 | 1357 | ||
| 1338 | /* set the Audio InforFrame Channel Allocation */ | ||
| 1339 | snd_hda_codec_write(codec, 0x1, 0, | ||
| 1340 | Nv_VERB_SET_Channel_Allocation, chanmask); | ||
| 1341 | |||
| 1342 | /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ | 1358 | /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ |
| 1343 | if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) | 1359 | if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) |
| 1344 | snd_hda_codec_write(codec, | 1360 | snd_hda_codec_write(codec, |
| @@ -1413,10 +1429,7 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
| 1413 | } | 1429 | } |
| 1414 | } | 1430 | } |
| 1415 | 1431 | ||
| 1416 | /* set the Audio Info Frame Checksum */ | 1432 | nvhdmi_8ch_7x_set_info_frame_parameters(codec, chs); |
| 1417 | snd_hda_codec_write(codec, 0x1, 0, | ||
| 1418 | Nv_VERB_SET_Info_Frame_Checksum, | ||
| 1419 | (0x71 - chan - chanmask)); | ||
| 1420 | 1433 | ||
| 1421 | mutex_unlock(&codec->spdif_mutex); | 1434 | mutex_unlock(&codec->spdif_mutex); |
| 1422 | return 0; | 1435 | return 0; |
| @@ -1512,6 +1525,11 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) | |||
| 1512 | spec->multiout.max_channels = 8; | 1525 | spec->multiout.max_channels = 8; |
| 1513 | spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x; | 1526 | spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x; |
| 1514 | codec->patch_ops = nvhdmi_patch_ops_8ch_7x; | 1527 | codec->patch_ops = nvhdmi_patch_ops_8ch_7x; |
| 1528 | |||
| 1529 | /* Initialize the audio infoframe channel mask and checksum to something | ||
| 1530 | * valid */ | ||
| 1531 | nvhdmi_8ch_7x_set_info_frame_parameters(codec, 8); | ||
| 1532 | |||
| 1515 | return 0; | 1533 | return 0; |
| 1516 | } | 1534 | } |
| 1517 | 1535 | ||
