diff options
author | Wu Fengguang <fengguang.wu@intel.com> | 2009-08-02 04:48:55 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-08-03 02:35:05 -0400 |
commit | 559059b27f1768e89adc204f3ba2cb82882c15ca (patch) | |
tree | 82a3abfc2affdeab3820b92d99cd39b60a807208 /sound/pci/hda/patch_intelhdmi.c | |
parent | 03cb2dafcbde938ed7d01d4b952ea60e3c4e8532 (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.c | 104 |
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 */ | 36 | static hda_nid_t cvt_nid; /* audio converter */ |
37 | #define PIN_NID 0x03 /* HDMI output pin */ | 37 | static 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 | ||
47 | static struct hda_verb pinout_enable_verb[] = { | ||
48 | {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
49 | {} /* terminator */ | ||
50 | }; | ||
51 | |||
52 | static 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 | |||
58 | static 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 | |||
71 | struct hdmi_audio_infoframe { | 47 | struct 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, | |||
244 | static void hdmi_enable_output(struct hda_codec *codec) | 220 | static 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 | */ |
257 | static void hdmi_start_infoframe_trans(struct hda_codec *codec) | 234 | static 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 | */ |
267 | static void hdmi_stop_infoframe_trans(struct hda_codec *codec) | 244 | static 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 | ||
274 | static int hdmi_get_channel_count(struct hda_codec *codec) | 251 | static 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 | ||
280 | static void hdmi_set_channel_count(struct hda_codec *codec, int chs) | 257 | static 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, | |||
465 | static void hdmi_setup_channel_mapping(struct hda_codec *codec, | 442 | static 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 | ||
660 | static int patch_intel_hdmi(struct hda_codec *codec) | 646 | static 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 | ||
668 | static 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 | |||
675 | static 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 | |||
682 | static struct hda_codec_preset snd_hda_preset_intelhdmi[] = { | 682 | static 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 | }; |