void ACAudioHWContext::InitCodecPort() { UINT16 uiTmp; DEBUGMSG(ZONE_AC, (L"+ACAudioHWContext::InitCodecPort()\r\n")); // power down everything TSC2101Write(m_hSPI, TSC2101_AUDCTRL_POWER, CPC_MBIAS_HND | CPC_MBIAS_HED | CPC_ASTPWD | CPC_SP1PWDN | CPC_SP2PWDN | CPC_DAPWDN | CPC_ADPWDN | CPC_VGPWDN | CPC_COPWDN | CPC_LSPWDN); // headset input not muted, AGC for Headset In off TSC2101Write(m_hSPI, TSC2101_AUDCTRL_HEADSET, HGC_ADPGA_HED(0x7F)); // handset input not muted, AGC for Handset In off TSC2101Write(m_hSPI, TSC2101_AUDCTRL_HANDSET, HNGC_ADPGA_HND(0x7F)); // mute analog sidetone, select MIC_INHED input for headset // Cell Phone In not connected TSC2101Write(m_hSPI, TSC2101_AUDCTRL_MIXER, MPC_ASTMU | MPC_ASTG(0x600) | MPC_MICADC | MPC_MICSEL(1)); // ADC, DAC, Analog Sidetone, cellphone, buzzer // softstepping enabled, 1dB AGC hysteresis, MICes bias 2V TSC2101Write(m_hSPI, TSC2101_AUDCTRL_4, AC4_MB_HED(0)); // Set codec output volume TSC2101Write(m_hSPI, TSC2101_AUDCTRL_DAC, DGC_DALVL(0) | DGC_DARVL(0)); // DAC left and right routed to SPK2, SPK1/2 unmuted TSC2101Write(m_hSPI, TSC2101_AUDCTRL_5, AC5_DAC2SPK1(3) | AC5_AST2SPK1 | AC5_KCL2SPK1 | AC5_DAC2SPK2(3) | AC5_AST2SPK2 | AC5_KCL2SPK2 | AC5_HDSCPTC); // OUT8P/N muted, CPOUT muted // TSC2101Write(m_hSPI, TSC2101_AUDCTRL_6, AC6_MUTSPK2 | TSC2101Write(m_hSPI, TSC2101_AUDCTRL_6, AC6_MUTSPK2 | AC6_SPL2LSK | AC6_AST2LSK | AC6_LDSCPTC | AC6_VGNDSCPTC); // Headset/Hook switch detect disabled TSC2101Write(m_hSPI, TSC2101_AUDCTRL_7, 0); // set I2S, word length, and reference sampling rate (RFS) divisor if (BITSPERSAMPLE == 20) uiTmp = 1; else if (BITSPERSAMPLE == 24) uiTmp = 2; else if (BITSPERSAMPLE == 32) uiTmp = 3; else uiTmp = 0; TSC2101Write(m_hSPI, TSC2101_AUDCTRL_1, AC1_WLEN(uiTmp) | AC1_DACFS(0) | AC1_ADCFS(0)); // make the TSC2101 the master vs. the McBSP, set the RFS to 44100 or 48000 uiTmp = AC3_SLVMS | ((SAMPLERATE == 44100) ? AC3_REFFS : 0); TSC2101Write(m_hSPI, TSC2101_AUDCTRL_3, uiTmp); // program the PLL's if (SAMPLERATE == 44100) { // 44.1 KHz, 12 MHz MCLK, 5264 D_VAL TSC2101Write(m_hSPI, TSC2101_AUDCTRL_PLL0, PLL1_PLLSEL | PLL1_PVAL(1) | PLL1_I_VAL(7)); TSC2101Write(m_hSPI, TSC2101_AUDCTRL_PLL1, PLL2_D_VAL(5264)); } else { // 48 KHz, 12 MHz MCLK, 1920 D_VAL TSC2101Write(m_hSPI, TSC2101_AUDCTRL_PLL0, PLL1_PLLSEL | PLL1_PVAL(1) | PLL1_I_VAL(8)); TSC2101Write(m_hSPI, TSC2101_AUDCTRL_PLL1, PLL2_D_VAL(1920)); } // go into idle mode and configure the clocks OUTREG16(&m_pMCBSPRegisters->usMCBSP_PCR, MCBSP_IDLEEN | MCBSP_CLKRM | MCBSP_SCLKME | MCBSP_FSXP | MCBSP_FSRP | MCBSP_CLKXP | MCBSP_CLKRP); if (BITSPERSAMPLE == 20) uiTmp = MCBSP_WORD_20; else if (BITSPERSAMPLE == 24) uiTmp = MCBSP_WORD_24; else if (BITSPERSAMPLE == 32) uiTmp = MCBSP_WORD_32; else uiTmp = MCBSP_WORD_16; // receive 1 word of BITSPERSAMPLE in a frame, // in 2 phases (1 word each) with a 1-bit delay OUTREG16(&m_pMCBSPRegisters->usMCBSP_RCR1, MCBSP_RFRLEN1(0) | MCBSP_RWDLEN1(uiTmp)); OUTREG16(&m_pMCBSPRegisters->usMCBSP_RCR2, MCBSP_RPHASE | MCBSP_RFRLEN2(0) | MCBSP_RWDLEN2(uiTmp) | MCBSP_RDATDLY(1)); // transmit 1 word of BITSPERSAMPLE in a frame, // in 2 phases (1 word each) with a 1-bit delay OUTREG16(&m_pMCBSPRegisters->usMCBSP_XCR1, MCBSP_XFRLEN1(0) | MCBSP_XWDLEN1(uiTmp)); OUTREG16(&m_pMCBSPRegisters->usMCBSP_XCR2, MCBSP_XPHASE | MCBSP_XFRLEN2(0) | MCBSP_XWDLEN2(uiTmp) | MCBSP_XDATDLY(1) | MCBSP_XFIG); // set the clocks OUTREG16(&m_pMCBSPRegisters->usMCBSP_SRGR1, MCBSP_FWID(BITSPERSAMPLE - 1) | MCBSP_CLKGDV(0)); OUTREG16(&m_pMCBSPRegisters->usMCBSP_SRGR2, MCBSP_GSYNC | MCBSP_CLKSP | MCBSP_FSGM | MCBSP_FPER(BITSPERSAMPLE * 2 - 1)); //Left Justify, Clockstop with no delay, Receiver Disabled OUTREG16(&m_pMCBSPRegisters->usMCBSP_SPCR1, MCBSP_RINTM(3)); // Set transmit interrupt on XSYNCERR. OUTREG16(&m_pMCBSPRegisters->usMCBSP_SPCR2, MCBSP_FREE | MCBSP_XINTM(3)); // Delay while new divisors take effect. Sleep(100); }
/* * Sample rate changing */ void tsc2101_set_samplerate(long sample_rate) { u8 count = 0; u16 data = 0; int clkgdv = 0; u16 srgr1, srgr2; /* wait for any frame to complete */ udelay(125); ADEBUG(); sample_rate = sample_rate; /* Search for the right sample rate */ while ((rate_reg_info[count].sample_rate != sample_rate) && (count < NUMBER_SAMPLE_RATES_SUPPORTED)) { count++; } if (count == NUMBER_SAMPLE_RATES_SUPPORTED) { printk(KERN_ERR "Invalid Sample Rate %d requested\n", (int) sample_rate); return; // -EPERM; } /* Set AC1 */ data = tsc2101_audio_read(TSC2101_AUDIO_CTRL_1); /* Clear prev settings */ data &= ~(AC1_DACFS(0x07) | AC1_ADCFS(0x07)); data |= AC1_DACFS(rate_reg_info[count].divisor) | AC1_ADCFS(rate_reg_info[count].divisor); tsc2101_audio_write(TSC2101_AUDIO_CTRL_1, data); /* Set the AC3 */ data = tsc2101_audio_read(TSC2101_AUDIO_CTRL_3); /*Clear prev settings */ data &= ~(AC3_REFFS | AC3_SLVMS); data |= (rate_reg_info[count].fs_44kHz) ? AC3_REFFS : 0; #ifdef TSC_MASTER data |= AC3_SLVMS; #endif /* #ifdef TSC_MASTER */ tsc2101_audio_write(TSC2101_AUDIO_CTRL_3, data); /* Program the PLLs. This code assumes that the 12 Mhz MCLK is in use. * If MCLK rate is something else, these values must be changed. * See the tsc2101 specification for the details. */ if (rate_reg_info[count].fs_44kHz) { /* samplerate = (44.1kHZ / x), where x is int. */ tsc2101_audio_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL | PLL1_PVAL(1) | PLL1_I_VAL(7)); /* PVAL 1; I_VAL 7 */ tsc2101_audio_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x1490)); /* D_VAL 5264 */ } else { /* samplerate = (48.kHZ / x), where x is int. */ tsc2101_audio_write(TSC2101_PLL_PROG_1, PLL1_PLLSEL | PLL1_PVAL(1) | PLL1_I_VAL(8)); /* PVAL 1; I_VAL 8 */ tsc2101_audio_write(TSC2101_PLL_PROG_2, PLL2_D_VAL(0x780)); /* D_VAL 1920 */ } /* Set the sample rate */ #ifndef TSC_MASTER clkgdv = CODEC_CLOCK / (sample_rate * (DEFAULT_BITPERSAMPLE * 2 - 1)); if (clkgdv) srgr1 = (FWID(DEFAULT_BITPERSAMPLE - 1) | CLKGDV(clkgdv)); else return (1); /* Stereo Mode */ srgr2 = (CLKSM | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1)); #else srgr1 = (FWID(DEFAULT_BITPERSAMPLE - 1) | CLKGDV(clkgdv)); srgr2 = ((GSYNC | CLKSP | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1))); #endif /* end of #ifdef TSC_MASTER */ OMAP_MCBSP_WRITE(OMAP1610_MCBSP1_BASE, SRGR2, srgr2); OMAP_MCBSP_WRITE(OMAP1610_MCBSP1_BASE, SRGR1, srgr1); }