aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorRemy Bruno <remy.bruno@trinnov.com>2006-10-17 06:41:56 -0400
committerJaroslav Kysela <perex@suse.cz>2007-02-09 03:01:04 -0500
commitd7923b2a816625dc4208d89471da6bdcab188cdb (patch)
treec7d9732deb8280d479c850ecce440be8e9dbabd2 /sound
parentccc656ce5f6627032bd44e660071bb71e65a231a (diff)
[ALSA] hdsp - Add DDS register support for RME9632 rev >= 152
Add DDS register support for RME9632 rev >= 152. This register sets the sample rate for these cards and is required in addition to the standard control register. It corresponds to a quartz divisor. 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')
-rw-r--r--sound/pci/rme9652/hdsp.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 849ffe4aa5ca..89b3c7ff5037 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -80,6 +80,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
80/* Write registers. These are defined as byte-offsets from the iobase value. 80/* Write registers. These are defined as byte-offsets from the iobase value.
81 */ 81 */
82#define HDSP_resetPointer 0 82#define HDSP_resetPointer 0
83#define HDSP_freqReg 0
83#define HDSP_outputBufferAddress 32 84#define HDSP_outputBufferAddress 32
84#define HDSP_inputBufferAddress 36 85#define HDSP_inputBufferAddress 36
85#define HDSP_controlRegister 64 86#define HDSP_controlRegister 64
@@ -469,6 +470,7 @@ struct hdsp {
469 struct pci_dev *pci; 470 struct pci_dev *pci;
470 struct snd_kcontrol *spdif_ctl; 471 struct snd_kcontrol *spdif_ctl;
471 unsigned short mixer_matrix[HDSP_MATRIX_MIXER_SIZE]; 472 unsigned short mixer_matrix[HDSP_MATRIX_MIXER_SIZE];
473 unsigned int dds_value; /* last value written to freq register */
472}; 474};
473 475
474/* These tables map the ALSA channels 1..N to the channels that we 476/* These tables map the ALSA channels 1..N to the channels that we
@@ -940,6 +942,11 @@ static snd_pcm_uframes_t hdsp_hw_pointer(struct hdsp *hdsp)
940static void hdsp_reset_hw_pointer(struct hdsp *hdsp) 942static void hdsp_reset_hw_pointer(struct hdsp *hdsp)
941{ 943{
942 hdsp_write (hdsp, HDSP_resetPointer, 0); 944 hdsp_write (hdsp, HDSP_resetPointer, 0);
945 if (hdsp->io_type == H9632 && hdsp->firmware_rev >= 152)
946 /* HDSP_resetPointer = HDSP_freqReg, which is strange and
947 * requires (?) to write again DDS value after a reset pointer
948 * (at least, it works like this) */
949 hdsp_write (hdsp, HDSP_freqReg, hdsp->dds_value);
943} 950}
944 951
945static void hdsp_start_audio(struct hdsp *s) 952static void hdsp_start_audio(struct hdsp *s)
@@ -984,6 +991,30 @@ static int hdsp_set_interrupt_interval(struct hdsp *s, unsigned int frames)
984 return 0; 991 return 0;
985} 992}
986 993
994static void hdsp_set_dds_value(struct hdsp *hdsp, int rate)
995{
996 u64 n;
997 u32 r;
998
999 if (rate >= 112000)
1000 rate /= 4;
1001 else if (rate >= 56000)
1002 rate /= 2;
1003
1004 /* RME says n = 104857600000000, but in the windows MADI driver, I see:
1005// return 104857600000000 / rate; // 100 MHz
1006 return 110100480000000 / rate; // 105 MHz
1007 */
1008 n = 104857600000000ULL; /* = 2^20 * 10^8 */
1009 div64_32(&n, rate, &r);
1010 /* n should be less than 2^32 for being written to FREQ register */
1011 snd_assert((n >> 32) == 0);
1012 /* HDSP_freqReg and HDSP_resetPointer are the same, so keep the DDS
1013 value to write it after a reset */
1014 hdsp->dds_value = n;
1015 hdsp_write(hdsp, HDSP_freqReg, hdsp->dds_value);
1016}
1017
987static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally) 1018static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally)
988{ 1019{
989 int reject_if_open = 0; 1020 int reject_if_open = 0;
@@ -1092,6 +1123,10 @@ static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally)
1092 hdsp->control_register |= rate_bits; 1123 hdsp->control_register |= rate_bits;
1093 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); 1124 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1094 1125
1126 /* For HDSP9632 rev 152, need to set DDS value in FREQ register */
1127 if (hdsp->io_type == H9632 && hdsp->firmware_rev >= 152)
1128 hdsp_set_dds_value(hdsp, rate);
1129
1095 if (rate >= 128000) { 1130 if (rate >= 128000) {
1096 hdsp->channel_map = channel_map_H9632_qs; 1131 hdsp->channel_map = channel_map_H9632_qs;
1097 } else if (rate > 48000) { 1132 } else if (rate > 48000) {
@@ -4945,6 +4980,7 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
4945 hdsp->irq = pci->irq; 4980 hdsp->irq = pci->irq;
4946 hdsp->precise_ptr = 0; 4981 hdsp->precise_ptr = 0;
4947 hdsp->use_midi_tasklet = 1; 4982 hdsp->use_midi_tasklet = 1;
4983 hdsp->dds_value = 0;
4948 4984
4949 if ((err = snd_hdsp_initialize_memory(hdsp)) < 0) 4985 if ((err = snd_hdsp_initialize_memory(hdsp)) < 0)
4950 return err; 4986 return err;