.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * ALSA driver for RME Hammerfall DSP MADI audio interface(s) |
---|
3 | 4 | * |
---|
.. | .. |
---|
23 | 24 | * |
---|
24 | 25 | * Modified 2011-01-25 variable period sizes on RayDAT/AIO by Adrian Knoth |
---|
25 | 26 | * |
---|
26 | | - * This program is free software; you can redistribute it and/or modify |
---|
27 | | - * it under the terms of the GNU General Public License as published by |
---|
28 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
29 | | - * (at your option) any later version. |
---|
30 | | - * |
---|
31 | | - * This program is distributed in the hope that it will be useful, |
---|
32 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
33 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
34 | | - * GNU General Public License for more details. |
---|
35 | | - * |
---|
36 | | - * You should have received a copy of the GNU General Public License |
---|
37 | | - * along with this program; if not, write to the Free Software |
---|
38 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
39 | | - * |
---|
| 27 | + * Modified 2019-05-23 fix AIO single speed ADAT capture and playback |
---|
| 28 | + * by Philippe.Bekaert@uhasselt.be |
---|
40 | 29 | */ |
---|
41 | 30 | |
---|
42 | 31 | /* ************* Register Documentation ******************************************************* |
---|
.. | .. |
---|
648 | 637 | #define HDSPM_SPEED_QUAD 2 |
---|
649 | 638 | |
---|
650 | 639 | /* names for speed modes */ |
---|
651 | | -static char *hdspm_speed_names[] = { "single", "double", "quad" }; |
---|
| 640 | +static const char * const hdspm_speed_names[] = { "single", "double", "quad" }; |
---|
652 | 641 | |
---|
653 | 642 | static const char *const texts_autosync_aes_tco[] = { "Word Clock", |
---|
654 | 643 | "AES1", "AES2", "AES3", "AES4", |
---|
.. | .. |
---|
695 | 684 | "192 kHz" |
---|
696 | 685 | }; |
---|
697 | 686 | |
---|
698 | | -static char *texts_ports_madi[] = { |
---|
| 687 | +static const char * const texts_ports_madi[] = { |
---|
699 | 688 | "MADI.1", "MADI.2", "MADI.3", "MADI.4", "MADI.5", "MADI.6", |
---|
700 | 689 | "MADI.7", "MADI.8", "MADI.9", "MADI.10", "MADI.11", "MADI.12", |
---|
701 | 690 | "MADI.13", "MADI.14", "MADI.15", "MADI.16", "MADI.17", "MADI.18", |
---|
.. | .. |
---|
710 | 699 | }; |
---|
711 | 700 | |
---|
712 | 701 | |
---|
713 | | -static char *texts_ports_raydat_ss[] = { |
---|
| 702 | +static const char * const texts_ports_raydat_ss[] = { |
---|
714 | 703 | "ADAT1.1", "ADAT1.2", "ADAT1.3", "ADAT1.4", "ADAT1.5", "ADAT1.6", |
---|
715 | 704 | "ADAT1.7", "ADAT1.8", "ADAT2.1", "ADAT2.2", "ADAT2.3", "ADAT2.4", |
---|
716 | 705 | "ADAT2.5", "ADAT2.6", "ADAT2.7", "ADAT2.8", "ADAT3.1", "ADAT3.2", |
---|
.. | .. |
---|
721 | 710 | "SPDIF.L", "SPDIF.R" |
---|
722 | 711 | }; |
---|
723 | 712 | |
---|
724 | | -static char *texts_ports_raydat_ds[] = { |
---|
| 713 | +static const char * const texts_ports_raydat_ds[] = { |
---|
725 | 714 | "ADAT1.1", "ADAT1.2", "ADAT1.3", "ADAT1.4", |
---|
726 | 715 | "ADAT2.1", "ADAT2.2", "ADAT2.3", "ADAT2.4", |
---|
727 | 716 | "ADAT3.1", "ADAT3.2", "ADAT3.3", "ADAT3.4", |
---|
.. | .. |
---|
730 | 719 | "SPDIF.L", "SPDIF.R" |
---|
731 | 720 | }; |
---|
732 | 721 | |
---|
733 | | -static char *texts_ports_raydat_qs[] = { |
---|
| 722 | +static const char * const texts_ports_raydat_qs[] = { |
---|
734 | 723 | "ADAT1.1", "ADAT1.2", |
---|
735 | 724 | "ADAT2.1", "ADAT2.2", |
---|
736 | 725 | "ADAT3.1", "ADAT3.2", |
---|
.. | .. |
---|
740 | 729 | }; |
---|
741 | 730 | |
---|
742 | 731 | |
---|
743 | | -static char *texts_ports_aio_in_ss[] = { |
---|
| 732 | +static const char * const texts_ports_aio_in_ss[] = { |
---|
744 | 733 | "Analogue.L", "Analogue.R", |
---|
745 | 734 | "AES.L", "AES.R", |
---|
746 | 735 | "SPDIF.L", "SPDIF.R", |
---|
.. | .. |
---|
749 | 738 | "AEB.1", "AEB.2", "AEB.3", "AEB.4" |
---|
750 | 739 | }; |
---|
751 | 740 | |
---|
752 | | -static char *texts_ports_aio_out_ss[] = { |
---|
| 741 | +static const char * const texts_ports_aio_out_ss[] = { |
---|
753 | 742 | "Analogue.L", "Analogue.R", |
---|
754 | 743 | "AES.L", "AES.R", |
---|
755 | 744 | "SPDIF.L", "SPDIF.R", |
---|
.. | .. |
---|
759 | 748 | "AEB.1", "AEB.2", "AEB.3", "AEB.4" |
---|
760 | 749 | }; |
---|
761 | 750 | |
---|
762 | | -static char *texts_ports_aio_in_ds[] = { |
---|
| 751 | +static const char * const texts_ports_aio_in_ds[] = { |
---|
763 | 752 | "Analogue.L", "Analogue.R", |
---|
764 | 753 | "AES.L", "AES.R", |
---|
765 | 754 | "SPDIF.L", "SPDIF.R", |
---|
.. | .. |
---|
767 | 756 | "AEB.1", "AEB.2", "AEB.3", "AEB.4" |
---|
768 | 757 | }; |
---|
769 | 758 | |
---|
770 | | -static char *texts_ports_aio_out_ds[] = { |
---|
| 759 | +static const char * const texts_ports_aio_out_ds[] = { |
---|
771 | 760 | "Analogue.L", "Analogue.R", |
---|
772 | 761 | "AES.L", "AES.R", |
---|
773 | 762 | "SPDIF.L", "SPDIF.R", |
---|
.. | .. |
---|
776 | 765 | "AEB.1", "AEB.2", "AEB.3", "AEB.4" |
---|
777 | 766 | }; |
---|
778 | 767 | |
---|
779 | | -static char *texts_ports_aio_in_qs[] = { |
---|
| 768 | +static const char * const texts_ports_aio_in_qs[] = { |
---|
780 | 769 | "Analogue.L", "Analogue.R", |
---|
781 | 770 | "AES.L", "AES.R", |
---|
782 | 771 | "SPDIF.L", "SPDIF.R", |
---|
.. | .. |
---|
784 | 773 | "AEB.1", "AEB.2", "AEB.3", "AEB.4" |
---|
785 | 774 | }; |
---|
786 | 775 | |
---|
787 | | -static char *texts_ports_aio_out_qs[] = { |
---|
| 776 | +static const char * const texts_ports_aio_out_qs[] = { |
---|
788 | 777 | "Analogue.L", "Analogue.R", |
---|
789 | 778 | "AES.L", "AES.R", |
---|
790 | 779 | "SPDIF.L", "SPDIF.R", |
---|
.. | .. |
---|
793 | 782 | "AEB.1", "AEB.2", "AEB.3", "AEB.4" |
---|
794 | 783 | }; |
---|
795 | 784 | |
---|
796 | | -static char *texts_ports_aes32[] = { |
---|
| 785 | +static const char * const texts_ports_aes32[] = { |
---|
797 | 786 | "AES.1", "AES.2", "AES.3", "AES.4", "AES.5", "AES.6", "AES.7", |
---|
798 | 787 | "AES.8", "AES.9.", "AES.10", "AES.11", "AES.12", "AES.13", "AES.14", |
---|
799 | 788 | "AES.15", "AES.16" |
---|
.. | .. |
---|
807 | 796 | where the data for that channel can be read/written from/to. |
---|
808 | 797 | */ |
---|
809 | 798 | |
---|
810 | | -static char channel_map_unity_ss[HDSPM_MAX_CHANNELS] = { |
---|
| 799 | +static const char channel_map_unity_ss[HDSPM_MAX_CHANNELS] = { |
---|
811 | 800 | 0, 1, 2, 3, 4, 5, 6, 7, |
---|
812 | 801 | 8, 9, 10, 11, 12, 13, 14, 15, |
---|
813 | 802 | 16, 17, 18, 19, 20, 21, 22, 23, |
---|
.. | .. |
---|
818 | 807 | 56, 57, 58, 59, 60, 61, 62, 63 |
---|
819 | 808 | }; |
---|
820 | 809 | |
---|
821 | | -static char channel_map_raydat_ss[HDSPM_MAX_CHANNELS] = { |
---|
| 810 | +static const char channel_map_raydat_ss[HDSPM_MAX_CHANNELS] = { |
---|
822 | 811 | 4, 5, 6, 7, 8, 9, 10, 11, /* ADAT 1 */ |
---|
823 | 812 | 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT 2 */ |
---|
824 | 813 | 20, 21, 22, 23, 24, 25, 26, 27, /* ADAT 3 */ |
---|
.. | .. |
---|
831 | 820 | -1, -1, -1, -1, -1, -1, -1, -1, |
---|
832 | 821 | }; |
---|
833 | 822 | |
---|
834 | | -static char channel_map_raydat_ds[HDSPM_MAX_CHANNELS] = { |
---|
| 823 | +static const char channel_map_raydat_ds[HDSPM_MAX_CHANNELS] = { |
---|
835 | 824 | 4, 5, 6, 7, /* ADAT 1 */ |
---|
836 | 825 | 8, 9, 10, 11, /* ADAT 2 */ |
---|
837 | 826 | 12, 13, 14, 15, /* ADAT 3 */ |
---|
.. | .. |
---|
846 | 835 | -1, -1, -1, -1, -1, -1, -1, -1, |
---|
847 | 836 | }; |
---|
848 | 837 | |
---|
849 | | -static char channel_map_raydat_qs[HDSPM_MAX_CHANNELS] = { |
---|
| 838 | +static const char channel_map_raydat_qs[HDSPM_MAX_CHANNELS] = { |
---|
850 | 839 | 4, 5, /* ADAT 1 */ |
---|
851 | 840 | 6, 7, /* ADAT 2 */ |
---|
852 | 841 | 8, 9, /* ADAT 3 */ |
---|
.. | .. |
---|
862 | 851 | -1, -1, -1, -1, -1, -1, -1, -1, |
---|
863 | 852 | }; |
---|
864 | 853 | |
---|
865 | | -static char channel_map_aio_in_ss[HDSPM_MAX_CHANNELS] = { |
---|
| 854 | +static const char channel_map_aio_in_ss[HDSPM_MAX_CHANNELS] = { |
---|
866 | 855 | 0, 1, /* line in */ |
---|
867 | 856 | 8, 9, /* aes in, */ |
---|
868 | 857 | 10, 11, /* spdif in */ |
---|
.. | .. |
---|
876 | 865 | -1, -1, -1, -1, -1, -1, -1, -1, |
---|
877 | 866 | }; |
---|
878 | 867 | |
---|
879 | | -static char channel_map_aio_out_ss[HDSPM_MAX_CHANNELS] = { |
---|
| 868 | +static const char channel_map_aio_out_ss[HDSPM_MAX_CHANNELS] = { |
---|
880 | 869 | 0, 1, /* line out */ |
---|
881 | 870 | 8, 9, /* aes out */ |
---|
882 | 871 | 10, 11, /* spdif out */ |
---|
.. | .. |
---|
891 | 880 | -1, -1, -1, -1, -1, -1, -1, -1, |
---|
892 | 881 | }; |
---|
893 | 882 | |
---|
894 | | -static char channel_map_aio_in_ds[HDSPM_MAX_CHANNELS] = { |
---|
| 883 | +static const char channel_map_aio_in_ds[HDSPM_MAX_CHANNELS] = { |
---|
895 | 884 | 0, 1, /* line in */ |
---|
896 | 885 | 8, 9, /* aes in */ |
---|
897 | 886 | 10, 11, /* spdif in */ |
---|
.. | .. |
---|
906 | 895 | -1, -1, -1, -1, -1, -1, -1, -1 |
---|
907 | 896 | }; |
---|
908 | 897 | |
---|
909 | | -static char channel_map_aio_out_ds[HDSPM_MAX_CHANNELS] = { |
---|
| 898 | +static const char channel_map_aio_out_ds[HDSPM_MAX_CHANNELS] = { |
---|
910 | 899 | 0, 1, /* line out */ |
---|
911 | 900 | 8, 9, /* aes out */ |
---|
912 | 901 | 10, 11, /* spdif out */ |
---|
.. | .. |
---|
921 | 910 | -1, -1, -1, -1, -1, -1, -1, -1 |
---|
922 | 911 | }; |
---|
923 | 912 | |
---|
924 | | -static char channel_map_aio_in_qs[HDSPM_MAX_CHANNELS] = { |
---|
| 913 | +static const char channel_map_aio_in_qs[HDSPM_MAX_CHANNELS] = { |
---|
925 | 914 | 0, 1, /* line in */ |
---|
926 | 915 | 8, 9, /* aes in */ |
---|
927 | 916 | 10, 11, /* spdif in */ |
---|
.. | .. |
---|
936 | 925 | -1, -1, -1, -1, -1, -1, -1, -1 |
---|
937 | 926 | }; |
---|
938 | 927 | |
---|
939 | | -static char channel_map_aio_out_qs[HDSPM_MAX_CHANNELS] = { |
---|
| 928 | +static const char channel_map_aio_out_qs[HDSPM_MAX_CHANNELS] = { |
---|
940 | 929 | 0, 1, /* line out */ |
---|
941 | 930 | 8, 9, /* aes out */ |
---|
942 | 931 | 10, 11, /* spdif out */ |
---|
.. | .. |
---|
952 | 941 | -1, -1, -1, -1, -1, -1, -1, -1 |
---|
953 | 942 | }; |
---|
954 | 943 | |
---|
955 | | -static char channel_map_aes32[HDSPM_MAX_CHANNELS] = { |
---|
| 944 | +static const char channel_map_aes32[HDSPM_MAX_CHANNELS] = { |
---|
956 | 945 | 0, 1, 2, 3, 4, 5, 6, 7, |
---|
957 | 946 | 8, 9, 10, 11, 12, 13, 14, 15, |
---|
958 | 947 | -1, -1, -1, -1, -1, -1, -1, -1, |
---|
.. | .. |
---|
1008 | 997 | u32 settings_register; /* cached value for AIO / RayDat (sync reference, master/slave) */ |
---|
1009 | 998 | |
---|
1010 | 999 | struct hdspm_midi midi[4]; |
---|
1011 | | - struct tasklet_struct midi_tasklet; |
---|
| 1000 | + struct work_struct midi_work; |
---|
1012 | 1001 | |
---|
1013 | 1002 | size_t period_bytes; |
---|
1014 | 1003 | unsigned char ss_in_channels; |
---|
.. | .. |
---|
1021 | 1010 | unsigned char max_channels_in; |
---|
1022 | 1011 | unsigned char max_channels_out; |
---|
1023 | 1012 | |
---|
1024 | | - signed char *channel_map_in; |
---|
1025 | | - signed char *channel_map_out; |
---|
| 1013 | + const signed char *channel_map_in; |
---|
| 1014 | + const signed char *channel_map_out; |
---|
1026 | 1015 | |
---|
1027 | | - signed char *channel_map_in_ss, *channel_map_in_ds, *channel_map_in_qs; |
---|
1028 | | - signed char *channel_map_out_ss, *channel_map_out_ds, *channel_map_out_qs; |
---|
| 1016 | + const signed char *channel_map_in_ss, *channel_map_in_ds, *channel_map_in_qs; |
---|
| 1017 | + const signed char *channel_map_out_ss, *channel_map_out_ds, *channel_map_out_qs; |
---|
1029 | 1018 | |
---|
1030 | | - char **port_names_in; |
---|
1031 | | - char **port_names_out; |
---|
| 1019 | + const char * const *port_names_in; |
---|
| 1020 | + const char * const *port_names_out; |
---|
1032 | 1021 | |
---|
1033 | | - char **port_names_in_ss, **port_names_in_ds, **port_names_in_qs; |
---|
1034 | | - char **port_names_out_ss, **port_names_out_ds, **port_names_out_qs; |
---|
| 1022 | + const char * const *port_names_in_ss; |
---|
| 1023 | + const char * const *port_names_in_ds; |
---|
| 1024 | + const char * const *port_names_in_qs; |
---|
| 1025 | + const char * const *port_names_out_ss; |
---|
| 1026 | + const char * const *port_names_out_ds; |
---|
| 1027 | + const char * const *port_names_out_qs; |
---|
1035 | 1028 | |
---|
1036 | 1029 | unsigned char *playback_buffer; /* suitably aligned address */ |
---|
1037 | 1030 | unsigned char *capture_buffer; /* suitably aligned address */ |
---|
.. | .. |
---|
1105 | 1098 | static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out); |
---|
1106 | 1099 | static int snd_hdspm_set_defaults(struct hdspm *hdspm); |
---|
1107 | 1100 | static int hdspm_system_clock_mode(struct hdspm *hdspm); |
---|
1108 | | -static void hdspm_set_sgbuf(struct hdspm *hdspm, |
---|
1109 | | - struct snd_pcm_substream *substream, |
---|
1110 | | - unsigned int reg, int channels); |
---|
| 1101 | +static void hdspm_set_channel_dma_addr(struct hdspm *hdspm, |
---|
| 1102 | + struct snd_pcm_substream *substream, |
---|
| 1103 | + unsigned int reg, int channels); |
---|
1111 | 1104 | |
---|
1112 | 1105 | static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx); |
---|
1113 | 1106 | static int hdspm_wc_sync_check(struct hdspm *hdspm); |
---|
.. | .. |
---|
1224 | 1217 | return ret; |
---|
1225 | 1218 | } |
---|
1226 | 1219 | |
---|
1227 | | -/* round arbitary sample rates to commonly known rates */ |
---|
| 1220 | +/* round arbitrary sample rates to commonly known rates */ |
---|
1228 | 1221 | static int hdspm_round_frequency(int rate) |
---|
1229 | 1222 | { |
---|
1230 | 1223 | if (rate < 38050) |
---|
.. | .. |
---|
2176 | 2169 | } |
---|
2177 | 2170 | |
---|
2178 | 2171 | |
---|
2179 | | -static void hdspm_midi_tasklet(unsigned long arg) |
---|
| 2172 | +static void hdspm_midi_work(struct work_struct *work) |
---|
2180 | 2173 | { |
---|
2181 | | - struct hdspm *hdspm = (struct hdspm *)arg; |
---|
| 2174 | + struct hdspm *hdspm = container_of(work, struct hdspm, midi_work); |
---|
2182 | 2175 | int i = 0; |
---|
2183 | 2176 | |
---|
2184 | 2177 | while (i < hdspm->midiPorts) { |
---|
.. | .. |
---|
3034 | 3027 | |
---|
3035 | 3028 | unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); |
---|
3036 | 3029 | unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & 0xF; |
---|
3037 | | - if ((syncref >= HDSPM_AES32_AUTOSYNC_FROM_WORD) && |
---|
3038 | | - (syncref <= HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN)) { |
---|
| 3030 | + /* syncref >= HDSPM_AES32_AUTOSYNC_FROM_WORD is always true */ |
---|
| 3031 | + if (syncref <= HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN) { |
---|
3039 | 3032 | return syncref; |
---|
3040 | 3033 | } |
---|
3041 | 3034 | return HDSPM_AES32_AUTOSYNC_FROM_NONE; |
---|
.. | .. |
---|
4489 | 4482 | |
---|
4490 | 4483 | |
---|
4491 | 4484 | |
---|
4492 | | -static struct snd_kcontrol_new snd_hdspm_controls_madi[] = { |
---|
| 4485 | +static const struct snd_kcontrol_new snd_hdspm_controls_madi[] = { |
---|
4493 | 4486 | HDSPM_MIXER("Mixer", 0), |
---|
4494 | 4487 | HDSPM_INTERNAL_CLOCK("Internal Clock", 0), |
---|
4495 | 4488 | HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), |
---|
.. | .. |
---|
4511 | 4504 | }; |
---|
4512 | 4505 | |
---|
4513 | 4506 | |
---|
4514 | | -static struct snd_kcontrol_new snd_hdspm_controls_madiface[] = { |
---|
| 4507 | +static const struct snd_kcontrol_new snd_hdspm_controls_madiface[] = { |
---|
4515 | 4508 | HDSPM_MIXER("Mixer", 0), |
---|
4516 | 4509 | HDSPM_INTERNAL_CLOCK("Internal Clock", 0), |
---|
4517 | 4510 | HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), |
---|
.. | .. |
---|
4524 | 4517 | HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0) |
---|
4525 | 4518 | }; |
---|
4526 | 4519 | |
---|
4527 | | -static struct snd_kcontrol_new snd_hdspm_controls_aio[] = { |
---|
| 4520 | +static const struct snd_kcontrol_new snd_hdspm_controls_aio[] = { |
---|
4528 | 4521 | HDSPM_MIXER("Mixer", 0), |
---|
4529 | 4522 | HDSPM_INTERNAL_CLOCK("Internal Clock", 0), |
---|
4530 | 4523 | HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), |
---|
.. | .. |
---|
4565 | 4558 | */ |
---|
4566 | 4559 | }; |
---|
4567 | 4560 | |
---|
4568 | | -static struct snd_kcontrol_new snd_hdspm_controls_raydat[] = { |
---|
| 4561 | +static const struct snd_kcontrol_new snd_hdspm_controls_raydat[] = { |
---|
4569 | 4562 | HDSPM_MIXER("Mixer", 0), |
---|
4570 | 4563 | HDSPM_INTERNAL_CLOCK("Internal Clock", 0), |
---|
4571 | 4564 | HDSPM_SYSTEM_CLOCK_MODE("Clock Mode", 0), |
---|
.. | .. |
---|
4593 | 4586 | HDSPM_TOGGLE_SETTING("Single Speed WordClock Out", HDSPM_c0_Wck48) |
---|
4594 | 4587 | }; |
---|
4595 | 4588 | |
---|
4596 | | -static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = { |
---|
| 4589 | +static const struct snd_kcontrol_new snd_hdspm_controls_aes32[] = { |
---|
4597 | 4590 | HDSPM_MIXER("Mixer", 0), |
---|
4598 | 4591 | HDSPM_INTERNAL_CLOCK("Internal Clock", 0), |
---|
4599 | 4592 | HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), |
---|
.. | .. |
---|
4635 | 4628 | |
---|
4636 | 4629 | |
---|
4637 | 4630 | /* Control elements for the optional TCO module */ |
---|
4638 | | -static struct snd_kcontrol_new snd_hdspm_controls_tco[] = { |
---|
| 4631 | +static const struct snd_kcontrol_new snd_hdspm_controls_tco[] = { |
---|
4639 | 4632 | HDSPM_TCO_SAMPLE_RATE("TCO Sample Rate", 0), |
---|
4640 | 4633 | HDSPM_TCO_PULL("TCO Pull", 0), |
---|
4641 | 4634 | HDSPM_TCO_WCK_CONVERSION("TCO WCK Conversion", 0), |
---|
.. | .. |
---|
4682 | 4675 | unsigned int idx, limit; |
---|
4683 | 4676 | int err; |
---|
4684 | 4677 | struct snd_kcontrol *kctl; |
---|
4685 | | - struct snd_kcontrol_new *list = NULL; |
---|
| 4678 | + const struct snd_kcontrol_new *list = NULL; |
---|
4686 | 4679 | |
---|
4687 | 4680 | switch (hdspm->io_type) { |
---|
4688 | 4681 | case MADI: |
---|
.. | .. |
---|
5287 | 5280 | |
---|
5288 | 5281 | static void snd_hdspm_proc_init(struct hdspm *hdspm) |
---|
5289 | 5282 | { |
---|
5290 | | - struct snd_info_entry *entry; |
---|
| 5283 | + void (*read)(struct snd_info_entry *, struct snd_info_buffer *) = NULL; |
---|
5291 | 5284 | |
---|
5292 | | - if (!snd_card_proc_new(hdspm->card, "hdspm", &entry)) { |
---|
5293 | | - switch (hdspm->io_type) { |
---|
5294 | | - case AES32: |
---|
5295 | | - snd_info_set_text_ops(entry, hdspm, |
---|
5296 | | - snd_hdspm_proc_read_aes32); |
---|
5297 | | - break; |
---|
5298 | | - case MADI: |
---|
5299 | | - snd_info_set_text_ops(entry, hdspm, |
---|
5300 | | - snd_hdspm_proc_read_madi); |
---|
5301 | | - break; |
---|
5302 | | - case MADIface: |
---|
5303 | | - /* snd_info_set_text_ops(entry, hdspm, |
---|
5304 | | - snd_hdspm_proc_read_madiface); */ |
---|
5305 | | - break; |
---|
5306 | | - case RayDAT: |
---|
5307 | | - snd_info_set_text_ops(entry, hdspm, |
---|
5308 | | - snd_hdspm_proc_read_raydat); |
---|
5309 | | - break; |
---|
5310 | | - case AIO: |
---|
5311 | | - break; |
---|
5312 | | - } |
---|
| 5285 | + switch (hdspm->io_type) { |
---|
| 5286 | + case AES32: |
---|
| 5287 | + read = snd_hdspm_proc_read_aes32; |
---|
| 5288 | + break; |
---|
| 5289 | + case MADI: |
---|
| 5290 | + read = snd_hdspm_proc_read_madi; |
---|
| 5291 | + break; |
---|
| 5292 | + case MADIface: |
---|
| 5293 | + /* read = snd_hdspm_proc_read_madiface; */ |
---|
| 5294 | + break; |
---|
| 5295 | + case RayDAT: |
---|
| 5296 | + read = snd_hdspm_proc_read_raydat; |
---|
| 5297 | + break; |
---|
| 5298 | + case AIO: |
---|
| 5299 | + break; |
---|
5313 | 5300 | } |
---|
5314 | 5301 | |
---|
5315 | | - if (!snd_card_proc_new(hdspm->card, "ports.in", &entry)) { |
---|
5316 | | - snd_info_set_text_ops(entry, hdspm, snd_hdspm_proc_ports_in); |
---|
5317 | | - } |
---|
5318 | | - |
---|
5319 | | - if (!snd_card_proc_new(hdspm->card, "ports.out", &entry)) { |
---|
5320 | | - snd_info_set_text_ops(entry, hdspm, snd_hdspm_proc_ports_out); |
---|
5321 | | - } |
---|
| 5302 | + snd_card_ro_proc_new(hdspm->card, "hdspm", hdspm, read); |
---|
| 5303 | + snd_card_ro_proc_new(hdspm->card, "ports.in", hdspm, |
---|
| 5304 | + snd_hdspm_proc_ports_in); |
---|
| 5305 | + snd_card_ro_proc_new(hdspm->card, "ports.out", hdspm, |
---|
| 5306 | + snd_hdspm_proc_ports_out); |
---|
5322 | 5307 | |
---|
5323 | 5308 | #ifdef CONFIG_SND_DEBUG |
---|
5324 | 5309 | /* debug file to read all hdspm registers */ |
---|
5325 | | - if (!snd_card_proc_new(hdspm->card, "debug", &entry)) |
---|
5326 | | - snd_info_set_text_ops(entry, hdspm, |
---|
5327 | | - snd_hdspm_proc_read_debug); |
---|
| 5310 | + snd_card_ro_proc_new(hdspm->card, "debug", hdspm, |
---|
| 5311 | + snd_hdspm_proc_read_debug); |
---|
5328 | 5312 | #endif |
---|
5329 | 5313 | } |
---|
5330 | 5314 | |
---|
.. | .. |
---|
5465 | 5449 | } |
---|
5466 | 5450 | |
---|
5467 | 5451 | if (schedule) |
---|
5468 | | - tasklet_hi_schedule(&hdspm->midi_tasklet); |
---|
| 5452 | + queue_work(system_highpri_wq, &hdspm->midi_work); |
---|
5469 | 5453 | } |
---|
5470 | 5454 | |
---|
5471 | 5455 | return IRQ_HANDLED; |
---|
.. | .. |
---|
5597 | 5581 | |
---|
5598 | 5582 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
---|
5599 | 5583 | |
---|
5600 | | - hdspm_set_sgbuf(hdspm, substream, HDSPM_pageAddressBufferOut, |
---|
5601 | | - params_channels(params)); |
---|
| 5584 | + for (i = 0; i < params_channels(params); ++i) { |
---|
| 5585 | + int c = hdspm->channel_map_out[i]; |
---|
5602 | 5586 | |
---|
5603 | | - for (i = 0; i < params_channels(params); ++i) |
---|
5604 | | - snd_hdspm_enable_out(hdspm, i, 1); |
---|
| 5587 | + if (c < 0) |
---|
| 5588 | + continue; /* just make sure */ |
---|
| 5589 | + hdspm_set_channel_dma_addr(hdspm, substream, |
---|
| 5590 | + HDSPM_pageAddressBufferOut, |
---|
| 5591 | + c); |
---|
| 5592 | + snd_hdspm_enable_out(hdspm, c, 1); |
---|
| 5593 | + } |
---|
5605 | 5594 | |
---|
5606 | 5595 | hdspm->playback_buffer = |
---|
5607 | 5596 | (unsigned char *) substream->runtime->dma_area; |
---|
.. | .. |
---|
5609 | 5598 | "Allocated sample buffer for playback at %p\n", |
---|
5610 | 5599 | hdspm->playback_buffer); |
---|
5611 | 5600 | } else { |
---|
5612 | | - hdspm_set_sgbuf(hdspm, substream, HDSPM_pageAddressBufferIn, |
---|
5613 | | - params_channels(params)); |
---|
| 5601 | + for (i = 0; i < params_channels(params); ++i) { |
---|
| 5602 | + int c = hdspm->channel_map_in[i]; |
---|
5614 | 5603 | |
---|
5615 | | - for (i = 0; i < params_channels(params); ++i) |
---|
5616 | | - snd_hdspm_enable_in(hdspm, i, 1); |
---|
| 5604 | + if (c < 0) |
---|
| 5605 | + continue; |
---|
| 5606 | + hdspm_set_channel_dma_addr(hdspm, substream, |
---|
| 5607 | + HDSPM_pageAddressBufferIn, |
---|
| 5608 | + c); |
---|
| 5609 | + snd_hdspm_enable_in(hdspm, c, 1); |
---|
| 5610 | + } |
---|
5617 | 5611 | |
---|
5618 | 5612 | hdspm->capture_buffer = |
---|
5619 | 5613 | (unsigned char *) substream->runtime->dma_area; |
---|
.. | .. |
---|
5674 | 5668 | struct hdspm *hdspm = snd_pcm_substream_chip(substream); |
---|
5675 | 5669 | |
---|
5676 | 5670 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
---|
5677 | | - |
---|
5678 | | - /* params_channels(params) should be enough, |
---|
5679 | | - but to get sure in case of error */ |
---|
5680 | | - for (i = 0; i < hdspm->max_channels_out; ++i) |
---|
| 5671 | + /* Just disable all channels. The saving when disabling a */ |
---|
| 5672 | + /* smaller set is not worth the trouble. */ |
---|
| 5673 | + for (i = 0; i < HDSPM_MAX_CHANNELS; ++i) |
---|
5681 | 5674 | snd_hdspm_enable_out(hdspm, i, 0); |
---|
5682 | 5675 | |
---|
5683 | 5676 | hdspm->playback_buffer = NULL; |
---|
5684 | 5677 | } else { |
---|
5685 | | - for (i = 0; i < hdspm->max_channels_in; ++i) |
---|
| 5678 | + for (i = 0; i < HDSPM_MAX_CHANNELS; ++i) |
---|
5686 | 5679 | snd_hdspm_enable_in(hdspm, i, 0); |
---|
5687 | 5680 | |
---|
5688 | 5681 | hdspm->capture_buffer = NULL; |
---|
5689 | | - |
---|
5690 | 5682 | } |
---|
5691 | 5683 | |
---|
5692 | 5684 | snd_pcm_lib_free_pages(substream); |
---|
.. | .. |
---|
5832 | 5824 | return 0; |
---|
5833 | 5825 | } |
---|
5834 | 5826 | |
---|
5835 | | -static struct snd_pcm_hardware snd_hdspm_playback_subinfo = { |
---|
| 5827 | +static const struct snd_pcm_hardware snd_hdspm_playback_subinfo = { |
---|
5836 | 5828 | .info = (SNDRV_PCM_INFO_MMAP | |
---|
5837 | 5829 | SNDRV_PCM_INFO_MMAP_VALID | |
---|
5838 | 5830 | SNDRV_PCM_INFO_NONINTERLEAVED | |
---|
.. | .. |
---|
5857 | 5849 | .fifo_size = 0 |
---|
5858 | 5850 | }; |
---|
5859 | 5851 | |
---|
5860 | | -static struct snd_pcm_hardware snd_hdspm_capture_subinfo = { |
---|
| 5852 | +static const struct snd_pcm_hardware snd_hdspm_capture_subinfo = { |
---|
5861 | 5853 | .info = (SNDRV_PCM_INFO_MMAP | |
---|
5862 | 5854 | SNDRV_PCM_INFO_MMAP_VALID | |
---|
5863 | 5855 | SNDRV_PCM_INFO_NONINTERLEAVED | |
---|
.. | .. |
---|
6380 | 6372 | .prepare = snd_hdspm_prepare, |
---|
6381 | 6373 | .trigger = snd_hdspm_trigger, |
---|
6382 | 6374 | .pointer = snd_hdspm_hw_pointer, |
---|
6383 | | - .page = snd_pcm_sgbuf_ops_page, |
---|
6384 | 6375 | }; |
---|
6385 | 6376 | |
---|
6386 | 6377 | static int snd_hdspm_create_hwdep(struct snd_card *card, |
---|
.. | .. |
---|
6411 | 6402 | ------------------------------------------------------------*/ |
---|
6412 | 6403 | static int snd_hdspm_preallocate_memory(struct hdspm *hdspm) |
---|
6413 | 6404 | { |
---|
6414 | | - int err; |
---|
6415 | 6405 | struct snd_pcm *pcm; |
---|
6416 | 6406 | size_t wanted; |
---|
6417 | 6407 | |
---|
.. | .. |
---|
6419 | 6409 | |
---|
6420 | 6410 | wanted = HDSPM_DMA_AREA_BYTES; |
---|
6421 | 6411 | |
---|
6422 | | - err = |
---|
6423 | | - snd_pcm_lib_preallocate_pages_for_all(pcm, |
---|
6424 | | - SNDRV_DMA_TYPE_DEV_SG, |
---|
6425 | | - snd_dma_pci_data(hdspm->pci), |
---|
6426 | | - wanted, |
---|
6427 | | - wanted); |
---|
6428 | | - if (err < 0) { |
---|
6429 | | - dev_dbg(hdspm->card->dev, |
---|
6430 | | - "Could not preallocate %zd Bytes\n", wanted); |
---|
6431 | | - |
---|
6432 | | - return err; |
---|
6433 | | - } else |
---|
6434 | | - dev_dbg(hdspm->card->dev, |
---|
6435 | | - " Preallocated %zd Bytes\n", wanted); |
---|
6436 | | - |
---|
| 6412 | + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, |
---|
| 6413 | + &hdspm->pci->dev, |
---|
| 6414 | + wanted, wanted); |
---|
| 6415 | + dev_dbg(hdspm->card->dev, " Preallocated %zd Bytes\n", wanted); |
---|
6437 | 6416 | return 0; |
---|
6438 | 6417 | } |
---|
6439 | 6418 | |
---|
6440 | | - |
---|
6441 | | -static void hdspm_set_sgbuf(struct hdspm *hdspm, |
---|
6442 | | - struct snd_pcm_substream *substream, |
---|
6443 | | - unsigned int reg, int channels) |
---|
| 6419 | +/* Inform the card what DMA addresses to use for the indicated channel. */ |
---|
| 6420 | +/* Each channel got 16 4K pages allocated for DMA transfers. */ |
---|
| 6421 | +static void hdspm_set_channel_dma_addr(struct hdspm *hdspm, |
---|
| 6422 | + struct snd_pcm_substream *substream, |
---|
| 6423 | + unsigned int reg, int channel) |
---|
6444 | 6424 | { |
---|
6445 | 6425 | int i; |
---|
6446 | 6426 | |
---|
6447 | | - /* continuous memory segment */ |
---|
6448 | | - for (i = 0; i < (channels * 16); i++) |
---|
| 6427 | + for (i = channel * 16; i < channel * 16 + 16; i++) |
---|
6449 | 6428 | hdspm_write(hdspm, reg + 4 * i, |
---|
6450 | | - snd_pcm_sgbuf_get_addr(substream, 4096 * i)); |
---|
| 6429 | + snd_pcm_sgbuf_get_addr(substream, 4096 * i)); |
---|
6451 | 6430 | } |
---|
6452 | 6431 | |
---|
6453 | 6432 | |
---|
.. | .. |
---|
6534 | 6513 | dev_dbg(card->dev, "Update mixer controls...\n"); |
---|
6535 | 6514 | hdspm_update_simple_mixer_controls(hdspm); |
---|
6536 | 6515 | |
---|
6537 | | - dev_dbg(card->dev, "Initializeing complete ???\n"); |
---|
| 6516 | + dev_dbg(card->dev, "Initializing complete?\n"); |
---|
6538 | 6517 | |
---|
6539 | 6518 | err = snd_card_register(card); |
---|
6540 | 6519 | if (err < 0) { |
---|
.. | .. |
---|
6559 | 6538 | hdspm->card = card; |
---|
6560 | 6539 | |
---|
6561 | 6540 | spin_lock_init(&hdspm->lock); |
---|
| 6541 | + INIT_WORK(&hdspm->midi_work, hdspm_midi_work); |
---|
6562 | 6542 | |
---|
6563 | 6543 | pci_read_config_word(hdspm->pci, |
---|
6564 | 6544 | PCI_CLASS_REVISION, &hdspm->firmware_rev); |
---|
.. | .. |
---|
6619 | 6599 | dev_dbg(card->dev, "grabbed memory region 0x%lx-0x%lx\n", |
---|
6620 | 6600 | hdspm->port, hdspm->port + io_extent - 1); |
---|
6621 | 6601 | |
---|
6622 | | - hdspm->iobase = ioremap_nocache(hdspm->port, io_extent); |
---|
| 6602 | + hdspm->iobase = ioremap(hdspm->port, io_extent); |
---|
6623 | 6603 | if (!hdspm->iobase) { |
---|
6624 | 6604 | dev_err(card->dev, "unable to remap region 0x%lx-0x%lx\n", |
---|
6625 | 6605 | hdspm->port, hdspm->port + io_extent - 1); |
---|
.. | .. |
---|
6638 | 6618 | dev_dbg(card->dev, "use IRQ %d\n", pci->irq); |
---|
6639 | 6619 | |
---|
6640 | 6620 | hdspm->irq = pci->irq; |
---|
| 6621 | + card->sync_irq = hdspm->irq; |
---|
6641 | 6622 | |
---|
6642 | 6623 | dev_dbg(card->dev, "kmalloc Mixer memory of %zd Bytes\n", |
---|
6643 | 6624 | sizeof(*hdspm->mixer)); |
---|
.. | .. |
---|
6856 | 6837 | |
---|
6857 | 6838 | } |
---|
6858 | 6839 | |
---|
6859 | | - tasklet_init(&hdspm->midi_tasklet, |
---|
6860 | | - hdspm_midi_tasklet, (unsigned long) hdspm); |
---|
6861 | | - |
---|
6862 | | - |
---|
6863 | 6840 | if (hdspm->io_type != MADIface) { |
---|
6864 | 6841 | hdspm->serial = (hdspm_read(hdspm, |
---|
6865 | 6842 | HDSPM_midiStatusIn0)>>8) & 0xFFFFFF; |
---|
.. | .. |
---|
6894 | 6871 | { |
---|
6895 | 6872 | |
---|
6896 | 6873 | if (hdspm->port) { |
---|
| 6874 | + cancel_work_sync(&hdspm->midi_work); |
---|
6897 | 6875 | |
---|
6898 | 6876 | /* stop th audio, and cancel all interrupts */ |
---|
6899 | 6877 | hdspm->control_register &= |
---|