diff options
Diffstat (limited to 'sound/pci/hda/hda_controller.c')
-rw-r--r-- | sound/pci/hda/hda_controller.c | 263 |
1 files changed, 119 insertions, 144 deletions
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index 17c2637d842c..4fd0b2ef26e9 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c | |||
@@ -27,10 +27,8 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/reboot.h> | ||
31 | #include <sound/core.h> | 30 | #include <sound/core.h> |
32 | #include <sound/initval.h> | 31 | #include <sound/initval.h> |
33 | #include "hda_priv.h" | ||
34 | #include "hda_controller.h" | 32 | #include "hda_controller.h" |
35 | 33 | ||
36 | #define CREATE_TRACE_POINTS | 34 | #define CREATE_TRACE_POINTS |
@@ -259,11 +257,18 @@ static void azx_timecounter_init(struct snd_pcm_substream *substream, | |||
259 | tc->cycle_last = last; | 257 | tc->cycle_last = last; |
260 | } | 258 | } |
261 | 259 | ||
260 | static inline struct hda_pcm_stream * | ||
261 | to_hda_pcm_stream(struct snd_pcm_substream *substream) | ||
262 | { | ||
263 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | ||
264 | return &apcm->info->stream[substream->stream]; | ||
265 | } | ||
266 | |||
262 | static u64 azx_adjust_codec_delay(struct snd_pcm_substream *substream, | 267 | static u64 azx_adjust_codec_delay(struct snd_pcm_substream *substream, |
263 | u64 nsec) | 268 | u64 nsec) |
264 | { | 269 | { |
265 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 270 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
266 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 271 | struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream); |
267 | u64 codec_frames, codec_nsecs; | 272 | u64 codec_frames, codec_nsecs; |
268 | 273 | ||
269 | if (!hinfo->ops.get_delay) | 274 | if (!hinfo->ops.get_delay) |
@@ -399,7 +404,7 @@ static int azx_setup_periods(struct azx *chip, | |||
399 | static int azx_pcm_close(struct snd_pcm_substream *substream) | 404 | static int azx_pcm_close(struct snd_pcm_substream *substream) |
400 | { | 405 | { |
401 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 406 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
402 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 407 | struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream); |
403 | struct azx *chip = apcm->chip; | 408 | struct azx *chip = apcm->chip; |
404 | struct azx_dev *azx_dev = get_azx_dev(substream); | 409 | struct azx_dev *azx_dev = get_azx_dev(substream); |
405 | unsigned long flags; | 410 | unsigned long flags; |
@@ -410,9 +415,11 @@ static int azx_pcm_close(struct snd_pcm_substream *substream) | |||
410 | azx_dev->running = 0; | 415 | azx_dev->running = 0; |
411 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 416 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
412 | azx_release_device(azx_dev); | 417 | azx_release_device(azx_dev); |
413 | hinfo->ops.close(hinfo, apcm->codec, substream); | 418 | if (hinfo->ops.close) |
419 | hinfo->ops.close(hinfo, apcm->codec, substream); | ||
414 | snd_hda_power_down(apcm->codec); | 420 | snd_hda_power_down(apcm->codec); |
415 | mutex_unlock(&chip->open_mutex); | 421 | mutex_unlock(&chip->open_mutex); |
422 | snd_hda_codec_pcm_put(apcm->info); | ||
416 | return 0; | 423 | return 0; |
417 | } | 424 | } |
418 | 425 | ||
@@ -441,7 +448,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream) | |||
441 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 448 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
442 | struct azx_dev *azx_dev = get_azx_dev(substream); | 449 | struct azx_dev *azx_dev = get_azx_dev(substream); |
443 | struct azx *chip = apcm->chip; | 450 | struct azx *chip = apcm->chip; |
444 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 451 | struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream); |
445 | int err; | 452 | int err; |
446 | 453 | ||
447 | /* reset BDL address */ | 454 | /* reset BDL address */ |
@@ -468,7 +475,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
468 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 475 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
469 | struct azx *chip = apcm->chip; | 476 | struct azx *chip = apcm->chip; |
470 | struct azx_dev *azx_dev = get_azx_dev(substream); | 477 | struct azx_dev *azx_dev = get_azx_dev(substream); |
471 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 478 | struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream); |
472 | struct snd_pcm_runtime *runtime = substream->runtime; | 479 | struct snd_pcm_runtime *runtime = substream->runtime; |
473 | unsigned int bufsize, period_bytes, format_val, stream_tag; | 480 | unsigned int bufsize, period_bytes, format_val, stream_tag; |
474 | int err; | 481 | int err; |
@@ -708,7 +715,7 @@ unsigned int azx_get_position(struct azx *chip, | |||
708 | 715 | ||
709 | if (substream->runtime) { | 716 | if (substream->runtime) { |
710 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 717 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
711 | struct hda_pcm_stream *hinfo = apcm->hinfo[stream]; | 718 | struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream); |
712 | 719 | ||
713 | if (chip->get_delay[stream]) | 720 | if (chip->get_delay[stream]) |
714 | delay += chip->get_delay[stream](chip, azx_dev, pos); | 721 | delay += chip->get_delay[stream](chip, azx_dev, pos); |
@@ -732,17 +739,32 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream) | |||
732 | azx_get_position(chip, azx_dev)); | 739 | azx_get_position(chip, azx_dev)); |
733 | } | 740 | } |
734 | 741 | ||
735 | static int azx_get_wallclock_tstamp(struct snd_pcm_substream *substream, | 742 | static int azx_get_time_info(struct snd_pcm_substream *substream, |
736 | struct timespec *ts) | 743 | struct timespec *system_ts, struct timespec *audio_ts, |
744 | struct snd_pcm_audio_tstamp_config *audio_tstamp_config, | ||
745 | struct snd_pcm_audio_tstamp_report *audio_tstamp_report) | ||
737 | { | 746 | { |
738 | struct azx_dev *azx_dev = get_azx_dev(substream); | 747 | struct azx_dev *azx_dev = get_azx_dev(substream); |
739 | u64 nsec; | 748 | u64 nsec; |
740 | 749 | ||
741 | nsec = timecounter_read(&azx_dev->azx_tc); | 750 | if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) && |
742 | nsec = div_u64(nsec, 3); /* can be optimized */ | 751 | (audio_tstamp_config->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK)) { |
743 | nsec = azx_adjust_codec_delay(substream, nsec); | 752 | |
753 | snd_pcm_gettime(substream->runtime, system_ts); | ||
744 | 754 | ||
745 | *ts = ns_to_timespec(nsec); | 755 | nsec = timecounter_read(&azx_dev->azx_tc); |
756 | nsec = div_u64(nsec, 3); /* can be optimized */ | ||
757 | if (audio_tstamp_config->report_delay) | ||
758 | nsec = azx_adjust_codec_delay(substream, nsec); | ||
759 | |||
760 | *audio_ts = ns_to_timespec(nsec); | ||
761 | |||
762 | audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK; | ||
763 | audio_tstamp_report->accuracy_report = 1; /* rest of structure is valid */ | ||
764 | audio_tstamp_report->accuracy = 42; /* 24 MHz WallClock == 42ns resolution */ | ||
765 | |||
766 | } else | ||
767 | audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT; | ||
746 | 768 | ||
747 | return 0; | 769 | return 0; |
748 | } | 770 | } |
@@ -756,7 +778,8 @@ static struct snd_pcm_hardware azx_pcm_hw = { | |||
756 | /* SNDRV_PCM_INFO_RESUME |*/ | 778 | /* SNDRV_PCM_INFO_RESUME |*/ |
757 | SNDRV_PCM_INFO_PAUSE | | 779 | SNDRV_PCM_INFO_PAUSE | |
758 | SNDRV_PCM_INFO_SYNC_START | | 780 | SNDRV_PCM_INFO_SYNC_START | |
759 | SNDRV_PCM_INFO_HAS_WALL_CLOCK | | 781 | SNDRV_PCM_INFO_HAS_WALL_CLOCK | /* legacy */ |
782 | SNDRV_PCM_INFO_HAS_LINK_ATIME | | ||
760 | SNDRV_PCM_INFO_NO_PERIOD_WAKEUP), | 783 | SNDRV_PCM_INFO_NO_PERIOD_WAKEUP), |
761 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 784 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
762 | .rates = SNDRV_PCM_RATE_48000, | 785 | .rates = SNDRV_PCM_RATE_48000, |
@@ -775,7 +798,7 @@ static struct snd_pcm_hardware azx_pcm_hw = { | |||
775 | static int azx_pcm_open(struct snd_pcm_substream *substream) | 798 | static int azx_pcm_open(struct snd_pcm_substream *substream) |
776 | { | 799 | { |
777 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 800 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
778 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 801 | struct hda_pcm_stream *hinfo = to_hda_pcm_stream(substream); |
779 | struct azx *chip = apcm->chip; | 802 | struct azx *chip = apcm->chip; |
780 | struct azx_dev *azx_dev; | 803 | struct azx_dev *azx_dev; |
781 | struct snd_pcm_runtime *runtime = substream->runtime; | 804 | struct snd_pcm_runtime *runtime = substream->runtime; |
@@ -783,11 +806,12 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
783 | int err; | 806 | int err; |
784 | int buff_step; | 807 | int buff_step; |
785 | 808 | ||
809 | snd_hda_codec_pcm_get(apcm->info); | ||
786 | mutex_lock(&chip->open_mutex); | 810 | mutex_lock(&chip->open_mutex); |
787 | azx_dev = azx_assign_device(chip, substream); | 811 | azx_dev = azx_assign_device(chip, substream); |
788 | if (azx_dev == NULL) { | 812 | if (azx_dev == NULL) { |
789 | mutex_unlock(&chip->open_mutex); | 813 | err = -EBUSY; |
790 | return -EBUSY; | 814 | goto unlock; |
791 | } | 815 | } |
792 | runtime->hw = azx_pcm_hw; | 816 | runtime->hw = azx_pcm_hw; |
793 | runtime->hw.channels_min = hinfo->channels_min; | 817 | runtime->hw.channels_min = hinfo->channels_min; |
@@ -821,13 +845,14 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
821 | buff_step); | 845 | buff_step); |
822 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, | 846 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, |
823 | buff_step); | 847 | buff_step); |
824 | snd_hda_power_up_d3wait(apcm->codec); | 848 | snd_hda_power_up(apcm->codec); |
825 | err = hinfo->ops.open(hinfo, apcm->codec, substream); | 849 | if (hinfo->ops.open) |
850 | err = hinfo->ops.open(hinfo, apcm->codec, substream); | ||
851 | else | ||
852 | err = -ENODEV; | ||
826 | if (err < 0) { | 853 | if (err < 0) { |
827 | azx_release_device(azx_dev); | 854 | azx_release_device(azx_dev); |
828 | snd_hda_power_down(apcm->codec); | 855 | goto powerdown; |
829 | mutex_unlock(&chip->open_mutex); | ||
830 | return err; | ||
831 | } | 856 | } |
832 | snd_pcm_limit_hw_rates(runtime); | 857 | snd_pcm_limit_hw_rates(runtime); |
833 | /* sanity check */ | 858 | /* sanity check */ |
@@ -836,16 +861,18 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
836 | snd_BUG_ON(!runtime->hw.formats) || | 861 | snd_BUG_ON(!runtime->hw.formats) || |
837 | snd_BUG_ON(!runtime->hw.rates)) { | 862 | snd_BUG_ON(!runtime->hw.rates)) { |
838 | azx_release_device(azx_dev); | 863 | azx_release_device(azx_dev); |
839 | hinfo->ops.close(hinfo, apcm->codec, substream); | 864 | if (hinfo->ops.close) |
840 | snd_hda_power_down(apcm->codec); | 865 | hinfo->ops.close(hinfo, apcm->codec, substream); |
841 | mutex_unlock(&chip->open_mutex); | 866 | err = -EINVAL; |
842 | return -EINVAL; | 867 | goto powerdown; |
843 | } | 868 | } |
844 | 869 | ||
845 | /* disable WALLCLOCK timestamps for capture streams | 870 | /* disable LINK_ATIME timestamps for capture streams |
846 | until we figure out how to handle digital inputs */ | 871 | until we figure out how to handle digital inputs */ |
847 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | 872 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { |
848 | runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK; | 873 | runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK; /* legacy */ |
874 | runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_LINK_ATIME; | ||
875 | } | ||
849 | 876 | ||
850 | spin_lock_irqsave(&chip->reg_lock, flags); | 877 | spin_lock_irqsave(&chip->reg_lock, flags); |
851 | azx_dev->substream = substream; | 878 | azx_dev->substream = substream; |
@@ -856,6 +883,13 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
856 | snd_pcm_set_sync(substream); | 883 | snd_pcm_set_sync(substream); |
857 | mutex_unlock(&chip->open_mutex); | 884 | mutex_unlock(&chip->open_mutex); |
858 | return 0; | 885 | return 0; |
886 | |||
887 | powerdown: | ||
888 | snd_hda_power_down(apcm->codec); | ||
889 | unlock: | ||
890 | mutex_unlock(&chip->open_mutex); | ||
891 | snd_hda_codec_pcm_put(apcm->info); | ||
892 | return err; | ||
859 | } | 893 | } |
860 | 894 | ||
861 | static int azx_pcm_mmap(struct snd_pcm_substream *substream, | 895 | static int azx_pcm_mmap(struct snd_pcm_substream *substream, |
@@ -877,7 +911,7 @@ static struct snd_pcm_ops azx_pcm_ops = { | |||
877 | .prepare = azx_pcm_prepare, | 911 | .prepare = azx_pcm_prepare, |
878 | .trigger = azx_pcm_trigger, | 912 | .trigger = azx_pcm_trigger, |
879 | .pointer = azx_pcm_pointer, | 913 | .pointer = azx_pcm_pointer, |
880 | .wall_clock = azx_get_wallclock_tstamp, | 914 | .get_time_info = azx_get_time_info, |
881 | .mmap = azx_pcm_mmap, | 915 | .mmap = azx_pcm_mmap, |
882 | .page = snd_pcm_sgbuf_ops_page, | 916 | .page = snd_pcm_sgbuf_ops_page, |
883 | }; | 917 | }; |
@@ -887,6 +921,7 @@ static void azx_pcm_free(struct snd_pcm *pcm) | |||
887 | struct azx_pcm *apcm = pcm->private_data; | 921 | struct azx_pcm *apcm = pcm->private_data; |
888 | if (apcm) { | 922 | if (apcm) { |
889 | list_del(&apcm->list); | 923 | list_del(&apcm->list); |
924 | apcm->info->pcm = NULL; | ||
890 | kfree(apcm); | 925 | kfree(apcm); |
891 | } | 926 | } |
892 | } | 927 | } |
@@ -923,6 +958,7 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
923 | apcm->chip = chip; | 958 | apcm->chip = chip; |
924 | apcm->pcm = pcm; | 959 | apcm->pcm = pcm; |
925 | apcm->codec = codec; | 960 | apcm->codec = codec; |
961 | apcm->info = cpcm; | ||
926 | pcm->private_data = apcm; | 962 | pcm->private_data = apcm; |
927 | pcm->private_free = azx_pcm_free; | 963 | pcm->private_free = azx_pcm_free; |
928 | if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM) | 964 | if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM) |
@@ -930,7 +966,6 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
930 | list_add_tail(&apcm->list, &chip->pcm_list); | 966 | list_add_tail(&apcm->list, &chip->pcm_list); |
931 | cpcm->pcm = pcm; | 967 | cpcm->pcm = pcm; |
932 | for (s = 0; s < 2; s++) { | 968 | for (s = 0; s < 2; s++) { |
933 | apcm->hinfo[s] = &cpcm->stream[s]; | ||
934 | if (cpcm->stream[s].substreams) | 969 | if (cpcm->stream[s].substreams) |
935 | snd_pcm_set_ops(pcm, s, &azx_pcm_ops); | 970 | snd_pcm_set_ops(pcm, s, &azx_pcm_ops); |
936 | } | 971 | } |
@@ -941,9 +976,6 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
941 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, | 976 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, |
942 | chip->card->dev, | 977 | chip->card->dev, |
943 | size, MAX_PREALLOC_SIZE); | 978 | size, MAX_PREALLOC_SIZE); |
944 | /* link to codec */ | ||
945 | for (s = 0; s < 2; s++) | ||
946 | pcm->streams[s].dev.parent = &codec->dev; | ||
947 | return 0; | 979 | return 0; |
948 | } | 980 | } |
949 | 981 | ||
@@ -952,14 +984,9 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
952 | */ | 984 | */ |
953 | static int azx_alloc_cmd_io(struct azx *chip) | 985 | static int azx_alloc_cmd_io(struct azx *chip) |
954 | { | 986 | { |
955 | int err; | ||
956 | |||
957 | /* single page (at least 4096 bytes) must suffice for both ringbuffes */ | 987 | /* single page (at least 4096 bytes) must suffice for both ringbuffes */ |
958 | err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, | 988 | return chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, |
959 | PAGE_SIZE, &chip->rb); | 989 | PAGE_SIZE, &chip->rb); |
960 | if (err < 0) | ||
961 | dev_err(chip->card->dev, "cannot allocate CORB/RIRB\n"); | ||
962 | return err; | ||
963 | } | 990 | } |
964 | 991 | ||
965 | static void azx_init_cmd_io(struct azx *chip) | 992 | static void azx_init_cmd_io(struct azx *chip) |
@@ -1445,7 +1472,6 @@ static void azx_load_dsp_cleanup(struct hda_bus *bus, | |||
1445 | int azx_alloc_stream_pages(struct azx *chip) | 1472 | int azx_alloc_stream_pages(struct azx *chip) |
1446 | { | 1473 | { |
1447 | int i, err; | 1474 | int i, err; |
1448 | struct snd_card *card = chip->card; | ||
1449 | 1475 | ||
1450 | for (i = 0; i < chip->num_streams; i++) { | 1476 | for (i = 0; i < chip->num_streams; i++) { |
1451 | dsp_lock_init(&chip->azx_dev[i]); | 1477 | dsp_lock_init(&chip->azx_dev[i]); |
@@ -1453,18 +1479,14 @@ int azx_alloc_stream_pages(struct azx *chip) | |||
1453 | err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, | 1479 | err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, |
1454 | BDL_SIZE, | 1480 | BDL_SIZE, |
1455 | &chip->azx_dev[i].bdl); | 1481 | &chip->azx_dev[i].bdl); |
1456 | if (err < 0) { | 1482 | if (err < 0) |
1457 | dev_err(card->dev, "cannot allocate BDL\n"); | ||
1458 | return -ENOMEM; | 1483 | return -ENOMEM; |
1459 | } | ||
1460 | } | 1484 | } |
1461 | /* allocate memory for the position buffer */ | 1485 | /* allocate memory for the position buffer */ |
1462 | err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, | 1486 | err = chip->ops->dma_alloc_pages(chip, SNDRV_DMA_TYPE_DEV, |
1463 | chip->num_streams * 8, &chip->posbuf); | 1487 | chip->num_streams * 8, &chip->posbuf); |
1464 | if (err < 0) { | 1488 | if (err < 0) |
1465 | dev_err(card->dev, "cannot allocate posbuf\n"); | ||
1466 | return -ENOMEM; | 1489 | return -ENOMEM; |
1467 | } | ||
1468 | 1490 | ||
1469 | /* allocate CORB/RIRB */ | 1491 | /* allocate CORB/RIRB */ |
1470 | err = azx_alloc_cmd_io(chip); | 1492 | err = azx_alloc_cmd_io(chip); |
@@ -1676,7 +1698,7 @@ irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
1676 | int i; | 1698 | int i; |
1677 | 1699 | ||
1678 | #ifdef CONFIG_PM | 1700 | #ifdef CONFIG_PM |
1679 | if (chip->driver_caps & AZX_DCAPS_PM_RUNTIME) | 1701 | if (azx_has_pm_runtime(chip)) |
1680 | if (!pm_runtime_active(chip->card->dev)) | 1702 | if (!pm_runtime_active(chip->card->dev)) |
1681 | return IRQ_NONE; | 1703 | return IRQ_NONE; |
1682 | #endif | 1704 | #endif |
@@ -1761,34 +1783,11 @@ static void azx_bus_reset(struct hda_bus *bus) | |||
1761 | bus->in_reset = 1; | 1783 | bus->in_reset = 1; |
1762 | azx_stop_chip(chip); | 1784 | azx_stop_chip(chip); |
1763 | azx_init_chip(chip, true); | 1785 | azx_init_chip(chip, true); |
1764 | #ifdef CONFIG_PM | 1786 | if (chip->initialized) |
1765 | if (chip->initialized) { | 1787 | snd_hda_bus_reset(chip->bus); |
1766 | struct azx_pcm *p; | ||
1767 | list_for_each_entry(p, &chip->pcm_list, list) | ||
1768 | snd_pcm_suspend_all(p->pcm); | ||
1769 | snd_hda_suspend(chip->bus); | ||
1770 | snd_hda_resume(chip->bus); | ||
1771 | } | ||
1772 | #endif | ||
1773 | bus->in_reset = 0; | 1788 | bus->in_reset = 0; |
1774 | } | 1789 | } |
1775 | 1790 | ||
1776 | #ifdef CONFIG_PM | ||
1777 | /* power-up/down the controller */ | ||
1778 | static void azx_power_notify(struct hda_bus *bus, bool power_up) | ||
1779 | { | ||
1780 | struct azx *chip = bus->private_data; | ||
1781 | |||
1782 | if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) | ||
1783 | return; | ||
1784 | |||
1785 | if (power_up) | ||
1786 | pm_runtime_get_sync(chip->card->dev); | ||
1787 | else | ||
1788 | pm_runtime_put_sync(chip->card->dev); | ||
1789 | } | ||
1790 | #endif | ||
1791 | |||
1792 | static int get_jackpoll_interval(struct azx *chip) | 1791 | static int get_jackpoll_interval(struct azx *chip) |
1793 | { | 1792 | { |
1794 | int i; | 1793 | int i; |
@@ -1810,41 +1809,59 @@ static int get_jackpoll_interval(struct azx *chip) | |||
1810 | return j; | 1809 | return j; |
1811 | } | 1810 | } |
1812 | 1811 | ||
1813 | /* Codec initialization */ | 1812 | static struct hda_bus_ops bus_ops = { |
1814 | int azx_codec_create(struct azx *chip, const char *model, | 1813 | .command = azx_send_cmd, |
1815 | unsigned int max_slots, | 1814 | .get_response = azx_get_response, |
1816 | int *power_save_to) | 1815 | .attach_pcm = azx_attach_pcm_stream, |
1817 | { | 1816 | .bus_reset = azx_bus_reset, |
1818 | struct hda_bus_template bus_temp; | ||
1819 | int c, codecs, err; | ||
1820 | |||
1821 | memset(&bus_temp, 0, sizeof(bus_temp)); | ||
1822 | bus_temp.private_data = chip; | ||
1823 | bus_temp.modelname = model; | ||
1824 | bus_temp.pci = chip->pci; | ||
1825 | bus_temp.ops.command = azx_send_cmd; | ||
1826 | bus_temp.ops.get_response = azx_get_response; | ||
1827 | bus_temp.ops.attach_pcm = azx_attach_pcm_stream; | ||
1828 | bus_temp.ops.bus_reset = azx_bus_reset; | ||
1829 | #ifdef CONFIG_PM | ||
1830 | bus_temp.power_save = power_save_to; | ||
1831 | bus_temp.ops.pm_notify = azx_power_notify; | ||
1832 | #endif | ||
1833 | #ifdef CONFIG_SND_HDA_DSP_LOADER | 1817 | #ifdef CONFIG_SND_HDA_DSP_LOADER |
1834 | bus_temp.ops.load_dsp_prepare = azx_load_dsp_prepare; | 1818 | .load_dsp_prepare = azx_load_dsp_prepare, |
1835 | bus_temp.ops.load_dsp_trigger = azx_load_dsp_trigger; | 1819 | .load_dsp_trigger = azx_load_dsp_trigger, |
1836 | bus_temp.ops.load_dsp_cleanup = azx_load_dsp_cleanup; | 1820 | .load_dsp_cleanup = azx_load_dsp_cleanup, |
1837 | #endif | 1821 | #endif |
1822 | }; | ||
1823 | |||
1824 | /* HD-audio bus initialization */ | ||
1825 | int azx_bus_create(struct azx *chip, const char *model) | ||
1826 | { | ||
1827 | struct hda_bus *bus; | ||
1828 | int err; | ||
1838 | 1829 | ||
1839 | err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus); | 1830 | err = snd_hda_bus_new(chip->card, &bus); |
1840 | if (err < 0) | 1831 | if (err < 0) |
1841 | return err; | 1832 | return err; |
1842 | 1833 | ||
1834 | chip->bus = bus; | ||
1835 | bus->private_data = chip; | ||
1836 | bus->pci = chip->pci; | ||
1837 | bus->modelname = model; | ||
1838 | bus->ops = bus_ops; | ||
1839 | |||
1843 | if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) { | 1840 | if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) { |
1844 | dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n"); | 1841 | dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n"); |
1845 | chip->bus->needs_damn_long_delay = 1; | 1842 | bus->needs_damn_long_delay = 1; |
1843 | } | ||
1844 | |||
1845 | /* AMD chipsets often cause the communication stalls upon certain | ||
1846 | * sequence like the pin-detection. It seems that forcing the synced | ||
1847 | * access works around the stall. Grrr... | ||
1848 | */ | ||
1849 | if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) { | ||
1850 | dev_dbg(chip->card->dev, "Enable sync_write for stable communication\n"); | ||
1851 | bus->sync_write = 1; | ||
1852 | bus->allow_bus_reset = 1; | ||
1846 | } | 1853 | } |
1847 | 1854 | ||
1855 | return 0; | ||
1856 | } | ||
1857 | EXPORT_SYMBOL_GPL(azx_bus_create); | ||
1858 | |||
1859 | /* Probe codecs */ | ||
1860 | int azx_probe_codecs(struct azx *chip, unsigned int max_slots) | ||
1861 | { | ||
1862 | struct hda_bus *bus = chip->bus; | ||
1863 | int c, codecs, err; | ||
1864 | |||
1848 | codecs = 0; | 1865 | codecs = 0; |
1849 | if (!max_slots) | 1866 | if (!max_slots) |
1850 | max_slots = AZX_DEFAULT_CODECS; | 1867 | max_slots = AZX_DEFAULT_CODECS; |
@@ -1872,21 +1889,11 @@ int azx_codec_create(struct azx *chip, const char *model, | |||
1872 | } | 1889 | } |
1873 | } | 1890 | } |
1874 | 1891 | ||
1875 | /* AMD chipsets often cause the communication stalls upon certain | ||
1876 | * sequence like the pin-detection. It seems that forcing the synced | ||
1877 | * access works around the stall. Grrr... | ||
1878 | */ | ||
1879 | if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) { | ||
1880 | dev_dbg(chip->card->dev, "Enable sync_write for stable communication\n"); | ||
1881 | chip->bus->sync_write = 1; | ||
1882 | chip->bus->allow_bus_reset = 1; | ||
1883 | } | ||
1884 | |||
1885 | /* Then create codec instances */ | 1892 | /* Then create codec instances */ |
1886 | for (c = 0; c < max_slots; c++) { | 1893 | for (c = 0; c < max_slots; c++) { |
1887 | if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { | 1894 | if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { |
1888 | struct hda_codec *codec; | 1895 | struct hda_codec *codec; |
1889 | err = snd_hda_codec_new(chip->bus, c, &codec); | 1896 | err = snd_hda_codec_new(bus, bus->card, c, &codec); |
1890 | if (err < 0) | 1897 | if (err < 0) |
1891 | continue; | 1898 | continue; |
1892 | codec->jackpoll_interval = get_jackpoll_interval(chip); | 1899 | codec->jackpoll_interval = get_jackpoll_interval(chip); |
@@ -1900,7 +1907,7 @@ int azx_codec_create(struct azx *chip, const char *model, | |||
1900 | } | 1907 | } |
1901 | return 0; | 1908 | return 0; |
1902 | } | 1909 | } |
1903 | EXPORT_SYMBOL_GPL(azx_codec_create); | 1910 | EXPORT_SYMBOL_GPL(azx_probe_codecs); |
1904 | 1911 | ||
1905 | /* configure each codec instance */ | 1912 | /* configure each codec instance */ |
1906 | int azx_codec_configure(struct azx *chip) | 1913 | int azx_codec_configure(struct azx *chip) |
@@ -1913,13 +1920,6 @@ int azx_codec_configure(struct azx *chip) | |||
1913 | } | 1920 | } |
1914 | EXPORT_SYMBOL_GPL(azx_codec_configure); | 1921 | EXPORT_SYMBOL_GPL(azx_codec_configure); |
1915 | 1922 | ||
1916 | /* mixer creation - all stuff is implemented in hda module */ | ||
1917 | int azx_mixer_create(struct azx *chip) | ||
1918 | { | ||
1919 | return snd_hda_build_controls(chip->bus); | ||
1920 | } | ||
1921 | EXPORT_SYMBOL_GPL(azx_mixer_create); | ||
1922 | |||
1923 | 1923 | ||
1924 | static bool is_input_stream(struct azx *chip, unsigned char index) | 1924 | static bool is_input_stream(struct azx *chip, unsigned char index) |
1925 | { | 1925 | { |
@@ -1966,30 +1966,5 @@ int azx_init_stream(struct azx *chip) | |||
1966 | } | 1966 | } |
1967 | EXPORT_SYMBOL_GPL(azx_init_stream); | 1967 | EXPORT_SYMBOL_GPL(azx_init_stream); |
1968 | 1968 | ||
1969 | /* | ||
1970 | * reboot notifier for hang-up problem at power-down | ||
1971 | */ | ||
1972 | static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf) | ||
1973 | { | ||
1974 | struct azx *chip = container_of(nb, struct azx, reboot_notifier); | ||
1975 | snd_hda_bus_reboot_notify(chip->bus); | ||
1976 | azx_stop_chip(chip); | ||
1977 | return NOTIFY_OK; | ||
1978 | } | ||
1979 | |||
1980 | void azx_notifier_register(struct azx *chip) | ||
1981 | { | ||
1982 | chip->reboot_notifier.notifier_call = azx_halt; | ||
1983 | register_reboot_notifier(&chip->reboot_notifier); | ||
1984 | } | ||
1985 | EXPORT_SYMBOL_GPL(azx_notifier_register); | ||
1986 | |||
1987 | void azx_notifier_unregister(struct azx *chip) | ||
1988 | { | ||
1989 | if (chip->reboot_notifier.notifier_call) | ||
1990 | unregister_reboot_notifier(&chip->reboot_notifier); | ||
1991 | } | ||
1992 | EXPORT_SYMBOL_GPL(azx_notifier_unregister); | ||
1993 | |||
1994 | MODULE_LICENSE("GPL"); | 1969 | MODULE_LICENSE("GPL"); |
1995 | MODULE_DESCRIPTION("Common HDA driver functions"); | 1970 | MODULE_DESCRIPTION("Common HDA driver functions"); |