diff options
| -rw-r--r-- | sound/pci/hda/hda_codec.c | 69 | ||||
| -rw-r--r-- | sound/pci/hda/hda_codec.h | 1 | ||||
| -rw-r--r-- | sound/pci/hda/patch_ca0132.c | 174 |
3 files changed, 99 insertions, 145 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 629131ad7b8b..c3077d5dec6e 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
| @@ -1386,6 +1386,44 @@ int snd_hda_codec_configure(struct hda_codec *codec) | |||
| 1386 | } | 1386 | } |
| 1387 | EXPORT_SYMBOL_HDA(snd_hda_codec_configure); | 1387 | EXPORT_SYMBOL_HDA(snd_hda_codec_configure); |
| 1388 | 1388 | ||
| 1389 | /* update the stream-id if changed */ | ||
| 1390 | static void update_pcm_stream_id(struct hda_codec *codec, | ||
| 1391 | struct hda_cvt_setup *p, hda_nid_t nid, | ||
| 1392 | u32 stream_tag, int channel_id) | ||
| 1393 | { | ||
| 1394 | unsigned int oldval, newval; | ||
| 1395 | |||
| 1396 | if (p->stream_tag != stream_tag || p->channel_id != channel_id) { | ||
| 1397 | oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | ||
| 1398 | newval = (stream_tag << 4) | channel_id; | ||
| 1399 | if (oldval != newval) | ||
| 1400 | snd_hda_codec_write(codec, nid, 0, | ||
| 1401 | AC_VERB_SET_CHANNEL_STREAMID, | ||
| 1402 | newval); | ||
| 1403 | p->stream_tag = stream_tag; | ||
| 1404 | p->channel_id = channel_id; | ||
| 1405 | } | ||
| 1406 | } | ||
| 1407 | |||
| 1408 | /* update the format-id if changed */ | ||
| 1409 | static void update_pcm_format(struct hda_codec *codec, struct hda_cvt_setup *p, | ||
| 1410 | hda_nid_t nid, int format) | ||
| 1411 | { | ||
| 1412 | unsigned int oldval; | ||
| 1413 | |||
| 1414 | if (p->format_id != format) { | ||
| 1415 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
| 1416 | AC_VERB_GET_STREAM_FORMAT, 0); | ||
| 1417 | if (oldval != format) { | ||
| 1418 | msleep(1); | ||
| 1419 | snd_hda_codec_write(codec, nid, 0, | ||
| 1420 | AC_VERB_SET_STREAM_FORMAT, | ||
| 1421 | format); | ||
| 1422 | } | ||
| 1423 | p->format_id = format; | ||
| 1424 | } | ||
| 1425 | } | ||
| 1426 | |||
| 1389 | /** | 1427 | /** |
| 1390 | * snd_hda_codec_setup_stream - set up the codec for streaming | 1428 | * snd_hda_codec_setup_stream - set up the codec for streaming |
| 1391 | * @codec: the CODEC to set up | 1429 | * @codec: the CODEC to set up |
| @@ -1400,7 +1438,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
| 1400 | { | 1438 | { |
| 1401 | struct hda_codec *c; | 1439 | struct hda_codec *c; |
| 1402 | struct hda_cvt_setup *p; | 1440 | struct hda_cvt_setup *p; |
| 1403 | unsigned int oldval, newval; | ||
| 1404 | int type; | 1441 | int type; |
| 1405 | int i; | 1442 | int i; |
| 1406 | 1443 | ||
| @@ -1413,29 +1450,13 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
| 1413 | p = get_hda_cvt_setup(codec, nid); | 1450 | p = get_hda_cvt_setup(codec, nid); |
| 1414 | if (!p) | 1451 | if (!p) |
| 1415 | return; | 1452 | return; |
| 1416 | /* update the stream-id if changed */ | 1453 | |
| 1417 | if (p->stream_tag != stream_tag || p->channel_id != channel_id) { | 1454 | if (codec->pcm_format_first) |
| 1418 | oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | 1455 | update_pcm_format(codec, p, nid, format); |
| 1419 | newval = (stream_tag << 4) | channel_id; | 1456 | update_pcm_stream_id(codec, p, nid, stream_tag, channel_id); |
| 1420 | if (oldval != newval) | 1457 | if (!codec->pcm_format_first) |
| 1421 | snd_hda_codec_write(codec, nid, 0, | 1458 | update_pcm_format(codec, p, nid, format); |
| 1422 | AC_VERB_SET_CHANNEL_STREAMID, | 1459 | |
| 1423 | newval); | ||
| 1424 | p->stream_tag = stream_tag; | ||
| 1425 | p->channel_id = channel_id; | ||
| 1426 | } | ||
| 1427 | /* update the format-id if changed */ | ||
| 1428 | if (p->format_id != format) { | ||
| 1429 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
| 1430 | AC_VERB_GET_STREAM_FORMAT, 0); | ||
| 1431 | if (oldval != format) { | ||
| 1432 | msleep(1); | ||
| 1433 | snd_hda_codec_write(codec, nid, 0, | ||
| 1434 | AC_VERB_SET_STREAM_FORMAT, | ||
| 1435 | format); | ||
| 1436 | } | ||
| 1437 | p->format_id = format; | ||
| 1438 | } | ||
| 1439 | p->active = 1; | 1460 | p->active = 1; |
| 1440 | p->dirty = 0; | 1461 | p->dirty = 0; |
| 1441 | 1462 | ||
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index c422d330ca54..7fbc1bcaf1a9 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
| @@ -861,6 +861,7 @@ struct hda_codec { | |||
| 861 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ | 861 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ |
| 862 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ | 862 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ |
| 863 | unsigned int no_jack_detect:1; /* Machine has no jack-detection */ | 863 | unsigned int no_jack_detect:1; /* Machine has no jack-detection */ |
| 864 | unsigned int pcm_format_first:1; /* PCM format must be set first */ | ||
| 864 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 865 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
| 865 | unsigned int power_on :1; /* current (global) power-state */ | 866 | unsigned int power_on :1; /* current (global) power-state */ |
| 866 | int power_transition; /* power-state in transition */ | 867 | int power_transition; /* power-state in transition */ |
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index d0d3540e39e7..49750a96d649 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
| @@ -246,7 +246,7 @@ static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) | |||
| 246 | AC_VERB_SET_AMP_GAIN_MUTE, | 246 | AC_VERB_SET_AMP_GAIN_MUTE, |
| 247 | AMP_OUT_UNMUTE); | 247 | AMP_OUT_UNMUTE); |
| 248 | } | 248 | } |
| 249 | if (dac) | 249 | if (dac && (get_wcaps(codec, dac) & AC_WCAP_OUT_AMP)) |
| 250 | snd_hda_codec_write(codec, dac, 0, | 250 | snd_hda_codec_write(codec, dac, 0, |
| 251 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); | 251 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); |
| 252 | } | 252 | } |
| @@ -261,7 +261,7 @@ static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) | |||
| 261 | AC_VERB_SET_AMP_GAIN_MUTE, | 261 | AC_VERB_SET_AMP_GAIN_MUTE, |
| 262 | AMP_IN_UNMUTE(0)); | 262 | AMP_IN_UNMUTE(0)); |
| 263 | } | 263 | } |
| 264 | if (adc) | 264 | if (adc && (get_wcaps(codec, adc) & AC_WCAP_IN_AMP)) |
| 265 | snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 265 | snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
| 266 | AMP_IN_UNMUTE(0)); | 266 | AMP_IN_UNMUTE(0)); |
| 267 | } | 267 | } |
| @@ -275,6 +275,10 @@ static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | |||
| 275 | int type = dir ? HDA_INPUT : HDA_OUTPUT; | 275 | int type = dir ? HDA_INPUT : HDA_OUTPUT; |
| 276 | struct snd_kcontrol_new knew = | 276 | struct snd_kcontrol_new knew = |
| 277 | HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); | 277 | HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); |
| 278 | if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_MUTE) == 0) { | ||
| 279 | snd_printdd("Skipping '%s %s Switch' (no mute on node 0x%x)\n", pfx, dirstr[dir], nid); | ||
| 280 | return 0; | ||
| 281 | } | ||
| 278 | sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); | 282 | sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); |
| 279 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); | 283 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); |
| 280 | } | 284 | } |
| @@ -286,6 +290,10 @@ static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | |||
| 286 | int type = dir ? HDA_INPUT : HDA_OUTPUT; | 290 | int type = dir ? HDA_INPUT : HDA_OUTPUT; |
| 287 | struct snd_kcontrol_new knew = | 291 | struct snd_kcontrol_new knew = |
| 288 | HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); | 292 | HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); |
| 293 | if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_NUM_STEPS) == 0) { | ||
| 294 | snd_printdd("Skipping '%s %s Volume' (no amp on node 0x%x)\n", pfx, dirstr[dir], nid); | ||
| 295 | return 0; | ||
| 296 | } | ||
| 289 | sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); | 297 | sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); |
| 290 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); | 298 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); |
| 291 | } | 299 | } |
| @@ -464,50 +472,17 @@ exit: | |||
| 464 | } | 472 | } |
| 465 | 473 | ||
| 466 | /* | 474 | /* |
| 467 | * PCM stuffs | 475 | * PCM callbacks |
| 468 | */ | 476 | */ |
| 469 | static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid, | 477 | static int ca0132_playback_pcm_open(struct hda_pcm_stream *hinfo, |
| 470 | u32 stream_tag, | 478 | struct hda_codec *codec, |
| 471 | int channel_id, int format) | 479 | struct snd_pcm_substream *substream) |
| 472 | { | 480 | { |
| 473 | unsigned int oldval, newval; | 481 | struct ca0132_spec *spec = codec->spec; |
| 474 | 482 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | |
| 475 | if (!nid) | 483 | 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 | } | 484 | } |
| 507 | 485 | ||
| 508 | /* | ||
| 509 | * PCM callbacks | ||
| 510 | */ | ||
| 511 | static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 486 | static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
| 512 | struct hda_codec *codec, | 487 | struct hda_codec *codec, |
| 513 | unsigned int stream_tag, | 488 | unsigned int stream_tag, |
| @@ -515,10 +490,8 @@ static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
| 515 | struct snd_pcm_substream *substream) | 490 | struct snd_pcm_substream *substream) |
| 516 | { | 491 | { |
| 517 | struct ca0132_spec *spec = codec->spec; | 492 | struct ca0132_spec *spec = codec->spec; |
| 518 | 493 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | |
| 519 | ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); | 494 | stream_tag, format, substream); |
| 520 | |||
| 521 | return 0; | ||
| 522 | } | 495 | } |
| 523 | 496 | ||
| 524 | static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 497 | static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
| @@ -526,92 +499,45 @@ static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
| 526 | struct snd_pcm_substream *substream) | 499 | struct snd_pcm_substream *substream) |
| 527 | { | 500 | { |
| 528 | struct ca0132_spec *spec = codec->spec; | 501 | struct ca0132_spec *spec = codec->spec; |
| 529 | 502 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | |
| 530 | ca0132_cleanup_stream(codec, spec->dacs[0]); | ||
| 531 | |||
| 532 | return 0; | ||
| 533 | } | 503 | } |
| 534 | 504 | ||
| 535 | /* | 505 | /* |
| 536 | * Digital out | 506 | * Digital out |
| 537 | */ | 507 | */ |
| 538 | static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 508 | static int ca0132_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, |
| 539 | struct hda_codec *codec, | 509 | struct hda_codec *codec, |
| 540 | unsigned int stream_tag, | 510 | struct snd_pcm_substream *substream) |
| 541 | unsigned int format, | ||
| 542 | struct snd_pcm_substream *substream) | ||
| 543 | { | 511 | { |
| 544 | struct ca0132_spec *spec = codec->spec; | 512 | struct ca0132_spec *spec = codec->spec; |
| 545 | 513 | 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 | } | 514 | } |
| 550 | 515 | ||
| 551 | static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 516 | static int ca0132_dig_playback_pcm_prepare(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 | } | ||
| 561 | |||
| 562 | /* | ||
| 563 | * Analog capture | ||
| 564 | */ | ||
| 565 | static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
| 566 | struct hda_codec *codec, | 517 | struct hda_codec *codec, |
| 567 | unsigned int stream_tag, | 518 | unsigned int stream_tag, |
| 568 | unsigned int format, | 519 | unsigned int format, |
| 569 | struct snd_pcm_substream *substream) | 520 | struct snd_pcm_substream *substream) |
| 570 | { | 521 | { |
| 571 | struct ca0132_spec *spec = codec->spec; | 522 | struct ca0132_spec *spec = codec->spec; |
| 572 | 523 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | |
| 573 | ca0132_setup_stream(codec, spec->adcs[substream->number], | 524 | stream_tag, format, substream); |
| 574 | stream_tag, 0, format); | ||
| 575 | |||
| 576 | return 0; | ||
| 577 | } | 525 | } |
| 578 | 526 | ||
| 579 | static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | 527 | static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
| 580 | struct hda_codec *codec, | 528 | struct hda_codec *codec, |
| 581 | struct snd_pcm_substream *substream) | 529 | struct snd_pcm_substream *substream) |
| 582 | { | 530 | { |
| 583 | struct ca0132_spec *spec = codec->spec; | 531 | struct ca0132_spec *spec = codec->spec; |
| 584 | 532 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | |
| 585 | ca0132_cleanup_stream(codec, spec->adcs[substream->number]); | ||
| 586 | |||
| 587 | return 0; | ||
| 588 | } | 533 | } |
| 589 | 534 | ||
| 590 | /* | 535 | static int ca0132_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, |
| 591 | * Digital capture | 536 | struct hda_codec *codec, |
| 592 | */ | 537 | struct snd_pcm_substream *substream) |
| 593 | static int ca0132_dig_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
| 594 | struct hda_codec *codec, | ||
| 595 | unsigned int stream_tag, | ||
| 596 | unsigned int format, | ||
| 597 | struct snd_pcm_substream *substream) | ||
| 598 | { | 538 | { |
| 599 | struct ca0132_spec *spec = codec->spec; | 539 | struct ca0132_spec *spec = codec->spec; |
| 600 | 540 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | |
| 601 | ca0132_setup_stream(codec, spec->dig_in, stream_tag, 0, format); | ||
| 602 | |||
| 603 | return 0; | ||
| 604 | } | ||
| 605 | |||
| 606 | static int ca0132_dig_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
| 607 | struct hda_codec *codec, | ||
| 608 | struct snd_pcm_substream *substream) | ||
| 609 | { | ||
| 610 | struct ca0132_spec *spec = codec->spec; | ||
| 611 | |||
| 612 | ca0132_cleanup_stream(codec, spec->dig_in); | ||
| 613 | |||
| 614 | return 0; | ||
| 615 | } | 541 | } |
| 616 | 542 | ||
| 617 | /* | 543 | /* |
| @@ -621,6 +547,7 @@ static struct hda_pcm_stream ca0132_pcm_analog_playback = { | |||
| 621 | .channels_min = 2, | 547 | .channels_min = 2, |
| 622 | .channels_max = 2, | 548 | .channels_max = 2, |
| 623 | .ops = { | 549 | .ops = { |
| 550 | .open = ca0132_playback_pcm_open, | ||
| 624 | .prepare = ca0132_playback_pcm_prepare, | 551 | .prepare = ca0132_playback_pcm_prepare, |
| 625 | .cleanup = ca0132_playback_pcm_cleanup | 552 | .cleanup = ca0132_playback_pcm_cleanup |
| 626 | }, | 553 | }, |
| @@ -630,10 +557,6 @@ static struct hda_pcm_stream ca0132_pcm_analog_capture = { | |||
| 630 | .substreams = 1, | 557 | .substreams = 1, |
| 631 | .channels_min = 2, | 558 | .channels_min = 2, |
| 632 | .channels_max = 2, | 559 | .channels_max = 2, |
| 633 | .ops = { | ||
| 634 | .prepare = ca0132_capture_pcm_prepare, | ||
| 635 | .cleanup = ca0132_capture_pcm_cleanup | ||
| 636 | }, | ||
| 637 | }; | 560 | }; |
| 638 | 561 | ||
| 639 | static struct hda_pcm_stream ca0132_pcm_digital_playback = { | 562 | static struct hda_pcm_stream ca0132_pcm_digital_playback = { |
| @@ -641,6 +564,8 @@ static struct hda_pcm_stream ca0132_pcm_digital_playback = { | |||
| 641 | .channels_min = 2, | 564 | .channels_min = 2, |
| 642 | .channels_max = 2, | 565 | .channels_max = 2, |
| 643 | .ops = { | 566 | .ops = { |
| 567 | .open = ca0132_dig_playback_pcm_open, | ||
| 568 | .close = ca0132_dig_playback_pcm_close, | ||
| 644 | .prepare = ca0132_dig_playback_pcm_prepare, | 569 | .prepare = ca0132_dig_playback_pcm_prepare, |
| 645 | .cleanup = ca0132_dig_playback_pcm_cleanup | 570 | .cleanup = ca0132_dig_playback_pcm_cleanup |
| 646 | }, | 571 | }, |
| @@ -650,10 +575,6 @@ static struct hda_pcm_stream ca0132_pcm_digital_capture = { | |||
| 650 | .substreams = 1, | 575 | .substreams = 1, |
| 651 | .channels_min = 2, | 576 | .channels_min = 2, |
| 652 | .channels_max = 2, | 577 | .channels_max = 2, |
| 653 | .ops = { | ||
| 654 | .prepare = ca0132_dig_capture_pcm_prepare, | ||
| 655 | .cleanup = ca0132_dig_capture_pcm_cleanup | ||
| 656 | }, | ||
| 657 | }; | 578 | }; |
| 658 | 579 | ||
| 659 | static int ca0132_build_pcms(struct hda_codec *codec) | 580 | static int ca0132_build_pcms(struct hda_codec *codec) |
| @@ -928,18 +849,16 @@ static int ca0132_build_controls(struct hda_codec *codec) | |||
| 928 | spec->dig_out); | 849 | spec->dig_out); |
| 929 | if (err < 0) | 850 | if (err < 0) |
| 930 | return err; | 851 | return err; |
| 931 | err = add_out_volume(codec, spec->dig_out, "IEC958"); | 852 | err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); |
| 932 | if (err < 0) | 853 | if (err < 0) |
| 933 | return err; | 854 | return err; |
| 855 | /* spec->multiout.share_spdif = 1; */ | ||
| 934 | } | 856 | } |
| 935 | 857 | ||
| 936 | if (spec->dig_in) { | 858 | if (spec->dig_in) { |
| 937 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in); | 859 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in); |
| 938 | if (err < 0) | 860 | if (err < 0) |
| 939 | return err; | 861 | return err; |
| 940 | err = add_in_volume(codec, spec->dig_in, "IEC958"); | ||
| 941 | if (err < 0) | ||
| 942 | return err; | ||
| 943 | } | 862 | } |
| 944 | return 0; | 863 | return 0; |
| 945 | } | 864 | } |
| @@ -961,6 +880,9 @@ static void ca0132_config(struct hda_codec *codec) | |||
| 961 | struct ca0132_spec *spec = codec->spec; | 880 | struct ca0132_spec *spec = codec->spec; |
| 962 | struct auto_pin_cfg *cfg = &spec->autocfg; | 881 | struct auto_pin_cfg *cfg = &spec->autocfg; |
| 963 | 882 | ||
| 883 | codec->pcm_format_first = 1; | ||
| 884 | codec->no_sticky_stream = 1; | ||
| 885 | |||
| 964 | /* line-outs */ | 886 | /* line-outs */ |
| 965 | cfg->line_outs = 1; | 887 | cfg->line_outs = 1; |
| 966 | cfg->line_out_pins[0] = 0x0b; /* front */ | 888 | cfg->line_out_pins[0] = 0x0b; /* front */ |
| @@ -988,14 +910,24 @@ static void ca0132_config(struct hda_codec *codec) | |||
| 988 | 910 | ||
| 989 | /* Mic-in */ | 911 | /* Mic-in */ |
| 990 | spec->input_pins[0] = 0x12; | 912 | spec->input_pins[0] = 0x12; |
| 991 | spec->input_labels[0] = "Mic-In"; | 913 | spec->input_labels[0] = "Mic"; |
| 992 | spec->adcs[0] = 0x07; | 914 | spec->adcs[0] = 0x07; |
| 993 | 915 | ||
| 994 | /* Line-In */ | 916 | /* Line-In */ |
| 995 | spec->input_pins[1] = 0x11; | 917 | spec->input_pins[1] = 0x11; |
| 996 | spec->input_labels[1] = "Line-In"; | 918 | spec->input_labels[1] = "Line"; |
| 997 | spec->adcs[1] = 0x08; | 919 | spec->adcs[1] = 0x08; |
| 998 | spec->num_inputs = 2; | 920 | spec->num_inputs = 2; |
| 921 | |||
| 922 | /* SPDIF I/O */ | ||
| 923 | spec->dig_out = 0x05; | ||
| 924 | spec->multiout.dig_out_nid = spec->dig_out; | ||
| 925 | cfg->dig_out_pins[0] = 0x0c; | ||
| 926 | cfg->dig_outs = 1; | ||
| 927 | cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF; | ||
| 928 | spec->dig_in = 0x09; | ||
| 929 | cfg->dig_in_pin = 0x0e; | ||
| 930 | cfg->dig_in_type = HDA_PCM_TYPE_SPDIF; | ||
| 999 | } | 931 | } |
| 1000 | 932 | ||
| 1001 | static void ca0132_init_chip(struct hda_codec *codec) | 933 | static void ca0132_init_chip(struct hda_codec *codec) |
