static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai, int div_id, int div) { struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); struct omap_mcbsp_reg_cfg *regs = &mcbsp->cfg_regs; if (div_id != OMAP_MCBSP_CLKGDV) return -ENODEV; mcbsp->clk_div = div; regs->srgr1 &= ~CLKGDV(0xff); regs->srgr1 |= CLKGDV(div - 1); return 0; }
static void omap1610_set_samplerate(long val) { int divisor = 0; int fs_44kHz = 0; /* We don't want to mess with clocks when frames are in flight */ /* TODO - could call omap1510_dma_flush_all, or could poll on enable bit to wait for DMA writes to stop. */ /* wait for any frame to complete */ udelay(125); DPRINTK(__FUNCTION__ " %d\n", val); /* * We have the following clock sources: * 12.000 MHz * * Available sampling rates: * 48kHz, 44.1kHz, 32kHz, 29.4kHz, 24kHz, * 22 kHz, 16 kHz, 14.7kHz, 12kHz, 11kHz, * 9.6kHz, 8.8kHz, 8kHz, (7.3kHz) * Won't bother supporting those in (). */ if (val >= 48000) { val = 48000; fs_44kHz=0; divisor=0; /* division to 1 */ } else if (val >= 44100) { val = 44100; fs_44kHz=1; divisor=0; /* division to 1 */ } else if (val >= 32000) { val = 32000; fs_44kHz=0; divisor=1; /* division to 1.5 */ } else if (val >= 29400) { val = 29400; fs_44kHz=1; divisor=1; /* division to 1.5 */ } else if (val >= 24000) { val = 24000; fs_44kHz=0; divisor=2; /* division to 2 */ } else if (val >= 22050) { val = 22050; fs_44kHz=1; divisor=2; /* division to 2 */ } else if (val >= 16000) { val = 16000; fs_44kHz=0; divisor=3; /* division to 3 */ } else if (val >= 14700) { val = 14700; fs_44kHz=1; divisor=3; /* division to 3 */ } else if (val >= 12000) { val = 12000; fs_44kHz=0; divisor=4; /* division to 4 */ } else if (val >= 11025) { val = 11025; fs_44kHz=1; divisor=4; /* division to 4 */ } else if (val >= 9600) { val = 9600; fs_44kHz=0; divisor=5; /* division to 5 */ } else if (val >= 8820) { val = 8820; fs_44kHz=1; divisor=5; /* division to 5 */ } else if( val >= 8000) { val = 8000; fs_44kHz=0; divisor=7; /* division to 6 */ } else { val = 7350; fs_44kHz=1; divisor=7; /* division to 6 */ } omap1610_tsc2101_write(TSC2101_AUDIO_CTRL_3, (fs_44kHz<<13)|(1<<11)); omap1610_tsc2101_write(TSC2101_AUDIO_CTRL_1, (divisor<<3)|divisor); if(fs_44kHz) { /* pll enable, P, J */ omap1610_tsc2101_write(TSC2101_PLL_PROG_1, (1<<15)|(1<<8)|(7<<2)); /* D (NB: in decimal!) */ omap1610_tsc2101_write(TSC2101_PLL_PROG_2, 5264<<2); } else { omap1610_tsc2101_write(TSC2101_PLL_PROG_1, (1<<15)|(1<<8)|(8<<2)); omap1610_tsc2101_write(TSC2101_PLL_PROG_2, 1920<<2); } #ifdef MCBSP_I2S_MASTER /* Set Sample Rate at McBSP Formula : Codec System Clock = CODEC_CLOCK, or half if clock_divider = 1; clkgdv = ((Codec System Clock / (SampleRate * BitsPerSample * 2)) - 1); FWID = BitsPerSample - 1; FPER = (BitsPerSample * 2) - 1; */ { int clkgdv=0; outw((FWID(15) | CLKGDV(clkgdv)), AUDIO_SRGR1); outw((GSYNC | CLKSP | FSGM | FPER(31)), AUDIO_SRGR2); } #endif audio_samplerate = val; FN_OUT(0); }
/* * 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); }
void omap2_mcbsp_set_srg_cfg_param(unsigned int id, int interface_mode, struct omap_mcbsp_reg_cfg *mcbsp_cfg, struct omap_mcbsp_srg_fsg_cfg *param) { struct omap_mcbsp *mcbsp = mcbsp_ptr[id]; void __iomem *io_base; u32 clk_rate, clkgdv; io_base = mcbsp->io_base; mcbsp->interface_mode = interface_mode; mcbsp_cfg->srgr1 = FWID(param->pulse_width); if (interface_mode == OMAP_MCBSP_MASTER) { clk_rate = clk_get_rate(mcbsp->fclk); clkgdv = clk_rate / (param->sample_rate * (param->bits_per_sample - 1)); if (clkgdv > 0xFF) clkgdv = 0xFF; mcbsp_cfg->srgr1 = mcbsp_cfg->srgr1 | CLKGDV(clkgdv); } if (param->dlb) mcbsp_cfg->spcr1 = mcbsp_cfg->spcr1 & ~(ALB); if (param->sync_mode == OMAP_MCBSP_SRG_FREERUNNING) mcbsp_cfg->spcr2 = mcbsp_cfg->spcr2 | FREE; mcbsp_cfg->srgr2 = FPER(param->period)|(param->fsgm? FSGM : 0); switch (param->srg_src) { case OMAP_MCBSP_SRGCLKSRC_CLKS: mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 & ~(SCLKME); mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 & ~(CLKSM); /* * McBSP master operation at low voltage is only possible if * CLKSP=0 In Master mode, if client driver tries to configiure * input clock polarity as falling edge, we force it to Rising */ if ((param->polarity == OMAP_MCBSP_CLKS_POLARITY_RISING) || (interface_mode == OMAP_MCBSP_MASTER)) mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 & ~(CLKSP); else mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 | (CLKSP); break; case OMAP_MCBSP_SRGCLKSRC_FCLK: mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 & ~(SCLKME); mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 | (CLKSM); break; case OMAP_MCBSP_SRGCLKSRC_CLKR: mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | (SCLKME); mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 & ~(CLKSM); if (param->polarity == OMAP_MCBSP_CLKR_POLARITY_FALLING) mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 & ~(CLKRP); else mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | (CLKRP); break; case OMAP_MCBSP_SRGCLKSRC_CLKX: mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | (SCLKME); mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 | (CLKSM); if (param->polarity == OMAP_MCBSP_CLKX_POLARITY_RISING) mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 & ~(CLKXP); else mcbsp_cfg->pcr0 = mcbsp_cfg->pcr0 | (CLKXP); break; } if (param->sync_mode == OMAP_MCBSP_SRG_FREERUNNING) mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 & ~(GSYNC); else if (param->sync_mode == OMAP_MCBSP_SRG_RUNNING) mcbsp_cfg->srgr2 = mcbsp_cfg->srgr2 | (GSYNC); mcbsp_cfg->xccr = OMAP_MCBSP_READ(mcbsp, XCCR) & ~(XDISABLE); if (param->dlb) mcbsp_cfg->xccr = mcbsp_cfg->xccr | (DILB); mcbsp_cfg->rccr = OMAP_MCBSP_READ(mcbsp, RCCR) & ~(RDISABLE); return; }
int davinci_set_samplerate(long sample_rate) { u8 count = 0; u8 j_val = 0; u16 d_val = 0; /* wait for any frame to complete */ udelay(125); /* Search for the right sample rate */ while ((reg_info[count].sample_rate != sample_rate) && (count < NUMBER_SAMPLE_RATES_SUPPORTED)) { count++; } if (count == NUMBER_SAMPLE_RATES_SUPPORTED) { DPRINTK("Invalid Sample Rate %d requested\n", (int)sample_rate); return -EPERM; } /* CODEC DATAPATH SETUP */ /* Fsref to 48kHz, dual rate mode upto 96kHz */ if (reg_info[count].Fsref == 96000) audio_aic33_write(REGISTER_ADDR7, FS_REF_DEFAULT_48 | ADC_DUAL_RATE_MODE | DAC_DUAL_RATE_MODE | LDAC_LCHAN | RDAC_RCHAN); /* Fsref to 44.1kHz, dual rate mode upto 88.2kHz */ else if (reg_info[count].Fsref == 88200) audio_aic33_write(REGISTER_ADDR7, FS_REF_44_1 | ADC_DUAL_RATE_MODE | DAC_DUAL_RATE_MODE | LDAC_LCHAN | RDAC_RCHAN); /* Fsref to 48kHz */ else if (reg_info[count].Fsref == 48000) audio_aic33_write(REGISTER_ADDR7, FS_REF_DEFAULT_48 | LDAC_LCHAN | RDAC_RCHAN); /* Fsref to 44.1kHz */ else if (reg_info[count].Fsref == 44100) audio_aic33_write(REGISTER_ADDR7, FS_REF_44_1 | LDAC_LCHAN | RDAC_RCHAN); /* Codec sample rate select */ audio_aic33_write(REGISTER_ADDR2, reg_info[count].data); /* If PLL is to be used for generation of Fsref Generate the Fsref using the PLL */ /*Enable the PLL | Q-value | P-value */ audio_aic33_write(REGISTER_ADDR3, PLL_ENABLE | 0x10 | 0x02); if ((reg_info[count].Fsref == 96000) || (reg_info[count].Fsref == 48000)) { /* * For MCLK = 22.5792 MHz and to get Fsref = 48kHz * Fsref = (MCLK * k * R)/(2048 * p); * Select P = 2, R= 1, K = 8.7075, which results in J = 8, * D = 7075 * * For MCLK = 27 MHz and to get Fsref = 48kHz * Fsref = (MCLK * k * R)/(2048 * p); * Select P = 2, R= 1, K = 7.2818, which results in J = 7, * D = 2818 * * For MCLK = 33.8688 MHz and to get Fsref = 48kHz * Fsref = (MCLK * k * R)/(2048 * p); * Select P = 2, R= 1, K = 5.8049, which results in J = 5, * D = 8049 */ switch (aic33_mclk) { case MCLK_22: j_val = 8; d_val = 7075; break; case MCLK_27: j_val = 7; d_val = 2818; break; case MCLK_33: j_val = 5; d_val = 8049; break; default: printk(KERN_ERR "unknown audio codec frequency \n"); } } else if ((reg_info[count].Fsref == 88200) || (reg_info[count].Fsref == 44100)) { /* * MCLK = 22.5792 MHz and to get Fsref = 44.1kHz * Fsref = (MCLK * k * R)/(2048 * p); * Select P = 2, R =1, K = 8.0000, which results in J = 8, * D = 0000 * * MCLK = 27 MHz and to get Fsref = 44.1kHz * Fsref = (MCLK * k * R)/(2048 * p); * Select P = 2, R =1, K = 6.6901, which results in J = 6, * D = 6901 * * MCLK = 33.8688 MHz and to get Fsref = 44.1kHz * Fsref = (MCLK * k * R)/(2048 * p); * Select P = 2, R =1, K = 5.3333, which results in J = 5, * D = 3333 */ switch (aic33_mclk) { case MCLK_22: j_val = 8; d_val = 0; break; case MCLK_27: j_val = 6; d_val = 6901; break; case MCLK_33: j_val = 5; d_val = 3333; break; default: printk(KERN_ERR "unknown audio codec frequency \n"); } } /* J-value */ audio_aic33_write(REGISTER_ADDR4, j_val << 2); /* D-value 8-MSB's */ audio_aic33_write(REGISTER_ADDR5, (unsigned char)(d_val >> 6)); /* D-value 6-LSB's */ audio_aic33_write(REGISTER_ADDR6, (unsigned char)(d_val << 2)); audio_samplerate = sample_rate; #ifndef AIC33_MASTER { int clkgdv = 0; unsigned long clkval = 0; struct clk *mbspclk; /* Set Sample Rate at McBSP Formula : Codec System Clock = Input clock to McBSP; clkgdv = ((Codec System Clock / (SampleRate * BitsPerSample * 2)) - 1); FWID = BitsPerSample - 1; FPER = (BitsPerSample * 2) - 1; */ mbspclk = davinci_mcbsp_get_clock(); if (mbspclk == NULL) { DPRINTK(" Failed to get internal clock to MCBSP"); return -EPERM; } clkval = clk_get_rate(mbspclk); DPRINTK("mcbsp_clk = %ld\n", clkval); if (clkval) clkgdv = (clkval / (sample_rate * DEFAULT_BITPERSAMPLE * 2)) - 1; else { DPRINTK(" Failed to get the MCBSP clock\n"); return -EPERM; } DPRINTK("clkgdv = %d\n", clkgdv); if (clkgdv > 255 || clkgdv < 0) { /* For requested sampling rate, the input clock to MCBSP cant be devided down to get the in range clock divider value for 16 bits sample */ DPRINTK("Invalid Sample Rate %d requested\n", (int)sample_rate); return -EPERM; } initial_config.srgr1 = (FWID(DEFAULT_BITPERSAMPLE - 1) | CLKGDV(clkgdv)); initial_config.srgr2 = (CLKSM | FSGM | FPER(DEFAULT_BITPERSAMPLE * 2 - 1)); davinci_mcbsp_stop_tx(AUDIO_MCBSP); davinci_mcbsp_stop_rx(AUDIO_MCBSP); davinci_mcbsp_config(AUDIO_MCBSP, &initial_config); } #endif /* AIC33_MASTER */ return 0; }