aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_cirrus.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-07-06 06:55:46 -0400
committerTakashi Iwai <tiwai@suse.de>2009-07-06 07:02:20 -0400
commit21a4dc43acdd547335f59ad52efeef5160247736 (patch)
tree48e230c8ed845ae3459d08dc08cbb270d60b833c /sound/pci/hda/patch_cirrus.c
parente5f1424807f4fa7aeddc376575e3b413c71c6fe1 (diff)
ALSA: hda - Fix cirrus codec parsing
The parser wasn't called in the proper order. Split now the parser to be called in patch_cirrus(), and the rest are just for building PCMs and controls. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_cirrus.c')
-rw-r--r--sound/pci/hda/patch_cirrus.c331
1 files changed, 198 insertions, 133 deletions
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index c4dc12e85732..051302e78345 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -56,7 +56,6 @@ struct cs_spec {
56 56
57 unsigned int hp_detect:1; 57 unsigned int hp_detect:1;
58 unsigned int mic_detect:1; 58 unsigned int mic_detect:1;
59 unsigned int built_up:1;
60}; 59};
61 60
62#define HP_EVENT 1 61#define HP_EVENT 1
@@ -213,7 +212,6 @@ static int cs_build_pcms(struct hda_codec *codec)
213 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 212 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
214 spec->multiout.max_channels; 213 spec->multiout.max_channels;
215 info->stream[SNDRV_PCM_STREAM_CAPTURE] = cs_pcm_analog_capture; 214 info->stream[SNDRV_PCM_STREAM_CAPTURE] = cs_pcm_analog_capture;
216 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs;
217 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 215 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
218 spec->adc_nid[spec->cur_input]; 216 spec->adc_nid[spec->cur_input];
219 codec->num_pcms++; 217 codec->num_pcms++;
@@ -242,6 +240,10 @@ static int cs_build_pcms(struct hda_codec *codec)
242 return 0; 240 return 0;
243} 241}
244 242
243/*
244 * parse codec topology
245 */
246
245static hda_nid_t get_dac(struct hda_codec *codec, hda_nid_t pin) 247static hda_nid_t get_dac(struct hda_codec *codec, hda_nid_t pin)
246{ 248{
247 hda_nid_t dac; 249 hda_nid_t dac;
@@ -252,6 +254,169 @@ static hda_nid_t get_dac(struct hda_codec *codec, hda_nid_t pin)
252 return dac; 254 return dac;
253} 255}
254 256
257static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
258{
259 struct cs_spec *spec = codec->spec;
260 struct auto_pin_cfg *cfg = &spec->autocfg;
261 hda_nid_t pin = cfg->input_pins[idx];
262 unsigned int val = snd_hda_query_pin_caps(codec, pin);
263 if (!(val & AC_PINCAP_PRES_DETECT))
264 return 0;
265 val = snd_hda_codec_get_pincfg(codec, pin);
266 return (get_defcfg_connect(val) == AC_JACK_PORT_COMPLEX);
267}
268
269static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
270 unsigned int *idxp)
271{
272 int i;
273 hda_nid_t nid;
274
275 nid = codec->start_nid;
276 for (i = 0; i < codec->num_nodes; i++, nid++) {
277 hda_nid_t pins[2];
278 unsigned int type;
279 int j, nums;
280 type = (get_wcaps(codec, nid) & AC_WCAP_TYPE)
281 >> AC_WCAP_TYPE_SHIFT;
282 if (type != AC_WID_AUD_IN)
283 continue;
284 nums = snd_hda_get_connections(codec, nid, pins,
285 ARRAY_SIZE(pins));
286 if (nums <= 0)
287 continue;
288 for (j = 0; j < nums; j++) {
289 if (pins[j] == pin) {
290 *idxp = j;
291 return nid;
292 }
293 }
294 }
295 return 0;
296}
297
298static int parse_output(struct hda_codec *codec)
299{
300 struct cs_spec *spec = codec->spec;
301 struct auto_pin_cfg *cfg = &spec->autocfg;
302 int i, err, extra_nids;
303 hda_nid_t dac;
304
305 for (i = 0; i < cfg->line_outs; i++) {
306 dac = get_dac(codec, cfg->line_out_pins[i]);
307 if (!dac)
308 break;
309 spec->dac_nid[i] = dac;
310 }
311 spec->multiout.num_dacs = i;
312 spec->multiout.dac_nids = spec->dac_nid;
313 spec->multiout.max_channels = i * 2;
314
315 /* add HP and speakers */
316 extra_nids = 0;
317 for (i = 0; i < cfg->hp_outs; i++) {
318 dac = get_dac(codec, cfg->hp_pins[i]);
319 if (!dac)
320 break;
321 if (!i)
322 spec->multiout.hp_nid = dac;
323 else
324 spec->multiout.extra_out_nid[extra_nids++] = dac;
325 }
326 for (i = 0; i < cfg->speaker_outs; i++) {
327 dac = get_dac(codec, cfg->speaker_pins[i]);
328 if (!dac)
329 break;
330 spec->multiout.extra_out_nid[extra_nids++] = dac;
331 }
332
333 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
334 cfg->speaker_outs = cfg->line_outs;
335 memcpy(cfg->speaker_pins, cfg->line_out_pins,
336 sizeof(cfg->speaker_pins));
337 cfg->line_outs = 0;
338 }
339
340 return 0;
341}
342
343static int parse_input(struct hda_codec *codec)
344{
345 struct cs_spec *spec = codec->spec;
346 struct auto_pin_cfg *cfg = &spec->autocfg;
347 int i, n, err;
348
349 for (i = 0; i < AUTO_PIN_LAST; i++) {
350 hda_nid_t pin = cfg->input_pins[i];
351 struct snd_kcontrol *kctl;
352 if (!pin)
353 continue;
354 spec->input_idx[spec->num_inputs] = i;
355 spec->capsrc_idx[i] = spec->num_inputs++;
356 spec->cur_input = i;
357 spec->adc_nid[i] = get_adc(codec, pin, &spec->adc_idx[i]);
358 }
359 if (!spec->num_inputs)
360 return 0;
361
362 /* check whether the automatic mic switch is available */
363 if (spec->num_inputs == 2 &&
364 spec->adc_nid[AUTO_PIN_MIC] && spec->adc_nid[AUTO_PIN_FRONT_MIC]) {
365 if (is_ext_mic(codec, cfg->input_pins[AUTO_PIN_FRONT_MIC])) {
366 if (!is_ext_mic(codec, cfg->input_pins[AUTO_PIN_MIC])) {
367 spec->mic_detect = 1;
368 spec->automic_idx = AUTO_PIN_FRONT_MIC;
369 }
370 } else {
371 if (is_ext_mic(codec, cfg->input_pins[AUTO_PIN_MIC])) {
372 spec->mic_detect = 1;
373 spec->automic_idx = AUTO_PIN_MIC;
374 }
375 }
376 }
377 return 0;
378}
379
380
381static int parse_digital_output(struct hda_codec *codec)
382{
383 struct cs_spec *spec = codec->spec;
384 struct auto_pin_cfg *cfg = &spec->autocfg;
385 hda_nid_t nid;
386 int err;
387
388 if (!cfg->dig_outs)
389 return 0;
390 if (snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) < 1)
391 return 0;
392 spec->multiout.dig_out_nid = nid;
393 spec->multiout.share_spdif = 1;
394 if (cfg->dig_outs > 1 &&
395 snd_hda_get_connections(codec, cfg->dig_out_pins[1], &nid, 1) > 0) {
396 spec->slave_dig_outs[0] = nid;
397 codec->slave_dig_outs = spec->slave_dig_outs;
398 }
399 return 0;
400}
401
402static int parse_digital_input(struct hda_codec *codec)
403{
404 struct cs_spec *spec = codec->spec;
405 struct auto_pin_cfg *cfg = &spec->autocfg;
406 int idx;
407
408 if (!cfg->dig_in_pin)
409 return 0;
410 spec->dig_in = get_adc(codec, cfg->dig_in_pin, &idx);
411 if (!spec->dig_in)
412 return 0;
413 return snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
414}
415
416/*
417 * create mixer controls
418 */
419
255static const char *dir_sfx[2] = { "Playback", "Capture" }; 420static const char *dir_sfx[2] = { "Playback", "Capture" };
256 421
257static int add_mute(struct hda_codec *codec, const char *name, int index, 422static int add_mute(struct hda_codec *codec, const char *name, int index,
@@ -376,55 +541,26 @@ static int build_output(struct hda_codec *codec)
376{ 541{
377 struct cs_spec *spec = codec->spec; 542 struct cs_spec *spec = codec->spec;
378 struct auto_pin_cfg *cfg = &spec->autocfg; 543 struct auto_pin_cfg *cfg = &spec->autocfg;
379 int i, err, extra_nids; 544 int i, err;
380 hda_nid_t dac;
381 545
382 for (i = 0; i < cfg->line_outs; i++) { 546 for (i = 0; i < cfg->line_outs; i++) {
383 dac = get_dac(codec, cfg->line_out_pins[i]); 547 err = add_output(codec, get_dac(codec, cfg->line_out_pins[i]),
384 if (!dac) 548 i, cfg->line_outs, cfg->line_out_type);
385 break;
386 spec->dac_nid[i] = dac;
387 err = add_output(codec, dac, i, cfg->line_outs,
388 cfg->line_out_type);
389 if (err < 0) 549 if (err < 0)
390 return err; 550 return err;
391 } 551 }
392 spec->multiout.num_dacs = i;
393 spec->multiout.dac_nids = spec->dac_nid;
394 spec->multiout.max_channels = i * 2;
395
396 /* add HP and speakers */
397 extra_nids = 0;
398 for (i = 0; i < cfg->hp_outs; i++) { 552 for (i = 0; i < cfg->hp_outs; i++) {
399 dac = get_dac(codec, cfg->hp_pins[i]); 553 err = add_output(codec, get_dac(codec, cfg->hp_pins[i]),
400 if (!dac) 554 i, cfg->hp_outs, AUTO_PIN_HP_OUT);
401 break;
402 if (!i)
403 spec->multiout.hp_nid = dac;
404 else
405 spec->multiout.extra_out_nid[extra_nids++] = dac;
406 err = add_output(codec, dac, i, cfg->hp_outs, AUTO_PIN_HP_OUT);
407 if (err < 0) 555 if (err < 0)
408 return err; 556 return err;
409 } 557 }
410 for (i = 0; i < cfg->speaker_outs; i++) { 558 for (i = 0; i < cfg->speaker_outs; i++) {
411 dac = get_dac(codec, cfg->speaker_pins[i]); 559 err = add_output(codec, get_dac(codec, cfg->speaker_pins[i]),
412 if (!dac) 560 i, cfg->speaker_outs, AUTO_PIN_SPEAKER_OUT);
413 break;
414 spec->multiout.extra_out_nid[extra_nids++] = dac;
415 err = add_output(codec, dac, i, cfg->speaker_outs,
416 AUTO_PIN_SPEAKER_OUT);
417 if (err < 0) 561 if (err < 0)
418 return err; 562 return err;
419 } 563 }
420
421 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
422 cfg->speaker_outs = cfg->line_outs;
423 memcpy(cfg->speaker_pins, cfg->line_out_pins,
424 sizeof(cfg->speaker_pins));
425 cfg->line_outs = 0;
426 }
427
428 return 0; 564 return 0;
429} 565}
430 566
@@ -506,48 +642,6 @@ static struct snd_kcontrol_new cs_capture_source = {
506 .put = cs_capture_source_put, 642 .put = cs_capture_source_put,
507}; 643};
508 644
509
510static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
511{
512 struct cs_spec *spec = codec->spec;
513 struct auto_pin_cfg *cfg = &spec->autocfg;
514 hda_nid_t pin = cfg->input_pins[idx];
515 unsigned int val = snd_hda_query_pin_caps(codec, pin);
516 if (!(val & AC_PINCAP_PRES_DETECT))
517 return 0;
518 val = snd_hda_codec_get_pincfg(codec, pin);
519 return (get_defcfg_connect(val) == AC_JACK_PORT_COMPLEX);
520}
521
522static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
523 unsigned int *idxp)
524{
525 int i;
526 hda_nid_t nid;
527
528 nid = codec->start_nid;
529 for (i = 0; i < codec->num_nodes; i++, nid++) {
530 hda_nid_t pins[2];
531 unsigned int type;
532 int j, nums;
533 type = (get_wcaps(codec, nid) & AC_WCAP_TYPE)
534 >> AC_WCAP_TYPE_SHIFT;
535 if (type != AC_WID_AUD_IN)
536 continue;
537 nums = snd_hda_get_connections(codec, nid, pins,
538 ARRAY_SIZE(pins));
539 if (nums <= 0)
540 continue;
541 for (j = 0; j < nums; j++) {
542 if (pins[j] == pin) {
543 *idxp = j;
544 return nid;
545 }
546 }
547 }
548 return 0;
549}
550
551static struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec, 645static struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec,
552 struct hda_ctl_ops *ops) 646 struct hda_ctl_ops *ops)
553{ 647{
@@ -574,38 +668,11 @@ static struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec,
574static int build_input(struct hda_codec *codec) 668static int build_input(struct hda_codec *codec)
575{ 669{
576 struct cs_spec *spec = codec->spec; 670 struct cs_spec *spec = codec->spec;
577 struct auto_pin_cfg *cfg = &spec->autocfg; 671 int i, err;
578 int i, n, err;
579 672
580 for (i = 0; i < AUTO_PIN_LAST; i++) {
581 hda_nid_t pin = cfg->input_pins[i];
582 struct snd_kcontrol *kctl;
583 if (!pin)
584 continue;
585 spec->input_idx[spec->num_inputs] = i;
586 spec->capsrc_idx[i] = spec->num_inputs++;
587 spec->cur_input = i;
588 spec->adc_nid[i] = get_adc(codec, pin, &spec->adc_idx[i]);
589 }
590 if (!spec->num_inputs) 673 if (!spec->num_inputs)
591 return 0; 674 return 0;
592 675
593 /* check whether the automatic mic switch is available */
594 if (spec->num_inputs == 2 &&
595 spec->adc_nid[AUTO_PIN_MIC] && spec->adc_nid[AUTO_PIN_FRONT_MIC]) {
596 if (is_ext_mic(codec, cfg->input_pins[AUTO_PIN_FRONT_MIC])) {
597 if (!is_ext_mic(codec, cfg->input_pins[AUTO_PIN_MIC])) {
598 spec->mic_detect = 1;
599 spec->automic_idx = AUTO_PIN_FRONT_MIC;
600 }
601 } else {
602 if (is_ext_mic(codec, cfg->input_pins[AUTO_PIN_MIC])) {
603 spec->mic_detect = 1;
604 spec->automic_idx = AUTO_PIN_MIC;
605 }
606 }
607 }
608
609 /* make bind-capture */ 676 /* make bind-capture */
610 spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw); 677 spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw);
611 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol); 678 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
@@ -632,47 +699,35 @@ static int build_input(struct hda_codec *codec)
632 return 0; 699 return 0;
633} 700}
634 701
702/*
703 */
704
635static int build_digital_output(struct hda_codec *codec) 705static int build_digital_output(struct hda_codec *codec)
636{ 706{
637 struct cs_spec *spec = codec->spec; 707 struct cs_spec *spec = codec->spec;
638 struct auto_pin_cfg *cfg = &spec->autocfg;
639 hda_nid_t nid;
640 int err; 708 int err;
641 709
642 if (!cfg->dig_outs)
643 return 0;
644 if (snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) < 1)
645 return 0;
646 spec->multiout.dig_out_nid = nid;
647 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 710 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
648 if (err < 0) 711 if (err < 0)
649 return err; 712 return err;
650 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); 713 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
651 if (err < 0) 714 if (err < 0)
652 return err; 715 return err;
653 spec->multiout.share_spdif = 1;
654 if (cfg->dig_outs > 1 &&
655 snd_hda_get_connections(codec, cfg->dig_out_pins[1], &nid, 1) > 0) {
656 spec->slave_dig_outs[0] = nid;
657 codec->slave_dig_outs = spec->slave_dig_outs;
658 }
659 return 0; 716 return 0;
660} 717}
661 718
662static int build_digital_input(struct hda_codec *codec) 719static int build_digital_input(struct hda_codec *codec)
663{ 720{
664 struct cs_spec *spec = codec->spec; 721 struct cs_spec *spec = codec->spec;
665 struct auto_pin_cfg *cfg = &spec->autocfg; 722 if (spec->dig_in)
666 int idx; 723 return snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
667 724 return 0;
668 if (!cfg->dig_in_pin)
669 return 0;
670 spec->dig_in = get_adc(codec, cfg->dig_in_pin, &idx);
671 if (!spec->dig_in)
672 return 0;
673 return snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
674} 725}
675 726
727/*
728 * auto-mute and auto-mic switching
729 */
730
676static void cs_automute(struct hda_codec *codec) 731static void cs_automute(struct hda_codec *codec)
677{ 732{
678 struct cs_spec *spec = codec->spec; 733 struct cs_spec *spec = codec->spec;
@@ -810,8 +865,6 @@ static int cs_init(struct hda_codec *codec)
810{ 865{
811 struct cs_spec *spec = codec->spec; 866 struct cs_spec *spec = codec->spec;
812 867
813 if (!spec->built_up)
814 return 0;
815 init_output(codec); 868 init_output(codec);
816 init_input(codec); 869 init_input(codec);
817 return 0; 870 return 0;
@@ -834,7 +887,6 @@ static int cs_build_controls(struct hda_codec *codec)
834 err = build_digital_input(codec); 887 err = build_digital_input(codec);
835 if (err < 0) 888 if (err < 0)
836 return err; 889 return err;
837 spec->built_up = 1;
838 return cs_init(codec); 890 return cs_init(codec);
839} 891}
840 892
@@ -892,6 +944,19 @@ static int patch_cs420x(struct hda_codec *codec)
892 if (err < 0) 944 if (err < 0)
893 goto error; 945 goto error;
894 946
947 err = parse_output(codec);
948 if (err < 0)
949 goto error;
950 err = parse_input(codec);
951 if (err < 0)
952 goto error;
953 err = parse_digital_output(codec);
954 if (err < 0)
955 goto error;
956 err = parse_digital_input(codec);
957 if (err < 0)
958 goto error;
959
895 codec->patch_ops = cs_patch_ops; 960 codec->patch_ops = cs_patch_ops;
896 961
897 return 0; 962 return 0;