.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * ALSA driver for Echoaudio soundcards. |
---|
3 | 4 | * Copyright (C) 2003-2004 Giuliano Pochini <pochini@shiny.it> |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify |
---|
6 | | - * it under the terms of the GNU General Public License as published by |
---|
7 | | - * the Free Software Foundation; version 2 of the License. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope that it will be useful, |
---|
10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | | - * GNU General Public License for more details. |
---|
13 | | - * |
---|
14 | | - * You should have received a copy of the GNU General Public License |
---|
15 | | - * along with this program; if not, write to the Free Software |
---|
16 | | - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
---|
| 5 | + * Copyright (C) 2020 Mark Hills <mark@xwax.org> |
---|
17 | 6 | */ |
---|
18 | 7 | |
---|
19 | 8 | #include <linux/module.h> |
---|
.. | .. |
---|
35 | 24 | module_param_array(enable, bool, NULL, 0444); |
---|
36 | 25 | MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard."); |
---|
37 | 26 | |
---|
38 | | -static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; |
---|
| 27 | +static const unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; |
---|
39 | 28 | static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1); |
---|
40 | 29 | |
---|
41 | 30 | |
---|
.. | .. |
---|
257 | 246 | SNDRV_PCM_HW_PARAM_RATE); |
---|
258 | 247 | struct echoaudio *chip = rule->private; |
---|
259 | 248 | struct snd_interval fixed; |
---|
| 249 | + int err; |
---|
260 | 250 | |
---|
261 | | - if (!chip->can_set_rate) { |
---|
| 251 | + mutex_lock(&chip->mode_mutex); |
---|
| 252 | + |
---|
| 253 | + if (chip->can_set_rate) { |
---|
| 254 | + err = 0; |
---|
| 255 | + } else { |
---|
262 | 256 | snd_interval_any(&fixed); |
---|
263 | 257 | fixed.min = fixed.max = chip->sample_rate; |
---|
264 | | - return snd_interval_refine(rate, &fixed); |
---|
| 258 | + err = snd_interval_refine(rate, &fixed); |
---|
265 | 259 | } |
---|
266 | | - return 0; |
---|
| 260 | + |
---|
| 261 | + mutex_unlock(&chip->mode_mutex); |
---|
| 262 | + return err; |
---|
267 | 263 | } |
---|
268 | 264 | |
---|
269 | 265 | |
---|
.. | .. |
---|
334 | 330 | SNDRV_PCM_HW_PARAM_RATE, -1)) < 0) |
---|
335 | 331 | return err; |
---|
336 | 332 | |
---|
337 | | - /* Finally allocate a page for the scatter-gather list */ |
---|
| 333 | + /* Allocate a page for the scatter-gather list */ |
---|
338 | 334 | if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, |
---|
339 | | - snd_dma_pci_data(chip->pci), |
---|
| 335 | + &chip->pci->dev, |
---|
340 | 336 | PAGE_SIZE, &pipe->sgpage)) < 0) { |
---|
341 | 337 | dev_err(chip->card->dev, "s-g list allocation failed\n"); |
---|
342 | 338 | return err; |
---|
343 | 339 | } |
---|
| 340 | + |
---|
| 341 | + /* |
---|
| 342 | + * Sole ownership required to set the rate |
---|
| 343 | + */ |
---|
| 344 | + |
---|
| 345 | + dev_dbg(chip->card->dev, "pcm_open opencount=%d can_set_rate=%d, rate_set=%d", |
---|
| 346 | + chip->opencount, chip->can_set_rate, chip->rate_set); |
---|
| 347 | + |
---|
| 348 | + chip->opencount++; |
---|
| 349 | + if (chip->opencount > 1 && chip->rate_set) |
---|
| 350 | + chip->can_set_rate = 0; |
---|
344 | 351 | |
---|
345 | 352 | return 0; |
---|
346 | 353 | } |
---|
.. | .. |
---|
365 | 372 | hw_rule_capture_format_by_channels, NULL, |
---|
366 | 373 | SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) |
---|
367 | 374 | return err; |
---|
368 | | - atomic_inc(&chip->opencount); |
---|
369 | | - if (atomic_read(&chip->opencount) > 1 && chip->rate_set) |
---|
370 | | - chip->can_set_rate=0; |
---|
371 | | - dev_dbg(chip->card->dev, "pcm_analog_in_open cs=%d oc=%d r=%d\n", |
---|
372 | | - chip->can_set_rate, atomic_read(&chip->opencount), |
---|
373 | | - chip->sample_rate); |
---|
| 375 | + |
---|
374 | 376 | return 0; |
---|
375 | 377 | } |
---|
376 | 378 | |
---|
.. | .. |
---|
400 | 402 | NULL, |
---|
401 | 403 | SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) |
---|
402 | 404 | return err; |
---|
403 | | - atomic_inc(&chip->opencount); |
---|
404 | | - if (atomic_read(&chip->opencount) > 1 && chip->rate_set) |
---|
405 | | - chip->can_set_rate=0; |
---|
406 | | - dev_dbg(chip->card->dev, "pcm_analog_out_open cs=%d oc=%d r=%d\n", |
---|
407 | | - chip->can_set_rate, atomic_read(&chip->opencount), |
---|
408 | | - chip->sample_rate); |
---|
| 405 | + |
---|
409 | 406 | return 0; |
---|
410 | 407 | } |
---|
411 | 408 | |
---|
.. | .. |
---|
440 | 437 | hw_rule_capture_format_by_channels, NULL, |
---|
441 | 438 | SNDRV_PCM_HW_PARAM_CHANNELS, -1)) < 0) |
---|
442 | 439 | goto din_exit; |
---|
443 | | - |
---|
444 | | - atomic_inc(&chip->opencount); |
---|
445 | | - if (atomic_read(&chip->opencount) > 1 && chip->rate_set) |
---|
446 | | - chip->can_set_rate=0; |
---|
447 | 440 | |
---|
448 | 441 | din_exit: |
---|
449 | 442 | mutex_unlock(&chip->mode_mutex); |
---|
.. | .. |
---|
483 | 476 | NULL, SNDRV_PCM_HW_PARAM_CHANNELS, |
---|
484 | 477 | -1)) < 0) |
---|
485 | 478 | goto dout_exit; |
---|
486 | | - atomic_inc(&chip->opencount); |
---|
487 | | - if (atomic_read(&chip->opencount) > 1 && chip->rate_set) |
---|
488 | | - chip->can_set_rate=0; |
---|
| 479 | + |
---|
489 | 480 | dout_exit: |
---|
490 | 481 | mutex_unlock(&chip->mode_mutex); |
---|
491 | 482 | return err; |
---|
.. | .. |
---|
500 | 491 | static int pcm_close(struct snd_pcm_substream *substream) |
---|
501 | 492 | { |
---|
502 | 493 | struct echoaudio *chip = snd_pcm_substream_chip(substream); |
---|
503 | | - int oc; |
---|
504 | 494 | |
---|
505 | 495 | /* Nothing to do here. Audio is already off and pipe will be |
---|
506 | 496 | * freed by its callback |
---|
507 | 497 | */ |
---|
508 | 498 | |
---|
509 | | - atomic_dec(&chip->opencount); |
---|
510 | | - oc = atomic_read(&chip->opencount); |
---|
511 | | - dev_dbg(chip->card->dev, "pcm_close oc=%d cs=%d rs=%d\n", oc, |
---|
512 | | - chip->can_set_rate, chip->rate_set); |
---|
513 | | - if (oc < 2) |
---|
514 | | - chip->can_set_rate = 1; |
---|
515 | | - if (oc == 0) |
---|
516 | | - chip->rate_set = 0; |
---|
517 | | - dev_dbg(chip->card->dev, "pcm_close2 oc=%d cs=%d rs=%d\n", oc, |
---|
518 | | - chip->can_set_rate, chip->rate_set); |
---|
| 499 | + mutex_lock(&chip->mode_mutex); |
---|
519 | 500 | |
---|
| 501 | + dev_dbg(chip->card->dev, "pcm_open opencount=%d can_set_rate=%d, rate_set=%d", |
---|
| 502 | + chip->opencount, chip->can_set_rate, chip->rate_set); |
---|
| 503 | + |
---|
| 504 | + chip->opencount--; |
---|
| 505 | + |
---|
| 506 | + switch (chip->opencount) { |
---|
| 507 | + case 1: |
---|
| 508 | + chip->can_set_rate = 1; |
---|
| 509 | + break; |
---|
| 510 | + |
---|
| 511 | + case 0: |
---|
| 512 | + chip->rate_set = 0; |
---|
| 513 | + break; |
---|
| 514 | + } |
---|
| 515 | + |
---|
| 516 | + mutex_unlock(&chip->mode_mutex); |
---|
520 | 517 | return 0; |
---|
521 | 518 | } |
---|
522 | 519 | |
---|
.. | .. |
---|
559 | 556 | "pcm_hw_params (bufsize=%dB periods=%d persize=%dB)\n", |
---|
560 | 557 | params_buffer_bytes(hw_params), params_periods(hw_params), |
---|
561 | 558 | params_period_bytes(hw_params)); |
---|
562 | | - err = snd_pcm_lib_malloc_pages(substream, |
---|
563 | | - params_buffer_bytes(hw_params)); |
---|
564 | | - if (err < 0) { |
---|
565 | | - dev_err(chip->card->dev, "malloc_pages err=%d\n", err); |
---|
566 | | - spin_lock_irq(&chip->lock); |
---|
567 | | - free_pipes(chip, pipe); |
---|
568 | | - spin_unlock_irq(&chip->lock); |
---|
569 | | - pipe->index = -1; |
---|
570 | | - return err; |
---|
571 | | - } |
---|
572 | 559 | |
---|
573 | 560 | sglist_init(chip, pipe); |
---|
574 | 561 | edge = PAGE_SIZE; |
---|
.. | .. |
---|
604 | 591 | /* This stuff is used by the irq handler, so it must be |
---|
605 | 592 | * initialized before chip->substream |
---|
606 | 593 | */ |
---|
607 | | - chip->last_period[pipe_index] = 0; |
---|
| 594 | + pipe->last_period = 0; |
---|
608 | 595 | pipe->last_counter = 0; |
---|
609 | 596 | pipe->position = 0; |
---|
610 | 597 | smp_wmb(); |
---|
.. | .. |
---|
683 | 670 | } |
---|
684 | 671 | spin_unlock_irq(&chip->lock); |
---|
685 | 672 | |
---|
686 | | - snd_pcm_lib_free_pages(substream); |
---|
687 | 673 | return 0; |
---|
688 | 674 | } |
---|
689 | 675 | |
---|
.. | .. |
---|
713 | 699 | break; |
---|
714 | 700 | case SNDRV_PCM_FORMAT_S32_BE: |
---|
715 | 701 | format.data_are_bigendian = 1; |
---|
716 | | - /* fall through */ |
---|
| 702 | + fallthrough; |
---|
717 | 703 | case SNDRV_PCM_FORMAT_S32_LE: |
---|
718 | 704 | format.bits_per_sample = 32; |
---|
719 | 705 | break; |
---|
.. | .. |
---|
726 | 712 | |
---|
727 | 713 | if (snd_BUG_ON(pipe_index >= px_num(chip))) |
---|
728 | 714 | return -EINVAL; |
---|
729 | | - if (snd_BUG_ON(!is_pipe_allocated(chip, pipe_index))) |
---|
| 715 | + |
---|
| 716 | + /* |
---|
| 717 | + * We passed checks we can do independently; now take |
---|
| 718 | + * exclusive control |
---|
| 719 | + */ |
---|
| 720 | + |
---|
| 721 | + spin_lock_irq(&chip->lock); |
---|
| 722 | + |
---|
| 723 | + if (snd_BUG_ON(!is_pipe_allocated(chip, pipe_index))) { |
---|
| 724 | + spin_unlock_irq(&chip->lock); |
---|
730 | 725 | return -EINVAL; |
---|
| 726 | + } |
---|
| 727 | + |
---|
731 | 728 | set_audio_format(chip, pipe_index, &format); |
---|
| 729 | + spin_unlock_irq(&chip->lock); |
---|
| 730 | + |
---|
732 | 731 | return 0; |
---|
733 | 732 | } |
---|
734 | 733 | |
---|
.. | .. |
---|
761 | 760 | pipe = chip->substream[i]->runtime->private_data; |
---|
762 | 761 | switch (pipe->state) { |
---|
763 | 762 | case PIPE_STATE_STOPPED: |
---|
764 | | - chip->last_period[i] = 0; |
---|
| 763 | + pipe->last_period = 0; |
---|
765 | 764 | pipe->last_counter = 0; |
---|
766 | 765 | pipe->position = 0; |
---|
767 | 766 | *pipe->dma_counter = 0; |
---|
768 | | - /* fall through */ |
---|
| 767 | + fallthrough; |
---|
769 | 768 | case PIPE_STATE_PAUSED: |
---|
770 | 769 | pipe->state = PIPE_STATE_STARTED; |
---|
771 | 770 | break; |
---|
.. | .. |
---|
809 | 808 | { |
---|
810 | 809 | struct snd_pcm_runtime *runtime = substream->runtime; |
---|
811 | 810 | struct audiopipe *pipe = runtime->private_data; |
---|
812 | | - size_t cnt, bufsize, pos; |
---|
| 811 | + u32 counter, step; |
---|
813 | 812 | |
---|
814 | | - cnt = le32_to_cpu(*pipe->dma_counter); |
---|
815 | | - pipe->position += cnt - pipe->last_counter; |
---|
816 | | - pipe->last_counter = cnt; |
---|
817 | | - bufsize = substream->runtime->buffer_size; |
---|
818 | | - pos = bytes_to_frames(substream->runtime, pipe->position); |
---|
| 813 | + /* |
---|
| 814 | + * IRQ handling runs concurrently. Do not share tracking of |
---|
| 815 | + * counter with it, which would race or require locking |
---|
| 816 | + */ |
---|
819 | 817 | |
---|
820 | | - while (pos >= bufsize) { |
---|
821 | | - pipe->position -= frames_to_bytes(substream->runtime, bufsize); |
---|
822 | | - pos -= bufsize; |
---|
823 | | - } |
---|
824 | | - return pos; |
---|
| 818 | + counter = le32_to_cpu(*pipe->dma_counter); /* presumed atomic */ |
---|
| 819 | + |
---|
| 820 | + step = counter - pipe->last_counter; /* handles wrapping */ |
---|
| 821 | + pipe->last_counter = counter; |
---|
| 822 | + |
---|
| 823 | + /* counter doesn't neccessarily wrap on a multiple of |
---|
| 824 | + * buffer_size, so can't derive the position; must |
---|
| 825 | + * accumulate */ |
---|
| 826 | + |
---|
| 827 | + pipe->position += step; |
---|
| 828 | + pipe->position %= frames_to_bytes(runtime, runtime->buffer_size); /* wrap */ |
---|
| 829 | + |
---|
| 830 | + return bytes_to_frames(runtime, pipe->position); |
---|
825 | 831 | } |
---|
826 | 832 | |
---|
827 | 833 | |
---|
.. | .. |
---|
830 | 836 | static const struct snd_pcm_ops analog_playback_ops = { |
---|
831 | 837 | .open = pcm_analog_out_open, |
---|
832 | 838 | .close = pcm_close, |
---|
833 | | - .ioctl = snd_pcm_lib_ioctl, |
---|
834 | 839 | .hw_params = pcm_analog_out_hw_params, |
---|
835 | 840 | .hw_free = pcm_hw_free, |
---|
836 | 841 | .prepare = pcm_prepare, |
---|
837 | 842 | .trigger = pcm_trigger, |
---|
838 | 843 | .pointer = pcm_pointer, |
---|
839 | | - .page = snd_pcm_sgbuf_ops_page, |
---|
840 | 844 | }; |
---|
841 | 845 | static const struct snd_pcm_ops analog_capture_ops = { |
---|
842 | 846 | .open = pcm_analog_in_open, |
---|
843 | 847 | .close = pcm_close, |
---|
844 | | - .ioctl = snd_pcm_lib_ioctl, |
---|
845 | 848 | .hw_params = pcm_analog_in_hw_params, |
---|
846 | 849 | .hw_free = pcm_hw_free, |
---|
847 | 850 | .prepare = pcm_prepare, |
---|
848 | 851 | .trigger = pcm_trigger, |
---|
849 | 852 | .pointer = pcm_pointer, |
---|
850 | | - .page = snd_pcm_sgbuf_ops_page, |
---|
851 | 853 | }; |
---|
852 | 854 | #ifdef ECHOCARD_HAS_DIGITAL_IO |
---|
853 | 855 | #ifndef ECHOCARD_HAS_VMIXER |
---|
854 | 856 | static const struct snd_pcm_ops digital_playback_ops = { |
---|
855 | 857 | .open = pcm_digital_out_open, |
---|
856 | 858 | .close = pcm_close, |
---|
857 | | - .ioctl = snd_pcm_lib_ioctl, |
---|
858 | 859 | .hw_params = pcm_digital_out_hw_params, |
---|
859 | 860 | .hw_free = pcm_hw_free, |
---|
860 | 861 | .prepare = pcm_prepare, |
---|
861 | 862 | .trigger = pcm_trigger, |
---|
862 | 863 | .pointer = pcm_pointer, |
---|
863 | | - .page = snd_pcm_sgbuf_ops_page, |
---|
864 | 864 | }; |
---|
865 | 865 | #endif /* !ECHOCARD_HAS_VMIXER */ |
---|
866 | 866 | static const struct snd_pcm_ops digital_capture_ops = { |
---|
867 | 867 | .open = pcm_digital_in_open, |
---|
868 | 868 | .close = pcm_close, |
---|
869 | | - .ioctl = snd_pcm_lib_ioctl, |
---|
870 | 869 | .hw_params = pcm_digital_in_hw_params, |
---|
871 | 870 | .hw_free = pcm_hw_free, |
---|
872 | 871 | .prepare = pcm_prepare, |
---|
873 | 872 | .trigger = pcm_trigger, |
---|
874 | 873 | .pointer = pcm_pointer, |
---|
875 | | - .page = snd_pcm_sgbuf_ops_page, |
---|
876 | 874 | }; |
---|
877 | 875 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ |
---|
878 | 876 | |
---|
.. | .. |
---|
881 | 879 | /* Preallocate memory only for the first substream because it's the most |
---|
882 | 880 | * used one |
---|
883 | 881 | */ |
---|
884 | | -static int snd_echo_preallocate_pages(struct snd_pcm *pcm, struct device *dev) |
---|
| 882 | +static void snd_echo_preallocate_pages(struct snd_pcm *pcm, struct device *dev) |
---|
885 | 883 | { |
---|
886 | 884 | struct snd_pcm_substream *ss; |
---|
887 | | - int stream, err; |
---|
| 885 | + int stream; |
---|
888 | 886 | |
---|
889 | 887 | for (stream = 0; stream < 2; stream++) |
---|
890 | | - for (ss = pcm->streams[stream].substream; ss; ss = ss->next) { |
---|
891 | | - err = snd_pcm_lib_preallocate_pages(ss, SNDRV_DMA_TYPE_DEV_SG, |
---|
892 | | - dev, |
---|
893 | | - ss->number ? 0 : 128<<10, |
---|
894 | | - 256<<10); |
---|
895 | | - if (err < 0) |
---|
896 | | - return err; |
---|
897 | | - } |
---|
898 | | - return 0; |
---|
| 888 | + for (ss = pcm->streams[stream].substream; ss; ss = ss->next) |
---|
| 889 | + snd_pcm_set_managed_buffer(ss, SNDRV_DMA_TYPE_DEV_SG, |
---|
| 890 | + dev, |
---|
| 891 | + ss->number ? 0 : 128<<10, |
---|
| 892 | + 256<<10); |
---|
899 | 893 | } |
---|
900 | 894 | |
---|
901 | 895 | |
---|
.. | .. |
---|
922 | 916 | strcpy(pcm->name, chip->card->shortname); |
---|
923 | 917 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops); |
---|
924 | 918 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); |
---|
925 | | - if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) |
---|
926 | | - return err; |
---|
| 919 | + snd_echo_preallocate_pages(pcm, &chip->pci->dev); |
---|
927 | 920 | |
---|
928 | 921 | #ifdef ECHOCARD_HAS_DIGITAL_IO |
---|
929 | 922 | /* PCM#1 Digital inputs, no outputs */ |
---|
.. | .. |
---|
934 | 927 | chip->digital_pcm = pcm; |
---|
935 | 928 | strcpy(pcm->name, chip->card->shortname); |
---|
936 | 929 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); |
---|
937 | | - if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) |
---|
938 | | - return err; |
---|
| 930 | + snd_echo_preallocate_pages(pcm, &chip->pci->dev); |
---|
939 | 931 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ |
---|
940 | 932 | |
---|
941 | 933 | #else /* ECHOCARD_HAS_VMIXER */ |
---|
.. | .. |
---|
955 | 947 | strcpy(pcm->name, chip->card->shortname); |
---|
956 | 948 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &analog_playback_ops); |
---|
957 | 949 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &analog_capture_ops); |
---|
958 | | - if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) |
---|
959 | | - return err; |
---|
| 950 | + snd_echo_preallocate_pages(pcm, &chip->pci->dev); |
---|
960 | 951 | |
---|
961 | 952 | #ifdef ECHOCARD_HAS_DIGITAL_IO |
---|
962 | 953 | /* PCM#1 Digital i/o */ |
---|
.. | .. |
---|
969 | 960 | strcpy(pcm->name, chip->card->shortname); |
---|
970 | 961 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &digital_playback_ops); |
---|
971 | 962 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &digital_capture_ops); |
---|
972 | | - if ((err = snd_echo_preallocate_pages(pcm, snd_dma_pci_data(chip->pci))) < 0) |
---|
973 | | - return err; |
---|
| 963 | + snd_echo_preallocate_pages(pcm, &chip->pci->dev); |
---|
974 | 964 | #endif /* ECHOCARD_HAS_DIGITAL_IO */ |
---|
975 | 965 | |
---|
976 | 966 | #endif /* ECHOCARD_HAS_VMIXER */ |
---|
.. | .. |
---|
1269 | 1259 | static int snd_echo_mixer_info(struct snd_kcontrol *kcontrol, |
---|
1270 | 1260 | struct snd_ctl_elem_info *uinfo) |
---|
1271 | 1261 | { |
---|
1272 | | - struct echoaudio *chip; |
---|
1273 | | - |
---|
1274 | | - chip = snd_kcontrol_chip(kcontrol); |
---|
1275 | 1262 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
---|
1276 | 1263 | uinfo->count = 1; |
---|
1277 | 1264 | uinfo->value.integer.min = ECHOGAIN_MINOUT; |
---|
1278 | 1265 | uinfo->value.integer.max = ECHOGAIN_MAXOUT; |
---|
1279 | | - uinfo->dimen.d[0] = num_busses_out(chip); |
---|
1280 | | - uinfo->dimen.d[1] = num_busses_in(chip); |
---|
1281 | 1266 | return 0; |
---|
1282 | 1267 | } |
---|
1283 | 1268 | |
---|
.. | .. |
---|
1341 | 1326 | static int snd_echo_vmixer_info(struct snd_kcontrol *kcontrol, |
---|
1342 | 1327 | struct snd_ctl_elem_info *uinfo) |
---|
1343 | 1328 | { |
---|
1344 | | - struct echoaudio *chip; |
---|
1345 | | - |
---|
1346 | | - chip = snd_kcontrol_chip(kcontrol); |
---|
1347 | 1329 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
---|
1348 | 1330 | uinfo->count = 1; |
---|
1349 | 1331 | uinfo->value.integer.min = ECHOGAIN_MINOUT; |
---|
1350 | 1332 | uinfo->value.integer.max = ECHOGAIN_MAXOUT; |
---|
1351 | | - uinfo->dimen.d[0] = num_busses_out(chip); |
---|
1352 | | - uinfo->dimen.d[1] = num_pipes_out(chip); |
---|
1353 | 1333 | return 0; |
---|
1354 | 1334 | } |
---|
1355 | 1335 | |
---|
.. | .. |
---|
1458 | 1438 | /* Do not allow the user to change the digital mode when a pcm |
---|
1459 | 1439 | device is open because it also changes the number of channels |
---|
1460 | 1440 | and the allowed sample rates */ |
---|
1461 | | - if (atomic_read(&chip->opencount)) { |
---|
| 1441 | + if (chip->opencount) { |
---|
1462 | 1442 | changed = -EAGAIN; |
---|
1463 | 1443 | } else { |
---|
1464 | 1444 | changed = set_digital_mode(chip, dmode); |
---|
.. | .. |
---|
1732 | 1712 | uinfo->count = 96; |
---|
1733 | 1713 | uinfo->value.integer.min = ECHOGAIN_MINOUT; |
---|
1734 | 1714 | uinfo->value.integer.max = 0; |
---|
1735 | | -#ifdef ECHOCARD_HAS_VMIXER |
---|
1736 | | - uinfo->dimen.d[0] = 3; /* Out, In, Virt */ |
---|
1737 | | -#else |
---|
1738 | | - uinfo->dimen.d[0] = 2; /* Out, In */ |
---|
1739 | | -#endif |
---|
1740 | | - uinfo->dimen.d[1] = 16; /* 16 channels */ |
---|
1741 | | - uinfo->dimen.d[2] = 2; /* 0=level, 1=peak */ |
---|
1742 | 1715 | return 0; |
---|
1743 | 1716 | } |
---|
1744 | 1717 | |
---|
.. | .. |
---|
1817 | 1790 | |
---|
1818 | 1791 | |
---|
1819 | 1792 | /****************************************************************************** |
---|
1820 | | - IRQ Handler |
---|
| 1793 | + IRQ Handling |
---|
1821 | 1794 | ******************************************************************************/ |
---|
| 1795 | +/* Check if a period has elapsed since last interrupt |
---|
| 1796 | + * |
---|
| 1797 | + * Don't make any updates to state; PCM core handles this with the |
---|
| 1798 | + * correct locks. |
---|
| 1799 | + * |
---|
| 1800 | + * \return true if a period has elapsed, otherwise false |
---|
| 1801 | + */ |
---|
| 1802 | +static bool period_has_elapsed(struct snd_pcm_substream *substream) |
---|
| 1803 | +{ |
---|
| 1804 | + struct snd_pcm_runtime *runtime = substream->runtime; |
---|
| 1805 | + struct audiopipe *pipe = runtime->private_data; |
---|
| 1806 | + u32 counter, step; |
---|
| 1807 | + size_t period_bytes; |
---|
| 1808 | + |
---|
| 1809 | + if (pipe->state != PIPE_STATE_STARTED) |
---|
| 1810 | + return false; |
---|
| 1811 | + |
---|
| 1812 | + period_bytes = frames_to_bytes(runtime, runtime->period_size); |
---|
| 1813 | + |
---|
| 1814 | + counter = le32_to_cpu(*pipe->dma_counter); /* presumed atomic */ |
---|
| 1815 | + |
---|
| 1816 | + step = counter - pipe->last_period; /* handles wrapping */ |
---|
| 1817 | + step -= step % period_bytes; /* acknowledge whole periods only */ |
---|
| 1818 | + |
---|
| 1819 | + if (step == 0) |
---|
| 1820 | + return false; /* haven't advanced a whole period yet */ |
---|
| 1821 | + |
---|
| 1822 | + pipe->last_period += step; /* used exclusively by us */ |
---|
| 1823 | + return true; |
---|
| 1824 | +} |
---|
1822 | 1825 | |
---|
1823 | 1826 | static irqreturn_t snd_echo_interrupt(int irq, void *dev_id) |
---|
1824 | 1827 | { |
---|
1825 | 1828 | struct echoaudio *chip = dev_id; |
---|
1826 | | - struct snd_pcm_substream *substream; |
---|
1827 | | - int period, ss, st; |
---|
| 1829 | + int ss, st; |
---|
1828 | 1830 | |
---|
1829 | 1831 | spin_lock(&chip->lock); |
---|
1830 | 1832 | st = service_irq(chip); |
---|
.. | .. |
---|
1835 | 1837 | /* The hardware doesn't tell us which substream caused the irq, |
---|
1836 | 1838 | thus we have to check all running substreams. */ |
---|
1837 | 1839 | for (ss = 0; ss < DSP_MAXPIPES; ss++) { |
---|
| 1840 | + struct snd_pcm_substream *substream; |
---|
| 1841 | + |
---|
1838 | 1842 | substream = chip->substream[ss]; |
---|
1839 | | - if (substream && ((struct audiopipe *)substream->runtime-> |
---|
1840 | | - private_data)->state == PIPE_STATE_STARTED) { |
---|
1841 | | - period = pcm_pointer(substream) / |
---|
1842 | | - substream->runtime->period_size; |
---|
1843 | | - if (period != chip->last_period[ss]) { |
---|
1844 | | - chip->last_period[ss] = period; |
---|
1845 | | - spin_unlock(&chip->lock); |
---|
1846 | | - snd_pcm_period_elapsed(substream); |
---|
1847 | | - spin_lock(&chip->lock); |
---|
1848 | | - } |
---|
| 1843 | + if (substream && period_has_elapsed(substream)) { |
---|
| 1844 | + spin_unlock(&chip->lock); |
---|
| 1845 | + snd_pcm_period_elapsed(substream); |
---|
| 1846 | + spin_lock(&chip->lock); |
---|
1849 | 1847 | } |
---|
1850 | 1848 | } |
---|
1851 | 1849 | spin_unlock(&chip->lock); |
---|
.. | .. |
---|
1906 | 1904 | struct echoaudio *chip; |
---|
1907 | 1905 | int err; |
---|
1908 | 1906 | size_t sz; |
---|
1909 | | - static struct snd_device_ops ops = { |
---|
| 1907 | + static const struct snd_device_ops ops = { |
---|
1910 | 1908 | .dev_free = snd_echo_dev_free, |
---|
1911 | 1909 | }; |
---|
1912 | 1910 | |
---|
.. | .. |
---|
1930 | 1928 | chip->card = card; |
---|
1931 | 1929 | chip->pci = pci; |
---|
1932 | 1930 | chip->irq = -1; |
---|
1933 | | - atomic_set(&chip->opencount, 0); |
---|
| 1931 | + chip->opencount = 0; |
---|
1934 | 1932 | mutex_init(&chip->mode_mutex); |
---|
1935 | 1933 | chip->can_set_rate = 1; |
---|
1936 | 1934 | } else { |
---|
.. | .. |
---|
1952 | 1950 | snd_echo_free(chip); |
---|
1953 | 1951 | return -EBUSY; |
---|
1954 | 1952 | } |
---|
1955 | | - chip->dsp_registers = (volatile u32 __iomem *) |
---|
1956 | | - ioremap_nocache(chip->dsp_registers_phys, sz); |
---|
| 1953 | + chip->dsp_registers = ioremap(chip->dsp_registers_phys, sz); |
---|
1957 | 1954 | if (!chip->dsp_registers) { |
---|
1958 | 1955 | dev_err(chip->card->dev, "ioremap failed\n"); |
---|
1959 | 1956 | snd_echo_free(chip); |
---|
.. | .. |
---|
1967 | 1964 | return -EBUSY; |
---|
1968 | 1965 | } |
---|
1969 | 1966 | chip->irq = pci->irq; |
---|
| 1967 | + card->sync_irq = chip->irq; |
---|
1970 | 1968 | dev_dbg(card->dev, "pci=%p irq=%d subdev=%04x Init hardware...\n", |
---|
1971 | 1969 | chip->pci, chip->irq, chip->pci->subsystem_device); |
---|
1972 | 1970 | |
---|
1973 | 1971 | /* Create the DSP comm page - this is the area of memory used for most |
---|
1974 | 1972 | of the communication with the DSP, which accesses it via bus mastering */ |
---|
1975 | | - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci), |
---|
| 1973 | + if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &chip->pci->dev, |
---|
1976 | 1974 | sizeof(struct comm_page), |
---|
1977 | 1975 | &chip->commpage_dma_buf) < 0) { |
---|
1978 | 1976 | dev_err(chip->card->dev, "cannot allocate the comm page\n"); |
---|
.. | .. |
---|
2010 | 2008 | struct snd_card *card; |
---|
2011 | 2009 | struct echoaudio *chip; |
---|
2012 | 2010 | char *dsp; |
---|
2013 | | - int i, err; |
---|
| 2011 | + __maybe_unused int i; |
---|
| 2012 | + int err; |
---|
2014 | 2013 | |
---|
2015 | 2014 | if (dev >= SNDRV_CARDS) |
---|
2016 | 2015 | return -ENODEV; |
---|
.. | .. |
---|
2170 | 2169 | { |
---|
2171 | 2170 | struct echoaudio *chip = dev_get_drvdata(dev); |
---|
2172 | 2171 | |
---|
2173 | | - snd_pcm_suspend_all(chip->analog_pcm); |
---|
2174 | | - snd_pcm_suspend_all(chip->digital_pcm); |
---|
2175 | | - |
---|
2176 | 2172 | #ifdef ECHOCARD_HAS_MIDI |
---|
2177 | 2173 | /* This call can sleep */ |
---|
2178 | 2174 | if (chip->midi_out) |
---|
.. | .. |
---|
2193 | 2189 | chip->dsp_code = NULL; |
---|
2194 | 2190 | free_irq(chip->irq, chip); |
---|
2195 | 2191 | chip->irq = -1; |
---|
| 2192 | + chip->card->sync_irq = -1; |
---|
2196 | 2193 | return 0; |
---|
2197 | 2194 | } |
---|
2198 | 2195 | |
---|
.. | .. |
---|
2206 | 2203 | u32 pipe_alloc_mask; |
---|
2207 | 2204 | int err; |
---|
2208 | 2205 | |
---|
2209 | | - commpage_bak = kmalloc(sizeof(*commpage), GFP_KERNEL); |
---|
| 2206 | + commpage = chip->comm_page; |
---|
| 2207 | + commpage_bak = kmemdup(commpage, sizeof(*commpage), GFP_KERNEL); |
---|
2210 | 2208 | if (commpage_bak == NULL) |
---|
2211 | 2209 | return -ENOMEM; |
---|
2212 | | - commpage = chip->comm_page; |
---|
2213 | | - memcpy(commpage_bak, commpage, sizeof(*commpage)); |
---|
2214 | 2210 | |
---|
2215 | 2211 | err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device); |
---|
2216 | 2212 | if (err < 0) { |
---|
.. | .. |
---|
2245 | 2241 | return -EBUSY; |
---|
2246 | 2242 | } |
---|
2247 | 2243 | chip->irq = pci->irq; |
---|
| 2244 | + chip->card->sync_irq = chip->irq; |
---|
2248 | 2245 | dev_dbg(dev, "resume irq=%d\n", chip->irq); |
---|
2249 | 2246 | |
---|
2250 | 2247 | #ifdef ECHOCARD_HAS_MIDI |
---|