aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/rme9652/hdspm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/rme9652/hdspm.c')
-rw-r--r--sound/pci/rme9652/hdspm.c382
1 files changed, 240 insertions, 142 deletions
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 223c3d9cc69e..9ea05e956474 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -969,6 +969,7 @@ static int snd_hdspm_create_pcm(struct snd_card *card,
969 struct hdspm *hdspm); 969 struct hdspm *hdspm);
970 970
971static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm); 971static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm);
972static inline int hdspm_get_pll_freq(struct hdspm *hdspm);
972static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm); 973static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm);
973static int hdspm_autosync_ref(struct hdspm *hdspm); 974static int hdspm_autosync_ref(struct hdspm *hdspm);
974static int snd_hdspm_set_defaults(struct hdspm *hdspm); 975static int snd_hdspm_set_defaults(struct hdspm *hdspm);
@@ -1075,6 +1076,20 @@ static int snd_hdspm_use_is_exclusive(struct hdspm *hdspm)
1075 return ret; 1076 return ret;
1076} 1077}
1077 1078
1079/* round arbitary sample rates to commonly known rates */
1080static int hdspm_round_frequency(int rate)
1081{
1082 if (rate < 38050)
1083 return 32000;
1084 if (rate < 46008)
1085 return 44100;
1086 else
1087 return 48000;
1088}
1089
1090static int hdspm_tco_sync_check(struct hdspm *hdspm);
1091static int hdspm_sync_in_sync_check(struct hdspm *hdspm);
1092
1078/* check for external sample rate */ 1093/* check for external sample rate */
1079static int hdspm_external_sample_rate(struct hdspm *hdspm) 1094static int hdspm_external_sample_rate(struct hdspm *hdspm)
1080{ 1095{
@@ -1216,22 +1231,45 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
1216 break; 1231 break;
1217 } 1232 }
1218 1233
1219 /* QS and DS rates normally can not be detected 1234 } /* endif HDSPM_madiLock */
1220 * automatically by the card. Only exception is MADI 1235
1221 * in 96k frame mode. 1236 /* check sample rate from TCO or SYNC_IN */
1222 * 1237 {
1223 * So if we read SS values (32 .. 48k), check for 1238 bool is_valid_input = 0;
1224 * user-provided DS/QS bits in the control register 1239 bool has_sync = 0;
1225 * and multiply the base frequency accordingly. 1240
1226 */ 1241 syncref = hdspm_autosync_ref(hdspm);
1227 if (rate <= 48000) { 1242 if (HDSPM_AUTOSYNC_FROM_TCO == syncref) {
1228 if (hdspm->control_register & HDSPM_QuadSpeed) 1243 is_valid_input = 1;
1229 rate *= 4; 1244 has_sync = (HDSPM_SYNC_CHECK_SYNC ==
1230 else if (hdspm->control_register & 1245 hdspm_tco_sync_check(hdspm));
1231 HDSPM_DoubleSpeed) 1246 } else if (HDSPM_AUTOSYNC_FROM_SYNC_IN == syncref) {
1232 rate *= 2; 1247 is_valid_input = 1;
1248 has_sync = (HDSPM_SYNC_CHECK_SYNC ==
1249 hdspm_sync_in_sync_check(hdspm));
1250 }
1251
1252 if (is_valid_input && has_sync) {
1253 rate = hdspm_round_frequency(
1254 hdspm_get_pll_freq(hdspm));
1233 } 1255 }
1234 } 1256 }
1257
1258 /* QS and DS rates normally can not be detected
1259 * automatically by the card. Only exception is MADI
1260 * in 96k frame mode.
1261 *
1262 * So if we read SS values (32 .. 48k), check for
1263 * user-provided DS/QS bits in the control register
1264 * and multiply the base frequency accordingly.
1265 */
1266 if (rate <= 48000) {
1267 if (hdspm->control_register & HDSPM_QuadSpeed)
1268 rate *= 4;
1269 else if (hdspm->control_register &
1270 HDSPM_DoubleSpeed)
1271 rate *= 2;
1272 }
1235 break; 1273 break;
1236 } 1274 }
1237 1275
@@ -1979,16 +2017,25 @@ static void hdspm_midi_tasklet(unsigned long arg)
1979/* get the system sample rate which is set */ 2017/* get the system sample rate which is set */
1980 2018
1981 2019
2020static inline int hdspm_get_pll_freq(struct hdspm *hdspm)
2021{
2022 unsigned int period, rate;
2023
2024 period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ);
2025 rate = hdspm_calc_dds_value(hdspm, period);
2026
2027 return rate;
2028}
2029
1982/** 2030/**
1983 * Calculate the real sample rate from the 2031 * Calculate the real sample rate from the
1984 * current DDS value. 2032 * current DDS value.
1985 **/ 2033 **/
1986static int hdspm_get_system_sample_rate(struct hdspm *hdspm) 2034static int hdspm_get_system_sample_rate(struct hdspm *hdspm)
1987{ 2035{
1988 unsigned int period, rate; 2036 unsigned int rate;
1989 2037
1990 period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ); 2038 rate = hdspm_get_pll_freq(hdspm);
1991 rate = hdspm_calc_dds_value(hdspm, period);
1992 2039
1993 if (rate > 207000) { 2040 if (rate > 207000) {
1994 /* Unreasonable high sample rate as seen on PCI MADI cards. */ 2041 /* Unreasonable high sample rate as seen on PCI MADI cards. */
@@ -2128,6 +2175,16 @@ static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx)
2128 return (status >> (idx*4)) & 0xF; 2175 return (status >> (idx*4)) & 0xF;
2129} 2176}
2130 2177
2178#define ENUMERATED_CTL_INFO(info, texts) \
2179{ \
2180 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; \
2181 uinfo->count = 1; \
2182 uinfo->value.enumerated.items = ARRAY_SIZE(texts); \
2183 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) \
2184 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; \
2185 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); \
2186}
2187
2131 2188
2132 2189
2133#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ 2190#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \
@@ -2143,14 +2200,7 @@ static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx)
2143static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol, 2200static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol,
2144 struct snd_ctl_elem_info *uinfo) 2201 struct snd_ctl_elem_info *uinfo)
2145{ 2202{
2146 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2203 ENUMERATED_CTL_INFO(uinfo, texts_freq);
2147 uinfo->count = 1;
2148 uinfo->value.enumerated.items = 10;
2149
2150 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2151 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2152 strcpy(uinfo->value.enumerated.name,
2153 texts_freq[uinfo->value.enumerated.item]);
2154 return 0; 2204 return 0;
2155} 2205}
2156 2206
@@ -2316,15 +2366,7 @@ static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol,
2316 struct snd_ctl_elem_info *uinfo) 2366 struct snd_ctl_elem_info *uinfo)
2317{ 2367{
2318 static char *texts[] = { "Master", "AutoSync" }; 2368 static char *texts[] = { "Master", "AutoSync" };
2319 2369 ENUMERATED_CTL_INFO(uinfo, texts);
2320 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2321 uinfo->count = 1;
2322 uinfo->value.enumerated.items = 2;
2323 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2324 uinfo->value.enumerated.item =
2325 uinfo->value.enumerated.items - 1;
2326 strcpy(uinfo->value.enumerated.name,
2327 texts[uinfo->value.enumerated.item]);
2328 return 0; 2370 return 0;
2329} 2371}
2330 2372
@@ -2888,6 +2930,112 @@ static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol,
2888 return 0; 2930 return 0;
2889} 2931}
2890 2932
2933
2934
2935#define HDSPM_TCO_VIDEO_INPUT_FORMAT(xname, xindex) \
2936{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2937 .name = xname, \
2938 .access = SNDRV_CTL_ELEM_ACCESS_READ |\
2939 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2940 .info = snd_hdspm_info_tco_video_input_format, \
2941 .get = snd_hdspm_get_tco_video_input_format, \
2942}
2943
2944static int snd_hdspm_info_tco_video_input_format(struct snd_kcontrol *kcontrol,
2945 struct snd_ctl_elem_info *uinfo)
2946{
2947 static char *texts[] = {"No video", "NTSC", "PAL"};
2948 ENUMERATED_CTL_INFO(uinfo, texts);
2949 return 0;
2950}
2951
2952static int snd_hdspm_get_tco_video_input_format(struct snd_kcontrol *kcontrol,
2953 struct snd_ctl_elem_value *ucontrol)
2954{
2955 u32 status;
2956 int ret = 0;
2957
2958 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2959 status = hdspm_read(hdspm, HDSPM_RD_TCO + 4);
2960 switch (status & (HDSPM_TCO1_Video_Input_Format_NTSC |
2961 HDSPM_TCO1_Video_Input_Format_PAL)) {
2962 case HDSPM_TCO1_Video_Input_Format_NTSC:
2963 /* ntsc */
2964 ret = 1;
2965 break;
2966 case HDSPM_TCO1_Video_Input_Format_PAL:
2967 /* pal */
2968 ret = 2;
2969 break;
2970 default:
2971 /* no video */
2972 ret = 0;
2973 break;
2974 }
2975 ucontrol->value.enumerated.item[0] = ret;
2976 return 0;
2977}
2978
2979
2980
2981#define HDSPM_TCO_LTC_FRAMES(xname, xindex) \
2982{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2983 .name = xname, \
2984 .access = SNDRV_CTL_ELEM_ACCESS_READ |\
2985 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2986 .info = snd_hdspm_info_tco_ltc_frames, \
2987 .get = snd_hdspm_get_tco_ltc_frames, \
2988}
2989
2990static int snd_hdspm_info_tco_ltc_frames(struct snd_kcontrol *kcontrol,
2991 struct snd_ctl_elem_info *uinfo)
2992{
2993 static char *texts[] = {"No lock", "24 fps", "25 fps", "29.97 fps",
2994 "30 fps"};
2995 ENUMERATED_CTL_INFO(uinfo, texts);
2996 return 0;
2997}
2998
2999static int hdspm_tco_ltc_frames(struct hdspm *hdspm)
3000{
3001 u32 status;
3002 int ret = 0;
3003
3004 status = hdspm_read(hdspm, HDSPM_RD_TCO + 4);
3005 if (status & HDSPM_TCO1_LTC_Input_valid) {
3006 switch (status & (HDSPM_TCO1_LTC_Format_LSB |
3007 HDSPM_TCO1_LTC_Format_MSB)) {
3008 case 0:
3009 /* 24 fps */
3010 ret = 1;
3011 break;
3012 case HDSPM_TCO1_LTC_Format_LSB:
3013 /* 25 fps */
3014 ret = 2;
3015 break;
3016 case HDSPM_TCO1_LTC_Format_MSB:
3017 /* 25 fps */
3018 ret = 3;
3019 break;
3020 default:
3021 /* 30 fps */
3022 ret = 4;
3023 break;
3024 }
3025 }
3026
3027 return ret;
3028}
3029
3030static int snd_hdspm_get_tco_ltc_frames(struct snd_kcontrol *kcontrol,
3031 struct snd_ctl_elem_value *ucontrol)
3032{
3033 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
3034
3035 ucontrol->value.enumerated.item[0] = hdspm_tco_ltc_frames(hdspm);
3036 return 0;
3037}
3038
2891#define HDSPM_TOGGLE_SETTING(xname, xindex) \ 3039#define HDSPM_TOGGLE_SETTING(xname, xindex) \
2892{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3040{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2893 .name = xname, \ 3041 .name = xname, \
@@ -2974,17 +3122,7 @@ static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol,
2974 struct snd_ctl_elem_info *uinfo) 3122 struct snd_ctl_elem_info *uinfo)
2975{ 3123{
2976 static char *texts[] = { "optical", "coaxial" }; 3124 static char *texts[] = { "optical", "coaxial" };
2977 3125 ENUMERATED_CTL_INFO(uinfo, texts);
2978 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2979 uinfo->count = 1;
2980 uinfo->value.enumerated.items = 2;
2981
2982 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2983 uinfo->value.enumerated.item =
2984 uinfo->value.enumerated.items - 1;
2985 strcpy(uinfo->value.enumerated.name,
2986 texts[uinfo->value.enumerated.item]);
2987
2988 return 0; 3126 return 0;
2989} 3127}
2990 3128
@@ -3046,17 +3184,7 @@ static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol,
3046 struct snd_ctl_elem_info *uinfo) 3184 struct snd_ctl_elem_info *uinfo)
3047{ 3185{
3048 static char *texts[] = { "Single", "Double" }; 3186 static char *texts[] = { "Single", "Double" };
3049 3187 ENUMERATED_CTL_INFO(uinfo, texts);
3050 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3051 uinfo->count = 1;
3052 uinfo->value.enumerated.items = 2;
3053
3054 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3055 uinfo->value.enumerated.item =
3056 uinfo->value.enumerated.items - 1;
3057 strcpy(uinfo->value.enumerated.name,
3058 texts[uinfo->value.enumerated.item]);
3059
3060 return 0; 3188 return 0;
3061} 3189}
3062 3190
@@ -3129,17 +3257,7 @@ static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol,
3129 struct snd_ctl_elem_info *uinfo) 3257 struct snd_ctl_elem_info *uinfo)
3130{ 3258{
3131 static char *texts[] = { "Single", "Double", "Quad" }; 3259 static char *texts[] = { "Single", "Double", "Quad" };
3132 3260 ENUMERATED_CTL_INFO(uinfo, texts);
3133 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3134 uinfo->count = 1;
3135 uinfo->value.enumerated.items = 3;
3136
3137 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3138 uinfo->value.enumerated.item =
3139 uinfo->value.enumerated.items - 1;
3140 strcpy(uinfo->value.enumerated.name,
3141 texts[uinfo->value.enumerated.item]);
3142
3143 return 0; 3261 return 0;
3144} 3262}
3145 3263
@@ -3215,17 +3333,7 @@ static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol,
3215 struct snd_ctl_elem_info *uinfo) 3333 struct snd_ctl_elem_info *uinfo)
3216{ 3334{
3217 static char *texts[] = { "Single", "Double", "Quad" }; 3335 static char *texts[] = { "Single", "Double", "Quad" };
3218 3336 ENUMERATED_CTL_INFO(uinfo, texts);
3219 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3220 uinfo->count = 1;
3221 uinfo->value.enumerated.items = 3;
3222
3223 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3224 uinfo->value.enumerated.item =
3225 uinfo->value.enumerated.items - 1;
3226 strcpy(uinfo->value.enumerated.name,
3227 texts[uinfo->value.enumerated.item]);
3228
3229 return 0; 3337 return 0;
3230} 3338}
3231 3339
@@ -3445,19 +3553,30 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
3445 .get = snd_hdspm_get_sync_check \ 3553 .get = snd_hdspm_get_sync_check \
3446} 3554}
3447 3555
3556#define HDSPM_TCO_LOCK_CHECK(xname, xindex) \
3557{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3558 .name = xname, \
3559 .private_value = xindex, \
3560 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
3561 .info = snd_hdspm_tco_info_lock_check, \
3562 .get = snd_hdspm_get_sync_check \
3563}
3564
3565
3448 3566
3449static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, 3567static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol,
3450 struct snd_ctl_elem_info *uinfo) 3568 struct snd_ctl_elem_info *uinfo)
3451{ 3569{
3452 static char *texts[] = { "No Lock", "Lock", "Sync", "N/A" }; 3570 static char *texts[] = { "No Lock", "Lock", "Sync", "N/A" };
3453 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3571 ENUMERATED_CTL_INFO(uinfo, texts);
3454 uinfo->count = 1; 3572 return 0;
3455 uinfo->value.enumerated.items = 4; 3573}
3456 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 3574
3457 uinfo->value.enumerated.item = 3575static int snd_hdspm_tco_info_lock_check(struct snd_kcontrol *kcontrol,
3458 uinfo->value.enumerated.items - 1; 3576 struct snd_ctl_elem_info *uinfo)
3459 strcpy(uinfo->value.enumerated.name, 3577{
3460 texts[uinfo->value.enumerated.item]); 3578 static char *texts[] = { "No Lock", "Lock" };
3579 ENUMERATED_CTL_INFO(uinfo, texts);
3461 return 0; 3580 return 0;
3462} 3581}
3463 3582
@@ -3590,6 +3709,14 @@ static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx)
3590 return 0; 3709 return 0;
3591} 3710}
3592 3711
3712static int hdspm_tco_input_check(struct hdspm *hdspm, u32 mask)
3713{
3714 u32 status;
3715 status = hdspm_read(hdspm, HDSPM_RD_TCO + 4);
3716
3717 return (status & mask) ? 1 : 0;
3718}
3719
3593 3720
3594static int hdspm_tco_sync_check(struct hdspm *hdspm) 3721static int hdspm_tco_sync_check(struct hdspm *hdspm)
3595{ 3722{
@@ -3697,6 +3824,22 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol,
3697 3824
3698 } 3825 }
3699 3826
3827 if (hdspm->tco) {
3828 switch (kcontrol->private_value) {
3829 case 11:
3830 /* Check TCO for lock state of its current input */
3831 val = hdspm_tco_input_check(hdspm, HDSPM_TCO1_TCO_lock);
3832 break;
3833 case 12:
3834 /* Check TCO for valid time code on LTC input. */
3835 val = hdspm_tco_input_check(hdspm,
3836 HDSPM_TCO1_LTC_Input_valid);
3837 break;
3838 default:
3839 break;
3840 }
3841 }
3842
3700 if (-1 == val) 3843 if (-1 == val)
3701 val = 3; 3844 val = 3;
3702 3845
@@ -3813,17 +3956,7 @@ static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol,
3813 struct snd_ctl_elem_info *uinfo) 3956 struct snd_ctl_elem_info *uinfo)
3814{ 3957{
3815 static char *texts[] = { "44.1 kHz", "48 kHz" }; 3958 static char *texts[] = { "44.1 kHz", "48 kHz" };
3816 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3959 ENUMERATED_CTL_INFO(uinfo, texts);
3817 uinfo->count = 1;
3818 uinfo->value.enumerated.items = 2;
3819
3820 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3821 uinfo->value.enumerated.item =
3822 uinfo->value.enumerated.items - 1;
3823
3824 strcpy(uinfo->value.enumerated.name,
3825 texts[uinfo->value.enumerated.item]);
3826
3827 return 0; 3960 return 0;
3828} 3961}
3829 3962
@@ -3869,17 +4002,7 @@ static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol,
3869 struct snd_ctl_elem_info *uinfo) 4002 struct snd_ctl_elem_info *uinfo)
3870{ 4003{
3871 static char *texts[] = { "0", "+ 0.1 %", "- 0.1 %", "+ 4 %", "- 4 %" }; 4004 static char *texts[] = { "0", "+ 0.1 %", "- 0.1 %", "+ 4 %", "- 4 %" };
3872 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4005 ENUMERATED_CTL_INFO(uinfo, texts);
3873 uinfo->count = 1;
3874 uinfo->value.enumerated.items = 5;
3875
3876 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3877 uinfo->value.enumerated.item =
3878 uinfo->value.enumerated.items - 1;
3879
3880 strcpy(uinfo->value.enumerated.name,
3881 texts[uinfo->value.enumerated.item]);
3882
3883 return 0; 4006 return 0;
3884} 4007}
3885 4008
@@ -3924,17 +4047,7 @@ static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol,
3924 struct snd_ctl_elem_info *uinfo) 4047 struct snd_ctl_elem_info *uinfo)
3925{ 4048{
3926 static char *texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" }; 4049 static char *texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" };
3927 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4050 ENUMERATED_CTL_INFO(uinfo, texts);
3928 uinfo->count = 1;
3929 uinfo->value.enumerated.items = 3;
3930
3931 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3932 uinfo->value.enumerated.item =
3933 uinfo->value.enumerated.items - 1;
3934
3935 strcpy(uinfo->value.enumerated.name,
3936 texts[uinfo->value.enumerated.item]);
3937
3938 return 0; 4051 return 0;
3939} 4052}
3940 4053
@@ -3981,17 +4094,7 @@ static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol,
3981{ 4094{
3982 static char *texts[] = { "24 fps", "25 fps", "29.97fps", 4095 static char *texts[] = { "24 fps", "25 fps", "29.97fps",
3983 "29.97 dfps", "30 fps", "30 dfps" }; 4096 "29.97 dfps", "30 fps", "30 dfps" };
3984 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4097 ENUMERATED_CTL_INFO(uinfo, texts);
3985 uinfo->count = 1;
3986 uinfo->value.enumerated.items = 6;
3987
3988 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3989 uinfo->value.enumerated.item =
3990 uinfo->value.enumerated.items - 1;
3991
3992 strcpy(uinfo->value.enumerated.name,
3993 texts[uinfo->value.enumerated.item]);
3994
3995 return 0; 4098 return 0;
3996} 4099}
3997 4100
@@ -4037,17 +4140,7 @@ static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol,
4037 struct snd_ctl_elem_info *uinfo) 4140 struct snd_ctl_elem_info *uinfo)
4038{ 4141{
4039 static char *texts[] = { "LTC", "Video", "WCK" }; 4142 static char *texts[] = { "LTC", "Video", "WCK" };
4040 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 4143 ENUMERATED_CTL_INFO(uinfo, texts);
4041 uinfo->count = 1;
4042 uinfo->value.enumerated.items = 3;
4043
4044 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
4045 uinfo->value.enumerated.item =
4046 uinfo->value.enumerated.items - 1;
4047
4048 strcpy(uinfo->value.enumerated.name,
4049 texts[uinfo->value.enumerated.item]);
4050
4051 return 0; 4144 return 0;
4052} 4145}
4053 4146
@@ -4145,6 +4238,7 @@ static struct snd_kcontrol_new snd_hdspm_controls_madi[] = {
4145 HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3), 4238 HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3),
4146 HDSPM_TOGGLE_SETTING("Line Out", HDSPM_LineOut), 4239 HDSPM_TOGGLE_SETTING("Line Out", HDSPM_LineOut),
4147 HDSPM_TOGGLE_SETTING("TX 64 channels mode", HDSPM_TX_64ch), 4240 HDSPM_TOGGLE_SETTING("TX 64 channels mode", HDSPM_TX_64ch),
4241 HDSPM_TOGGLE_SETTING("Disable 96K frames", HDSPM_SMUX),
4148 HDSPM_TOGGLE_SETTING("Clear Track Marker", HDSPM_clr_tms), 4242 HDSPM_TOGGLE_SETTING("Clear Track Marker", HDSPM_clr_tms),
4149 HDSPM_TOGGLE_SETTING("Safe Mode", HDSPM_AutoInp), 4243 HDSPM_TOGGLE_SETTING("Safe Mode", HDSPM_AutoInp),
4150 HDSPM_INPUT_SELECT("Input Select", 0), 4244 HDSPM_INPUT_SELECT("Input Select", 0),
@@ -4272,7 +4366,11 @@ static struct snd_kcontrol_new snd_hdspm_controls_tco[] = {
4272 HDSPM_TCO_WCK_CONVERSION("TCO WCK Conversion", 0), 4366 HDSPM_TCO_WCK_CONVERSION("TCO WCK Conversion", 0),
4273 HDSPM_TCO_FRAME_RATE("TCO Frame Rate", 0), 4367 HDSPM_TCO_FRAME_RATE("TCO Frame Rate", 0),
4274 HDSPM_TCO_SYNC_SOURCE("TCO Sync Source", 0), 4368 HDSPM_TCO_SYNC_SOURCE("TCO Sync Source", 0),
4275 HDSPM_TCO_WORD_TERM("TCO Word Term", 0) 4369 HDSPM_TCO_WORD_TERM("TCO Word Term", 0),
4370 HDSPM_TCO_LOCK_CHECK("TCO Input Check", 11),
4371 HDSPM_TCO_LOCK_CHECK("TCO LTC Valid", 12),
4372 HDSPM_TCO_LTC_FRAMES("TCO Detected Frame Rate", 0),
4373 HDSPM_TCO_VIDEO_INPUT_FORMAT("Video Input Format", 0)
4276}; 4374};
4277 4375
4278 4376