From 3f7bf918bfa2f4b8aa461ae82249e3c187bbff81 Mon Sep 17 00:00:00 2001 From: Adrian Knoth Date: Sun, 10 Mar 2013 00:37:21 +0100 Subject: ALSA: hdspm - Refactor sample rate acquisition This commit introduces hdspm_get_pll_freq() to avoid code duplication. Reading the sample rate from the DDS register will be required by upcoming code. Signed-off-by: Adrian Knoth Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdspm.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'sound/pci/rme9652') diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 223c3d9cc69e..50cba5ce54fe 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, struct hdspm *hdspm); static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm); +static inline int hdspm_get_pll_freq(struct hdspm *hdspm); static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm); static int hdspm_autosync_ref(struct hdspm *hdspm); static int snd_hdspm_set_defaults(struct hdspm *hdspm); @@ -1979,16 +1980,25 @@ static void hdspm_midi_tasklet(unsigned long arg) /* get the system sample rate which is set */ +static inline int hdspm_get_pll_freq(struct hdspm *hdspm) +{ + unsigned int period, rate; + + period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ); + rate = hdspm_calc_dds_value(hdspm, period); + + return rate; +} + /** * Calculate the real sample rate from the * current DDS value. **/ static int hdspm_get_system_sample_rate(struct hdspm *hdspm) { - unsigned int period, rate; + unsigned int rate; - period = hdspm_read(hdspm, HDSPM_RD_PLL_FREQ); - rate = hdspm_calc_dds_value(hdspm, period); + rate = hdspm_get_pll_freq(hdspm); if (rate > 207000) { /* Unreasonable high sample rate as seen on PCI MADI cards. */ -- cgit v1.2.2 From fcdc4ba1d8c69847540cb3152f0ca44e238111ee Mon Sep 17 00:00:00 2001 From: Adrian Knoth Date: Sun, 10 Mar 2013 00:37:22 +0100 Subject: ALSA: hdspm - Allow the TCO and SYNC-IN to be used in slave mode When using the additional Time Code Option module in slave mode or the SYNC-In wordclock connector, the sample rate needs to be returned by hdspm_external_sample_rate(). Since this sample rate may contain any value with 1Hz granularity, we need to round it to a common rate as done by the OSX driver. [Fixed missing function declarations by tiwai] Signed-off-by: Adrian Knoth Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdspm.c | 65 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 14 deletions(-) (limited to 'sound/pci/rme9652') diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 50cba5ce54fe..c56bfe402234 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -1076,6 +1076,20 @@ static int snd_hdspm_use_is_exclusive(struct hdspm *hdspm) return ret; } +/* round arbitary sample rates to commonly known rates */ +static int hdspm_round_frequency(int rate) +{ + if (rate < 38050) + return 32000; + if (rate < 46008) + return 44100; + else + return 48000; +} + +static int hdspm_tco_sync_check(struct hdspm *hdspm); +static int hdspm_sync_in_sync_check(struct hdspm *hdspm); + /* check for external sample rate */ static int hdspm_external_sample_rate(struct hdspm *hdspm) { @@ -1217,22 +1231,45 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm) break; } - /* QS and DS rates normally can not be detected - * automatically by the card. Only exception is MADI - * in 96k frame mode. - * - * So if we read SS values (32 .. 48k), check for - * user-provided DS/QS bits in the control register - * and multiply the base frequency accordingly. - */ - if (rate <= 48000) { - if (hdspm->control_register & HDSPM_QuadSpeed) - rate *= 4; - else if (hdspm->control_register & - HDSPM_DoubleSpeed) - rate *= 2; + } /* endif HDSPM_madiLock */ + + /* check sample rate from TCO or SYNC_IN */ + { + bool is_valid_input = 0; + bool has_sync = 0; + + syncref = hdspm_autosync_ref(hdspm); + if (HDSPM_AUTOSYNC_FROM_TCO == syncref) { + is_valid_input = 1; + has_sync = (HDSPM_SYNC_CHECK_SYNC == + hdspm_tco_sync_check(hdspm)); + } else if (HDSPM_AUTOSYNC_FROM_SYNC_IN == syncref) { + is_valid_input = 1; + has_sync = (HDSPM_SYNC_CHECK_SYNC == + hdspm_sync_in_sync_check(hdspm)); + } + + if (is_valid_input && has_sync) { + rate = hdspm_round_frequency( + hdspm_get_pll_freq(hdspm)); } } + + /* QS and DS rates normally can not be detected + * automatically by the card. Only exception is MADI + * in 96k frame mode. + * + * So if we read SS values (32 .. 48k), check for + * user-provided DS/QS bits in the control register + * and multiply the base frequency accordingly. + */ + if (rate <= 48000) { + if (hdspm->control_register & HDSPM_QuadSpeed) + rate *= 4; + else if (hdspm->control_register & + HDSPM_DoubleSpeed) + rate *= 2; + } break; } -- cgit v1.2.2 From 696be0fbe244ca6d267fb1ce67a4a5f6c8fe37bc Mon Sep 17 00:00:00 2001 From: Adrian Knoth Date: Sun, 10 Mar 2013 00:37:23 +0100 Subject: ALSA: hdspm - Provide ALSA control to disable 96K frames For 96kHz, MADI allows to multiplex the samples (SMUX) or to use a dedicated 96K mode. The RME cards default to 96K mode, but since not all external MADI equipment supports this, provide a switch to users that changes the on-wire protocol to SMUX. Signed-off-by: Adrian Knoth Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdspm.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci/rme9652') diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index c56bfe402234..c03ee011bfb6 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -4192,6 +4192,7 @@ static struct snd_kcontrol_new snd_hdspm_controls_madi[] = { HDSPM_SYNC_CHECK("SYNC IN SyncCheck", 3), HDSPM_TOGGLE_SETTING("Line Out", HDSPM_LineOut), HDSPM_TOGGLE_SETTING("TX 64 channels mode", HDSPM_TX_64ch), + HDSPM_TOGGLE_SETTING("Disable 96K frames", HDSPM_SMUX), HDSPM_TOGGLE_SETTING("Clear Track Marker", HDSPM_clr_tms), HDSPM_TOGGLE_SETTING("Safe Mode", HDSPM_AutoInp), HDSPM_INPUT_SELECT("Input Select", 0), -- cgit v1.2.2 From e5b7b1fe3b263441a1fc89bc6a4cca5e80f348b0 Mon Sep 17 00:00:00 2001 From: Adrian Knoth Date: Sun, 10 Mar 2013 00:37:24 +0100 Subject: ALSA: hdspm - Remove duplicate code from ALSA controls Considerably shorten the code by using a macro. Though this won't lower the binary size, it makes the source more readable. Signed-off-by: Adrian Knoth Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdspm.c | 146 +++++++--------------------------------------- 1 file changed, 22 insertions(+), 124 deletions(-) (limited to 'sound/pci/rme9652') diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index c03ee011bfb6..82f209f283aa 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -2175,6 +2175,16 @@ static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx) return (status >> (idx*4)) & 0xF; } +#define ENUMERATED_CTL_INFO(info, texts) \ +{ \ + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; \ + uinfo->count = 1; \ + uinfo->value.enumerated.items = ARRAY_SIZE(texts); \ + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) \ + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; \ + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); \ +} + #define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ @@ -2190,14 +2200,7 @@ static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx) static int snd_hdspm_info_autosync_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 10; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts_freq[uinfo->value.enumerated.item]); + ENUMERATED_CTL_INFO(uinfo, texts_freq); return 0; } @@ -2363,15 +2366,7 @@ static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static char *texts[] = { "Master", "AutoSync" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); + ENUMERATED_CTL_INFO(uinfo, texts); return 0; } @@ -3021,17 +3016,7 @@ static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static char *texts[] = { "optical", "coaxial" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - + ENUMERATED_CTL_INFO(uinfo, texts); return 0; } @@ -3093,17 +3078,7 @@ static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static char *texts[] = { "Single", "Double" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - + ENUMERATED_CTL_INFO(uinfo, texts); return 0; } @@ -3176,17 +3151,7 @@ static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static char *texts[] = { "Single", "Double", "Quad" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - + ENUMERATED_CTL_INFO(uinfo, texts); return 0; } @@ -3262,17 +3227,7 @@ static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static char *texts[] = { "Single", "Double", "Quad" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - + ENUMERATED_CTL_INFO(uinfo, texts); return 0; } @@ -3497,14 +3452,7 @@ static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static char *texts[] = { "No Lock", "Lock", "Sync", "N/A" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 4; - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); + ENUMERATED_CTL_INFO(uinfo, texts); return 0; } @@ -3860,17 +3808,7 @@ static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static char *texts[] = { "44.1 kHz", "48 kHz" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - + ENUMERATED_CTL_INFO(uinfo, texts); return 0; } @@ -3916,17 +3854,7 @@ static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static char *texts[] = { "0", "+ 0.1 %", "- 0.1 %", "+ 4 %", "- 4 %" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 5; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - + ENUMERATED_CTL_INFO(uinfo, texts); return 0; } @@ -3971,17 +3899,7 @@ static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static char *texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - + ENUMERATED_CTL_INFO(uinfo, texts); return 0; } @@ -4028,17 +3946,7 @@ static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol, { static char *texts[] = { "24 fps", "25 fps", "29.97fps", "29.97 dfps", "30 fps", "30 dfps" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 6; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - + ENUMERATED_CTL_INFO(uinfo, texts); return 0; } @@ -4084,17 +3992,7 @@ static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static char *texts[] = { "LTC", "Video", "WCK" }; - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - + ENUMERATED_CTL_INFO(uinfo, texts); return 0; } -- cgit v1.2.2 From 345422133ae07147aa695a469bfec8f97d77a81c Mon Sep 17 00:00:00 2001 From: Adrian Knoth Date: Sun, 10 Mar 2013 00:37:25 +0100 Subject: ALSA: hdspm - Also check for TCO sync states This patch prepares snd_hdspm_get_sync_check() to also check the TCO sync state. The added feature will be exposed to the user in a later commit. Signed-off-by: Adrian Knoth Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdspm.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'sound/pci/rme9652') diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 82f209f283aa..8b7c9fb901c7 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -3447,6 +3447,16 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol, .get = snd_hdspm_get_sync_check \ } +#define HDSPM_TCO_LOCK_CHECK(xname, xindex) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .private_value = xindex, \ + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ + .info = snd_hdspm_tco_info_lock_check, \ + .get = snd_hdspm_get_sync_check \ +} + + static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -3456,6 +3466,14 @@ static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, return 0; } +static int snd_hdspm_tco_info_lock_check(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *texts[] = { "No Lock", "Lock" }; + ENUMERATED_CTL_INFO(uinfo, texts); + return 0; +} + static int hdspm_wc_sync_check(struct hdspm *hdspm) { int status, status2; @@ -3585,6 +3603,14 @@ static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx) return 0; } +static int hdspm_tco_input_check(struct hdspm *hdspm, u32 mask) +{ + u32 status; + status = hdspm_read(hdspm, HDSPM_RD_TCO + 4); + + return (status & mask) ? 1 : 0; +} + static int hdspm_tco_sync_check(struct hdspm *hdspm) { @@ -3692,6 +3718,22 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol, } + if (hdspm->tco) { + switch (kcontrol->private_value) { + case 11: + /* Check TCO for lock state of its current input */ + val = hdspm_tco_input_check(hdspm, HDSPM_TCO1_TCO_lock); + break; + case 12: + /* Check TCO for valid time code on LTC input. */ + val = hdspm_tco_input_check(hdspm, + HDSPM_TCO1_LTC_Input_valid); + break; + default: + break; + } + } + if (-1 == val) val = 3; -- cgit v1.2.2 From f99c78812fcc38a32f9f1694cf75dd7f7e329ae7 Mon Sep 17 00:00:00 2001 From: Adrian Knoth Date: Sun, 10 Mar 2013 00:37:26 +0100 Subject: ALSA: hdspm - Add ALSA controls to read the TCO LTC state This patch adds new ALSA controls to query the LTC state from userspace. Signed-off-by: Adrian Knoth Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdspm.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'sound/pci/rme9652') diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 8b7c9fb901c7..e23572dd0e46 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -2930,6 +2930,112 @@ static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol, return 0; } + + +#define HDSPM_TCO_VIDEO_INPUT_FORMAT(xname, xindex) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .access = SNDRV_CTL_ELEM_ACCESS_READ |\ + SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ + .info = snd_hdspm_info_tco_video_input_format, \ + .get = snd_hdspm_get_tco_video_input_format, \ +} + +static int snd_hdspm_info_tco_video_input_format(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *texts[] = {"No video", "NTSC", "PAL"}; + ENUMERATED_CTL_INFO(uinfo, texts); + return 0; +} + +static int snd_hdspm_get_tco_video_input_format(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u32 status; + int ret = 0; + + struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); + status = hdspm_read(hdspm, HDSPM_RD_TCO + 4); + switch (status & (HDSPM_TCO1_Video_Input_Format_NTSC | + HDSPM_TCO1_Video_Input_Format_PAL)) { + case HDSPM_TCO1_Video_Input_Format_NTSC: + /* ntsc */ + ret = 1; + break; + case HDSPM_TCO1_Video_Input_Format_PAL: + /* pal */ + ret = 2; + break; + default: + /* no video */ + ret = 0; + break; + } + ucontrol->value.enumerated.item[0] = ret; + return 0; +} + + + +#define HDSPM_TCO_LTC_FRAMES(xname, xindex) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .access = SNDRV_CTL_ELEM_ACCESS_READ |\ + SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ + .info = snd_hdspm_info_tco_ltc_frames, \ + .get = snd_hdspm_get_tco_ltc_frames, \ +} + +static int snd_hdspm_info_tco_ltc_frames(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *texts[] = {"No lock", "24 fps", "25 fps", "29.97 fps", + "30 fps"}; + ENUMERATED_CTL_INFO(uinfo, texts); + return 0; +} + +static int hdspm_tco_ltc_frames(struct hdspm *hdspm) +{ + u32 status; + int ret = 0; + + status = hdspm_read(hdspm, HDSPM_RD_TCO + 4); + if (status & HDSPM_TCO1_LTC_Input_valid) { + switch (status & (HDSPM_TCO1_LTC_Format_LSB | + HDSPM_TCO1_LTC_Format_MSB)) { + case 0: + /* 24 fps */ + ret = 1; + break; + case HDSPM_TCO1_LTC_Format_LSB: + /* 25 fps */ + ret = 2; + break; + case HDSPM_TCO1_LTC_Format_MSB: + /* 25 fps */ + ret = 3; + break; + default: + /* 30 fps */ + ret = 4; + break; + } + } + + return ret; +} + +static int snd_hdspm_get_tco_ltc_frames(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = hdspm_tco_ltc_frames(hdspm); + return 0; +} + #define HDSPM_TOGGLE_SETTING(xname, xindex) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ .name = xname, \ -- cgit v1.2.2 From a817650ebb451ef27db2baa7e10d0c28609bed13 Mon Sep 17 00:00:00 2001 From: Adrian Knoth Date: Sun, 10 Mar 2013 00:37:27 +0100 Subject: ALSA: hdspm - Enable new TCO ALSA controls Expose the newly added TCO LTC and sync check functions to userspace. Signed-off-by: Adrian Knoth Signed-off-by: Takashi Iwai --- sound/pci/rme9652/hdspm.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sound/pci/rme9652') diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index e23572dd0e46..9ea05e956474 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -4366,7 +4366,11 @@ static struct snd_kcontrol_new snd_hdspm_controls_tco[] = { HDSPM_TCO_WCK_CONVERSION("TCO WCK Conversion", 0), HDSPM_TCO_FRAME_RATE("TCO Frame Rate", 0), HDSPM_TCO_SYNC_SOURCE("TCO Sync Source", 0), - HDSPM_TCO_WORD_TERM("TCO Word Term", 0) + HDSPM_TCO_WORD_TERM("TCO Word Term", 0), + HDSPM_TCO_LOCK_CHECK("TCO Input Check", 11), + HDSPM_TCO_LOCK_CHECK("TCO LTC Valid", 12), + HDSPM_TCO_LTC_FRAMES("TCO Detected Frame Rate", 0), + HDSPM_TCO_VIDEO_INPUT_FORMAT("Video Input Format", 0) }; -- cgit v1.2.2