Example #1
0
static inline void aic33_configure()
{
	DPRINTK(" CONFIGURING AIC33\n");

	/* Page select register */
	audio_aic33_write(REGISTER_ADDR0, 0x0);

	/* audio_aic33_write(REGISTER_ADDR38, 0x10); */
	davinci_set_mono_stereo(aic33_local.nochan);
#ifdef AIC33_MASTER
	/* Enable bit and word clock as Master mode, 3-d disabled */
	audio_aic33_write(REGISTER_ADDR8, 0xc0 /*0xc4 */ );
#endif

	aic33_update(SET_LINE, aic33_local.line);
	aic33_update(SET_VOLUME, aic33_local.volume);
	aic33_update(SET_RECSRC, aic33_local.recsrc);
	aic33_update(SET_IGAIN, aic33_local.igain);
	aic33_update(SET_OGAIN, aic33_local.ogain);
	aic33_update(SET_MICBIAS, aic33_local.micbias);
}
Example #2
0
int davinci_set_samplerate(long sample_rate)
{
	u8 count = 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(7,
				  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(7,
				  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(7,
				  FS_REF_DEFAULT_48 | LDAC_LCHAN | RDAC_RCHAN);

	/* Fsref to 44.1kHz */
	else if (reg_info[count].Fsref == 44100)
		audio_aic33_write(7, FS_REF_44_1 | LDAC_LCHAN | RDAC_RCHAN);


	/* Codec sample rate select */
	audio_aic33_write(2, reg_info[count].data);

	/* If PLL is to be used for generation of Fsref
	   Generate the Fsref using the PLL */
#if(MCLK==33)

	if ((reg_info[count].Fsref == 96000) | (reg_info[count].Fsref == 48000)) {
		/* 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 */

		/*Enable the PLL | Q-value | P-value */
		audio_aic33_write(3, PLL_ENABLE | 0x10 | 0x02);
		audio_aic33_write(4, 0x14);	/* J-value */
		audio_aic33_write(5, 0x7D);	/* D-value 8-MSB's */
		audio_aic33_write(6, 0x04);	/* D-value 6-LSB's */

	}

	else if ((reg_info[count].Fsref == 88200) | (reg_info[count].Fsref ==
						     44100)) {

		/* 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 */

		/*Enable the PLL | Q-value | P-value */
		audio_aic33_write(3, PLL_ENABLE | 0x10 | 0x02);
		audio_aic33_write(4, 0x14);	/* J-value */
		audio_aic33_write(5, 0x34);	/* D-value 8-MSB's */
		audio_aic33_write(6, 0x14);	/* D-value 6-LSB's */
	}
#elif(MCLK==22)

	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 */

		/*Enable the PLL | Q-value | P-value */
		audio_aic33_write(3, PLL_ENABLE | 0x10 | 0x02);
		audio_aic33_write(4, (8 << 2));	/* J-value */
		audio_aic33_write(5, (unsigned char)(7075 >> 6));	/* D-value 8-MSB's */
		audio_aic33_write(6, (unsigned char)(7075 << 2));	/* D-value 6-LSB's */

	}
Example #3
0
static int aic33_update(int flag, int val)
{
	u16 volume;
	s16 left_gain, left_val, right_gain, right_val;

	switch (flag) {
	case SET_VOLUME:
		/* Ignore separate left/right channel for now,
	   	   even the codec does support it. */
		val &= 0xff;

		if (val < 0 || val > 100) {
			DPRINTK("Trying a bad volume value(%d)!\n", val);
			return -EPERM;
		}
		// Convert 0 -> 100 volume to 0x77 (LHV_MIN) -> 0x00 (LHV_MAX)
		volume =
		    ((val * OUTPUT_VOLUME_RANGE) / 100) + OUTPUT_VOLUME_MIN;

		aic33_local.volume_reg = OUTPUT_VOLUME_MAX - volume;

		if (aic33_local.nochan == STEREO) {
			audio_aic33_write(47, LOPM_ON | aic33_local.volume_reg);
			audio_aic33_write(64, LOPM_ON | aic33_local.volume_reg);
			audio_aic33_write(82, LOPM_ON | aic33_local.volume_reg);
			audio_aic33_write(92, LOPM_ON | aic33_local.volume_reg);
		} else if (aic33_local.nochan == MONO) {
#ifdef CONFIG_MONOSTEREO_DIFFJACK
			/* DACL1 to MONO_LOP/M routing and volume control */
			audio_aic33_write(75, LOPM_ON | aic33_local.volume_reg);

			/* DACR1 to MONO_LOP/M routing and volume control */
			audio_aic33_write(78, LOPM_ON | aic33_local.volume_reg);
#else
			audio_aic33_write(47, LOPM_ON | aic33_local.volume_reg);
			audio_aic33_write(64, LOPM_ON | aic33_local.volume_reg);
			audio_aic33_write(82, LOPM_ON | aic33_local.volume_reg);
			audio_aic33_write(92, LOPM_ON | aic33_local.volume_reg);
#endif
		}

		break;

	case SET_LINE:
	case SET_MIC:
		/* Ignore separate left/right channel for now,
	   	   even the codec does support it. */
		val &= 0xff;

		if (val < 0 || val > 100) {
			DPRINTK("Trying a bad volume value(%d)!\n", val);
			return -EPERM;
		}

		volume = ((val * INPUT_VOLUME_RANGE) / 100) + INPUT_VOLUME_MIN;

		aic33_local.input_volume_reg = volume;

		audio_aic33_write(15, aic33_local.input_volume_reg);
		audio_aic33_write(16, aic33_local.input_volume_reg);

		break;

	case SET_RECSRC:
		/* Ignore separate left/right channel for now,
	   	   even the codec does support it. */
		val &= 0xff;

		if (hweight32(val) > 1)
			val &= ~aic33_local.recsrc;

		if (val == SOUND_MASK_MIC) {
			/* enable the mic input*/
			DPRINTK("Enabling mic\n");
			audio_aic33_write(17, 0x0);
			audio_aic33_write(18, 0x0);

			/* enable ADC's and disable the line input*/
			audio_aic33_write(19, 0x7C);
			audio_aic33_write(22, 0x7C);

		}
		else if (val == SOUND_MASK_LINE) {
			/* enable ADC's, enable line iput */
			DPRINTK(" Enabling line in\n");
			audio_aic33_write(19, 0x4);
			audio_aic33_write(22, 0x4);

			/* disable the mic input */
			audio_aic33_write(17, 0xff);
			audio_aic33_write(18, 0xff);
		}
		else {
			/* do nothing */
		}
		aic33_local.recsrc = val;
		break;

	case SET_IGAIN:
		left_val = val & 0xFF;
		right_val = val >> 8;

		if (left_val < 0 || left_val > 100) {
			DPRINTK("Trying a bad igain value(%d)!\n", left_val);
			return -EPERM;
		}
		if (right_val < 0 || right_val > 100) {
			DPRINTK("Trying a bad igain value(%d)!\n", right_val);
			return -EPERM;
		}

		left_gain = ((left_val * INPUT_GAIN_RANGE) / 100) + INPUT_GAIN_MIN;
		right_gain = ((right_val * INPUT_GAIN_RANGE) / 100) + INPUT_GAIN_MIN;

		DPRINTK("left gain reg val = 0x%x", left_gain << 1);
		DPRINTK("right gain reg val = 0x%x", left_gain << 1);

		/* Left AGC control */
		audio_aic33_write(26, 0x80);
		audio_aic33_write(27, left_gain << 1);
		audio_aic33_write(28, 0x0);

		/* Right AGC control */
		audio_aic33_write(29, 0x80);
		audio_aic33_write(30, right_gain << 1);
		audio_aic33_write(31, 0x0);

		break;

	case SET_OGAIN:
		left_val = val & 0xFF;
		right_val = val >> 8;

		if (left_val < 0 || left_val > 100) {
			DPRINTK("Trying a bad igain value(%d)!\n", left_val);
			return -EPERM;
		}
		if (right_val < 0 || right_val > 100) {
			DPRINTK("Trying a bad igain value(%d)!\n", right_val);
			return -EPERM;
		}

		left_gain = ((left_val * OUTPUT_GAIN_RANGE) / 100) + OUTPUT_GAIN_MIN;
		left_gain = OUTPUT_GAIN_MAX - left_gain;
		right_gain = ((right_val * OUTPUT_GAIN_RANGE) / 100) + OUTPUT_GAIN_MIN;
		right_gain = OUTPUT_GAIN_MAX - right_gain;

		/* Left/Right DAC digital volume gain */
		audio_aic33_write(43, left_gain);
		audio_aic33_write(44, right_gain);
		break;

	case SET_MICBIAS:
		/* Ignore separate left/right channel for now,
	   	   even the codec does support it. */
		val &= 0xff;

		if (val < 0 || val > 3) {
			DPRINTK
			    ("Request for non supported mic bias level(%d)!\n",
			     val);
			return -EPERM;
		}

		if (val == 0)
			audio_aic33_write(25, 0x00);

		else if (val == 1)
			audio_aic33_write(25, MICBIAS_OUTPUT_2_0V);

		else if (val == 2)
			audio_aic33_write(25, MICBIAS_OUTPUT_2_5V);

		else if (val == 3)
			audio_aic33_write(25, MICBIAS_OUTPUT_AVDD);

		break;

	case SET_BASS:
		break;

	case SET_TREBLE:
		break;
	}
	return 0;
}
Example #4
0
static void davinci_set_mono_stereo(int mode)
{
	if (mode == MONO) {

#ifdef CONFIG_MONOSTEREO_DIFFJACK
		/* MONO_LOP/M Output level control register */
		audio_aic33_write(REGISTER_ADDR79, 0x99);
#else
		/* Driver power ON pop control */
		audio_aic33_write(REGISTER_ADDR42, 0x6C);

		/* HPLOUT/HPROUT output level control */
		audio_aic33_write(REGISTER_ADDR51, 0x99);
		audio_aic33_write(REGISTER_ADDR65, 0x99);

		/* LEFT_LOP/M, RIGHT_LOP/M output level control */
		audio_aic33_write(REGISTER_ADDR86, 0x99);
		audio_aic33_write(REGISTER_ADDR93, 0x99);
#endif
		/* Left DAC power up, Right DAC power down */
		audio_aic33_write(REGISTER_ADDR37, 0xa0);
	} else if (mode == STEREO) {
		/* Driver power ON pop control */
		audio_aic33_write(REGISTER_ADDR42, 0x6C);

		/* HPLOUT/HPROUT output level control */
		audio_aic33_write(REGISTER_ADDR51, 0x99);
		audio_aic33_write(REGISTER_ADDR65, 0x99);

		/* LEFT_LOP/M, RIGHT_LOP/M output level control */
		audio_aic33_write(REGISTER_ADDR86, 0x99);
		audio_aic33_write(REGISTER_ADDR93, 0x99);

		/* Left/Right DAC power up */
		audio_aic33_write(REGISTER_ADDR37, 0xe0);
	} else
		DPRINTK(" REQUEST FOR INVALID MODE\n");
}
Example #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;
}