From 72ad431c8c189f85e9f93ff6f09558bc28f41fd0 Mon Sep 17
00:00:00 2001
From: Daniel T. Chen <crimsun garnish.localdomain>
Date: Sun, 29 Oct 2006 18:10:29 -0500
Subject: [PATCH] [UBUNTU:sound/pci/rme9652/] Add required
DDS register support for RME9632 revisions newer than 152
UpstreamStatus: Added in upstream alsa-kernel hg changeset:
4656: 15b42d2128b5 [http://hg-mirror.alsa-project.org/alsa-ke
rnel?cs=15b42d2128b5;style=raw ]
New RME9632 revisions require an additional sample rate
register
to be set, corresponding to a quartz divisor.
This commit is suitable for Dapper, Edgy, and Feisty
(although one
typedef tweak is necessary for the latter two) linux-source.
Signed-off-by: Remy Bruno <remy.bruno trinnov.com>
Signed-off-by: Daniel T Chen <crimsun ubuntu.com>
---
sound/pci/rme9652/hdsp.c | 36
++++++++++++++++++++++++++++++++++++
1 files changed, 36 insertions(+), 0 deletions(-)
diff --git a/sound/pci/rme9652/hdsp.c
b/sound/pci/rme9652/hdsp.c
index 858960e..0e63165 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
 -80,6
+80,7  #define H9632_QS_CHANNELS 4
/* Write registers. These are defined as byte-offsets from
the iobase value.
*/
#define HDSP_resetPointer 0
+#define HDSP_freqReg 0
#define HDSP_outputBufferAddress 32
#define HDSP_inputBufferAddress 36
#define HDSP_controlRegister 64
 -473,6
+474,7  struct _hdsp {
struct pci_dev *pci;
snd_kcontrol_t *spdif_ctl;
unsigned short
mixer_matrix[HDSP_MATRIX_MIXER_SIZE];
+ unsigned int dds_value; /* last value written to
freq register */
};
/* These tables map the ALSA channels 1..N to the channels
that we
 -943,6
+945,11  static snd_pcm_uframes_t hdsp_hw_pointer
static void hdsp_reset_hw_pointer(hdsp_t *hdsp)
{
hdsp_write (hdsp, HDSP_resetPointer, 0);
+ if (hdsp->io_type == H9632 &&
hdsp->firmware_rev >= 152)
+ /* HDSP_resetPointer = HDSP_freqReg, which is strange and
+ * requires (?) to write again DDS value after a reset
pointer
+ * (at least, it works like this) */
+ hdsp_write (hdsp, HDSP_freqReg, hdsp->dds_value);
}
static void hdsp_start_audio(hdsp_t *s)
 -987,6
+994,30  static int hdsp_set_interrupt_interval(h
return 0;
}
+static void hdsp_set_dds_value(hdsp_t *hdsp, int rate)
+{
+ u64 n;
+ u32 r;
+
+ if (rate >= 112000)
+ rate /= 4;
+ 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 */
+ div64_32(&n, rate, &r);
+ /* n should be less than 2^32 for being written to FREQ
register */
+ snd_assert((n >> 32) == 0);
+ /* HDSP_freqReg and HDSP_resetPointer are the same, so
keep the DDS
+ value to write it after a reset */
+ hdsp->dds_value = n;
+ hdsp_write(hdsp, HDSP_freqReg, hdsp->dds_value);
+}
+
static int hdsp_set_rate(hdsp_t *hdsp, int rate, int
called_internally)
{
int reject_if_open = 0;
 -1095,6
+1126,10  static int hdsp_set_rate(hdsp_t *hdsp, i
hdsp->control_register |= rate_bits;
hdsp_write(hdsp, HDSP_controlRegister,
hdsp->control_register);
+ /* For HDSP9632 rev 152, need to set DDS value in FREQ
register */
+ if (hdsp->io_type == H9632 &&
hdsp->firmware_rev >= 152)
+ hdsp_set_dds_value(hdsp, rate);
+
if (rate >= 128000) {
hdsp->channel_map = channel_map_H9632_qs;
} else if (rate > 48000) {
 -4947,6
+4982,7  static int __devinit snd_hdsp_create(snd
hdsp->irq = pci->irq;
hdsp->precise_ptr = 0;
hdsp->use_midi_tasklet = 1;
+ hdsp->dds_value = 0;
if ((err = snd_hdsp_initialize_memory(hdsp)) < 0)
return err;
--
1.4.1
--
Daniel T. Chen crimsun ubuntu.com
GPG key: 0xC88ABDA3
--
kernel-team mailing list
kernel-team lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team
|