Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=e4b6088c8cf16781f7f7b887811b164daf625968
Commit:     e4b6088c8cf16781f7f7b887811b164daf625968
Parent:     02a5039fc72611801e20679d2030d627ed043463
Author:     Julian Cable <[EMAIL PROTECTED]>
AuthorDate: Mon Mar 19 11:44:40 2007 +0100
Committer:  Jaroslav Kysela <[EMAIL PROTECTED]>
CommitDate: Fri May 11 16:55:50 2007 +0200

    [ALSA] hdsp - Add support for fine tuning of sample rate support to HDSP 
9632
    
    Add 'DDS Sample Rate Offset' control. Allows values in Hz from -5000 to 
+5000.
    The value is added to the nominal sample rate and written to the DDS 
register.
    
    Signed-off-by: Julian Cable <[EMAIL PROTECTED]>
    Signed-off-by: Takashi Iwai <[EMAIL PROTECTED]>
    Signed-off-by: Jaroslav Kysela <[EMAIL PROTECTED]>
---
 sound/pci/rme9652/hdsp.c |   85 ++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 79 insertions(+), 6 deletions(-)

diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 6540037..4b20f84 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -275,6 +275,11 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
 #define HDSP_Frequency128KHz   
(HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0)
 #define HDSP_Frequency176_4KHz 
(HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1)
 #define HDSP_Frequency192KHz   
(HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0)
+/* RME says n = 104857600000000, but in the windows MADI driver, I see:
+       return 104857600000000 / rate; // 100 MHz
+       return 110100480000000 / rate; // 105 MHz
+*/
+#define DDS_NUMERATOR 104857600000000ULL;  /*  =  2^20 * 10^8 */
 
 #define hdsp_encode_latency(x)       (((x)<<1) & HDSP_LatencyMask)
 #define hdsp_decode_latency(x)       (((x) & HDSP_LatencyMask)>>1)
@@ -1001,11 +1006,7 @@ static void hdsp_set_dds_value(struct hdsp *hdsp, int 
rate)
        else if (rate >= 56000)
                rate /= 2;
 
-       /* RME says n = 104857600000000, but in the windows MADI driver, I see:
-//     return 104857600000000 / rate; // 100 MHz
-       return 110100480000000 / rate; // 105 MHz
-        */        
-       n = 104857600000000ULL;  /*  =  2^20 * 10^8 */
+       n = DDS_NUMERATOR;
        div64_32(&n, rate, &r);
        /* n should be less than 2^32 for being written to FREQ register */
        snd_assert((n >> 32) == 0);
@@ -3085,11 +3086,83 @@ static int snd_hdsp_get_adat_sync_check(struct 
snd_kcontrol *kcontrol, struct sn
        return 0;
 }
 
+#define HDSP_DDS_OFFSET(xname, xindex) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
+  .name = xname, \
+  .index = xindex, \
+  .info = snd_hdsp_info_dds_offset, \
+  .get = snd_hdsp_get_dds_offset, \
+  .put = snd_hdsp_put_dds_offset \
+}
+
+static int hdsp_dds_offset(struct hdsp *hdsp)
+{
+       u64 n;
+       u32 r;
+       unsigned int dds_value = hdsp->dds_value;
+       int system_sample_rate = hdsp->system_sample_rate;
+
+       n = DDS_NUMERATOR;
+       /*
+        * dds_value = n / rate
+        * rate = n / dds_value
+        */
+       div64_32(&n, dds_value, &r);
+       if (system_sample_rate >= 112000)
+               n *= 4;
+       else if (system_sample_rate >= 56000)
+               n *= 2;
+       return ((int)n) - system_sample_rate;
+}
+
+static int hdsp_set_dds_offset(struct hdsp *hdsp, int offset_hz)
+{
+       int rate = hdsp->system_sample_rate + offset_hz;
+       hdsp_set_dds_value(hdsp, rate);
+       return 0;
+}
+
+static int snd_hdsp_info_dds_offset(struct snd_kcontrol *kcontrol, struct 
snd_ctl_elem_info *uinfo)
+{
+       uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+       uinfo->count = 1;
+       uinfo->value.integer.min = -5000;
+       uinfo->value.integer.max = 5000;
+       return 0;
+}
+
+static int snd_hdsp_get_dds_offset(struct snd_kcontrol *kcontrol, struct 
snd_ctl_elem_value *ucontrol)
+{
+       struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+       
+       ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp);
+       return 0;
+}
+
+static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct 
snd_ctl_elem_value *ucontrol)
+{
+       struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
+       int change;
+       int val;
+       
+       if (!snd_hdsp_use_is_exclusive(hdsp))
+               return -EBUSY;
+       val = ucontrol->value.enumerated.item[0];
+       spin_lock_irq(&hdsp->lock);
+       if (val != hdsp_dds_offset(hdsp))
+               change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0;
+       else
+               change = 0;
+       spin_unlock_irq(&hdsp->lock);
+       return change;
+}
+
 static struct snd_kcontrol_new snd_hdsp_9632_controls[] = {
 HDSP_DA_GAIN("DA Gain", 0),
 HDSP_AD_GAIN("AD Gain", 0),
 HDSP_PHONE_GAIN("Phones Gain", 0),
-HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0)
+HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0),
+HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0)
 };
 
 static struct snd_kcontrol_new snd_hdsp_controls[] = {
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to