aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_intelhdmi.c
diff options
context:
space:
mode:
authorWu Fengguang <fengguang.wu@intel.com>2009-08-02 04:48:55 -0400
committerTakashi Iwai <tiwai@suse.de>2009-08-03 02:35:05 -0400
commit559059b27f1768e89adc204f3ba2cb82882c15ca (patch)
tree82a3abfc2affdeab3820b92d99cd39b60a807208 /sound/pci/hda/patch_intelhdmi.c
parent03cb2dafcbde938ed7d01d4b952ea60e3c4e8532 (diff)
ALSA: hda: add IbexPeak/Clarkdale HDMI model with static cvt/pin number
The new IbexPeak HDMI codec has 3 pin nodes and 2 converter nodes. Here we assume only the first ones will be used. Signed-off-by: Wu Fengguang <fengguang.wu@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_intelhdmi.c')
-rw-r--r--sound/pci/hda/patch_intelhdmi.c104
1 files changed, 52 insertions, 52 deletions
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index 032850eba369..01a18ed475ac 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -33,8 +33,8 @@
33#include "hda_codec.h" 33#include "hda_codec.h"
34#include "hda_local.h" 34#include "hda_local.h"
35 35
36#define CVT_NID 0x02 /* audio converter */ 36static hda_nid_t cvt_nid; /* audio converter */
37#define PIN_NID 0x03 /* HDMI output pin */ 37static hda_nid_t pin_nid; /* HDMI output pin */
38 38
39#define INTEL_HDMI_EVENT_TAG 0x08 39#define INTEL_HDMI_EVENT_TAG 0x08
40 40
@@ -44,30 +44,6 @@ struct intel_hdmi_spec {
44 struct hdmi_eld sink_eld; 44 struct hdmi_eld sink_eld;
45}; 45};
46 46
47static struct hda_verb pinout_enable_verb[] = {
48 {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
49 {} /* terminator */
50};
51
52static struct hda_verb unsolicited_response_verb[] = {
53 {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN |
54 INTEL_HDMI_EVENT_TAG},
55 {}
56};
57
58static struct hda_verb def_chan_map[] = {
59 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x00},
60 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x11},
61 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x22},
62 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x33},
63 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x44},
64 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x55},
65 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x66},
66 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x77},
67 {}
68};
69
70
71struct hdmi_audio_infoframe { 47struct hdmi_audio_infoframe {
72 u8 type; /* 0x84 */ 48 u8 type; /* 0x84 */
73 u8 ver; /* 0x01 */ 49 u8 ver; /* 0x01 */
@@ -244,11 +220,12 @@ static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid,
244static void hdmi_enable_output(struct hda_codec *codec) 220static void hdmi_enable_output(struct hda_codec *codec)
245{ 221{
246 /* Unmute */ 222 /* Unmute */
247 if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) 223 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
248 snd_hda_codec_write(codec, PIN_NID, 0, 224 snd_hda_codec_write(codec, pin_nid, 0,
249 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 225 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
250 /* Enable pin out */ 226 /* Enable pin out */
251 snd_hda_sequence_write(codec, pinout_enable_verb); 227 snd_hda_codec_write(codec, pin_nid, 0,
228 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
252} 229}
253 230
254/* 231/*
@@ -256,8 +233,8 @@ static void hdmi_enable_output(struct hda_codec *codec)
256 */ 233 */
257static void hdmi_start_infoframe_trans(struct hda_codec *codec) 234static void hdmi_start_infoframe_trans(struct hda_codec *codec)
258{ 235{
259 hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); 236 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
260 snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, 237 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
261 AC_DIPXMIT_BEST); 238 AC_DIPXMIT_BEST);
262} 239}
263 240
@@ -266,20 +243,20 @@ static void hdmi_start_infoframe_trans(struct hda_codec *codec)
266 */ 243 */
267static void hdmi_stop_infoframe_trans(struct hda_codec *codec) 244static void hdmi_stop_infoframe_trans(struct hda_codec *codec)
268{ 245{
269 hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); 246 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
270 snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, 247 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
271 AC_DIPXMIT_DISABLE); 248 AC_DIPXMIT_DISABLE);
272} 249}
273 250
274static int hdmi_get_channel_count(struct hda_codec *codec) 251static int hdmi_get_channel_count(struct hda_codec *codec)
275{ 252{
276 return 1 + snd_hda_codec_read(codec, CVT_NID, 0, 253 return 1 + snd_hda_codec_read(codec, cvt_nid, 0,
277 AC_VERB_GET_CVT_CHAN_COUNT, 0); 254 AC_VERB_GET_CVT_CHAN_COUNT, 0);
278} 255}
279 256
280static void hdmi_set_channel_count(struct hda_codec *codec, int chs) 257static void hdmi_set_channel_count(struct hda_codec *codec, int chs)
281{ 258{
282 snd_hda_codec_write(codec, CVT_NID, 0, 259 snd_hda_codec_write(codec, cvt_nid, 0,
283 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); 260 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
284 261
285 if (chs != hdmi_get_channel_count(codec)) 262 if (chs != hdmi_get_channel_count(codec))
@@ -294,7 +271,7 @@ static void hdmi_debug_channel_mapping(struct hda_codec *codec)
294 int slot; 271 int slot;
295 272
296 for (i = 0; i < 8; i++) { 273 for (i = 0; i < 8; i++) {
297 slot = snd_hda_codec_read(codec, CVT_NID, 0, 274 slot = snd_hda_codec_read(codec, cvt_nid, 0,
298 AC_VERB_GET_HDMI_CHAN_SLOT, i); 275 AC_VERB_GET_HDMI_CHAN_SLOT, i);
299 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n", 276 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
300 slot >> 4, slot & 0x7); 277 slot >> 4, slot & 0x7);
@@ -307,7 +284,7 @@ static void hdmi_parse_eld(struct hda_codec *codec)
307 struct intel_hdmi_spec *spec = codec->spec; 284 struct intel_hdmi_spec *spec = codec->spec;
308 struct hdmi_eld *eld = &spec->sink_eld; 285 struct hdmi_eld *eld = &spec->sink_eld;
309 286
310 if (!snd_hdmi_get_eld(eld, codec, PIN_NID)) 287 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
311 snd_hdmi_show_eld(eld); 288 snd_hdmi_show_eld(eld);
312} 289}
313 290
@@ -322,11 +299,11 @@ static void hdmi_debug_dip_size(struct hda_codec *codec)
322 int i; 299 int i;
323 int size; 300 int size;
324 301
325 size = snd_hdmi_get_eld_size(codec, PIN_NID); 302 size = snd_hdmi_get_eld_size(codec, pin_nid);
326 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size); 303 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
327 304
328 for (i = 0; i < 8; i++) { 305 for (i = 0; i < 8; i++) {
329 size = snd_hda_codec_read(codec, PIN_NID, 0, 306 size = snd_hda_codec_read(codec, pin_nid, 0,
330 AC_VERB_GET_HDMI_DIP_SIZE, i); 307 AC_VERB_GET_HDMI_DIP_SIZE, i);
331 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size); 308 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
332 } 309 }
@@ -340,15 +317,15 @@ static void hdmi_clear_dip_buffers(struct hda_codec *codec)
340 int size; 317 int size;
341 int pi, bi; 318 int pi, bi;
342 for (i = 0; i < 8; i++) { 319 for (i = 0; i < 8; i++) {
343 size = snd_hda_codec_read(codec, PIN_NID, 0, 320 size = snd_hda_codec_read(codec, pin_nid, 0,
344 AC_VERB_GET_HDMI_DIP_SIZE, i); 321 AC_VERB_GET_HDMI_DIP_SIZE, i);
345 if (size == 0) 322 if (size == 0)
346 continue; 323 continue;
347 324
348 hdmi_set_dip_index(codec, PIN_NID, i, 0x0); 325 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
349 for (j = 1; j < 1000; j++) { 326 for (j = 1; j < 1000; j++) {
350 hdmi_write_dip_byte(codec, PIN_NID, 0x0); 327 hdmi_write_dip_byte(codec, pin_nid, 0x0);
351 hdmi_get_dip_index(codec, PIN_NID, &pi, &bi); 328 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
352 if (pi != i) 329 if (pi != i)
353 snd_printd(KERN_INFO "dip index %d: %d != %d\n", 330 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
354 bi, pi, i); 331 bi, pi, i);
@@ -376,9 +353,9 @@ static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
376 sum += params[i]; 353 sum += params[i];
377 ai->checksum = - sum; 354 ai->checksum = - sum;
378 355
379 hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); 356 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
380 for (i = 0; i < sizeof(ai); i++) 357 for (i = 0; i < sizeof(ai); i++)
381 hdmi_write_dip_byte(codec, PIN_NID, params[i]); 358 hdmi_write_dip_byte(codec, pin_nid, params[i]);
382} 359}
383 360
384/* 361/*
@@ -465,6 +442,8 @@ static int hdmi_setup_channel_allocation(struct hda_codec *codec,
465static void hdmi_setup_channel_mapping(struct hda_codec *codec, 442static void hdmi_setup_channel_mapping(struct hda_codec *codec,
466 struct hdmi_audio_infoframe *ai) 443 struct hdmi_audio_infoframe *ai)
467{ 444{
445 int i;
446
468 if (!ai->CA) 447 if (!ai->CA)
469 return; 448 return;
470 449
@@ -473,7 +452,11 @@ static void hdmi_setup_channel_mapping(struct hda_codec *codec,
473 * ALSA sequence is front/surr/clfe/side? 452 * ALSA sequence is front/surr/clfe/side?
474 */ 453 */
475 454
476 snd_hda_sequence_write(codec, def_chan_map); 455 for (i = 0; i < 8; i++)
456 snd_hda_codec_write(codec, cvt_nid, 0,
457 AC_VERB_SET_HDMI_CHAN_SLOT,
458 (i << 4) | i);
459
477 hdmi_debug_channel_mapping(codec); 460 hdmi_debug_channel_mapping(codec);
478} 461}
479 462
@@ -597,7 +580,6 @@ static struct hda_pcm_stream intel_hdmi_pcm_playback = {
597 .substreams = 1, 580 .substreams = 1,
598 .channels_min = 2, 581 .channels_min = 2,
599 .channels_max = 8, 582 .channels_max = 8,
600 .nid = CVT_NID, /* NID to query formats and rates and setup streams */
601 .ops = { 583 .ops = {
602 .open = intel_hdmi_playback_pcm_open, 584 .open = intel_hdmi_playback_pcm_open,
603 .close = intel_hdmi_playback_pcm_close, 585 .close = intel_hdmi_playback_pcm_close,
@@ -613,6 +595,9 @@ static int intel_hdmi_build_pcms(struct hda_codec *codec)
613 codec->num_pcms = 1; 595 codec->num_pcms = 1;
614 codec->pcm_info = info; 596 codec->pcm_info = info;
615 597
598 /* NID to query formats and rates and setup streams */
599 intel_hdmi_pcm_playback.nid = cvt_nid;
600
616 info->name = "INTEL HDMI"; 601 info->name = "INTEL HDMI";
617 info->pcm_type = HDA_PCM_TYPE_HDMI; 602 info->pcm_type = HDA_PCM_TYPE_HDMI;
618 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback; 603 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback;
@@ -636,8 +621,9 @@ static int intel_hdmi_init(struct hda_codec *codec)
636{ 621{
637 hdmi_enable_output(codec); 622 hdmi_enable_output(codec);
638 623
639 snd_hda_sequence_write(codec, unsolicited_response_verb); 624 snd_hda_codec_write(codec, pin_nid, 0,
640 625 AC_VERB_SET_UNSOLICITED_ENABLE,
626 AC_USRSP_EN | INTEL_HDMI_EVENT_TAG);
641 return 0; 627 return 0;
642} 628}
643 629
@@ -657,7 +643,7 @@ static struct hda_codec_ops intel_hdmi_patch_ops = {
657 .unsol_event = intel_hdmi_unsol_event, 643 .unsol_event = intel_hdmi_unsol_event,
658}; 644};
659 645
660static int patch_intel_hdmi(struct hda_codec *codec) 646static int do_patch_intel_hdmi(struct hda_codec *codec)
661{ 647{
662 struct intel_hdmi_spec *spec; 648 struct intel_hdmi_spec *spec;
663 649
@@ -667,7 +653,7 @@ static int patch_intel_hdmi(struct hda_codec *codec)
667 653
668 spec->multiout.num_dacs = 0; /* no analog */ 654 spec->multiout.num_dacs = 0; /* no analog */
669 spec->multiout.max_channels = 8; 655 spec->multiout.max_channels = 8;
670 spec->multiout.dig_out_nid = CVT_NID; 656 spec->multiout.dig_out_nid = cvt_nid;
671 657
672 codec->spec = spec; 658 codec->spec = spec;
673 codec->patch_ops = intel_hdmi_patch_ops; 659 codec->patch_ops = intel_hdmi_patch_ops;
@@ -679,13 +665,27 @@ static int patch_intel_hdmi(struct hda_codec *codec)
679 return 0; 665 return 0;
680} 666}
681 667
668static int patch_intel_hdmi(struct hda_codec *codec)
669{
670 cvt_nid = 0x02;
671 pin_nid = 0x03;
672 return do_patch_intel_hdmi(codec);
673}
674
675static int patch_intel_hdmi_ibexpeak(struct hda_codec *codec)
676{
677 cvt_nid = 0x02;
678 pin_nid = 0x04;
679 return do_patch_intel_hdmi(codec);
680}
681
682static struct hda_codec_preset snd_hda_preset_intelhdmi[] = { 682static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
683 { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi }, 683 { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi },
684 { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, 684 { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi },
685 { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, 685 { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi },
686 { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, 686 { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi },
687 { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, 687 { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi },
688 { .id = 0x80860054, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, 688 { .id = 0x80860054, .name = "Q57 DEVIBX", .patch = patch_intel_hdmi_ibexpeak },
689 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, 689 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
690 {} /* terminator */ 690 {} /* terminator */
691}; 691};