📄 ens1370.c
字号:
unsigned int ctrl; /* control register */ unsigned int sctrl; /* serial control register */ unsigned int cssr; /* control status register */ unsigned int uartc; /* uart control register */ unsigned int rev; /* chip revision */ union {#ifdef CHIP1371 struct { struct snd_ac97 *ac97; } es1371;#else struct { int pclkdiv_lock; struct snd_ak4531 *ak4531; } es1370;#endif } u; struct pci_dev *pci; struct snd_card *card; struct snd_pcm *pcm1; /* DAC1/ADC PCM */ struct snd_pcm *pcm2; /* DAC2 PCM */ struct snd_pcm_substream *playback1_substream; struct snd_pcm_substream *playback2_substream; struct snd_pcm_substream *capture_substream; unsigned int p1_dma_size; unsigned int p2_dma_size; unsigned int c_dma_size; unsigned int p1_period_size; unsigned int p2_period_size; unsigned int c_period_size; struct snd_rawmidi *rmidi; struct snd_rawmidi_substream *midi_input; struct snd_rawmidi_substream *midi_output; unsigned int spdif; unsigned int spdif_default; unsigned int spdif_stream;#ifdef CHIP1370 struct snd_dma_buffer dma_bug;#endif#ifdef SUPPORT_JOYSTICK struct gameport *gameport;#endif};static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id);static struct pci_device_id snd_audiopci_ids[] = {#ifdef CHIP1370 { 0x1274, 0x5000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1370 */#endif#ifdef CHIP1371 { 0x1274, 0x1371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1371 */ { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */ { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */#endif { 0, }};MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);/* * constants */#define POLL_COUNT 0xa000#ifdef CHIP1370static unsigned int snd_es1370_fixed_rates[] = {5512, 11025, 22050, 44100};static struct snd_pcm_hw_constraint_list snd_es1370_hw_constraints_rates = { .count = 4, .list = snd_es1370_fixed_rates, .mask = 0,};static struct snd_ratnum es1370_clock = { .num = ES_1370_SRCLOCK, .den_min = 29, .den_max = 353, .den_step = 1,};static struct snd_pcm_hw_constraint_ratnums snd_es1370_hw_constraints_clock = { .nrats = 1, .rats = &es1370_clock,};#elsestatic struct snd_ratden es1371_dac_clock = { .num_min = 3000 * (1 << 15), .num_max = 48000 * (1 << 15), .num_step = 3000, .den = 1 << 15,};static struct snd_pcm_hw_constraint_ratdens snd_es1371_hw_constraints_dac_clock = { .nrats = 1, .rats = &es1371_dac_clock,};static struct snd_ratnum es1371_adc_clock = { .num = 48000 << 15, .den_min = 32768, .den_max = 393216, .den_step = 1,};static struct snd_pcm_hw_constraint_ratnums snd_es1371_hw_constraints_adc_clock = { .nrats = 1, .rats = &es1371_adc_clock,};#endifstatic const unsigned int snd_ensoniq_sample_shift[] = {0, 1, 1, 2};/* * common I/O routines */#ifdef CHIP1371static unsigned int snd_es1371_wait_src_ready(struct ensoniq * ensoniq){ unsigned int t, r = 0; for (t = 0; t < POLL_COUNT; t++) { r = inl(ES_REG(ensoniq, 1371_SMPRATE)); if ((r & ES_1371_SRC_RAM_BUSY) == 0) return r; cond_resched(); } snd_printk(KERN_ERR "wait source ready timeout 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_SMPRATE), r); return 0;}static unsigned int snd_es1371_src_read(struct ensoniq * ensoniq, unsigned short reg){ unsigned int temp, i, orig, r; /* wait for ready */ temp = orig = snd_es1371_wait_src_ready(ensoniq); /* expose the SRC state bits */ r = temp & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_P2 | ES_1371_DIS_R1); r |= ES_1371_SRC_RAM_ADDRO(reg) | 0x10000; outl(r, ES_REG(ensoniq, 1371_SMPRATE)); /* now, wait for busy and the correct time to read */ temp = snd_es1371_wait_src_ready(ensoniq); if ((temp & 0x00870000) != 0x00010000) { /* wait for the right state */ for (i = 0; i < POLL_COUNT; i++) { temp = inl(ES_REG(ensoniq, 1371_SMPRATE)); if ((temp & 0x00870000) == 0x00010000) break; } } /* hide the state bits */ r = orig & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_P2 | ES_1371_DIS_R1); r |= ES_1371_SRC_RAM_ADDRO(reg); outl(r, ES_REG(ensoniq, 1371_SMPRATE)); return temp;}static void snd_es1371_src_write(struct ensoniq * ensoniq, unsigned short reg, unsigned short data){ unsigned int r; r = snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_P2 | ES_1371_DIS_R1); r |= ES_1371_SRC_RAM_ADDRO(reg) | ES_1371_SRC_RAM_DATAO(data); outl(r | ES_1371_SRC_RAM_WE, ES_REG(ensoniq, 1371_SMPRATE));}#endif /* CHIP1371 */#ifdef CHIP1370static void snd_es1370_codec_write(struct snd_ak4531 *ak4531, unsigned short reg, unsigned short val){ struct ensoniq *ensoniq = ak4531->private_data; unsigned long end_time = jiffies + HZ / 10;#if 0 printk("CODEC WRITE: reg = 0x%x, val = 0x%x (0x%x), creg = 0x%x\n", reg, val, ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC));#endif do { if (!(inl(ES_REG(ensoniq, STATUS)) & ES_1370_CSTAT)) { outw(ES_1370_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1370_CODEC)); return; } schedule_timeout_uninterruptible(1); } while (time_after(end_time, jiffies)); snd_printk(KERN_ERR "codec write timeout, status = 0x%x\n", inl(ES_REG(ensoniq, STATUS)));}#endif /* CHIP1370 */#ifdef CHIP1371static void snd_es1371_codec_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val){ struct ensoniq *ensoniq = ac97->private_data; unsigned int t, x; mutex_lock(&ensoniq->src_mutex); for (t = 0; t < POLL_COUNT; t++) { if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { /* save the current state for latter */ x = snd_es1371_wait_src_ready(ensoniq); outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000, ES_REG(ensoniq, 1371_SMPRATE)); /* wait for not busy (state 0) first to avoid transition states */ for (t = 0; t < POLL_COUNT; t++) { if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) == 0x00000000) break; } /* wait for a SAFE time to write addr/data and then do it, dammit */ for (t = 0; t < POLL_COUNT; t++) { if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) == 0x00010000) break; } outl(ES_1371_CODEC_WRITE(reg, val), ES_REG(ensoniq, 1371_CODEC)); /* restore SRC reg */ snd_es1371_wait_src_ready(ensoniq); outl(x, ES_REG(ensoniq, 1371_SMPRATE)); mutex_unlock(&ensoniq->src_mutex); return; } } mutex_unlock(&ensoniq->src_mutex); snd_printk(KERN_ERR "codec write timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC)));}static unsigned short snd_es1371_codec_read(struct snd_ac97 *ac97, unsigned short reg){ struct ensoniq *ensoniq = ac97->private_data; unsigned int t, x, fail = 0; __again: mutex_lock(&ensoniq->src_mutex); for (t = 0; t < POLL_COUNT; t++) { if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) { /* save the current state for latter */ x = snd_es1371_wait_src_ready(ensoniq); outl((x & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_P2 | ES_1371_DIS_R1)) | 0x00010000, ES_REG(ensoniq, 1371_SMPRATE)); /* wait for not busy (state 0) first to avoid transition states */ for (t = 0; t < POLL_COUNT; t++) { if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) == 0x00000000) break; } /* wait for a SAFE time to write addr/data and then do it, dammit */ for (t = 0; t < POLL_COUNT; t++) { if ((inl(ES_REG(ensoniq, 1371_SMPRATE)) & 0x00870000) == 0x00010000) break; } outl(ES_1371_CODEC_READS(reg), ES_REG(ensoniq, 1371_CODEC)); /* restore SRC reg */ snd_es1371_wait_src_ready(ensoniq); outl(x, ES_REG(ensoniq, 1371_SMPRATE)); /* wait for WIP again */ for (t = 0; t < POLL_COUNT; t++) { if (!(inl(ES_REG(ensoniq, 1371_CODEC)) & ES_1371_CODEC_WIP)) break; } /* now wait for the stinkin' data (RDY) */ for (t = 0; t < POLL_COUNT; t++) { if ((x = inl(ES_REG(ensoniq, 1371_CODEC))) & ES_1371_CODEC_RDY) { mutex_unlock(&ensoniq->src_mutex); return ES_1371_CODEC_READ(x); } } mutex_unlock(&ensoniq->src_mutex); if (++fail > 10) { snd_printk(KERN_ERR "codec read timeout (final) " "at 0x%lx, reg = 0x%x [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), reg, inl(ES_REG(ensoniq, 1371_CODEC))); return 0; } goto __again; } } mutex_unlock(&ensoniq->src_mutex); snd_printk(KERN_ERR "es1371: codec read timeout at 0x%lx [0x%x]\n", ES_REG(ensoniq, 1371_CODEC), inl(ES_REG(ensoniq, 1371_CODEC))); return 0;}static void snd_es1371_codec_wait(struct snd_ac97 *ac97){ msleep(750); snd_es1371_codec_read(ac97, AC97_RESET); snd_es1371_codec_read(ac97, AC97_VENDOR_ID1); snd_es1371_codec_read(ac97, AC97_VENDOR_ID2); msleep(50);}static void snd_es1371_adc_rate(struct ensoniq * ensoniq, unsigned int rate){ unsigned int n, truncm, freq, result; mutex_lock(&ensoniq->src_mutex); n = rate / 3000; if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9))) n--; truncm = (21 * n - 1) | 1; freq = ((48000UL << 15) / rate) * n; result = (48000UL << 15) / (freq / n); if (rate >= 24000) { if (truncm > 239) truncm = 239; snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N, (((239 - truncm) >> 1) << 9) | (n << 4)); } else { if (truncm > 119) truncm = 119; snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_TRUNC_N, 0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4)); } snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_INT_REGS, (snd_es1371_src_read(ensoniq, ES_SMPREG_ADC + ES_SMPREG_INT_REGS) & 0x00ff) | ((freq >> 5) & 0xfc00)); snd_es1371_src_write(ensoniq, ES_SMPREG_ADC + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff); snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC, n << 8); snd_es1371_src_write(ensoniq, ES_SMPREG_VOL_ADC + 1, n << 8); mutex_unlock(&ensoniq->src_mutex);}static void snd_es1371_dac1_rate(struct ensoniq * ensoniq, unsigned int rate){ unsigned int freq, r; mutex_lock(&ensoniq->src_mutex); freq = ((rate << 15) + 1500) / 3000; r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P2 | ES_1371_DIS_R1)) | ES_1371_DIS_P1; outl(r, ES_REG(ensoniq, 1371_SMPRATE)); snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS, (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_INT_REGS) & 0x00ff) | ((freq >> 5) & 0xfc00)); snd_es1371_src_write(ensoniq, ES_SMPREG_DAC1 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff); r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P2 | ES_1371_DIS_R1)); outl(r, ES_REG(ensoniq, 1371_SMPRATE)); mutex_unlock(&ensoniq->src_mutex);}static void snd_es1371_dac2_rate(struct ensoniq * ensoniq, unsigned int rate){ unsigned int freq, r; mutex_lock(&ensoniq->src_mutex); freq = ((rate << 15) + 1500) / 3000; r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_R1)) | ES_1371_DIS_P2; outl(r, ES_REG(ensoniq, 1371_SMPRATE)); snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS, (snd_es1371_src_read(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_INT_REGS) & 0x00ff) | ((freq >> 5) & 0xfc00)); snd_es1371_src_write(ensoniq, ES_SMPREG_DAC2 + ES_SMPREG_VFREQ_FRAC, freq & 0x7fff); r = (snd_es1371_wait_src_ready(ensoniq) & (ES_1371_SRC_DISABLE | ES_1371_DIS_P1 | ES_1371_DIS_R1)); outl(r, ES_REG(ensoniq, 1371_SMPRATE)); mutex_unlock(&ensoniq->src_mutex);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -