📄 cs4281m.c
字号:
// pm->u32DacASR = readl(s->pBA0 + BA0_PASR); pm->u32AdcASR = readl(s->pBA0 + BA0_CASR); pm->u32DacSR = readl(s->pBA0 + BA0_DACSR); pm->u32AdcSR = readl(s->pBA0 + BA0_ADCSR); // // Loop through all of the PipeLines // for(i = 0; i < CS4281_NUMBER_OF_PIPELINES; i++) { if(s->pl[i].flags & CS4281_PIPELINE_VALID) { // // Ask the DMAengines and FIFOs to Suspend. // cs4281_SuspendDMAengine(s,&s->pl[i]); cs4281_SuspendFIFO(s,&s->pl[i]); } } // // We need to save the contents of the Midi Control Register. // pm->u32MIDCR_Save = readl(s->pBA0 + BA0_MIDCR);/** save off the AC97 part information*/ cs4281_ac97_suspend(s); // // Turn off the serial ports. // writel(0, s->pBA0 + BA0_SERMC); // // Power off FM, Joystick, AC link, // writel(0, s->pBA0 + BA0_SSPM); // // DLL off. // writel(0, s->pBA0 + BA0_CLKCR1); // // AC link off. // writel(0, s->pBA0 + BA0_SPMC); // // Put the chip into D3(hot) state. // // PokeBA0(BA0_PMCS, 0x00000003); // // Gershwin CLKRUN - Clear CKRA // u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1); writel(u32CLKCR1 & 0xFFFEFFFF, s->pBA0 + BA0_CLKCR1);#ifdef CSDEBUG printpm(s); printpipelines(s);#endif s->pm.flags &= ~CS4281_PM_SUSPENDING; s->pm.flags |= CS4281_PM_SUSPENDED; CS_DBGOUT(CS_PM | CS_FUNCTION, 9, printk("cs4281: cs4281_suspend()- flags=%d\n", (unsigned)s->pm.flags)); return 0;}static int cs4281_resume(struct cs4281_state *s){ int i; unsigned temp1; u32 u32CLKCR1; struct cs4281_pm *pm = &s->pm; CS_DBGOUT(CS_PM | CS_FUNCTION, 4, printk( "cs4281: cs4281_resume()+ flags=%d\n", (unsigned)s->pm.flags)); if(!(s->pm.flags & CS4281_PM_SUSPENDED)) { CS_DBGOUT(CS_PM | CS_ERROR, 2, printk("cs4281: cs4281_resume() unable to resume, not SUSPENDED\n")); return 1; } s->pm.flags &= ~CS4281_PM_SUSPENDED; s->pm.flags |= CS4281_PM_RESUMING;//// Gershwin CLKRUN - Set CKRA// u32CLKCR1 = readl(s->pBA0 + BA0_CLKCR1); writel(u32CLKCR1 | 0x00010000, s->pBA0 + BA0_CLKCR1); // // set the power state. // //old PokeBA0(BA0_PMCS, 0); // // Program the clock circuit and serial ports. // temp1 = cs4281_hw_init(s); if (temp1) { CS_DBGOUT(CS_ERROR | CS_INIT, 1, printk(KERN_ERR "cs4281: resume cs4281_hw_init() error.\n")); return -1; } // // restore the Power state // writel(pm->u32SSPMValue, s->pBA0 + BA0_SSPM); // // Set post SRC mix setting (FM or ALT48K) // writel(pm->u32SSPM_BITS, s->pBA0 + BA0_SSPM); // // Loop through all of the PipeLines // for(i = 0; i < CS4281_NUMBER_OF_PIPELINES; i++) { if(s->pl[i].flags & CS4281_PIPELINE_VALID) { // // Ask the DMAengines and FIFOs to Resume. // cs4281_ResumeDMAengine(s,&s->pl[i]); cs4281_ResumeFIFO(s,&s->pl[i]); } } // // We need to restore the contents of the Midi Control Register. // writel(pm->u32MIDCR_Save, s->pBA0 + BA0_MIDCR); cs4281_ac97_resume(s); // // Restore the PCM Playback Left and Right Volume Control. // writel(pm->u32PPLVCvalue, s->pBA0 + BA0_PPLVC); writel(pm->u32PPRVCvalue, s->pBA0 + BA0_PPRVC); // // Restore the FM Synthesis Left and Right Volume Control. // writel(pm->u32FMLVCvalue, s->pBA0 + BA0_FMLVC); writel(pm->u32FMRVCvalue, s->pBA0 + BA0_FMRVC); // // Restore the JSCTL value. // writel(pm->u32JSCTLvalue, s->pBA0 + BA0_JSCTL); // // Restore the GPIOR register value. // writel(pm->u32GPIORvalue, s->pBA0 + BA0_GPIOR); // // Restore Sound System Control Register // writel(pm->u32SSCR, s->pBA0 + BA0_SSCR); // // Restore SRC Slot Assignment register // writel(pm->u32SRCSA, s->pBA0 + BA0_SRCSA); // // Restore sample rate // writel(pm->u32DacASR, s->pBA0 + BA0_PASR); writel(pm->u32AdcASR, s->pBA0 + BA0_CASR); writel(pm->u32DacSR, s->pBA0 + BA0_DACSR); writel(pm->u32AdcSR, s->pBA0 + BA0_ADCSR); // // Restore CFL1/2 registers we saved to compensate for OEM bugs. // // PokeBA0(BA0_CFLR, ulConfig); // // Gershwin CLKRUN - Clear CKRA // writel(pm->u32CLKCR1_SAVE, s->pBA0 + BA0_CLKCR1); // // Enable interrupts on the part. // writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR);#ifdef CSDEBUG printpm(s); printpipelines(s);#endif/** change the state, restore the current hwptrs, then stop the dac/adc*/ s->pm.flags |= CS4281_PM_IDLE; s->pm.flags &= ~(CS4281_PM_SUSPENDING | CS4281_PM_SUSPENDED | CS4281_PM_RESUMING | CS4281_PM_RESUMED); writel(s->pm.u32hwptr_playback, s->pBA0 + BA0_DCA0); writel(s->pm.u32hwptr_capture, s->pBA0 + BA0_DCA1); start_dac(s); start_adc(s); CS_DBGOUT(CS_PM | CS_FUNCTION, 9, printk("cs4281: cs4281_resume()- flags=%d\n", (unsigned)s->pm.flags)); return 0;}#endif//******************************************************************************// "cs4281_play_rate()" --//******************************************************************************static void cs4281_play_rate(struct cs4281_state *card, u32 playrate){ u32 DACSRvalue = 1; // Based on the sample rate, program the DACSR register. if (playrate == 8000) DACSRvalue = 5; if (playrate == 11025) DACSRvalue = 4; else if (playrate == 22050) DACSRvalue = 2; else if (playrate == 44100) DACSRvalue = 1; else if ((playrate <= 48000) && (playrate >= 6023)) DACSRvalue = 24576000 / (playrate * 16); else if (playrate < 6023) // Not allowed by open. return; else if (playrate > 48000) // Not allowed by open. return; CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 2, printk(KERN_INFO "cs4281: cs4281_play_rate(): DACSRvalue=0x%.8x playrate=%d\n", DACSRvalue, playrate)); // Write the 'sample rate select code' // to the 'DAC Sample Rate' register. writel(DACSRvalue, card->pBA0 + BA0_DACSR); // (744h)}//******************************************************************************// "cs4281_record_rate()" -- Initialize the record sample rate converter.//******************************************************************************static void cs4281_record_rate(struct cs4281_state *card, u32 outrate){ u32 ADCSRvalue = 1; // // Based on the sample rate, program the ADCSR register // if (outrate == 8000) ADCSRvalue = 5; if (outrate == 11025) ADCSRvalue = 4; else if (outrate == 22050) ADCSRvalue = 2; else if (outrate == 44100) ADCSRvalue = 1; else if ((outrate <= 48000) && (outrate >= 6023)) ADCSRvalue = 24576000 / (outrate * 16); else if (outrate < 6023) { // Not allowed by open. return; } else if (outrate > 48000) { // Not allowed by open. return; } CS_DBGOUT(CS_WAVE_READ | CS_PARMS, 2, printk(KERN_INFO "cs4281: cs4281_record_rate(): ADCSRvalue=0x%.8x outrate=%d\n", ADCSRvalue, outrate)); // Write the 'sample rate select code // to the 'ADC Sample Rate' register. writel(ADCSRvalue, card->pBA0 + BA0_ADCSR); // (748h)}static void stop_dac(struct cs4281_state *s){ unsigned long flags; unsigned temp1; CS_DBGOUT(CS_WAVE_WRITE, 3, printk(KERN_INFO "cs4281: stop_dac():\n")); spin_lock_irqsave(&s->lock, flags); s->ena &= ~FMODE_WRITE; temp1 = readl(s->pBA0 + BA0_DCR0) | DCRn_MSK; writel(temp1, s->pBA0 + BA0_DCR0); spin_unlock_irqrestore(&s->lock, flags);}static void start_dac(struct cs4281_state *s){ unsigned long flags; unsigned temp1; CS_DBGOUT(CS_FUNCTION, 3, printk(KERN_INFO "cs4281: start_dac()+\n")); spin_lock_irqsave(&s->lock, flags); if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped || (s->dma_dac.count > 0 && s->dma_dac.ready))#ifndef NOT_CS4281_PM && (s->pm.flags & CS4281_PM_IDLE))#else)#endif { s->ena |= FMODE_WRITE; temp1 = readl(s->pBA0 + BA0_DCR0) & ~DCRn_MSK; // Clear DMA0 channel mask. writel(temp1, s->pBA0 + BA0_DCR0); // Start DMA'ing. writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR); // Enable interrupts. writel(7, s->pBA0 + BA0_PPRVC); writel(7, s->pBA0 + BA0_PPLVC); CS_DBGOUT(CS_WAVE_WRITE | CS_PARMS, 8, printk(KERN_INFO "cs4281: start_dac(): writel 0x%x start dma\n", temp1)); } spin_unlock_irqrestore(&s->lock, flags); CS_DBGOUT(CS_FUNCTION, 3, printk(KERN_INFO "cs4281: start_dac()-\n"));}static void stop_adc(struct cs4281_state *s){ unsigned long flags; unsigned temp1; CS_DBGOUT(CS_FUNCTION, 3, printk(KERN_INFO "cs4281: stop_adc()+\n")); spin_lock_irqsave(&s->lock, flags); s->ena &= ~FMODE_READ; if (s->conversion == 1) { s->conversion = 0; s->prop_adc.fmt = s->prop_adc.fmt_original; } temp1 = readl(s->pBA0 + BA0_DCR1) | DCRn_MSK; writel(temp1, s->pBA0 + BA0_DCR1); spin_unlock_irqrestore(&s->lock, flags); CS_DBGOUT(CS_FUNCTION, 3, printk(KERN_INFO "cs4281: stop_adc()-\n"));}static void start_adc(struct cs4281_state *s){ unsigned long flags; unsigned temp1; CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO "cs4281: start_adc()+\n")); if (!(s->ena & FMODE_READ) && (s->dma_adc.mapped || s->dma_adc.count <= (signed) (s->dma_adc.dmasize - 2 * s->dma_adc.fragsize)) && s->dma_adc.ready#ifndef NOT_CS4281_PM && (s->pm.flags & CS4281_PM_IDLE))#else) #endif { if (s->prop_adc.fmt & AFMT_S8 || s->prop_adc.fmt & AFMT_U8) { // // now only use 16 bit capture, due to truncation issue // in the chip, noticable distortion occurs. // allocate buffer and then convert from 16 bit to // 8 bit for the user buffer. // s->prop_adc.fmt_original = s->prop_adc.fmt; if (s->prop_adc.fmt & AFMT_S8) { s->prop_adc.fmt &= ~AFMT_S8; s->prop_adc.fmt |= AFMT_S16_LE; } if (s->prop_adc.fmt & AFMT_U8) { s->prop_adc.fmt &= ~AFMT_U8; s->prop_adc.fmt |= AFMT_U16_LE; } // // prog_dmabuf_adc performs a stop_adc() but that is // ok since we really haven't started the DMA yet. // prog_codec(s, CS_TYPE_ADC); if (prog_dmabuf_adc(s) != 0) { CS_DBGOUT(CS_ERROR, 2, printk(KERN_INFO "cs4281: start_adc(): error in prog_dmabuf_adc\n")); } s->conversion = 1; } spin_lock_irqsave(&s->lock, flags); s->ena |= FMODE_READ; temp1 = readl(s->pBA0 + BA0_DCR1) & ~DCRn_MSK; // Clear DMA1 channel mask bit. writel(temp1, s->pBA0 + BA0_DCR1); // Start recording writel(HICR_IEV | HICR_CHGM, s->pBA0 + BA0_HICR); // Enable interrupts. spin_unlock_irqrestore(&s->lock, flags); CS_DBGOUT(CS_PARMS, 6, printk(KERN_INFO "cs4281: start_adc(): writel 0x%x \n", temp1)); } CS_DBGOUT(CS_FUNCTION, 2, printk(KERN_INFO "cs4281: start_adc()-\n"));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -