At Tue, 29 Dec 2009 09:57:24 +0100, Stefan Ringel wrote:
Am 28.12.2009 23:23, schrieb Takashi Iwai:
At Mon, 28 Dec 2009 22:34:09 +0100, I wrote:
At Sun, 27 Dec 2009 17:20:25 +0100, Stefan Ringel wrote:
I have tested with patch_intelhdmi.c and it works, and I have tested with patch_atihdmi.c (changing convert nid and pin nid) and it works also. But I have problems to attach codec #2 and #3. Next I'm updating patch_nvhdmi.c and testing it.
Did you test also more than 2 channels? Each codec looks supporting to 8 channels output, so it might do actually. But, it might be also separated 4x2 channels.
So far, only two HDMI codecs are supported individually. For using these four codecs, we'd need a hack.
Something like below...
Takashi
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index 6afdab0..bad7fab 100644 --- a/sound/pci/hda/patch_nvhdmi.c +++ b/sound/pci/hda/patch_nvhdmi.c @@ -392,6 +392,136 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) }
/*
- Quad 2ch codecs on G2x
- 4 x 2ch codecs for 8 channels output
- */
+static int nvhdmi_pcm_prepare_quad_2ch(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
unsigned int stream_tag,
unsigned int format,
struct snd_pcm_substream *substream)
+{
- int i, ncodecs;
- struct hda_codec *c;
- mutex_lock(&codec->spdif_mutex);
- ncodecs = substream->runtime->channels / 2;
- /* turn off SPDIF once */
- if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
unsigned int ctls = codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff;
for (i = 0; i < ncodecs; i++) {
c = codec->bus->caddr_tbl[i];
if (c)
snd_hda_codec_write(c, Nv_Master_Convert_nid, 0,
AC_VERB_SET_DIGI_CONVERT_1,
ctls);
}
- }
- /* set the stream id */
- for (i = 0; i < ncodecs; i++) {
c = codec->bus->caddr_tbl[i];
if (c)
snd_hda_codec_setup_stream(c, Nv_Master_Convert_nid,
stream_tag, i << 1, format);
- }
- /* turn on SPDIF again (if needed) */
- if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
for (i = 0; i < ncodecs; i++) {
c = codec->bus->caddr_tbl[i];
if (c) {
snd_hda_codec_write(c, Nv_Master_Convert_nid, 0,
AC_VERB_SET_DIGI_CONVERT_1,
codec->spdif_ctls & 0xff);
snd_hda_codec_write(c, Nv_Master_Convert_nid, 0,
AC_VERB_SET_DIGI_CONVERT_2,
codec->spdif_ctls >> 8);
}
}
- }
- mutex_unlock(&codec->spdif_mutex);
- return 0;
+}
+static int nvhdmi_pcm_cleanup_quad_2ch(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
struct snd_pcm_substream *substream)
+{
- int i, ncodecs;
- struct hda_codec *c;
- mutex_lock(&codec->spdif_mutex);
- ncodecs = substream->runtime->channels / 2;
- for (i = 0; i < ncodecs; i++) {
c = codec->bus->caddr_tbl[i];
if (c)
snd_hda_codec_cleanup_stream(c, Nv_Master_Convert_nid);
- }
- mutex_unlock(&codec->spdif_mutex);
- return 0;
+}
+static struct hda_pcm_stream nvhdmi_pcm_playback_quad_2ch = {
- .substreams = 1,
- .channels_min = 2,
- .channels_max = 8,
- .nid = Nv_Master_Convert_nid,
- .rates = SUPPORTED_RATES,
- .maxbps = SUPPORTED_MAXBPS,
- .formats = SUPPORTED_FORMATS,
- .ops = {
.prepare = nvhdmi_pcm_prepare_quad_2ch,
.cleanup = nvhdmi_pcm_cleanup_quad_2ch,
- },
+};
+static int nvhdmi_build_pcms_quad_2ch(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_playback_quad_2ch;
- return 0;
+}
+static struct hda_codec_ops nvhdmi_patch_ops_quad_2ch = {
- .build_controls = nvhdmi_build_controls,
- .build_pcms = nvhdmi_build_pcms_quad_2ch,
- .init = nvhdmi_init,
- .free = nvhdmi_free,
+};
+static int patch_nvhdmi_quad_2ch(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_quad_2ch;
- return 0;
+}
+/*
- patch entries
*/ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { @@ -400,6 +530,9 @@ 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 = "G2x HDMI", .patch = patch_nvhdmi_quad_2ch },
- { .id = 0x10de000b, .name = "G2x HDMI", .patch = patch_nvhdmi_quad_2ch },
- { .id = 0x10de000d, .name = "G2x HDMI", .patch = patch_nvhdmi_quad_2ch }, { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, {} /* terminator */
@@ -410,6 +543,9 @@ 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:10de000d"); MODULE_ALIAS("snd-hda-codec-id:10de0067"); MODULE_ALIAS("snd-hda-codec-id:10de8001");
I think it's false. It must initialize in native mode (EPT) -> this patch can't sound, I'd tested it.
Possibly. It was just too quick.
Anyway, Wei seems preparing the patches for new codecs, so I'll keep my hands away from this.
Takashi