diff options
| author | Takashi Iwai <tiwai@suse.de> | 2012-08-08 11:20:18 -0400 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2012-08-08 11:25:02 -0400 |
| commit | 27ebeb0b1b5bb26908e485a7e8bd2ec30366ffef (patch) | |
| tree | 3dd8505b7eb6f6f81411efa960f0c9483cb2b5b3 | |
| parent | 55cf87fe0e9783e25f442be1e48b8319d86131ea (diff) | |
ALSA: hda - Use the standard PCM ops for CA0132
Now with the workaround using codec->pcm_format_first flag, we can
clean up the home-baked codes in patch_ca0132.c.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
| -rw-r--r-- | sound/pci/hda/patch_ca0132.c | 142 |
1 files changed, 29 insertions, 113 deletions
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 2685590925ff..31512a0f1d07 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
| @@ -464,50 +464,17 @@ exit: | |||
| 464 | } | 464 | } |
| 465 | 465 | ||
| 466 | /* | 466 | /* |
| 467 | * PCM stuffs | 467 | * PCM callbacks |
| 468 | */ | 468 | */ |
| 469 | static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid, | 469 | static int ca0132_playback_pcm_open(struct hda_pcm_stream *hinfo, |
| 470 | u32 stream_tag, | 470 | struct hda_codec *codec, |
| 471 | int channel_id, int format) | 471 | struct snd_pcm_substream *substream) |
| 472 | { | 472 | { |
| 473 | unsigned int oldval, newval; | 473 | struct ca0132_spec *spec = codec->spec; |
| 474 | 474 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | |
| 475 | if (!nid) | 475 | hinfo); |
| 476 | return; | ||
| 477 | |||
| 478 | snd_printdd("ca0132_setup_stream: " | ||
| 479 | "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", | ||
| 480 | nid, stream_tag, channel_id, format); | ||
| 481 | |||
| 482 | /* update the format-id if changed */ | ||
| 483 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
| 484 | AC_VERB_GET_STREAM_FORMAT, | ||
| 485 | 0); | ||
| 486 | if (oldval != format) { | ||
| 487 | msleep(20); | ||
| 488 | snd_hda_codec_write(codec, nid, 0, | ||
| 489 | AC_VERB_SET_STREAM_FORMAT, | ||
| 490 | format); | ||
| 491 | } | ||
| 492 | |||
| 493 | oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | ||
| 494 | newval = (stream_tag << 4) | channel_id; | ||
| 495 | if (oldval != newval) { | ||
| 496 | snd_hda_codec_write(codec, nid, 0, | ||
| 497 | AC_VERB_SET_CHANNEL_STREAMID, | ||
| 498 | newval); | ||
| 499 | } | ||
| 500 | } | ||
| 501 | |||
| 502 | static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) | ||
| 503 | { | ||
| 504 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); | ||
| 505 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0); | ||
| 506 | } | 476 | } |
| 507 | 477 | ||
| 508 | /* | ||
| 509 | * PCM callbacks | ||
| 510 | */ | ||
| 511 | static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 478 | static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
| 512 | struct hda_codec *codec, | 479 | struct hda_codec *codec, |
| 513 | unsigned int stream_tag, | 480 | unsigned int stream_tag, |
| @@ -515,10 +482,8 @@ static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
| 515 | struct snd_pcm_substream *substream) | 482 | struct snd_pcm_substream *substream) |
| 516 | { | 483 | { |
| 517 | struct ca0132_spec *spec = codec->spec; | 484 | struct ca0132_spec *spec = codec->spec; |
| 518 | 485 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | |
| 519 | ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); | 486 | stream_tag, format, substream); |
| 520 | |||
| 521 | return 0; | ||
| 522 | } | 487 | } |
| 523 | 488 | ||
| 524 | static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 489 | static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
| @@ -526,92 +491,45 @@ static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
| 526 | struct snd_pcm_substream *substream) | 491 | struct snd_pcm_substream *substream) |
| 527 | { | 492 | { |
| 528 | struct ca0132_spec *spec = codec->spec; | 493 | struct ca0132_spec *spec = codec->spec; |
| 529 | 494 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | |
| 530 | ca0132_cleanup_stream(codec, spec->dacs[0]); | ||
| 531 | |||
| 532 | return 0; | ||
| 533 | } | 495 | } |
| 534 | 496 | ||
| 535 | /* | 497 | /* |
| 536 | * Digital out | 498 | * Digital out |
| 537 | */ | 499 | */ |
| 538 | static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 500 | static int ca0132_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, |
| 539 | struct hda_codec *codec, | 501 | struct hda_codec *codec, |
| 540 | unsigned int stream_tag, | 502 | struct snd_pcm_substream *substream) |
| 541 | unsigned int format, | ||
| 542 | struct snd_pcm_substream *substream) | ||
| 543 | { | 503 | { |
| 544 | struct ca0132_spec *spec = codec->spec; | 504 | struct ca0132_spec *spec = codec->spec; |
| 545 | 505 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | |
| 546 | ca0132_setup_stream(codec, spec->dig_out, stream_tag, 0, format); | ||
| 547 | |||
| 548 | return 0; | ||
| 549 | } | ||
| 550 | |||
| 551 | static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
| 552 | struct hda_codec *codec, | ||
| 553 | struct snd_pcm_substream *substream) | ||
| 554 | { | ||
| 555 | struct ca0132_spec *spec = codec->spec; | ||
| 556 | |||
| 557 | ca0132_cleanup_stream(codec, spec->dig_out); | ||
| 558 | |||
| 559 | return 0; | ||
| 560 | } | 506 | } |
| 561 | 507 | ||
| 562 | /* | 508 | static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
| 563 | * Analog capture | ||
| 564 | */ | ||
| 565 | static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
| 566 | struct hda_codec *codec, | 509 | struct hda_codec *codec, |
| 567 | unsigned int stream_tag, | 510 | unsigned int stream_tag, |
| 568 | unsigned int format, | 511 | unsigned int format, |
| 569 | struct snd_pcm_substream *substream) | 512 | struct snd_pcm_substream *substream) |
| 570 | { | 513 | { |
| 571 | struct ca0132_spec *spec = codec->spec; | 514 | struct ca0132_spec *spec = codec->spec; |
| 572 | 515 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | |
| 573 | ca0132_setup_stream(codec, spec->adcs[substream->number], | 516 | stream_tag, format, substream); |
| 574 | stream_tag, 0, format); | ||
| 575 | |||
| 576 | return 0; | ||
| 577 | } | 517 | } |
| 578 | 518 | ||
| 579 | static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | 519 | static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
| 580 | struct hda_codec *codec, | ||
| 581 | struct snd_pcm_substream *substream) | ||
| 582 | { | ||
| 583 | struct ca0132_spec *spec = codec->spec; | ||
| 584 | |||
| 585 | ca0132_cleanup_stream(codec, spec->adcs[substream->number]); | ||
| 586 | |||
| 587 | return 0; | ||
| 588 | } | ||
| 589 | |||
| 590 | /* | ||
| 591 | * Digital capture | ||
| 592 | */ | ||
| 593 | static int ca0132_dig_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
| 594 | struct hda_codec *codec, | 520 | struct hda_codec *codec, |
| 595 | unsigned int stream_tag, | ||
| 596 | unsigned int format, | ||
| 597 | struct snd_pcm_substream *substream) | 521 | struct snd_pcm_substream *substream) |
| 598 | { | 522 | { |
| 599 | struct ca0132_spec *spec = codec->spec; | 523 | struct ca0132_spec *spec = codec->spec; |
| 600 | 524 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | |
| 601 | ca0132_setup_stream(codec, spec->dig_in, stream_tag, 0, format); | ||
| 602 | |||
| 603 | return 0; | ||
| 604 | } | 525 | } |
| 605 | 526 | ||
| 606 | static int ca0132_dig_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | 527 | static int ca0132_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, |
| 607 | struct hda_codec *codec, | 528 | struct hda_codec *codec, |
| 608 | struct snd_pcm_substream *substream) | 529 | struct snd_pcm_substream *substream) |
| 609 | { | 530 | { |
| 610 | struct ca0132_spec *spec = codec->spec; | 531 | struct ca0132_spec *spec = codec->spec; |
| 611 | 532 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | |
| 612 | ca0132_cleanup_stream(codec, spec->dig_in); | ||
| 613 | |||
| 614 | return 0; | ||
| 615 | } | 533 | } |
| 616 | 534 | ||
| 617 | /* | 535 | /* |
| @@ -621,6 +539,7 @@ static struct hda_pcm_stream ca0132_pcm_analog_playback = { | |||
| 621 | .channels_min = 2, | 539 | .channels_min = 2, |
| 622 | .channels_max = 2, | 540 | .channels_max = 2, |
| 623 | .ops = { | 541 | .ops = { |
| 542 | .open = ca0132_playback_pcm_open, | ||
| 624 | .prepare = ca0132_playback_pcm_prepare, | 543 | .prepare = ca0132_playback_pcm_prepare, |
| 625 | .cleanup = ca0132_playback_pcm_cleanup | 544 | .cleanup = ca0132_playback_pcm_cleanup |
| 626 | }, | 545 | }, |
| @@ -630,10 +549,6 @@ static struct hda_pcm_stream ca0132_pcm_analog_capture = { | |||
| 630 | .substreams = 1, | 549 | .substreams = 1, |
| 631 | .channels_min = 2, | 550 | .channels_min = 2, |
| 632 | .channels_max = 2, | 551 | .channels_max = 2, |
| 633 | .ops = { | ||
| 634 | .prepare = ca0132_capture_pcm_prepare, | ||
| 635 | .cleanup = ca0132_capture_pcm_cleanup | ||
| 636 | }, | ||
| 637 | }; | 552 | }; |
| 638 | 553 | ||
| 639 | static struct hda_pcm_stream ca0132_pcm_digital_playback = { | 554 | static struct hda_pcm_stream ca0132_pcm_digital_playback = { |
| @@ -641,6 +556,8 @@ static struct hda_pcm_stream ca0132_pcm_digital_playback = { | |||
| 641 | .channels_min = 2, | 556 | .channels_min = 2, |
| 642 | .channels_max = 2, | 557 | .channels_max = 2, |
| 643 | .ops = { | 558 | .ops = { |
| 559 | .open = ca0132_dig_playback_pcm_open, | ||
| 560 | .close = ca0132_dig_playback_pcm_close, | ||
| 644 | .prepare = ca0132_dig_playback_pcm_prepare, | 561 | .prepare = ca0132_dig_playback_pcm_prepare, |
| 645 | .cleanup = ca0132_dig_playback_pcm_cleanup | 562 | .cleanup = ca0132_dig_playback_pcm_cleanup |
| 646 | }, | 563 | }, |
| @@ -650,10 +567,6 @@ static struct hda_pcm_stream ca0132_pcm_digital_capture = { | |||
| 650 | .substreams = 1, | 567 | .substreams = 1, |
| 651 | .channels_min = 2, | 568 | .channels_min = 2, |
| 652 | .channels_max = 2, | 569 | .channels_max = 2, |
| 653 | .ops = { | ||
| 654 | .prepare = ca0132_dig_capture_pcm_prepare, | ||
| 655 | .cleanup = ca0132_dig_capture_pcm_cleanup | ||
| 656 | }, | ||
| 657 | }; | 570 | }; |
| 658 | 571 | ||
| 659 | static int ca0132_build_pcms(struct hda_codec *codec) | 572 | static int ca0132_build_pcms(struct hda_codec *codec) |
| @@ -961,6 +874,9 @@ static void ca0132_config(struct hda_codec *codec) | |||
| 961 | struct ca0132_spec *spec = codec->spec; | 874 | struct ca0132_spec *spec = codec->spec; |
| 962 | struct auto_pin_cfg *cfg = &spec->autocfg; | 875 | struct auto_pin_cfg *cfg = &spec->autocfg; |
| 963 | 876 | ||
| 877 | codec->pcm_format_first = 1; | ||
| 878 | codec->no_sticky_stream = 1; | ||
| 879 | |||
| 964 | /* line-outs */ | 880 | /* line-outs */ |
| 965 | cfg->line_outs = 1; | 881 | cfg->line_outs = 1; |
| 966 | cfg->line_out_pins[0] = 0x0b; /* front */ | 882 | cfg->line_out_pins[0] = 0x0b; /* front */ |
