diff options
author | Remy Bruno <remy.bruno@trinnov.com> | 2007-08-31 06:21:08 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2007-10-16 09:59:37 -0400 |
commit | 6534599d14892c5b0838b7170f071c850f5ea8e9 (patch) | |
tree | 965f9f327de849194e555d01b1388aa89cfc0fdf /sound/pci/rme9652/hdspm.c | |
parent | 5149fe2c15e2dfe349bfde27e1fea5593b40671f (diff) |
[ALSA] hdspm - Fix autosync bug
* better report of speed mode change failures
* autosync_ref control bugfix (was reporting pref_sync_ref instead)
(changed HDSPM_AES32_AUTOSYNC_FROM_NONE value to comply with array
indexing in snd_hdspm_info_autosync_ref())
* added support for master modes up to 192kHz (clock source control
value was restricted up to 96kHz)
Signed-off-by: Remy Bruno <remy.bruno@trinnov.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci/rme9652/hdspm.c')
-rw-r--r-- | sound/pci/rme9652/hdspm.c | 60 |
1 files changed, 30 insertions, 30 deletions
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 30e0c4dc9484..f1bdda6cbcff 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -359,7 +359,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
359 | #define HDSPM_AES32_AUTOSYNC_FROM_AES6 6 | 359 | #define HDSPM_AES32_AUTOSYNC_FROM_AES6 6 |
360 | #define HDSPM_AES32_AUTOSYNC_FROM_AES7 7 | 360 | #define HDSPM_AES32_AUTOSYNC_FROM_AES7 7 |
361 | #define HDSPM_AES32_AUTOSYNC_FROM_AES8 8 | 361 | #define HDSPM_AES32_AUTOSYNC_FROM_AES8 8 |
362 | #define HDSPM_AES32_AUTOSYNC_FROM_NONE -1 | 362 | #define HDSPM_AES32_AUTOSYNC_FROM_NONE 9 |
363 | 363 | ||
364 | /* status2 */ | 364 | /* status2 */ |
365 | /* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */ | 365 | /* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */ |
@@ -413,6 +413,13 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | |||
413 | /* revisions >= 230 indicate AES32 card */ | 413 | /* revisions >= 230 indicate AES32 card */ |
414 | #define HDSPM_AESREVISION 230 | 414 | #define HDSPM_AESREVISION 230 |
415 | 415 | ||
416 | /* speed factor modes */ | ||
417 | #define HDSPM_SPEED_SINGLE 0 | ||
418 | #define HDSPM_SPEED_DOUBLE 1 | ||
419 | #define HDSPM_SPEED_QUAD 2 | ||
420 | /* names for speed modes */ | ||
421 | static char *hdspm_speed_names[] = { "single", "double", "quad" }; | ||
422 | |||
416 | struct hdspm_midi { | 423 | struct hdspm_midi { |
417 | struct hdspm *hdspm; | 424 | struct hdspm *hdspm; |
418 | int id; | 425 | int id; |
@@ -831,7 +838,7 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) | |||
831 | rate /= 2; | 838 | rate /= 2; |
832 | 839 | ||
833 | /* RME says n = 104857600000000, but in the windows MADI driver, I see: | 840 | /* RME says n = 104857600000000, but in the windows MADI driver, I see: |
834 | return 104857600000000 / rate; // 100 MHz | 841 | // return 104857600000000 / rate; // 100 MHz |
835 | return 110100480000000 / rate; // 105 MHz | 842 | return 110100480000000 / rate; // 105 MHz |
836 | */ | 843 | */ |
837 | /* n = 104857600000000ULL; */ /* = 2^20 * 10^8 */ | 844 | /* n = 104857600000000ULL; */ /* = 2^20 * 10^8 */ |
@@ -845,11 +852,10 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) | |||
845 | /* dummy set rate lets see what happens */ | 852 | /* dummy set rate lets see what happens */ |
846 | static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) | 853 | static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) |
847 | { | 854 | { |
848 | int reject_if_open = 0; | ||
849 | int current_rate; | 855 | int current_rate; |
850 | int rate_bits; | 856 | int rate_bits; |
851 | int not_set = 0; | 857 | int not_set = 0; |
852 | int is_single, is_double, is_quad; | 858 | int current_speed, target_speed; |
853 | 859 | ||
854 | /* ASSUMPTION: hdspm->lock is either set, or there is no need for | 860 | /* ASSUMPTION: hdspm->lock is either set, or there is no need for |
855 | it (e.g. during module initialization). | 861 | it (e.g. during module initialization). |
@@ -903,66 +909,60 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) | |||
903 | changes in the read/write routines. | 909 | changes in the read/write routines. |
904 | */ | 910 | */ |
905 | 911 | ||
906 | is_single = (current_rate <= 48000); | 912 | if (current_rate <= 48000) |
907 | is_double = (current_rate > 48000 && current_rate <= 96000); | 913 | current_speed = HDSPM_SPEED_SINGLE; |
908 | is_quad = (current_rate > 96000); | 914 | else if (current_rate <= 96000) |
915 | current_speed = HDSPM_SPEED_DOUBLE; | ||
916 | else | ||
917 | current_speed = HDSPM_SPEED_QUAD; | ||
918 | |||
919 | if (rate <= 48000) | ||
920 | target_speed = HDSPM_SPEED_SINGLE; | ||
921 | else if (rate <= 96000) | ||
922 | target_speed = HDSPM_SPEED_DOUBLE; | ||
923 | else | ||
924 | target_speed = HDSPM_SPEED_QUAD; | ||
909 | 925 | ||
910 | switch (rate) { | 926 | switch (rate) { |
911 | case 32000: | 927 | case 32000: |
912 | if (!is_single) | ||
913 | reject_if_open = 1; | ||
914 | rate_bits = HDSPM_Frequency32KHz; | 928 | rate_bits = HDSPM_Frequency32KHz; |
915 | break; | 929 | break; |
916 | case 44100: | 930 | case 44100: |
917 | if (!is_single) | ||
918 | reject_if_open = 1; | ||
919 | rate_bits = HDSPM_Frequency44_1KHz; | 931 | rate_bits = HDSPM_Frequency44_1KHz; |
920 | break; | 932 | break; |
921 | case 48000: | 933 | case 48000: |
922 | if (!is_single) | ||
923 | reject_if_open = 1; | ||
924 | rate_bits = HDSPM_Frequency48KHz; | 934 | rate_bits = HDSPM_Frequency48KHz; |
925 | break; | 935 | break; |
926 | case 64000: | 936 | case 64000: |
927 | if (!is_double) | ||
928 | reject_if_open = 1; | ||
929 | rate_bits = HDSPM_Frequency64KHz; | 937 | rate_bits = HDSPM_Frequency64KHz; |
930 | break; | 938 | break; |
931 | case 88200: | 939 | case 88200: |
932 | if (!is_double) | ||
933 | reject_if_open = 1; | ||
934 | rate_bits = HDSPM_Frequency88_2KHz; | 940 | rate_bits = HDSPM_Frequency88_2KHz; |
935 | break; | 941 | break; |
936 | case 96000: | 942 | case 96000: |
937 | if (!is_double) | ||
938 | reject_if_open = 1; | ||
939 | rate_bits = HDSPM_Frequency96KHz; | 943 | rate_bits = HDSPM_Frequency96KHz; |
940 | break; | 944 | break; |
941 | case 128000: | 945 | case 128000: |
942 | if (!is_quad) | ||
943 | reject_if_open = 1; | ||
944 | rate_bits = HDSPM_Frequency128KHz; | 946 | rate_bits = HDSPM_Frequency128KHz; |
945 | break; | 947 | break; |
946 | case 176400: | 948 | case 176400: |
947 | if (!is_quad) | ||
948 | reject_if_open = 1; | ||
949 | rate_bits = HDSPM_Frequency176_4KHz; | 949 | rate_bits = HDSPM_Frequency176_4KHz; |
950 | break; | 950 | break; |
951 | case 192000: | 951 | case 192000: |
952 | if (!is_quad) | ||
953 | reject_if_open = 1; | ||
954 | rate_bits = HDSPM_Frequency192KHz; | 952 | rate_bits = HDSPM_Frequency192KHz; |
955 | break; | 953 | break; |
956 | default: | 954 | default: |
957 | return -EINVAL; | 955 | return -EINVAL; |
958 | } | 956 | } |
959 | 957 | ||
960 | if (reject_if_open | 958 | if (current_speed != target_speed |
961 | && (hdspm->capture_pid >= 0 || hdspm->playback_pid >= 0)) { | 959 | && (hdspm->capture_pid >= 0 || hdspm->playback_pid >= 0)) { |
962 | snd_printk | 960 | snd_printk |
963 | (KERN_ERR "HDSPM: " | 961 | (KERN_ERR "HDSPM: " |
964 | "cannot change between single- and double-speed mode " | 962 | "cannot change from %s speed to %s speed mode " |
965 | "(capture PID = %d, playback PID = %d)\n", | 963 | "(capture PID = %d, playback PID = %d)\n", |
964 | hdspm_speed_names[current_speed], | ||
965 | hdspm_speed_names[target_speed], | ||
966 | hdspm->capture_pid, hdspm->playback_pid); | 966 | hdspm->capture_pid, hdspm->playback_pid); |
967 | return -EBUSY; | 967 | return -EBUSY; |
968 | } | 968 | } |
@@ -1603,8 +1603,8 @@ static int snd_hdspm_put_clock_source(struct snd_kcontrol *kcontrol, | |||
1603 | val = ucontrol->value.enumerated.item[0]; | 1603 | val = ucontrol->value.enumerated.item[0]; |
1604 | if (val < 0) | 1604 | if (val < 0) |
1605 | val = 0; | 1605 | val = 0; |
1606 | if (val > 6) | 1606 | if (val > 9) |
1607 | val = 6; | 1607 | val = 9; |
1608 | spin_lock_irq(&hdspm->lock); | 1608 | spin_lock_irq(&hdspm->lock); |
1609 | if (val != hdspm_clock_source(hdspm)) | 1609 | if (val != hdspm_clock_source(hdspm)) |
1610 | change = (hdspm_set_clock_source(hdspm, val) == 0) ? 1 : 0; | 1610 | change = (hdspm_set_clock_source(hdspm, val) == 0) ? 1 : 0; |
@@ -1853,7 +1853,7 @@ static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol, | |||
1853 | { | 1853 | { |
1854 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); | 1854 | struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); |
1855 | 1855 | ||
1856 | ucontrol->value.enumerated.item[0] = hdspm_pref_sync_ref(hdspm); | 1856 | ucontrol->value.enumerated.item[0] = hdspm_autosync_ref(hdspm); |
1857 | return 0; | 1857 | return 0; |
1858 | } | 1858 | } |
1859 | 1859 | ||