Am 14.12.2009 12:32, schrieb Takashi Iwai: > At Sat, 12 Dec 2009 13:06:11 +0100, > Stefan Ringel wrote: > >> I forgot this attachment 1.patch and alsa-info.txt. >> > Thanks. Now I added your patch for the Nvidia controller part. > > Looking through alsa-info.sh, the new Nvidia provides 4 codecs > for 8-channel HDMI, instead of 4 pins in one codec. This is fairly > crazy setup, but who knows why... > > Could you try the patch below? This is a very quick and blind hack. > > > thanks, > > Takashi > > --- > diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c > index 6afdab0..343ea27 100644 > --- a/sound/pci/hda/patch_nvhdmi.c > +++ b/sound/pci/hda/patch_nvhdmi.c > @@ -391,6 +391,180 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) > return 0; > } > > +/* 4x 2ch codecs */ > + > +static int nvhdmi_dig_playback_pcm_close_sep_8ch(struct hda_pcm_stream *hinfo, > + struct hda_codec *codec, > + struct snd_pcm_substream *substream) > +{ > + struct nvhdmi_spec *spec = codec->spec; > + int i; > + for (i = 0; i < 4; i++) { > + struct hda_codec *cp = codec->bus->caddr_tbl[i]; > + if (!cp) > + continue; > + snd_hda_codec_write(cp, Nv_Master_Convert_nid, 0, > + AC_VERB_SET_CHANNEL_STREAMID, 0); > + snd_hda_codec_write(cp, Nv_Master_Convert_nid, 0, > + AC_VERB_SET_STREAM_FORMAT, 0); > + } > + return snd_hda_multi_out_dig_close(codec, &spec->multiout); > +} > + > +static int nvhdmi_dig_playback_pcm_prepare_sep_8ch(struct hda_pcm_stream *hinfo, > + struct hda_codec *codec, > + unsigned int stream_tag, > + unsigned int format, > + struct snd_pcm_substream *substream) > +{ > + int chs; > + unsigned int dataDCC1, dataDCC2, chan, chanmask, channel_id; > + int i; > + > + mutex_lock(&codec->spdif_mutex); > + > + chs = substream->runtime->channels; > + chan = chs ? (chs - 1) : 1; > + > + switch (chs) { > + default: > + case 0: > + case 2: > + chanmask = 0x00; > + break; > + case 4: > + chanmask = 0x08; > + break; > + case 6: > + chanmask = 0x0b; > + break; > + case 8: > + chanmask = 0x13; > + break; > + } > + dataDCC1 = AC_DIG1_ENABLE | AC_DIG1_COPYRIGHT; > + dataDCC2 = 0x2; > + > + for (i = 0; i < 4; i++) { > + struct hda_codec *cp = codec->bus->caddr_tbl[i]; > + if (!cp) > + continue; > + if (chs == 2) > + channel_id = 0; > + else > + channel_id = i * 2; > + > + /* set the Audio InforFrame Channel Allocation */ > + snd_hda_codec_write(cp, 0x1, 0, > + Nv_VERB_SET_Channel_Allocation, chanmask); > + > + /* turn off SPDIF once; > + *otherwise the IEC958 bits won't be updated > + */ > + if (codec->spdif_status_reset && > + (codec->spdif_ctls & AC_DIG1_ENABLE)) > + snd_hda_codec_write(cp, > + Nv_Master_Convert_nid, > + 0, > + AC_VERB_SET_DIGI_CONVERT_1, > + codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); > + /* set the stream id */ > + snd_hda_codec_write(cp, > + Nv_Master_Convert_nid, > + 0, > + AC_VERB_SET_CHANNEL_STREAMID, > + (stream_tag << 4) | channel_id); > + /* set the stream format */ > + snd_hda_codec_write(cp, > + Nv_Master_Convert_nid, > + 0, > + AC_VERB_SET_STREAM_FORMAT, > + format); > + /* turn on again (if needed) */ > + /* enable and set the channel status audio/data flag */ > + if (codec->spdif_status_reset && > + (codec->spdif_ctls & AC_DIG1_ENABLE)) { > + snd_hda_codec_write(cp, > + Nv_Master_Convert_nid, > + 0, > + AC_VERB_SET_DIGI_CONVERT_1, > + codec->spdif_ctls & 0xff); > + snd_hda_codec_write(cp, > + Nv_Master_Convert_nid, > + 0, > + AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); > + } > + > + /* set the Audio Info Frame Checksum */ > + snd_hda_codec_write(cp, 0x1, 0, > + Nv_VERB_SET_Info_Frame_Checksum, > + (0x71 - chan - chanmask)); > + } > + > + mutex_unlock(&codec->spdif_mutex); > + return 0; > +} > + > +static struct hda_pcm_stream nvhdmi_pcm_digital_playback_sep_8ch = { > + .substreams = 1, > + .channels_min = 2, > + .channels_max = 8, > + .nid = Nv_Master_Convert_nid, > + .rates = SUPPORTED_RATES, > + .maxbps = SUPPORTED_MAXBPS, > + .formats = SUPPORTED_FORMATS, > + .ops = { > + .open = nvhdmi_dig_playback_pcm_open, > + .close = nvhdmi_dig_playback_pcm_close_sep_8ch, > + .prepare = nvhdmi_dig_playback_pcm_prepare_sep_8ch > + }, > +}; > + > +static int nvhdmi_build_pcms_sep_8ch(struct hda_codec *codec) > +{ > + struct nvhdmi_spec *spec = codec->spec; > + struct hda_pcm *info = &spec->pcm_rec; > + > + codec->num_pcms = 1; > + codec->pcm_info = info; > + > + info->name = "NVIDIA HDMI"; > + info->pcm_type = HDA_PCM_TYPE_HDMI; > + info->stream[SNDRV_PCM_STREAM_PLAYBACK] > + = nvhdmi_pcm_digital_playback_sep_8ch; > + > + return 0; > +} > + > +static struct hda_codec_ops nvhdmi_patch_ops_sep_8ch = { > + .build_controls = nvhdmi_build_controls, > + .build_pcms = nvhdmi_build_pcms_sep_8ch, > + .init = nvhdmi_init, > + .free = nvhdmi_free, > +}; > + > +static int patch_nvhdmi_sep_8ch(struct hda_codec *codec) > +{ > + struct nvhdmi_spec *spec; > + > + if (codec->addr > 0) > + return 0; > + > + spec = kzalloc(sizeof(*spec), GFP_KERNEL); > + if (spec == NULL) > + return -ENOMEM; > + > + codec->spec = spec; > + > + spec->multiout.num_dacs = 0; /* no analog */ > + spec->multiout.max_channels = 8; > + spec->multiout.dig_out_nid = Nv_Master_Convert_nid; > + > + codec->patch_ops = nvhdmi_patch_ops_sep_8ch; > + > + return 0; > +} > + > /* > * patch entries > */ > @@ -400,6 +574,8 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { > { .id = 0x10de0005, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, > { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, > { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch }, > + { .id = 0x10de000a, .name = "MCP HDMI", .patch = patch_nvhdmi_sep_8ch }, > + { .id = 0x10de000b, .name = "MCP HDMI", .patch = patch_nvhdmi_sep_8ch }, > { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, > { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, > {} /* terminator */ > @@ -410,6 +586,8 @@ MODULE_ALIAS("snd-hda-codec-id:10de0003"); > MODULE_ALIAS("snd-hda-codec-id:10de0005"); > MODULE_ALIAS("snd-hda-codec-id:10de0006"); > MODULE_ALIAS("snd-hda-codec-id:10de0007"); > +MODULE_ALIAS("snd-hda-codec-id:10de000a"); > +MODULE_ALIAS("snd-hda-codec-id:10de000b"); > MODULE_ALIAS("snd-hda-codec-id:10de0067"); > MODULE_ALIAS("snd-hda-codec-id:10de8001"); > > hi Takashi, one codec-id missed (0x10de000d) and codec-name is "G2xx HDMI". Stefan Ringel <stefan.ringel@xxxxxxxx> _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel