📄 rme96.c
字号:
* edge of CLATCH after the last data bit clocks in the whole data word. * A fast processor could probably drive the SPI interface faster than the * DAC can handle (3MHz for the 1855, unknown for the 1852). The udelay(1) * limits the data rate to 500KHz and only causes a delay of 33 microsecs. * * NOTE: increased delay from 1 to 10, since there where problems setting * the volume. */static voidsnd_rme96_write_SPI(struct rme96 *rme96, u16 val){ int i; for (i = 0; i < 16; i++) { if (val & 0x8000) { rme96->areg |= RME96_AR_CDATA; } else { rme96->areg &= ~RME96_AR_CDATA; } rme96->areg &= ~(RME96_AR_CCLK | RME96_AR_CLATCH); writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); udelay(10); rme96->areg |= RME96_AR_CCLK; writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); udelay(10); val <<= 1; } rme96->areg &= ~(RME96_AR_CCLK | RME96_AR_CDATA); rme96->areg |= RME96_AR_CLATCH; writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); udelay(10); rme96->areg &= ~RME96_AR_CLATCH; writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);}static voidsnd_rme96_apply_dac_volume(struct rme96 *rme96){ if (RME96_DAC_IS_1852(rme96)) { snd_rme96_write_SPI(rme96, (rme96->vol[0] << 2) | 0x0); snd_rme96_write_SPI(rme96, (rme96->vol[1] << 2) | 0x2); } else if (RME96_DAC_IS_1855(rme96)) { snd_rme96_write_SPI(rme96, (rme96->vol[0] & 0x3FF) | 0x000); snd_rme96_write_SPI(rme96, (rme96->vol[1] & 0x3FF) | 0x400); }}static voidsnd_rme96_reset_dac(struct rme96 *rme96){ writel(rme96->wcreg | RME96_WCR_PD, rme96->iobase + RME96_IO_CONTROL_REGISTER); writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);}static intsnd_rme96_getmontracks(struct rme96 *rme96){ return ((rme96->wcreg >> RME96_WCR_BITPOS_MONITOR_0) & 1) + (((rme96->wcreg >> RME96_WCR_BITPOS_MONITOR_1) & 1) << 1);}static intsnd_rme96_setmontracks(struct rme96 *rme96, int montracks){ if (montracks & 1) { rme96->wcreg |= RME96_WCR_MONITOR_0; } else { rme96->wcreg &= ~RME96_WCR_MONITOR_0; } if (montracks & 2) { rme96->wcreg |= RME96_WCR_MONITOR_1; } else { rme96->wcreg &= ~RME96_WCR_MONITOR_1; } writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); return 0;}static intsnd_rme96_getattenuation(struct rme96 *rme96){ return ((rme96->wcreg >> RME96_WCR_BITPOS_GAIN_0) & 1) + (((rme96->wcreg >> RME96_WCR_BITPOS_GAIN_1) & 1) << 1);}static intsnd_rme96_setattenuation(struct rme96 *rme96, int attenuation){ switch (attenuation) { case 0: rme96->wcreg = (rme96->wcreg & ~RME96_WCR_GAIN_0) & ~RME96_WCR_GAIN_1; break; case 1: rme96->wcreg = (rme96->wcreg | RME96_WCR_GAIN_0) & ~RME96_WCR_GAIN_1; break; case 2: rme96->wcreg = (rme96->wcreg & ~RME96_WCR_GAIN_0) | RME96_WCR_GAIN_1; break; case 3: rme96->wcreg = (rme96->wcreg | RME96_WCR_GAIN_0) | RME96_WCR_GAIN_1; break; default: return -EINVAL; } writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); return 0;}static intsnd_rme96_capture_getrate(struct rme96 *rme96, int *is_adat){ int n, rate; *is_adat = 0; if (rme96->areg & RME96_AR_ANALOG) { /* Analog input, overrides S/PDIF setting */ n = ((rme96->areg >> RME96_AR_BITPOS_F0) & 1) + (((rme96->areg >> RME96_AR_BITPOS_F1) & 1) << 1); switch (n) { case 1: rate = 32000; break; case 2: rate = 44100; break; case 3: rate = 48000; break; default: return -1; } return (rme96->areg & RME96_AR_BITPOS_F2) ? rate << 1 : rate; } rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER); if (rme96->rcreg & RME96_RCR_LOCK) { /* ADAT rate */ *is_adat = 1; if (rme96->rcreg & RME96_RCR_T_OUT) { return 48000; } return 44100; } if (rme96->rcreg & RME96_RCR_VERF) { return -1; } /* S/PDIF rate */ n = ((rme96->rcreg >> RME96_RCR_BITPOS_F0) & 1) + (((rme96->rcreg >> RME96_RCR_BITPOS_F1) & 1) << 1) + (((rme96->rcreg >> RME96_RCR_BITPOS_F2) & 1) << 2); switch (n) { case 0: if (rme96->rcreg & RME96_RCR_T_OUT) { return 64000; } return -1; case 3: return 96000; case 4: return 88200; case 5: return 48000; case 6: return 44100; case 7: return 32000; default: break; } return -1;}static intsnd_rme96_playback_getrate(struct rme96 *rme96){ int rate, dummy; if (!(rme96->wcreg & RME96_WCR_MASTER) && snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0) { /* slave clock */ return rate; } rate = ((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_0) & 1) + (((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_1) & 1) << 1); switch (rate) { case 1: rate = 32000; break; case 2: rate = 44100; break; case 3: rate = 48000; break; default: return -1; } return (rme96->wcreg & RME96_WCR_DS) ? rate << 1 : rate;}static intsnd_rme96_playback_setrate(struct rme96 *rme96, int rate){ int ds; ds = rme96->wcreg & RME96_WCR_DS; switch (rate) { case 32000: rme96->wcreg &= ~RME96_WCR_DS; rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_0) & ~RME96_WCR_FREQ_1; break; case 44100: rme96->wcreg &= ~RME96_WCR_DS; rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_1) & ~RME96_WCR_FREQ_0; break; case 48000: rme96->wcreg &= ~RME96_WCR_DS; rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_0) | RME96_WCR_FREQ_1; break; case 64000: rme96->wcreg |= RME96_WCR_DS; rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_0) & ~RME96_WCR_FREQ_1; break; case 88200: rme96->wcreg |= RME96_WCR_DS; rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_1) & ~RME96_WCR_FREQ_0; break; case 96000: rme96->wcreg |= RME96_WCR_DS; rme96->wcreg = (rme96->wcreg | RME96_WCR_FREQ_0) | RME96_WCR_FREQ_1; break; default: return -EINVAL; } if ((!ds && rme96->wcreg & RME96_WCR_DS) || (ds && !(rme96->wcreg & RME96_WCR_DS))) { /* change to/from double-speed: reset the DAC (if available) */ snd_rme96_reset_dac(rme96); } else { writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); } return 0;}static intsnd_rme96_capture_analog_setrate(struct rme96 *rme96, int rate){ switch (rate) { case 32000: rme96->areg = ((rme96->areg | RME96_AR_FREQPAD_0) & ~RME96_AR_FREQPAD_1) & ~RME96_AR_FREQPAD_2; break; case 44100: rme96->areg = ((rme96->areg & ~RME96_AR_FREQPAD_0) | RME96_AR_FREQPAD_1) & ~RME96_AR_FREQPAD_2; break; case 48000: rme96->areg = ((rme96->areg | RME96_AR_FREQPAD_0) | RME96_AR_FREQPAD_1) & ~RME96_AR_FREQPAD_2; break; case 64000: if (rme96->rev < 4) { return -EINVAL; } rme96->areg = ((rme96->areg | RME96_AR_FREQPAD_0) & ~RME96_AR_FREQPAD_1) | RME96_AR_FREQPAD_2; break; case 88200: if (rme96->rev < 4) { return -EINVAL; } rme96->areg = ((rme96->areg & ~RME96_AR_FREQPAD_0) | RME96_AR_FREQPAD_1) | RME96_AR_FREQPAD_2; break; case 96000: rme96->areg = ((rme96->areg | RME96_AR_FREQPAD_0) | RME96_AR_FREQPAD_1) | RME96_AR_FREQPAD_2; break; default: return -EINVAL; } writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); return 0;}static intsnd_rme96_setclockmode(struct rme96 *rme96, int mode){ switch (mode) { case RME96_CLOCKMODE_SLAVE: /* AutoSync */ rme96->wcreg &= ~RME96_WCR_MASTER; rme96->areg &= ~RME96_AR_WSEL; break; case RME96_CLOCKMODE_MASTER: /* Internal */ rme96->wcreg |= RME96_WCR_MASTER; rme96->areg &= ~RME96_AR_WSEL; break; case RME96_CLOCKMODE_WORDCLOCK: /* Word clock is a master mode */ rme96->wcreg |= RME96_WCR_MASTER; rme96->areg |= RME96_AR_WSEL; break; default: return -EINVAL; } writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); return 0;}static intsnd_rme96_getclockmode(struct rme96 *rme96){ if (rme96->areg & RME96_AR_WSEL) { return RME96_CLOCKMODE_WORDCLOCK; } return (rme96->wcreg & RME96_WCR_MASTER) ? RME96_CLOCKMODE_MASTER : RME96_CLOCKMODE_SLAVE;}static intsnd_rme96_setinputtype(struct rme96 *rme96, int type){ int n; switch (type) { case RME96_INPUT_OPTICAL: rme96->wcreg = (rme96->wcreg & ~RME96_WCR_INP_0) & ~RME96_WCR_INP_1; break; case RME96_INPUT_COAXIAL: rme96->wcreg = (rme96->wcreg | RME96_WCR_INP_0) & ~RME96_WCR_INP_1; break; case RME96_INPUT_INTERNAL: rme96->wcreg = (rme96->wcreg & ~RME96_WCR_INP_0) | RME96_WCR_INP_1; break; case RME96_INPUT_XLR: if ((rme96->pci->device != PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && rme96->pci->device != PCI_DEVICE_ID_RME_DIGI96_8_PRO) || (rme96->pci->device == PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST && rme96->rev > 4)) { /* Only Digi96/8 PRO and Digi96/8 PAD supports XLR */ return -EINVAL; } rme96->wcreg = (rme96->wcreg | RME96_WCR_INP_0) | RME96_WCR_INP_1; break; case RME96_INPUT_ANALOG: if (!RME96_HAS_ANALOG_IN(rme96)) { return -EINVAL; } rme96->areg |= RME96_AR_ANALOG; writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); if (rme96->rev < 4) { /* * Revision less than 004 does not support 64 and * 88.2 kHz */ if (snd_rme96_capture_getrate(rme96, &n) == 88200) { snd_rme96_capture_analog_setrate(rme96, 44100); } if (snd_rme96_capture_getrate(rme96, &n) == 64000) { snd_rme96_capture_analog_setrate(rme96, 32000); } } return 0; default: return -EINVAL; } if (type != RME96_INPUT_ANALOG && RME96_HAS_ANALOG_IN(rme96)) { rme96->areg &= ~RME96_AR_ANALOG; writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); } writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); return 0;}static intsnd_rme96_getinputtype(struct rme96 *rme96){ if (rme96->areg & RME96_AR_ANALOG) { return RME96_INPUT_ANALOG; } return ((rme96->wcreg >> RME96_WCR_BITPOS_INP_0) & 1) + (((rme96->wcreg >> RME96_WCR_BITPOS_INP_1) & 1) << 1);}static voidsnd_rme96_setframelog(struct rme96 *rme96, int n_channels, int is_playback){ int frlog; if (n_channels == 2) { frlog = 1; } else { /* assume 8 channels */ frlog = 3; } if (is_playback) { frlog += (rme96->wcreg & RME96_WCR_MODE24) ? 2 : 1; rme96->playback_frlog = frlog; } else { frlog += (rme96->wcreg & RME96_WCR_MODE24_2) ? 2 : 1; rme96->capture_frlog = frlog; }}static intsnd_rme96_playback_setformat(struct rme96 *rme96, int format){ switch (format) { case SNDRV_PCM_FORMAT_S16_LE: rme96->wcreg &= ~RME96_WCR_MODE24; break; case SNDRV_PCM_FORMAT_S32_LE: rme96->wcreg |= RME96_WCR_MODE24; break; default: return -EINVAL; } writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); return 0;}static intsnd_rme96_capture_setformat(struct rme96 *rme96, int format){ switch (format) { case SNDRV_PCM_FORMAT_S16_LE: rme96->wcreg &= ~RME96_WCR_MODE24_2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -