예제 #1
0
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;
}
예제 #2
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);
}
예제 #3
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);
}
예제 #4
0
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;
	}
예제 #5
0
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;
}