*
*/
-#include <sound/driver.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
"{RME HDSP-9652},"
"{RME HDSP-9632}}");
+#ifdef HDSP_FW_LOADER
+MODULE_FIRMWARE("multiface_firmware.bin");
+MODULE_FIRMWARE("multiface_firmware_rev11.bin");
+MODULE_FIRMWARE("digiface_firmware.bin");
+MODULE_FIRMWARE("digiface_firmware_rev11.bin");
+#endif
#define HDSP_MAX_CHANNELS 26
#define HDSP_MAX_DS_CHANNELS 14
#define HDSP_statusRegister 0
#define HDSP_timecode 128
#define HDSP_status2Register 192
-#define HDSP_midiDataOut0 352
-#define HDSP_midiDataOut1 356
#define HDSP_midiDataIn0 360
#define HDSP_midiDataIn1 364
#define HDSP_midiStatusOut0 384
#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)
#define HDSP_midi1IRQPending (1<<31)
#define HDSP_spdifFrequencyMask (HDSP_spdifFrequency0|HDSP_spdifFrequency1|HDSP_spdifFrequency2)
+#define HDSP_spdifFrequencyMask_9632 (HDSP_spdifFrequency0|\
+ HDSP_spdifFrequency1|\
+ HDSP_spdifFrequency2|\
+ HDSP_spdifFrequency3)
#define HDSP_spdifFrequency32KHz (HDSP_spdifFrequency0)
#define HDSP_spdifFrequency44_1KHz (HDSP_spdifFrequency1)
#define HDSP_spdifFrequency96KHz (HDSP_spdifFrequency2|HDSP_spdifFrequency1)
/* This is for H9632 cards */
-#define HDSP_spdifFrequency128KHz HDSP_spdifFrequencyMask
+#define HDSP_spdifFrequency128KHz (HDSP_spdifFrequency0|\
+ HDSP_spdifFrequency1|\
+ HDSP_spdifFrequency2)
#define HDSP_spdifFrequency176_4KHz HDSP_spdifFrequency3
#define HDSP_spdifFrequency192KHz (HDSP_spdifFrequency3|HDSP_spdifFrequency0)
static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out)
{
- switch (hdsp->firmware_rev) {
- case 0xa:
- return (64 * out) + (32 + (in));
- case 0x96:
- case 0x97:
- case 0x98:
- return (32 * out) + (16 + (in));
+ switch (hdsp->io_type) {
+ case Multiface:
+ case Digiface:
default:
+ if (hdsp->firmware_rev == 0xa)
+ return (64 * out) + (32 + (in));
+ else
+ return (52 * out) + (26 + (in));
+ case H9632:
+ return (32 * out) + (16 + (in));
+ case H9652:
return (52 * out) + (26 + (in));
}
}
static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out)
{
- switch (hdsp->firmware_rev) {
- case 0xa:
- return (64 * out) + in;
- case 0x96:
- case 0x97:
- case 0x98:
- return (32 * out) + in;
+ switch (hdsp->io_type) {
+ case Multiface:
+ case Digiface:
default:
+ if (hdsp->firmware_rev == 0xa)
+ return (64 * out) + in;
+ else
+ return (52 * out) + in;
+ case H9632:
+ return (32 * out) + in;
+ case H9652:
return (52 * out) + in;
}
}
#ifdef HDSP_FW_LOADER
-static int __devinit hdsp_request_fw_loader(struct hdsp *hdsp);
+static int hdsp_request_fw_loader(struct hdsp *hdsp);
#endif
static int hdsp_check_for_firmware (struct hdsp *hdsp, int load_on_demand)
return ret;
}
-static int hdsp_external_sample_rate (struct hdsp *hdsp)
-{
- unsigned int status2 = hdsp_read(hdsp, HDSP_status2Register);
- unsigned int rate_bits = status2 & HDSP_systemFrequencyMask;
-
- switch (rate_bits) {
- case HDSP_systemFrequency32: return 32000;
- case HDSP_systemFrequency44_1: return 44100;
- case HDSP_systemFrequency48: return 48000;
- case HDSP_systemFrequency64: return 64000;
- case HDSP_systemFrequency88_2: return 88200;
- case HDSP_systemFrequency96: return 96000;
- default:
- return 0;
- }
-}
-
static int hdsp_spdif_sample_rate(struct hdsp *hdsp)
{
unsigned int status = hdsp_read(hdsp, HDSP_statusRegister);
unsigned int rate_bits = (status & HDSP_spdifFrequencyMask);
+ /* For the 9632, the mask is different */
+ if (hdsp->io_type == H9632)
+ rate_bits = (status & HDSP_spdifFrequencyMask_9632);
+
if (status & HDSP_SPDIFErrorFlag)
return 0;
return 0;
}
+static int hdsp_external_sample_rate(struct hdsp *hdsp)
+{
+ unsigned int status2 = hdsp_read(hdsp, HDSP_status2Register);
+ unsigned int rate_bits = status2 & HDSP_systemFrequencyMask;
+
+ /* For the 9632 card, there seems to be no bit for indicating external
+ * sample rate greater than 96kHz. The card reports the corresponding
+ * single speed. So the best means seems to get spdif rate when
+ * autosync reference is spdif */
+ if (hdsp->io_type == H9632 &&
+ hdsp_autosync_ref(hdsp) == HDSP_AUTOSYNC_FROM_SPDIF)
+ return hdsp_spdif_sample_rate(hdsp);
+
+ switch (rate_bits) {
+ case HDSP_systemFrequency32: return 32000;
+ case HDSP_systemFrequency44_1: return 44100;
+ case HDSP_systemFrequency48: return 48000;
+ case HDSP_systemFrequency64: return 64000;
+ case HDSP_systemFrequency88_2: return 88200;
+ case HDSP_systemFrequency96: return 96000;
+ default:
+ return 0;
+ }
+}
+
static void hdsp_compute_period_size(struct hdsp *hdsp)
{
hdsp->period_bytes = 1 << ((hdsp_decode_latency(hdsp->control_register) + 8));
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);
return 0;
}
-static int snd_hdsp_info_spdif_bits(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_spdif_bits snd_ctl_boolean_mono_info
static int snd_hdsp_get_spdif_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
return change;
}
-static int snd_hdsp_info_clock_source_lock(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_clock_source_lock snd_ctl_boolean_mono_info
static int snd_hdsp_get_clock_source_lock(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
change = (int)ucontrol->value.integer.value[0] != hdsp->clock_source_locked;
if (change)
- hdsp->clock_source_locked = ucontrol->value.integer.value[0];
+ hdsp->clock_source_locked = !!ucontrol->value.integer.value[0];
return change;
}
return 0;
}
-static int snd_hdsp_info_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_xlr_breakout_cable snd_ctl_boolean_mono_info
static int snd_hdsp_get_xlr_breakout_cable(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
return 0;
}
-static int snd_hdsp_info_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_aeb snd_ctl_boolean_mono_info
static int snd_hdsp_get_aeb(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
return 0;
}
-static int snd_hdsp_info_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_line_out snd_ctl_boolean_mono_info
static int snd_hdsp_get_line_out(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
return 0;
}
-static int snd_hdsp_info_precise_pointer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_precise_pointer snd_ctl_boolean_mono_info
static int snd_hdsp_get_precise_pointer(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
return 0;
}
-static int snd_hdsp_info_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
-{
- uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
- uinfo->count = 1;
- uinfo->value.integer.min = 0;
- uinfo->value.integer.max = 1;
- return 0;
-}
+#define snd_hdsp_info_use_midi_tasklet snd_ctl_boolean_mono_info
static int snd_hdsp_get_use_midi_tasklet(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
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;
+
+ if (!dds_value)
+ return 0;
+
+ 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[] = {
}
-static void __devinit snd_hdsp_proc_init(struct hdsp *hdsp)
+static void snd_hdsp_proc_init(struct hdsp *hdsp)
{
struct snd_info_entry *entry;
/* ASSUMPTION: hdsp->lock is either held, or
there is no need to hold it (e.g. during module
- initalization).
+ initialization).
*/
/* set defaults:
else
runtime->status->hw_ptr = 0;
if (other) {
- struct list_head *pos;
struct snd_pcm_substream *s;
struct snd_pcm_runtime *oruntime = other->runtime;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == other) {
oruntime->status->hw_ptr = runtime->status->hw_ptr;
break;
other = hdsp->playback_substream;
if (other) {
- struct list_head *pos;
struct snd_pcm_substream *s;
- snd_pcm_group_for_each(pos, substream) {
- s = snd_pcm_group_substream_entry(pos);
+ snd_pcm_group_for_each_entry(s, substream) {
if (s == other) {
snd_pcm_trigger_done(s, substream);
if (cmd == SNDRV_PCM_TRIGGER_START)
.copy = snd_hdsp_capture_copy,
};
-static int __devinit snd_hdsp_create_hwdep(struct snd_card *card,
- struct hdsp *hdsp)
+static int snd_hdsp_create_hwdep(struct snd_card *card, struct hdsp *hdsp)
{
struct snd_hwdep *hw;
int err;
#ifdef HDSP_FW_LOADER
/* load firmware via hotplug fw loader */
-static int __devinit hdsp_request_fw_loader(struct hdsp *hdsp)
+static int hdsp_request_fw_loader(struct hdsp *hdsp)
{
const char *fwfile;
const struct firmware *fw;