📄 rme9652.c
字号:
if ((restart = s->running)) { rme9652_stop(s); } frames >>= 7; n = 0; while (frames) { n++; frames >>= 1; } s->control_register &= ~RME9652_latency; s->control_register |= rme9652_encode_latency(n); rme9652_write(s, RME9652_control_register, s->control_register); rme9652_compute_period_size(s); if (restart) rme9652_start(s); spin_unlock_irq(&s->lock); return 0;}static int rme9652_set_rate(rme9652_t *rme9652, int rate){ int restart; int reject_if_open = 0; int xrate; if (!snd_rme9652_use_is_exclusive (rme9652)) { return -EBUSY; } /* Changing from a "single speed" to a "double speed" rate is not allowed if any substreams are open. This is because such a change causes a shift in the location of the DMA buffers and a reduction in the number of available buffers. Note that a similar but essentially insoluble problem exists for externally-driven rate changes. All we can do is to flag rate changes in the read/write routines. */ spin_lock_irq(&rme9652->lock); xrate = rme9652_adat_sample_rate(rme9652); switch (rate) { case 44100: if (xrate > 48000) { reject_if_open = 1; } rate = 0; break; case 48000: if (xrate > 48000) { reject_if_open = 1; } rate = RME9652_freq; break; case 88200: if (xrate < 48000) { reject_if_open = 1; } rate = RME9652_DS; break; case 96000: if (xrate < 48000) { reject_if_open = 1; } rate = RME9652_DS | RME9652_freq; break; default: spin_unlock_irq(&rme9652->lock); return -EINVAL; } if (reject_if_open && (rme9652->capture_pid >= 0 || rme9652->playback_pid >= 0)) { spin_unlock_irq(&rme9652->lock); return -EBUSY; } if ((restart = rme9652->running)) { rme9652_stop(rme9652); } rme9652->control_register &= ~(RME9652_freq | RME9652_DS); rme9652->control_register |= rate; rme9652_write(rme9652, RME9652_control_register, rme9652->control_register); if (restart) { rme9652_start(rme9652); } if (rate & RME9652_DS) { if (rme9652->ss_channels == RME9652_NCHANNELS) { rme9652->channel_map = channel_map_9652_ds; } else { rme9652->channel_map = channel_map_9636_ds; } } else { if (rme9652->ss_channels == RME9652_NCHANNELS) { rme9652->channel_map = channel_map_9652_ss; } else { rme9652->channel_map = channel_map_9636_ss; } } spin_unlock_irq(&rme9652->lock); return 0;}static void rme9652_set_thru(rme9652_t *rme9652, int channel, int enable){ int i; rme9652->passthru = 0; if (channel < 0) { /* set thru for all channels */ if (enable) { for (i = 0; i < RME9652_NCHANNELS; i++) { rme9652->thru_bits |= (1 << i); rme9652_write(rme9652, RME9652_thru_base + i * 4, 1); } } else { for (i = 0; i < RME9652_NCHANNELS; i++) { rme9652->thru_bits &= ~(1 << i); rme9652_write(rme9652, RME9652_thru_base + i * 4, 0); } } } else { int mapped_channel; snd_assert(channel == RME9652_NCHANNELS, return); mapped_channel = rme9652->channel_map[channel]; if (enable) { rme9652->thru_bits |= (1 << mapped_channel); } else { rme9652->thru_bits &= ~(1 << mapped_channel); } rme9652_write(rme9652, RME9652_thru_base + mapped_channel * 4, enable ? 1 : 0); }}static int rme9652_set_passthru(rme9652_t *rme9652, int onoff){ if (onoff) { rme9652_set_thru(rme9652, -1, 1); /* we don't want interrupts, so do a custom version of rme9652_start(). */ rme9652->control_register = RME9652_inp_0 | rme9652_encode_latency(7) | RME9652_start_bit; rme9652_reset_hw_pointer(rme9652); rme9652_write(rme9652, RME9652_control_register, rme9652->control_register); rme9652->passthru = 1; } else { rme9652_set_thru(rme9652, -1, 0); rme9652_stop(rme9652); rme9652->passthru = 0; } return 0;}static void rme9652_spdif_set_bit (rme9652_t *rme9652, int mask, int onoff){ if (onoff) rme9652->control_register |= mask; else rme9652->control_register &= ~mask; rme9652_write(rme9652, RME9652_control_register, rme9652->control_register);}static void rme9652_spdif_write_byte (rme9652_t *rme9652, const int val){ long mask; long i; for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) { if (val & mask) rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_WRITE, 1); else rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_WRITE, 0); rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 1); rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 0); }}static int rme9652_spdif_read_byte (rme9652_t *rme9652){ long mask; long val; long i; val = 0; for (i = 0, mask = 0x80; i < 8; i++, mask >>= 1) { rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 1); if (rme9652_read (rme9652, RME9652_status_register) & RME9652_SPDIF_READ) val |= mask; rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_CLOCK, 0); } return val;}static void rme9652_write_spdif_codec (rme9652_t *rme9652, const int address, const int data){ rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1); rme9652_spdif_write_byte (rme9652, 0x20); rme9652_spdif_write_byte (rme9652, address); rme9652_spdif_write_byte (rme9652, data); rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0);}static int rme9652_spdif_read_codec (rme9652_t *rme9652, const int address){ int ret; rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1); rme9652_spdif_write_byte (rme9652, 0x20); rme9652_spdif_write_byte (rme9652, address); rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0); rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 1); rme9652_spdif_write_byte (rme9652, 0x21); ret = rme9652_spdif_read_byte (rme9652); rme9652_spdif_set_bit (rme9652, RME9652_SPDIF_SELECT, 0); return ret;}static void rme9652_initialize_spdif_receiver (rme9652_t *rme9652){ /* XXX what unsets this ? */ rme9652->control_register |= RME9652_SPDIF_RESET; rme9652_write_spdif_codec (rme9652, 4, 0x40); rme9652_write_spdif_codec (rme9652, 17, 0x13); rme9652_write_spdif_codec (rme9652, 6, 0x02);}static inline int rme9652_spdif_sample_rate(rme9652_t *s){ unsigned int rate_bits; if (rme9652_read(s, RME9652_status_register) & RME9652_ERF) { return -1; /* error condition */ } if (s->hw_rev == 15) { int x, y, ret; x = rme9652_spdif_read_codec (s, 30); if (x != 0) y = 48000 * 64 / x; else y = 0; if (y > 30400 && y < 33600) ret = 32000; else if (y > 41900 && y < 46000) ret = 44100; else if (y > 46000 && y < 50400) ret = 48000; else if (y > 60800 && y < 67200) ret = 64000; else if (y > 83700 && y < 92000) ret = 88200; else if (y > 92000 && y < 100000) ret = 96000; else ret = 0; return ret; } rate_bits = rme9652_read(s, RME9652_status_register) & RME9652_F; switch (rme9652_decode_spdif_rate(rate_bits)) { case 0x7: return 32000; break; case 0x6: return 44100; break; case 0x5: return 48000; break; case 0x4: return 88200; break; case 0x3: return 96000; break; case 0x0: return 64000; break; default: snd_printk("%s: unknown S/PDIF input rate (bits = 0x%x)\n", s->card_name, rate_bits); return 0; break; }}/*----------------------------------------------------------------------------- Control Interface ----------------------------------------------------------------------------*/static u32 snd_rme9652_convert_from_aes(snd_aes_iec958_t *aes){ u32 val = 0; val |= (aes->status[0] & IEC958_AES0_PROFESSIONAL) ? RME9652_PRO : 0; val |= (aes->status[0] & IEC958_AES0_NONAUDIO) ? RME9652_Dolby : 0; if (val & RME9652_PRO) val |= (aes->status[0] & IEC958_AES0_PRO_EMPHASIS_5015) ? RME9652_EMP : 0; else val |= (aes->status[0] & IEC958_AES0_CON_EMPHASIS_5015) ? RME9652_EMP : 0; return val;}static void snd_rme9652_convert_to_aes(snd_aes_iec958_t *aes, u32 val){ aes->status[0] = ((val & RME9652_PRO) ? IEC958_AES0_PROFESSIONAL : 0) | ((val & RME9652_Dolby) ? IEC958_AES0_NONAUDIO : 0); if (val & RME9652_PRO) aes->status[0] |= (val & RME9652_EMP) ? IEC958_AES0_PRO_EMPHASIS_5015 : 0; else aes->status[0] |= (val & RME9652_EMP) ? IEC958_AES0_CON_EMPHASIS_5015 : 0;}static int snd_rme9652_control_spdif_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->count = 1; return 0;}static int snd_rme9652_control_spdif_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif); return 0;}static int snd_rme9652_control_spdif_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); int change; u32 val; val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958); spin_lock_irq(&rme9652->lock); change = val != rme9652->creg_spdif; rme9652->creg_spdif = val; spin_unlock_irq(&rme9652->lock); return change;}static int snd_rme9652_control_spdif_stream_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->count = 1; return 0;}static int snd_rme9652_control_spdif_stream_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); snd_rme9652_convert_to_aes(&ucontrol->value.iec958, rme9652->creg_spdif_stream); return 0;}static int snd_rme9652_control_spdif_stream_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ rme9652_t *rme9652 = snd_kcontrol_chip(kcontrol); int change; u32 val; val = snd_rme9652_convert_from_aes(&ucontrol->value.iec958); spin_lock_irq(&rme9652->lock); change = val != rme9652->creg_spdif_stream; rme9652->creg_spdif_stream = val; rme9652->control_register &= ~(RME9652_PRO | RME9652_Dolby | RME9652_EMP); rme9652_write(rme9652, RME9652_control_register, rme9652->control_register |= val); spin_unlock_irq(&rme9652->lock); return change;}static int snd_rme9652_control_spdif_mask_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo){ uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->count = 1; return 0;}static int snd_rme9652_control_spdif_mask_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol){ ucontrol->value.iec958.status[0] = kcontrol->private_value; return 0;}#define RME9652_ADAT1_IN(xname, xindex) \{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ .info = snd_rme9652_info_adat1_in, \ .get = snd_rme9652_get_adat1_in, \ .put = snd_rme9652_put_adat1_in }static unsigned int rme9652_adat1_in(rme9652_t *rme9652){ if (rme9652->control_register & RME9652_ADAT1_INTERNAL) return 1; return 0;}static int rme9652_set_adat1_input(rme9652_t *rme9652, int internal){ int restart = 0; if (internal) { rme9652->control_register |= RME9652_ADAT1_INTERNAL; } else { rme9652->control_register &= ~RME9652_ADAT1_INTERNAL; } /* XXX do we actually need to stop the card when we do this ? */ if ((restart = rme9652->running)) { rme9652_stop(rme9652); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -