aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/patch_cmedia.c233
1 files changed, 230 insertions, 3 deletions
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index a44d64e828d..e64e29dac82 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -29,6 +29,7 @@
29#include <sound/core.h> 29#include <sound/core.h>
30#include "hda_codec.h" 30#include "hda_codec.h"
31#include "hda_local.h" 31#include "hda_local.h"
32#define NUM_PINS 11
32 33
33 34
34/* board config type */ 35/* board config type */
@@ -38,6 +39,7 @@ enum {
38 CMI_FULL, /* back 6-jack + front-panel 2-jack */ 39 CMI_FULL, /* back 6-jack + front-panel 2-jack */
39 CMI_FULL_DIG, /* back 6-jack + front-panel 2-jack + digital I/O */ 40 CMI_FULL_DIG, /* back 6-jack + front-panel 2-jack + digital I/O */
40 CMI_ALLOUT, /* back 5-jack + front-panel 2-jack + digital out */ 41 CMI_ALLOUT, /* back 5-jack + front-panel 2-jack + digital out */
42 CMI_AUTO, /* let driver guess it */
41}; 43};
42 44
43struct cmi_spec { 45struct cmi_spec {
@@ -48,6 +50,7 @@ struct cmi_spec {
48 50
49 /* playback */ 51 /* playback */
50 struct hda_multi_out multiout; 52 struct hda_multi_out multiout;
53 hda_nid_t dac_nids[4]; /* NID for each DAC */
51 54
52 /* capture */ 55 /* capture */
53 hda_nid_t *adc_nids; 56 hda_nid_t *adc_nids;
@@ -63,6 +66,15 @@ struct cmi_spec {
63 const struct cmi_channel_mode *channel_modes; 66 const struct cmi_channel_mode *channel_modes;
64 67
65 struct hda_pcm pcm_rec[2]; /* PCM information */ 68 struct hda_pcm pcm_rec[2]; /* PCM information */
69
70 /* pin deafault configuration */
71 hda_nid_t pin_nid[NUM_PINS];
72 unsigned int def_conf[NUM_PINS];
73 unsigned int pin_def_confs;
74
75 /* multichannel pins */
76 hda_nid_t multich_pin[4]; /* max 8-channel */
77 struct hda_verb multi_init[9]; /* 2 verbs for each pin + terminator */
66}; 78};
67 79
68/* 80/*
@@ -353,6 +365,175 @@ static int cmi9880_build_controls(struct hda_codec *codec)
353 return 0; 365 return 0;
354} 366}
355 367
368#define AC_DEFCFG_ASSOC_SHIFT 4
369#define get_defcfg_connect(cfg) ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT)
370#define get_defcfg_association(cfg) ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT)
371#define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE)
372
373/* get all pin default configuration in def_conf */
374static int cmi9880_get_pin_def_config(struct hda_codec *codec)
375{
376 struct cmi_spec *spec = codec->spec;
377 hda_nid_t nid, nid_start;
378 int i = 0, nodes;
379
380 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start);
381 for (nid = nid_start; nid < nodes + nid_start; nid++) {
382 unsigned int wid_caps = snd_hda_param_read(codec, nid,
383 AC_PAR_AUDIO_WIDGET_CAP);
384 unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
385 /* read all default configuration for pin complex */
386 if (wid_type == AC_WID_PIN) {
387 spec->pin_nid[i] = nid;
388 spec->def_conf[i] =
389 snd_hda_codec_read(codec, nid, 0,
390 AC_VERB_GET_CONFIG_DEFAULT, 0);
391 i++;
392 }
393 }
394 spec->pin_def_confs = i;
395 return 0;
396}
397
398/* get a pin default configuration of nid in def_conf */
399static unsigned int cmi9880_get_def_config(struct hda_codec *codec, hda_nid_t nid)
400{
401 struct cmi_spec *spec = codec->spec;
402 int i = 0;
403
404 while (spec->pin_nid[i] != nid && i < spec->pin_def_confs)
405 i++;
406 if (i == spec->pin_def_confs)
407 return (unsigned int) -1;
408 else
409 return spec->def_conf[i];
410}
411
412/* decide what pins to use for multichannel playback */
413static int cmi9880_get_multich_pins(struct hda_codec *codec)
414{
415 struct cmi_spec *spec = codec->spec;
416 int i, j, pins, seq[4];
417 int max_channel = 0;
418 unsigned int def_conf, sequence;
419 hda_nid_t nid;
420
421 memset(spec->multich_pin, 0, sizeof(spec->multich_pin));
422 for (pins = 0, i = 0; i < spec->pin_def_confs && pins < 4; i++) {
423 def_conf = spec->def_conf[i];
424 /* skip pin not connected */
425 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
426 continue;
427 /* get the sequence if association == 1 */
428 /* the other pins have association = 0, incorrect in spec 1.0 */
429 if (get_defcfg_association(def_conf) == 1) {
430 sequence = get_defcfg_sequence(def_conf);
431 seq[pins] = sequence;
432 spec->multich_pin[pins] = spec->pin_nid[i];
433 pins++; // ready for next slot
434 max_channel += 2;
435 }
436 }
437 /* sort by sequence, data collected here will be for Windows */
438 for (i = 0; i < pins; i++) {
439 for (j = i + 1; j < pins; j++) {
440 if (seq[j] < seq[i]) {
441 sequence = seq[j];
442 nid = spec->multich_pin[j];
443 seq[j] = seq[i];
444 spec->multich_pin[j] = spec->multich_pin[i];
445 seq[i] = sequence;
446 spec->multich_pin[i] = nid;
447 }
448 }
449 }
450 /* the pin assignment is for front, C/LFE, surround and back */
451 if (max_channel >= 6) {
452 hda_nid_t temp;
453 /* exchange pin of C/LFE and surround */
454 temp = spec->multich_pin[1];
455 spec->multich_pin[1] = spec->multich_pin[2];
456 spec->multich_pin[2] = temp;
457 }
458 return max_channel;
459}
460
461/* fill in the multi_dac_nids table, which will decide
462 which audio widget to use for each channel */
463static int cmi9880_fill_multi_dac_nids(struct hda_codec *codec)
464{
465 struct cmi_spec *spec = codec->spec;
466 hda_nid_t nid;
467 int assigned[4];
468 int i, j;
469
470 /* clear the table, only one c-media dac assumed here */
471 memset(spec->dac_nids, 0, sizeof(spec->dac_nids));
472 memset(assigned, 0, sizeof(assigned));
473 /* check the pins we found */
474 for (i = 0; i < spec->multiout.max_channels / 2; i++) {
475 nid = spec->multich_pin[i];
476 /* nid 0x0b~0x0e is hardwired to audio widget 0x3~0x6 */
477 if (nid <= 0x0e && nid >= 0x0b) {
478 spec->dac_nids[i] = nid - 0x08;
479 assigned[nid - 0x0b] = 1;
480 }
481 }
482 /* left pin can be connect to any audio widget */
483 for (i = 0; i < spec->multiout.max_channels / 2; i++) {
484 if (!assigned[i]) {
485 /* search for an empty channel */
486 /* I should also check the pin type */
487 for (j = 0; j < ARRAY_SIZE(spec->dac_nids); j++)
488 if (! spec->dac_nids[j]) {
489 spec->dac_nids[j] = i + 3;
490 assigned[i] = 1;
491 break;
492 }
493 }
494 }
495 return 0;
496}
497
498/* create multi_init table, which is used for multichannel initialization */
499static int cmi9880_fill_multi_init(struct hda_codec *codec)
500{
501 struct cmi_spec *spec = codec->spec;
502 hda_nid_t nid;
503 int i, j, k, len;
504
505 /* clear the table, only one c-media dac assumed here */
506 memset(spec->multi_init, 0, sizeof(spec->multi_init));
507 for (j = 0, i = 0; i < spec->multiout.max_channels / 2; i++) {
508 hda_nid_t conn[4];
509 nid = spec->multich_pin[i];
510 /* set as output */
511 spec->multi_init[j].nid = nid;
512 spec->multi_init[j].verb = AC_VERB_SET_PIN_WIDGET_CONTROL;
513 spec->multi_init[j].param = 0xc0;
514 j++;
515 /* nid 0x0f,0x10,0x1f,0x20 are needed to set connection */
516 switch (nid) {
517 case 0x0f:
518 case 0x10:
519 case 0x1f:
520 case 0x20:
521 /* set connection */
522 spec->multi_init[j].nid = nid;
523 spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL;
524 /* find the index in connect list */
525 len = snd_hda_get_connections(codec, nid, conn, 4);
526 for (k = 0; k < len; k++)
527 if (conn[k] == spec->dac_nids[i])
528 break;
529 spec->multi_init[j].param = k < len ? k : 0;
530 j++;
531 break;
532 }
533 }
534 return 0;
535}
536
356static int cmi9880_init(struct hda_codec *codec) 537static int cmi9880_init(struct hda_codec *codec)
357{ 538{
358 struct cmi_spec *spec = codec->spec; 539 struct cmi_spec *spec = codec->spec;
@@ -360,6 +541,8 @@ static int cmi9880_init(struct hda_codec *codec)
360 snd_hda_sequence_write(codec, cmi9880_allout_init); 541 snd_hda_sequence_write(codec, cmi9880_allout_init);
361 else 542 else
362 snd_hda_sequence_write(codec, cmi9880_basic_init); 543 snd_hda_sequence_write(codec, cmi9880_basic_init);
544 if (spec->board_config == CMI_AUTO)
545 snd_hda_sequence_write(codec, spec->multi_init);
363 return 0; 546 return 0;
364} 547}
365 548
@@ -546,6 +729,7 @@ static struct hda_board_config cmi9880_cfg_tbl[] = {
546 { .modelname = "full", .config = CMI_FULL }, 729 { .modelname = "full", .config = CMI_FULL },
547 { .modelname = "full_dig", .config = CMI_FULL_DIG }, 730 { .modelname = "full_dig", .config = CMI_FULL_DIG },
548 { .modelname = "allout", .config = CMI_ALLOUT }, 731 { .modelname = "allout", .config = CMI_ALLOUT },
732 { .modelname = "auto", .config = CMI_AUTO },
549 {} /* terminator */ 733 {} /* terminator */
550}; 734};
551 735
@@ -570,10 +754,13 @@ static int patch_cmi9880(struct hda_codec *codec)
570 codec->spec = spec; 754 codec->spec = spec;
571 spec->board_config = snd_hda_check_board_config(codec, cmi9880_cfg_tbl); 755 spec->board_config = snd_hda_check_board_config(codec, cmi9880_cfg_tbl);
572 if (spec->board_config < 0) { 756 if (spec->board_config < 0) {
573 snd_printd(KERN_INFO "hda_codec: Unknown model for CMI9880\n"); 757 snd_printdd(KERN_INFO "hda_codec: Unknown model for CMI9880\n");
574 spec->board_config = CMI_FULL_DIG; /* try everything */ 758 spec->board_config = CMI_AUTO; /* try everything */
575 } 759 }
576 760
761 /* copy default DAC NIDs */
762 memcpy(spec->dac_nids, cmi9880_dac_nids, sizeof(spec->dac_nids));
763
577 switch (spec->board_config) { 764 switch (spec->board_config) {
578 case CMI_MINIMAL: 765 case CMI_MINIMAL:
579 case CMI_MIN_FP: 766 case CMI_MIN_FP:
@@ -605,10 +792,50 @@ static int patch_cmi9880(struct hda_codec *codec)
605 spec->input_mux = &cmi9880_no_line_mux; 792 spec->input_mux = &cmi9880_no_line_mux;
606 spec->multiout.dig_out_nid = CMI_DIG_OUT_NID; 793 spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
607 break; 794 break;
795 case CMI_AUTO:
796 {
797 unsigned int port_e, port_f, port_g, port_h;
798 unsigned int port_spdifi, port_spdifo;
799 /* collect pin default configuration */
800 cmi9880_get_pin_def_config(codec);
801 port_e = cmi9880_get_def_config(codec, 0x0f);
802 port_f = cmi9880_get_def_config(codec, 0x10);
803 port_g = cmi9880_get_def_config(codec, 0x1f);
804 port_h = cmi9880_get_def_config(codec, 0x20);
805 port_spdifi = cmi9880_get_def_config(codec, 0x13);
806 port_spdifo = cmi9880_get_def_config(codec, 0x12);
807 spec->front_panel = 1;
808 if ((get_defcfg_connect(port_e) == AC_JACK_PORT_NONE)
809 || (get_defcfg_connect(port_f) == AC_JACK_PORT_NONE)) {
810 spec->surr_switch = 1;
811 /* no front panel */
812 if ((get_defcfg_connect(port_g) == AC_JACK_PORT_NONE)
813 || (get_defcfg_connect(port_h) == AC_JACK_PORT_NONE)) {
814 /* no optional rear panel */
815 spec->board_config = CMI_MINIMAL;
816 spec->front_panel = 0;
817 spec->num_ch_modes = 2;
818 } else
819 spec->board_config = CMI_MIN_FP;
820 spec->num_ch_modes = 3;
821 spec->channel_modes = cmi9880_channel_modes;
822 spec->input_mux = &cmi9880_basic_mux;
823 } else {
824 spec->input_mux = &cmi9880_basic_mux;
825 if (get_defcfg_connect(port_spdifo) != 1)
826 spec->multiout.dig_out_nid = CMI_DIG_OUT_NID;
827 if (get_defcfg_connect(port_spdifi) != 1)
828 spec->dig_in_nid = CMI_DIG_IN_NID;
829 }
830 spec->multiout.max_channels = cmi9880_get_multich_pins(codec);
831 cmi9880_fill_multi_dac_nids(codec);
832 cmi9880_fill_multi_init(codec);
833 }
834 break;
608 } 835 }
609 836
610 spec->multiout.num_dacs = 4; 837 spec->multiout.num_dacs = 4;
611 spec->multiout.dac_nids = cmi9880_dac_nids; 838 spec->multiout.dac_nids = spec->dac_nids;
612 839
613 spec->adc_nids = cmi9880_adc_nids; 840 spec->adc_nids = cmi9880_adc_nids;
614 841