* [PATCH 00/11] Intel IbexPeak HDMI codec support
@ 2009-10-15 7:03 Wu Fengguang
2009-10-15 7:03 ` [PATCH 01/11] hda - select IbexPeak handler for Calpella Wu Fengguang
` (11 more replies)
0 siblings, 12 replies; 13+ messages in thread
From: Wu Fengguang @ 2009-10-15 7:03 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Wu Fengguang
Hi Takashi,
This series adds support for the Intel IbexPeak HDMI codec, which can
connect up to 3 monitors and support 2 independant A/V pipes. The patches
are tested OK on IbexPeak and G45. DisplayPort is also working with another
in-house KMS patch. However we have not tested dual monitor configurations
(which should be rare for now).
Thanks,
Fengguang
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 01/11] hda - select IbexPeak handler for Calpella
2009-10-15 7:03 [PATCH 00/11] Intel IbexPeak HDMI codec support Wu Fengguang
@ 2009-10-15 7:03 ` Wu Fengguang
2009-10-15 7:03 ` [PATCH 02/11] hda - vectorize get_empty_pcm_device() Wu Fengguang
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wu Fengguang @ 2009-10-15 7:03 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Wu Fengguang
[-- Attachment #1: hdmi-calpella.patch --]
[-- Type: text/plain, Size: 1052 bytes --]
An earlier patch merely adds id for 0x80862804.
It has 2/3 cvt/pin nodes and shall be tied to the IbexPeak handler.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
sound/pci/hda/patch_intelhdmi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-10-15 09:34:00.000000000 +0800
+++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-10-15 10:16:52.000000000 +0800
@@ -684,7 +684,7 @@ static struct hda_codec_preset snd_hda_p
{ .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi },
{ .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi },
{ .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi },
- { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi },
+ { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi_ibexpeak },
{ .id = 0x80860054, .name = "Q57 DEVIBX", .patch = patch_intel_hdmi_ibexpeak },
{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
{} /* terminator */
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 02/11] hda - vectorize get_empty_pcm_device()
2009-10-15 7:03 [PATCH 00/11] Intel IbexPeak HDMI codec support Wu Fengguang
2009-10-15 7:03 ` [PATCH 01/11] hda - select IbexPeak handler for Calpella Wu Fengguang
@ 2009-10-15 7:03 ` Wu Fengguang
2009-10-15 7:03 ` [PATCH 03/11] hda - allow up to 4 HDMI devices Wu Fengguang
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wu Fengguang @ 2009-10-15 7:03 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Wu Fengguang
[-- Attachment #1: hdmi-dev-array.patch --]
[-- Type: text/plain, Size: 2130 bytes --]
This unifies the code and data structure,
and makes it easy to add more HDMI devices.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
sound/pci/hda/hda_codec.c | 49 +++++++++++-------------------------
1 file changed, 16 insertions(+), 33 deletions(-)
--- sound-2.6.orig/sound/pci/hda/hda_codec.c 2009-10-15 10:16:52.000000000 +0800
+++ sound-2.6/sound/pci/hda/hda_codec.c 2009-10-15 10:17:00.000000000 +0800
@@ -2885,43 +2885,26 @@ static int get_empty_pcm_device(struct h
static const char *dev_name[HDA_PCM_NTYPES] = {
"Audio", "SPDIF", "HDMI", "Modem"
};
- /* starting device index for each PCM type */
- static int dev_idx[HDA_PCM_NTYPES] = {
- [HDA_PCM_TYPE_AUDIO] = 0,
- [HDA_PCM_TYPE_SPDIF] = 1,
- [HDA_PCM_TYPE_HDMI] = 3,
- [HDA_PCM_TYPE_MODEM] = 6
+ /* audio device indices; not linear to keep compatibility */
+ static int audio_idx[HDA_PCM_NTYPES][5] = {
+ [HDA_PCM_TYPE_AUDIO] = { 0, 2, 4, 5, -1 },
+ [HDA_PCM_TYPE_SPDIF] = { 1, -1 },
+ [HDA_PCM_TYPE_HDMI] = { 3, -1 },
+ [HDA_PCM_TYPE_MODEM] = { 6, -1 },
};
- /* normal audio device indices; not linear to keep compatibility */
- static int audio_idx[4] = { 0, 2, 4, 5 };
- int i, dev;
-
- switch (type) {
- case HDA_PCM_TYPE_AUDIO:
- for (i = 0; i < ARRAY_SIZE(audio_idx); i++) {
- dev = audio_idx[i];
- if (!test_bit(dev, bus->pcm_dev_bits))
- goto ok;
- }
- snd_printk(KERN_WARNING "Too many audio devices\n");
- return -EAGAIN;
- case HDA_PCM_TYPE_SPDIF:
- case HDA_PCM_TYPE_HDMI:
- case HDA_PCM_TYPE_MODEM:
- dev = dev_idx[type];
- if (test_bit(dev, bus->pcm_dev_bits)) {
- snd_printk(KERN_WARNING "%s already defined\n",
- dev_name[type]);
- return -EAGAIN;
- }
- break;
- default:
+ int i;
+
+ if (type >= HDA_PCM_NTYPES) {
snd_printk(KERN_WARNING "Invalid PCM type %d\n", type);
return -EINVAL;
}
- ok:
- set_bit(dev, bus->pcm_dev_bits);
- return dev;
+
+ for (i = 0; audio_idx[type][i] >= 0 ; i++)
+ if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
+ return audio_idx[type][i];
+
+ snd_printk(KERN_WARNING "Too many %s devices\n", dev_name[type]);
+ return -EAGAIN;
}
/*
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 03/11] hda - allow up to 4 HDMI devices
2009-10-15 7:03 [PATCH 00/11] Intel IbexPeak HDMI codec support Wu Fengguang
2009-10-15 7:03 ` [PATCH 01/11] hda - select IbexPeak handler for Calpella Wu Fengguang
2009-10-15 7:03 ` [PATCH 02/11] hda - vectorize get_empty_pcm_device() Wu Fengguang
@ 2009-10-15 7:03 ` Wu Fengguang
2009-10-15 7:03 ` [PATCH 04/11] hda - convert intelhdmi global references to local parameters Wu Fengguang
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wu Fengguang @ 2009-10-15 7:03 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Wu Fengguang
[-- Attachment #1: hdmi-allow-more-devices.patch --]
[-- Type: text/plain, Size: 787 bytes --]
The new Intel HDMI codec supports 2 independant HDMI/DisplayPort pipes.
We'll be exporting them as 2 pcm devices. So bump up the allowed number
of HDMI devices.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
sound/pci/hda/hda_codec.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- sound-2.6.orig/sound/pci/hda/hda_codec.c 2009-10-15 10:17:00.000000000 +0800
+++ sound-2.6/sound/pci/hda/hda_codec.c 2009-10-15 10:17:02.000000000 +0800
@@ -2889,7 +2889,7 @@ static int get_empty_pcm_device(struct h
static int audio_idx[HDA_PCM_NTYPES][5] = {
[HDA_PCM_TYPE_AUDIO] = { 0, 2, 4, 5, -1 },
[HDA_PCM_TYPE_SPDIF] = { 1, -1 },
- [HDA_PCM_TYPE_HDMI] = { 3, -1 },
+ [HDA_PCM_TYPE_HDMI] = { 3, 7, 8, 9, -1 },
[HDA_PCM_TYPE_MODEM] = { 6, -1 },
};
int i;
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 04/11] hda - convert intelhdmi global references to local parameters
2009-10-15 7:03 [PATCH 00/11] Intel IbexPeak HDMI codec support Wu Fengguang
` (2 preceding siblings ...)
2009-10-15 7:03 ` [PATCH 03/11] hda - allow up to 4 HDMI devices Wu Fengguang
@ 2009-10-15 7:03 ` Wu Fengguang
2009-10-15 7:03 ` [PATCH 05/11] hda - remove intelhdmi dependency on multiout Wu Fengguang
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wu Fengguang @ 2009-10-15 7:03 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Wu Fengguang
[-- Attachment #1: hdmi-local-pin-params.patch --]
[-- Type: text/plain, Size: 7751 bytes --]
No behavior change.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
sound/pci/hda/patch_intelhdmi.c | 80 ++++++++++++++++--------------
1 file changed, 43 insertions(+), 37 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-10-15 10:18:16.000000000 +0800
+++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-10-15 10:19:06.000000000 +0800
@@ -189,35 +189,36 @@ static struct cea_channel_speaker_alloca
*/
#ifdef BE_PARANOID
-static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t nid,
+static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
int *packet_index, int *byte_index)
{
int val;
- val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_INDEX, 0);
+ val = snd_hda_codec_read(codec, pin_nid, 0,
+ AC_VERB_GET_HDMI_DIP_INDEX, 0);
*packet_index = val >> 5;
*byte_index = val & 0x1f;
}
#endif
-static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t nid,
+static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
int packet_index, int byte_index)
{
int val;
val = (packet_index << 5) | (byte_index & 0x1f);
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
+ snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
}
-static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid,
+static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
unsigned char val)
{
- snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
+ snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
}
-static void hdmi_enable_output(struct hda_codec *codec)
+static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
{
/* Unmute */
if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
@@ -231,7 +232,8 @@ static void hdmi_enable_output(struct hd
/*
* Enable Audio InfoFrame Transmission
*/
-static void hdmi_start_infoframe_trans(struct hda_codec *codec)
+static void hdmi_start_infoframe_trans(struct hda_codec *codec,
+ hda_nid_t pin_nid)
{
hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
@@ -241,37 +243,40 @@ static void hdmi_start_infoframe_trans(s
/*
* Disable Audio InfoFrame Transmission
*/
-static void hdmi_stop_infoframe_trans(struct hda_codec *codec)
+static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
+ hda_nid_t pin_nid)
{
hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
AC_DIPXMIT_DISABLE);
}
-static int hdmi_get_channel_count(struct hda_codec *codec)
+static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
{
- return 1 + snd_hda_codec_read(codec, cvt_nid, 0,
+ return 1 + snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_CVT_CHAN_COUNT, 0);
}
-static void hdmi_set_channel_count(struct hda_codec *codec, int chs)
+static void hdmi_set_channel_count(struct hda_codec *codec,
+ hda_nid_t nid, int chs)
{
- snd_hda_codec_write(codec, cvt_nid, 0,
- AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
- if (chs != hdmi_get_channel_count(codec))
+#ifdef CONFIG_SND_DEBUG_VERBOSE
+ if (chs != hdmi_get_channel_count(codec, nid))
snd_printd(KERN_INFO "HDMI channel count: expect %d, get %d\n",
- chs, hdmi_get_channel_count(codec));
+ chs, hdmi_get_channel_count(codec, nid));
+#endif
}
-static void hdmi_debug_channel_mapping(struct hda_codec *codec)
+static void hdmi_debug_channel_mapping(struct hda_codec *codec, hda_nid_t nid)
{
#ifdef CONFIG_SND_DEBUG_VERBOSE
int i;
int slot;
for (i = 0; i < 8; i++) {
- slot = snd_hda_codec_read(codec, cvt_nid, 0,
+ slot = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_HDMI_CHAN_SLOT, i);
printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
slot >> 4, slot & 0x7);
@@ -293,7 +298,7 @@ static void hdmi_parse_eld(struct hda_co
* Audio InfoFrame routines
*/
-static void hdmi_debug_dip_size(struct hda_codec *codec)
+static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
{
#ifdef CONFIG_SND_DEBUG_VERBOSE
int i;
@@ -310,7 +315,7 @@ static void hdmi_debug_dip_size(struct h
#endif
}
-static void hdmi_clear_dip_buffers(struct hda_codec *codec)
+static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
{
#ifdef BE_PARANOID
int i, j;
@@ -340,14 +345,15 @@ static void hdmi_clear_dip_buffers(struc
}
static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
- struct hdmi_audio_infoframe *ai)
+ hda_nid_t pin_nid,
+ struct hdmi_audio_infoframe *ai)
{
u8 *params = (u8 *)ai;
u8 sum = 0;
int i;
- hdmi_debug_dip_size(codec);
- hdmi_clear_dip_buffers(codec); /* be paranoid */
+ hdmi_debug_dip_size(codec, pin_nid);
+ hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
for (i = 0; i < sizeof(ai); i++)
sum += params[i];
@@ -386,7 +392,7 @@ static void init_channel_allocations(voi
*
* TODO: it could select the wrong CA from multiple candidates.
*/
-static int hdmi_setup_channel_allocation(struct hda_codec *codec,
+static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
struct hdmi_audio_infoframe *ai)
{
struct intel_hdmi_spec *spec = codec->spec;
@@ -439,8 +445,8 @@ static int hdmi_setup_channel_allocation
return ai->CA;
}
-static void hdmi_setup_channel_mapping(struct hda_codec *codec,
- struct hdmi_audio_infoframe *ai)
+static void hdmi_setup_channel_mapping(struct hda_codec *codec, hda_nid_t nid,
+ struct hdmi_audio_infoframe *ai)
{
int i;
@@ -453,15 +459,15 @@ static void hdmi_setup_channel_mapping(s
*/
for (i = 0; i < 8; i++)
- snd_hda_codec_write(codec, cvt_nid, 0,
+ snd_hda_codec_write(codec, nid, 0,
AC_VERB_SET_HDMI_CHAN_SLOT,
(i << 4) | i);
- hdmi_debug_channel_mapping(codec);
+ hdmi_debug_channel_mapping(codec, nid);
}
-static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
+static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
struct snd_pcm_substream *substream)
{
struct hdmi_audio_infoframe ai = {
@@ -471,11 +477,11 @@ static void hdmi_setup_audio_infoframe(s
.CC02_CT47 = substream->runtime->channels - 1,
};
- hdmi_setup_channel_allocation(codec, &ai);
- hdmi_setup_channel_mapping(codec, &ai);
+ hdmi_setup_channel_allocation(codec, nid, &ai);
+ hdmi_setup_channel_mapping(codec, nid, &ai);
- hdmi_fill_audio_infoframe(codec, &ai);
- hdmi_start_infoframe_trans(codec);
+ hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
+ hdmi_start_infoframe_trans(codec, pin_nid);
}
@@ -553,7 +559,7 @@ static int intel_hdmi_playback_pcm_close
{
struct intel_hdmi_spec *spec = codec->spec;
- hdmi_stop_infoframe_trans(codec);
+ hdmi_stop_infoframe_trans(codec, pin_nid);
return snd_hda_multi_out_dig_close(codec, &spec->multiout);
}
@@ -569,9 +575,9 @@ static int intel_hdmi_playback_pcm_prepa
snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
format, substream);
- hdmi_set_channel_count(codec, substream->runtime->channels);
+ hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
- hdmi_setup_audio_infoframe(codec, substream);
+ hdmi_setup_audio_infoframe(codec, cvt_nid, substream);
return 0;
}
@@ -619,7 +625,7 @@ static int intel_hdmi_build_controls(str
static int intel_hdmi_init(struct hda_codec *codec)
{
- hdmi_enable_output(codec);
+ hdmi_enable_output(codec, pin_nid);
snd_hda_codec_write(codec, pin_nid, 0,
AC_VERB_SET_UNSOLICITED_ENABLE,
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 05/11] hda - remove intelhdmi dependency on multiout
2009-10-15 7:03 [PATCH 00/11] Intel IbexPeak HDMI codec support Wu Fengguang
` (3 preceding siblings ...)
2009-10-15 7:03 ` [PATCH 04/11] hda - convert intelhdmi global references to local parameters Wu Fengguang
@ 2009-10-15 7:03 ` Wu Fengguang
2009-10-15 7:03 ` [PATCH 06/11] hda - use pcm prepare/cleanup callbacks for intelhdmi Wu Fengguang
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wu Fengguang @ 2009-10-15 7:03 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Wu Fengguang
[-- Attachment #1: hdmi-remove-multiout.patch --]
[-- Type: text/plain, Size: 2487 bytes --]
We'll be managing multiple HDMI audio sources/sinks on our own.
So remove multiout dependency from intelhdmi.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
sound/pci/hda/patch_intelhdmi.c | 23 +++++++----------------
1 file changed, 7 insertions(+), 16 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-10-15 12:31:57.000000000 +0800
+++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-10-15 12:33:18.000000000 +0800
@@ -39,7 +39,6 @@ static hda_nid_t pin_nid; /* HDMI output
#define INTEL_HDMI_EVENT_TAG 0x08
struct intel_hdmi_spec {
- struct hda_multi_out multiout;
struct hda_pcm pcm_rec;
struct hdmi_eld sink_eld;
};
@@ -548,9 +547,7 @@ static int intel_hdmi_playback_pcm_open(
struct hda_codec *codec,
struct snd_pcm_substream *substream)
{
- struct intel_hdmi_spec *spec = codec->spec;
-
- return snd_hda_multi_out_dig_open(codec, &spec->multiout);
+ return 0;
}
static int intel_hdmi_playback_pcm_close(struct hda_pcm_stream *hinfo,
@@ -561,7 +558,8 @@ static int intel_hdmi_playback_pcm_close
hdmi_stop_infoframe_trans(codec, pin_nid);
- return snd_hda_multi_out_dig_close(codec, &spec->multiout);
+ snd_hda_codec_cleanup_stream(codec, hinfo->nid);
+ return 0;
}
static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
@@ -570,15 +568,12 @@ static int intel_hdmi_playback_pcm_prepa
unsigned int format,
struct snd_pcm_substream *substream)
{
- struct intel_hdmi_spec *spec = codec->spec;
-
- snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
- format, substream);
-
- hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
+ hdmi_set_channel_count(codec, cvt_nid,
+ substream->runtime->channels);
hdmi_setup_audio_infoframe(codec, cvt_nid, substream);
+ snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
return 0;
}
@@ -616,7 +611,7 @@ static int intel_hdmi_build_controls(str
struct intel_hdmi_spec *spec = codec->spec;
int err;
- err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
+ err = snd_hda_create_spdif_out_ctls(codec, cvt_nid);
if (err < 0)
return err;
@@ -657,10 +652,6 @@ static int do_patch_intel_hdmi(struct hd
if (spec == NULL)
return -ENOMEM;
- spec->multiout.num_dacs = 0; /* no analog */
- spec->multiout.max_channels = 8;
- spec->multiout.dig_out_nid = cvt_nid;
-
codec->spec = spec;
codec->patch_ops = intel_hdmi_patch_ops;
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 06/11] hda - use pcm prepare/cleanup callbacks for intelhdmi
2009-10-15 7:03 [PATCH 00/11] Intel IbexPeak HDMI codec support Wu Fengguang
` (4 preceding siblings ...)
2009-10-15 7:03 ` [PATCH 05/11] hda - remove intelhdmi dependency on multiout Wu Fengguang
@ 2009-10-15 7:03 ` Wu Fengguang
2009-10-15 7:03 ` [PATCH 07/11] hda - reorder intelhdmi prepare/cleanup callbacks Wu Fengguang
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wu Fengguang @ 2009-10-15 7:03 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Wu Fengguang
[-- Attachment #1: hdmi-pcm-prepare-cleanup.patch --]
[-- Type: text/plain, Size: 1355 bytes --]
Remove pcm callbacks open/close in favor of the prepare/cleanup.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
sound/pci/hda/patch_intelhdmi.c | 18 +++++-------------
1 file changed, 5 insertions(+), 13 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-10-15 12:33:18.000000000 +0800
+++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-10-15 12:35:36.000000000 +0800
@@ -543,16 +543,9 @@ static void intel_hdmi_unsol_event(struc
* Callbacks
*/
-static int intel_hdmi_playback_pcm_open(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
-{
- return 0;
-}
-
-static int intel_hdmi_playback_pcm_close(struct hda_pcm_stream *hinfo,
- struct hda_codec *codec,
- struct snd_pcm_substream *substream)
+static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+ struct hda_codec *codec,
+ struct snd_pcm_substream *substream)
{
struct intel_hdmi_spec *spec = codec->spec;
@@ -582,9 +575,8 @@ static struct hda_pcm_stream intel_hdmi_
.channels_min = 2,
.channels_max = 8,
.ops = {
- .open = intel_hdmi_playback_pcm_open,
- .close = intel_hdmi_playback_pcm_close,
- .prepare = intel_hdmi_playback_pcm_prepare
+ .prepare = intel_hdmi_playback_pcm_prepare,
+ .cleanup = intel_hdmi_playback_pcm_cleanup,
},
};
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 07/11] hda - reorder intelhdmi prepare/cleanup callbacks
2009-10-15 7:03 [PATCH 00/11] Intel IbexPeak HDMI codec support Wu Fengguang
` (5 preceding siblings ...)
2009-10-15 7:03 ` [PATCH 06/11] hda - use pcm prepare/cleanup callbacks for intelhdmi Wu Fengguang
@ 2009-10-15 7:03 ` Wu Fengguang
2009-10-15 7:03 ` [PATCH 08/11] hda - vectorize intelhdmi Wu Fengguang
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wu Fengguang @ 2009-10-15 7:03 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Wu Fengguang
[-- Attachment #1: hdmi-swap-pcm-prepare-cleanup.patch --]
[-- Type: text/plain, Size: 1784 bytes --]
No behavior change.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
sound/pci/hda/patch_intelhdmi.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-10-15 10:19:14.000000000 +0800
+++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-10-15 10:19:31.000000000 +0800
@@ -543,30 +543,30 @@ static void intel_hdmi_unsol_event(struc
* Callbacks
*/
-static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
+static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
+ unsigned int stream_tag,
+ unsigned int format,
struct snd_pcm_substream *substream)
{
- struct intel_hdmi_spec *spec = codec->spec;
+ hdmi_set_channel_count(codec, cvt_nid,
+ substream->runtime->channels);
- hdmi_stop_infoframe_trans(codec, pin_nid);
+ hdmi_setup_audio_infoframe(codec, cvt_nid, substream);
- snd_hda_codec_cleanup_stream(codec, hinfo->nid);
+ snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
return 0;
}
-static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
+static int intel_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
struct hda_codec *codec,
- unsigned int stream_tag,
- unsigned int format,
struct snd_pcm_substream *substream)
{
- hdmi_set_channel_count(codec, cvt_nid,
- substream->runtime->channels);
+ struct intel_hdmi_spec *spec = codec->spec;
- hdmi_setup_audio_infoframe(codec, cvt_nid, substream);
+ hdmi_stop_infoframe_trans(codec, pin_nid);
- snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
+ snd_hda_codec_cleanup_stream(codec, hinfo->nid);
return 0;
}
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 08/11] hda - vectorize intelhdmi
2009-10-15 7:03 [PATCH 00/11] Intel IbexPeak HDMI codec support Wu Fengguang
` (6 preceding siblings ...)
2009-10-15 7:03 ` [PATCH 07/11] hda - reorder intelhdmi prepare/cleanup callbacks Wu Fengguang
@ 2009-10-15 7:03 ` Wu Fengguang
2009-10-15 7:03 ` [PATCH 09/11] hda - get intelhdmi max channels from widget caps Wu Fengguang
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wu Fengguang @ 2009-10-15 7:03 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Wu Fengguang
[-- Attachment #1: alsa-ibexpeak-hdmi-pin-array.patch --]
[-- Type: text/plain, Size: 12029 bytes --]
The Intel IbexPeak HDMI codec supports 2 converters and 3 pins,
which requires converting the cvt_nid/pin_nid to arrays.
The active pin number (the one connected with a live HDMI monitor/sink)
will be dynamically identified on hotplug events.
It exports two HDMI devices, so that user space can choose the A/V pipe
for sending the audio samples.
It's still undefined behavior when there are two active monitors
connected and routed to the same audio converter.
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
sound/pci/hda/hda_eld.c | 5
sound/pci/hda/hda_local.h | 6
sound/pci/hda/patch_intelhdmi.c | 191 +++++++++++++++++++++++-------
3 files changed, 155 insertions(+), 47 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-10-15 12:35:40.000000000 +0800
+++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-10-15 12:38:34.000000000 +0800
@@ -33,14 +33,43 @@
#include "hda_codec.h"
#include "hda_local.h"
-static hda_nid_t cvt_nid; /* audio converter */
-static hda_nid_t pin_nid; /* HDMI output pin */
+/*
+ * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
+ * could support two independent pipes, each of them can be connected to one or
+ * more ports (DVI, HDMI or DisplayPort).
+ *
+ * The HDA correspondence of pipes/ports are converter/pin nodes.
+ */
+#define INTEL_HDMI_CVTS 2
+#define INTEL_HDMI_PINS 3
-#define INTEL_HDMI_EVENT_TAG 0x08
+static char *intel_hdmi_pcm_names[INTEL_HDMI_CVTS] = {
+ "INTEL HDMI 0",
+ "INTEL HDMI 1",
+};
struct intel_hdmi_spec {
- struct hda_pcm pcm_rec;
- struct hdmi_eld sink_eld;
+ int num_cvts;
+ int num_pins;
+ hda_nid_t cvt[INTEL_HDMI_CVTS+1]; /* audio sources */
+ hda_nid_t pin[INTEL_HDMI_PINS+1]; /* audio sinks */
+
+ /*
+ * source connection for each pin
+ */
+ hda_nid_t pin_cvt[INTEL_HDMI_PINS+1];
+
+ /*
+ * HDMI sink attached to each pin
+ */
+ bool sink_present[INTEL_HDMI_PINS];
+ bool sink_eldv[INTEL_HDMI_PINS];
+ struct hdmi_eld sink_eld[INTEL_HDMI_PINS];
+
+ /*
+ * export one pcm per pipe
+ */
+ struct hda_pcm pcm_rec[INTEL_HDMI_CVTS];
};
struct hdmi_audio_infoframe {
@@ -183,6 +212,19 @@ static struct cea_channel_speaker_alloca
{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
};
+
+static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
+{
+ int i;
+
+ for (i = 0; nids[i]; i++)
+ if (nids[i] == nid)
+ return i;
+
+ snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
+ return -EINVAL;
+}
+
/*
* HDMI routines
*/
@@ -283,12 +325,12 @@ static void hdmi_debug_channel_mapping(s
#endif
}
-static void hdmi_parse_eld(struct hda_codec *codec)
+static void hdmi_parse_eld(struct hda_codec *codec, int index)
{
struct intel_hdmi_spec *spec = codec->spec;
- struct hdmi_eld *eld = &spec->sink_eld;
+ struct hdmi_eld *eld = &spec->sink_eld[index];
- if (!snd_hdmi_get_eld(eld, codec, pin_nid))
+ if (!snd_hdmi_get_eld(eld, codec, spec->pin[index]))
snd_hdmi_show_eld(eld);
}
@@ -395,7 +437,7 @@ static int hdmi_setup_channel_allocation
struct hdmi_audio_infoframe *ai)
{
struct intel_hdmi_spec *spec = codec->spec;
- struct hdmi_eld *eld = &spec->sink_eld;
+ struct hdmi_eld *eld;
int i;
int spk_mask = 0;
int channels = 1 + (ai->CC02_CT47 & 0x7);
@@ -407,6 +449,11 @@ static int hdmi_setup_channel_allocation
if (channels <= 2)
return 0;
+ i = hda_node_index(spec->pin_cvt, nid);
+ if (i < 0)
+ return 0;
+ eld = &spec->sink_eld[i];
+
/*
* HDMI sink's ELD info cannot always be retrieved for now, e.g.
* in console or for audio devices. Assume the highest speakers
@@ -469,6 +516,9 @@ static void hdmi_setup_channel_mapping(s
static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
struct snd_pcm_substream *substream)
{
+ struct intel_hdmi_spec *spec = codec->spec;
+ hda_nid_t pin_nid;
+ int i;
struct hdmi_audio_infoframe ai = {
.type = 0x84,
.ver = 0x01,
@@ -479,8 +529,16 @@ static void hdmi_setup_audio_infoframe(s
hdmi_setup_channel_allocation(codec, nid, &ai);
hdmi_setup_channel_mapping(codec, nid, &ai);
- hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
- hdmi_start_infoframe_trans(codec, pin_nid);
+ for (i = 0; i < spec->num_pins; i++) {
+ if (spec->pin_cvt[i] != nid)
+ continue;
+ if (spec->sink_present[i] != true)
+ continue;
+
+ pin_nid = spec->pin[i];
+ hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
+ hdmi_start_infoframe_trans(codec, pin_nid);
+ }
}
@@ -490,27 +548,39 @@ static void hdmi_setup_audio_infoframe(s
static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
{
+ struct intel_hdmi_spec *spec = codec->spec;
+ int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
int pind = !!(res & AC_UNSOL_RES_PD);
int eldv = !!(res & AC_UNSOL_RES_ELDV);
+ int index;
printk(KERN_INFO
- "HDMI hot plug event: Presence_Detect=%d ELD_Valid=%d\n",
- pind, eldv);
+ "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
+ tag, pind, eldv);
+
+ index = hda_node_index(spec->pin, tag);
+ if (index < 0)
+ return;
+
+ spec->sink_present[index] = pind;
+ spec->sink_eldv[index] = eldv;
if (pind && eldv) {
- hdmi_parse_eld(codec);
+ hdmi_parse_eld(codec, index);
/* TODO: do real things about ELD */
}
}
static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
{
+ int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
printk(KERN_INFO
- "HDMI content protection event: SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
+ "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
+ tag,
subtag,
cp_state,
cp_ready);
@@ -525,10 +595,11 @@ static void hdmi_non_intrinsic_event(str
static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
{
+ struct intel_hdmi_spec *spec = codec->spec;
int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
- if (tag != INTEL_HDMI_EVENT_TAG) {
+ if (hda_node_index(spec->pin, tag) < 0) {
snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
return;
}
@@ -549,10 +620,10 @@ static int intel_hdmi_playback_pcm_prepa
unsigned int format,
struct snd_pcm_substream *substream)
{
- hdmi_set_channel_count(codec, cvt_nid,
+ hdmi_set_channel_count(codec, hinfo->nid,
substream->runtime->channels);
- hdmi_setup_audio_infoframe(codec, cvt_nid, substream);
+ hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
return 0;
@@ -563,8 +634,14 @@ static int intel_hdmi_playback_pcm_clean
struct snd_pcm_substream *substream)
{
struct intel_hdmi_spec *spec = codec->spec;
+ int i;
+
+ for (i = 0; i < spec->num_pins; i++) {
+ if (spec->pin_cvt[i] != hinfo->nid)
+ continue;
- hdmi_stop_infoframe_trans(codec, pin_nid);
+ hdmi_stop_infoframe_trans(codec, spec->pin[i]);
+ }
snd_hda_codec_cleanup_stream(codec, hinfo->nid);
return 0;
@@ -583,17 +660,19 @@ static struct hda_pcm_stream intel_hdmi_
static int intel_hdmi_build_pcms(struct hda_codec *codec)
{
struct intel_hdmi_spec *spec = codec->spec;
- struct hda_pcm *info = &spec->pcm_rec;
+ struct hda_pcm *info = spec->pcm_rec;
+ int i;
- codec->num_pcms = 1;
+ codec->num_pcms = spec->num_cvts;
codec->pcm_info = info;
- /* NID to query formats and rates and setup streams */
- intel_hdmi_pcm_playback.nid = cvt_nid;
-
- info->name = "INTEL HDMI";
- info->pcm_type = HDA_PCM_TYPE_HDMI;
- info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback;
+ for (i = 0; i < codec->num_pcms; i++, info++) {
+ info->name = intel_hdmi_pcm_names[i];
+ info->pcm_type = HDA_PCM_TYPE_HDMI;
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
+ intel_hdmi_pcm_playback;
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
+ }
return 0;
}
@@ -602,29 +681,39 @@ static int intel_hdmi_build_controls(str
{
struct intel_hdmi_spec *spec = codec->spec;
int err;
+ int i;
- err = snd_hda_create_spdif_out_ctls(codec, cvt_nid);
- if (err < 0)
- return err;
+ for (i = 0; i < codec->num_pcms; i++) {
+ err = snd_hda_create_spdif_out_ctls(codec, spec->cvt[i]);
+ if (err < 0)
+ return err;
+ }
return 0;
}
static int intel_hdmi_init(struct hda_codec *codec)
{
- hdmi_enable_output(codec, pin_nid);
+ struct intel_hdmi_spec *spec = codec->spec;
+ int i;
- snd_hda_codec_write(codec, pin_nid, 0,
- AC_VERB_SET_UNSOLICITED_ENABLE,
- AC_USRSP_EN | INTEL_HDMI_EVENT_TAG);
+ for (i = 0; spec->pin[i]; i++) {
+ hdmi_enable_output(codec, spec->pin[i]);
+ snd_hda_codec_write(codec, spec->pin[i], 0,
+ AC_VERB_SET_UNSOLICITED_ENABLE,
+ AC_USRSP_EN | spec->pin[i]);
+ }
return 0;
}
static void intel_hdmi_free(struct hda_codec *codec)
{
struct intel_hdmi_spec *spec = codec->spec;
+ int i;
+
+ for (i = 0; i < spec->num_pins; i++)
+ snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
- snd_hda_eld_proc_free(codec, &spec->sink_eld);
kfree(spec);
}
@@ -636,18 +725,38 @@ static struct hda_codec_ops intel_hdmi_p
.unsol_event = intel_hdmi_unsol_event,
};
-static int do_patch_intel_hdmi(struct hda_codec *codec)
+static struct intel_hdmi_spec static_specs[] = {
+ {
+ .num_cvts = 1,
+ .num_pins = 1,
+ .cvt = { 0x2 },
+ .pin = { 0x3 },
+ .pin_cvt = { 0x2 },
+ },
+ {
+ .num_cvts = 2,
+ .num_pins = 3,
+ .cvt = { 0x2, 0x3 },
+ .pin = { 0x4, 0x5, 0x6 },
+ .pin_cvt = { 0x2, 0x2, 0x2 },
+ },
+};
+
+static int do_patch_intel_hdmi(struct hda_codec *codec, int spec_id)
{
struct intel_hdmi_spec *spec;
+ int i;
spec = kzalloc(sizeof(*spec), GFP_KERNEL);
if (spec == NULL)
return -ENOMEM;
+ *spec = static_specs[spec_id];
codec->spec = spec;
codec->patch_ops = intel_hdmi_patch_ops;
- snd_hda_eld_proc_new(codec, &spec->sink_eld);
+ for (i = 0; i < spec->num_pins; i++)
+ snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
init_channel_allocations();
@@ -656,16 +765,12 @@ static int do_patch_intel_hdmi(struct hd
static int patch_intel_hdmi(struct hda_codec *codec)
{
- cvt_nid = 0x02;
- pin_nid = 0x03;
- return do_patch_intel_hdmi(codec);
+ return do_patch_intel_hdmi(codec, 0);
}
static int patch_intel_hdmi_ibexpeak(struct hda_codec *codec)
{
- cvt_nid = 0x02;
- pin_nid = 0x04;
- return do_patch_intel_hdmi(codec);
+ return do_patch_intel_hdmi(codec, 1);
}
static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
--- sound-2.6.orig/sound/pci/hda/hda_eld.c 2009-10-15 11:16:02.000000000 +0800
+++ sound-2.6/sound/pci/hda/hda_eld.c 2009-10-15 12:35:42.000000000 +0800
@@ -560,13 +560,14 @@ static void hdmi_write_eld_info(struct s
}
-int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld)
+int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
+ int index)
{
char name[32];
struct snd_info_entry *entry;
int err;
- snprintf(name, sizeof(name), "eld#%d", codec->addr);
+ snprintf(name, sizeof(name), "eld#%d.%d", codec->addr, index);
err = snd_card_proc_new(codec->bus->card, name, &entry);
if (err < 0)
return err;
--- sound-2.6.orig/sound/pci/hda/hda_local.h 2009-10-15 11:16:02.000000000 +0800
+++ sound-2.6/sound/pci/hda/hda_local.h 2009-10-15 12:35:42.000000000 +0800
@@ -541,11 +541,13 @@ int snd_hdmi_get_eld(struct hdmi_eld *,
void snd_hdmi_show_eld(struct hdmi_eld *eld);
#ifdef CONFIG_PROC_FS
-int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld);
+int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
+ int index);
void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld);
#else
static inline int snd_hda_eld_proc_new(struct hda_codec *codec,
- struct hdmi_eld *eld)
+ struct hdmi_eld *eld,
+ int index)
{
return 0;
}
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 09/11] hda - get intelhdmi max channels from widget caps
2009-10-15 7:03 [PATCH 00/11] Intel IbexPeak HDMI codec support Wu Fengguang
` (7 preceding siblings ...)
2009-10-15 7:03 ` [PATCH 08/11] hda - vectorize intelhdmi Wu Fengguang
@ 2009-10-15 7:03 ` Wu Fengguang
2009-10-15 7:03 ` [PATCH 10/11] hda - auto parse intelhdmi cvt/pin configurations Wu Fengguang
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Wu Fengguang @ 2009-10-15 7:03 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Wu Fengguang
[-- Attachment #1: hdmi-dyn-channel.patch --]
[-- Type: text/plain, Size: 1161 bytes --]
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
sound/pci/hda/patch_intelhdmi.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-10-15 12:38:50.000000000 +0800
+++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-10-15 12:38:57.000000000 +0800
@@ -650,7 +650,6 @@ static int intel_hdmi_playback_pcm_clean
static struct hda_pcm_stream intel_hdmi_pcm_playback = {
.substreams = 1,
.channels_min = 2,
- .channels_max = 8,
.ops = {
.prepare = intel_hdmi_playback_pcm_prepare,
.cleanup = intel_hdmi_playback_pcm_cleanup,
@@ -667,11 +666,17 @@ static int intel_hdmi_build_pcms(struct
codec->pcm_info = info;
for (i = 0; i < codec->num_pcms; i++, info++) {
+ unsigned int chans;
+
+ chans = get_wcaps(codec, spec->cvt[i]);
+ chans = get_wcaps_channels(chans);
+
info->name = intel_hdmi_pcm_names[i];
info->pcm_type = HDA_PCM_TYPE_HDMI;
info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
intel_hdmi_pcm_playback;
info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
+ info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
}
return 0;
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 10/11] hda - auto parse intelhdmi cvt/pin configurations
2009-10-15 7:03 [PATCH 00/11] Intel IbexPeak HDMI codec support Wu Fengguang
` (8 preceding siblings ...)
2009-10-15 7:03 ` [PATCH 09/11] hda - get intelhdmi max channels from widget caps Wu Fengguang
@ 2009-10-15 7:03 ` Wu Fengguang
2009-10-15 7:03 ` [PATCH 11/11] hda - remove static intelhdmi configurations Wu Fengguang
2009-10-30 10:47 ` [PATCH 00/11] Intel IbexPeak HDMI codec support Takashi Iwai
11 siblings, 0 replies; 13+ messages in thread
From: Wu Fengguang @ 2009-10-15 7:03 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Wu Fengguang
[-- Attachment #1: hdmi-auto-parse.patch --]
[-- Type: text/plain, Size: 3661 bytes --]
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
sound/pci/hda/patch_intelhdmi.c | 120 +++++++++++++++++++++++++++++-
1 file changed, 119 insertions(+), 1 deletion(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-10-15 12:38:57.000000000 +0800
+++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-10-15 12:41:02.000000000 +0800
@@ -213,6 +213,10 @@ static struct cea_channel_speaker_alloca
};
+/*
+ * HDA/HDMI auto parsing
+ */
+
static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
{
int i;
@@ -225,6 +229,113 @@ static int hda_node_index(hda_nid_t *nid
return -EINVAL;
}
+static int intel_hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
+{
+ struct intel_hdmi_spec *spec = codec->spec;
+ hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
+ int conn_len, curr;
+ int index;
+
+ if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
+ snd_printk(KERN_WARNING
+ "HDMI: pin %d wcaps %#x "
+ "does not support connection list\n",
+ pin_nid, get_wcaps(codec, pin_nid));
+ return -EINVAL;
+ }
+
+ conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
+ HDA_MAX_CONNECTIONS);
+ if (conn_len > 1)
+ curr = snd_hda_codec_read(codec, pin_nid, 0,
+ AC_VERB_GET_CONNECT_SEL, 0);
+ else
+ curr = 0;
+
+ index = hda_node_index(spec->pin, pin_nid);
+ if (index < 0)
+ return -EINVAL;
+
+ spec->pin_cvt[index] = conn_list[curr];
+
+ return 0;
+}
+
+static int intel_hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
+{
+ struct intel_hdmi_spec *spec = codec->spec;
+
+ if (spec->num_pins >= INTEL_HDMI_PINS) {
+ snd_printk(KERN_WARNING
+ "HDMI: no space for pin %d \n", pin_nid);
+ return -EINVAL;
+ }
+
+ spec->pin[spec->num_pins] = pin_nid;
+ spec->num_pins++;
+
+ /*
+ * It is assumed that converter nodes come first in the node list and
+ * hence have been registered and usable now.
+ */
+ return intel_hdmi_read_pin_conn(codec, pin_nid);
+}
+
+static int intel_hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
+{
+ struct intel_hdmi_spec *spec = codec->spec;
+
+ if (spec->num_cvts >= INTEL_HDMI_CVTS) {
+ snd_printk(KERN_WARNING
+ "HDMI: no space for converter %d \n", nid);
+ return -EINVAL;
+ }
+
+ spec->cvt[spec->num_cvts] = nid;
+ spec->num_cvts++;
+
+ return 0;
+}
+
+static int intel_hdmi_parse_codec(struct hda_codec *codec)
+{
+ hda_nid_t nid;
+ int i, nodes;
+
+ nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
+ if (!nid || nodes < 0) {
+ snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < nodes; i++, nid++) {
+ unsigned int caps;
+ unsigned int type;
+
+ caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
+ type = get_wcaps_type(caps);
+
+ if (!(caps & AC_WCAP_DIGITAL))
+ continue;
+
+ switch (type) {
+ case AC_WID_AUD_OUT:
+ if (intel_hdmi_add_cvt(codec, nid) < 0)
+ return -EINVAL;
+ break;
+ case AC_WID_PIN:
+ caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
+ if (!(caps & AC_PINCAP_HDMI))
+ continue;
+ if (intel_hdmi_add_pin(codec, nid) < 0)
+ return -EINVAL;
+ break;
+ }
+ }
+
+ return 0;
+}
+
/*
* HDMI routines
*/
@@ -756,8 +867,15 @@ static int do_patch_intel_hdmi(struct hd
if (spec == NULL)
return -ENOMEM;
- *spec = static_specs[spec_id];
codec->spec = spec;
+ if (intel_hdmi_parse_codec(codec) < 0) {
+ codec->spec = NULL;
+ kfree(spec);
+ return -EINVAL;
+ }
+ if (memcmp(spec, static_specs + spec_id, sizeof(*spec)))
+ snd_printk(KERN_WARNING
+ "HDMI: auto parse disagree with known config\n");
codec->patch_ops = intel_hdmi_patch_ops;
for (i = 0; i < spec->num_pins; i++)
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 11/11] hda - remove static intelhdmi configurations
2009-10-15 7:03 [PATCH 00/11] Intel IbexPeak HDMI codec support Wu Fengguang
` (9 preceding siblings ...)
2009-10-15 7:03 ` [PATCH 10/11] hda - auto parse intelhdmi cvt/pin configurations Wu Fengguang
@ 2009-10-15 7:03 ` Wu Fengguang
2009-10-30 10:47 ` [PATCH 00/11] Intel IbexPeak HDMI codec support Takashi Iwai
11 siblings, 0 replies; 13+ messages in thread
From: Wu Fengguang @ 2009-10-15 7:03 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel, Wu Fengguang
[-- Attachment #1: hdmi-remove-static.patch --]
[-- Type: text/plain, Size: 2319 bytes --]
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
sound/pci/hda/patch_intelhdmi.c | 36 ++----------------------------
1 file changed, 3 insertions(+), 33 deletions(-)
--- sound-2.6.orig/sound/pci/hda/patch_intelhdmi.c 2009-10-15 10:20:35.000000000 +0800
+++ sound-2.6/sound/pci/hda/patch_intelhdmi.c 2009-10-15 10:20:55.000000000 +0800
@@ -841,24 +841,7 @@ static struct hda_codec_ops intel_hdmi_p
.unsol_event = intel_hdmi_unsol_event,
};
-static struct intel_hdmi_spec static_specs[] = {
- {
- .num_cvts = 1,
- .num_pins = 1,
- .cvt = { 0x2 },
- .pin = { 0x3 },
- .pin_cvt = { 0x2 },
- },
- {
- .num_cvts = 2,
- .num_pins = 3,
- .cvt = { 0x2, 0x3 },
- .pin = { 0x4, 0x5, 0x6 },
- .pin_cvt = { 0x2, 0x2, 0x2 },
- },
-};
-
-static int do_patch_intel_hdmi(struct hda_codec *codec, int spec_id)
+static int patch_intel_hdmi(struct hda_codec *codec)
{
struct intel_hdmi_spec *spec;
int i;
@@ -873,9 +856,6 @@ static int do_patch_intel_hdmi(struct hd
kfree(spec);
return -EINVAL;
}
- if (memcmp(spec, static_specs + spec_id, sizeof(*spec)))
- snd_printk(KERN_WARNING
- "HDMI: auto parse disagree with known config\n");
codec->patch_ops = intel_hdmi_patch_ops;
for (i = 0; i < spec->num_pins; i++)
@@ -886,23 +866,13 @@ static int do_patch_intel_hdmi(struct hd
return 0;
}
-static int patch_intel_hdmi(struct hda_codec *codec)
-{
- return do_patch_intel_hdmi(codec, 0);
-}
-
-static int patch_intel_hdmi_ibexpeak(struct hda_codec *codec)
-{
- return do_patch_intel_hdmi(codec, 1);
-}
-
static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
{ .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi },
{ .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi },
{ .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi },
{ .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi },
- { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi_ibexpeak },
- { .id = 0x80860054, .name = "Q57 DEVIBX", .patch = patch_intel_hdmi_ibexpeak },
+ { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi },
+ { .id = 0x80860054, .name = "Q57 DEVIBX", .patch = patch_intel_hdmi },
{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
{} /* terminator */
};
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 00/11] Intel IbexPeak HDMI codec support
2009-10-15 7:03 [PATCH 00/11] Intel IbexPeak HDMI codec support Wu Fengguang
` (10 preceding siblings ...)
2009-10-15 7:03 ` [PATCH 11/11] hda - remove static intelhdmi configurations Wu Fengguang
@ 2009-10-30 10:47 ` Takashi Iwai
11 siblings, 0 replies; 13+ messages in thread
From: Takashi Iwai @ 2009-10-30 10:47 UTC (permalink / raw)
To: Wu Fengguang; +Cc: alsa-devel
At Thu, 15 Oct 2009 15:03:48 +0800,
Wu Fengguang wrote:
>
> Hi Takashi,
>
> This series adds support for the Intel IbexPeak HDMI codec, which can
> connect up to 3 monitors and support 2 independant A/V pipes. The patches
> are tested OK on IbexPeak and G45. DisplayPort is also working with another
> in-house KMS patch. However we have not tested dual monitor configurations
> (which should be rare for now).
Thanks, applied now all patches.
Takashi
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2009-10-30 10:47 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-15 7:03 [PATCH 00/11] Intel IbexPeak HDMI codec support Wu Fengguang
2009-10-15 7:03 ` [PATCH 01/11] hda - select IbexPeak handler for Calpella Wu Fengguang
2009-10-15 7:03 ` [PATCH 02/11] hda - vectorize get_empty_pcm_device() Wu Fengguang
2009-10-15 7:03 ` [PATCH 03/11] hda - allow up to 4 HDMI devices Wu Fengguang
2009-10-15 7:03 ` [PATCH 04/11] hda - convert intelhdmi global references to local parameters Wu Fengguang
2009-10-15 7:03 ` [PATCH 05/11] hda - remove intelhdmi dependency on multiout Wu Fengguang
2009-10-15 7:03 ` [PATCH 06/11] hda - use pcm prepare/cleanup callbacks for intelhdmi Wu Fengguang
2009-10-15 7:03 ` [PATCH 07/11] hda - reorder intelhdmi prepare/cleanup callbacks Wu Fengguang
2009-10-15 7:03 ` [PATCH 08/11] hda - vectorize intelhdmi Wu Fengguang
2009-10-15 7:03 ` [PATCH 09/11] hda - get intelhdmi max channels from widget caps Wu Fengguang
2009-10-15 7:03 ` [PATCH 10/11] hda - auto parse intelhdmi cvt/pin configurations Wu Fengguang
2009-10-15 7:03 ` [PATCH 11/11] hda - remove static intelhdmi configurations Wu Fengguang
2009-10-30 10:47 ` [PATCH 00/11] Intel IbexPeak HDMI codec support Takashi Iwai
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.