diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-07-06 06:55:46 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-07-06 07:02:20 -0400 |
commit | 21a4dc43acdd547335f59ad52efeef5160247736 (patch) | |
tree | 48e230c8ed845ae3459d08dc08cbb270d60b833c /sound/pci/hda/patch_cirrus.c | |
parent | e5f1424807f4fa7aeddc376575e3b413c71c6fe1 (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.c | 331 |
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 | |||
245 | static hda_nid_t get_dac(struct hda_codec *codec, hda_nid_t pin) | 247 | static 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 | ||
257 | static 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 | |||
269 | static 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 | |||
298 | static 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 | |||
343 | static 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 | |||
381 | static 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 | |||
402 | static 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 | |||
255 | static const char *dir_sfx[2] = { "Playback", "Capture" }; | 420 | static const char *dir_sfx[2] = { "Playback", "Capture" }; |
256 | 421 | ||
257 | static int add_mute(struct hda_codec *codec, const char *name, int index, | 422 | static 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 | |||
510 | static 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 | |||
522 | static 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 | |||
551 | static struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec, | 645 | static 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, | |||
574 | static int build_input(struct hda_codec *codec) | 668 | static 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 | |||
635 | static int build_digital_output(struct hda_codec *codec) | 705 | static 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 | ||
662 | static int build_digital_input(struct hda_codec *codec) | 719 | static 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 | |||
676 | static void cs_automute(struct hda_codec *codec) | 731 | static 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; |