Ejemplo n.º 1
0
static void cpcap_audio_configure_output(
	struct cpcap_audio_state *state,
	struct cpcap_audio_state *previous_state)
{
	static unsigned int prev_aud_out_data;

	if (is_output_changed(previous_state, state) ||
	    is_codec_changed(previous_state, state) ||
	    is_stdac_changed(previous_state, state)) {
		bool activate_ext_loudspeaker = false;
		struct cpcap_regacc reg_changes = { 0 };

		cpcap_audio_set_output_amp_switches(state);

		activate_ext_loudspeaker = cpcap_audio_set_bits_for_speaker(
						state->codec_primary_speaker,
						 state->codec_primary_balance,
						 &(reg_changes.value));

		activate_ext_loudspeaker = activate_ext_loudspeaker ||
					cpcap_audio_set_bits_for_speaker(
						state->codec_secondary_speaker,
						 CPCAP_AUDIO_BALANCE_NEUTRAL,
						 &(reg_changes.value));

		activate_ext_loudspeaker = activate_ext_loudspeaker ||
					cpcap_audio_set_bits_for_speaker(
						state->stdac_primary_speaker,
						 state->stdac_primary_balance,
						 &(reg_changes.value));

		activate_ext_loudspeaker = activate_ext_loudspeaker ||
					cpcap_audio_set_bits_for_speaker(
						state->stdac_secondary_speaker,
						 CPCAP_AUDIO_BALANCE_NEUTRAL,
						 &(reg_changes.value));

		activate_ext_loudspeaker = activate_ext_loudspeaker ||
					cpcap_audio_set_bits_for_speaker(
						state->ext_primary_speaker,
						 state->ext_primary_balance,
						 &(reg_changes.value));

		activate_ext_loudspeaker = activate_ext_loudspeaker ||
					cpcap_audio_set_bits_for_speaker(
						state->ext_secondary_speaker,
						 CPCAP_AUDIO_BALANCE_NEUTRAL,
						 &(reg_changes.value));

		reg_changes.mask = reg_changes.value | prev_aud_out_data;

		prev_aud_out_data = reg_changes.value;

		logged_cpcap_write(state->cpcap, CPCAP_REG_RXOA,
					reg_changes.value, reg_changes.mask);
	}
}
Ejemplo n.º 2
0
void cpcap_audio_set_audio_state(struct cpcap_audio_state *state)
{
	struct cpcap_audio_state *previous_state = &previous_state_struct;

	if (state->codec_mute == CPCAP_AUDIO_CODEC_BYPASS_LOOP)
		state->codec_mode = CPCAP_AUDIO_CODEC_ON;

	if (state->codec_mode == CPCAP_AUDIO_CODEC_OFF ||
	    state->codec_mode == CPCAP_AUDIO_CODEC_CLOCK_ONLY ||
		state->rat_type == CPCAP_AUDIO_RAT_CDMA)
		state->codec_mute = CPCAP_AUDIO_CODEC_MUTE;
	else
		state->codec_mute = CPCAP_AUDIO_CODEC_UNMUTE;

	if (state->stdac_mode != CPCAP_AUDIO_STDAC_ON)
		state->stdac_mute = CPCAP_AUDIO_STDAC_MUTE;
	else
		state->stdac_mute = CPCAP_AUDIO_STDAC_UNMUTE;

	if (state->stdac_mode == CPCAP_AUDIO_STDAC_CLOCK_ONLY)
		state->stdac_mode = CPCAP_AUDIO_STDAC_ON;

	if ((state->codec_mode != CPCAP_AUDIO_CODEC_OFF  &&
	     state->codec_mode != CPCAP_AUDIO_CODEC_CLOCK_ONLY) ||
	    state->stdac_mode != CPCAP_AUDIO_STDAC_OFF ||
	    (state->codec_primary_speaker != CPCAP_AUDIO_OUT_NONE  &&
	     state->codec_primary_speaker != CPCAP_AUDIO_OUT_BT_MONO) ||
	    state->stdac_primary_speaker != CPCAP_AUDIO_OUT_NONE ||
	    state->ext_primary_speaker != CPCAP_AUDIO_OUT_NONE ||
	    (state->microphone != CPCAP_AUDIO_IN_NONE &&
	     state->microphone != CPCAP_AUDIO_IN_BT_MONO))
		cpcap_audio_configure_power(1);

	if (is_speaker_turning_off(state, previous_state))
		cpcap_audio_configure_output(state, previous_state);

	if (is_codec_changed(state, previous_state)) {
		int codec_mute = state->codec_mute;

		state->codec_mute = CPCAP_AUDIO_CODEC_MUTE;

		cpcap_audio_configure_aud_mute(state, previous_state);

		previous_state->codec_mute = state->codec_mute;

		state->codec_mute = codec_mute;

		cpcap_audio_configure_codec(state, previous_state);
	}
	if (is_stdac_changed(state, previous_state)) {
		int stdac_mute = state->stdac_mute;

		state->stdac_mute = CPCAP_AUDIO_STDAC_MUTE;

		cpcap_audio_configure_aud_mute(state, previous_state);

		previous_state->stdac_mute = state->stdac_mute;

		state->stdac_mute = stdac_mute;

		cpcap_audio_configure_stdac(state, previous_state);
	}

	cpcap_audio_configure_analog_source(state, previous_state);

	cpcap_audio_configure_input(state, previous_state);

	cpcap_audio_configure_input_gains(state, previous_state);

	cpcap_audio_configure_output(state, previous_state);

	cpcap_audio_configure_output_gains(state, previous_state);

	cpcap_audio_configure_aud_mute(state, previous_state);

	if ((state->codec_mode == CPCAP_AUDIO_CODEC_OFF ||
	     state->codec_mode == CPCAP_AUDIO_CODEC_CLOCK_ONLY) &&
	    state->stdac_mode == CPCAP_AUDIO_STDAC_OFF &&
	    (state->codec_primary_speaker == CPCAP_AUDIO_OUT_NONE ||
	     state->codec_primary_speaker == CPCAP_AUDIO_OUT_BT_MONO) &&
	    state->stdac_primary_speaker == CPCAP_AUDIO_OUT_NONE &&
	    state->ext_primary_speaker == CPCAP_AUDIO_OUT_NONE &&
	    (state->microphone == CPCAP_AUDIO_IN_NONE ||
	     state->microphone == CPCAP_AUDIO_IN_BT_MONO))
		cpcap_audio_configure_power(0);

	previous_state_struct = *state;

	cpcap_audio_register_dump(state);
}
Ejemplo n.º 3
0
static void cpcap_audio_configure_stdac(struct cpcap_audio_state *state,
				struct cpcap_audio_state *previous_state)
{
	const unsigned int SDAC_FREQ_MASK = CPCAP_BIT_ST_DAC_CLK0
			| CPCAP_BIT_ST_DAC_CLK1 | CPCAP_BIT_ST_DAC_CLK2;
	const unsigned int SDAC_RESET_FREQ_MASK = SDAC_FREQ_MASK
					| CPCAP_BIT_ST_CLOCK_TREE_RESET;
	static unsigned int prev_stdac_data, prev_sdai_data;

	if (is_stdac_changed(state, previous_state)) {
		unsigned int temp_stdac_rate = state->stdac_rate;
		struct cpcap_regacc sdai_changes = { 0 };
		struct cpcap_regacc stdac_changes = { 0 };

		int stdac_freq_config = 0;
		if (state->rat_type == CPCAP_AUDIO_RAT_CDMA)
			stdac_freq_config = (CPCAP_BIT_ST_DAC_CLK0
					| CPCAP_BIT_ST_DAC_CLK1) ; /*19.2Mhz*/
		else
			stdac_freq_config = CPCAP_BIT_ST_DAC_CLK2 ; /* 26Mhz */

		/* We need to turn off stdac before changing its settings */
		if (previous_state->stdac_mode != CPCAP_AUDIO_STDAC_OFF) {
			stdac_changes.mask = prev_stdac_data |
					CPCAP_BIT_DF_RESET_ST_DAC |
					CPCAP_BIT_ST_CLOCK_TREE_RESET;

			logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
				stdac_changes.value, stdac_changes.mask);

			prev_stdac_data = 0;
			previous_state->stdac_mode = CPCAP_AUDIO_STDAC_OFF;
		}

		temp_stdac_rate &= 0x0000000F;
		temp_stdac_rate = temp_stdac_rate << 4;

		switch (state->stdac_mode) {
		case CPCAP_AUDIO_STDAC_ON:
			stdac_changes.value |= CPCAP_BIT_ST_DAC_EN;
		/* falling through intentionally */
		case CPCAP_AUDIO_STDAC_CLOCK_ONLY:
			stdac_changes.value |= temp_stdac_rate |
				CPCAP_BIT_DF_RESET_ST_DAC | stdac_freq_config;
			sdai_changes.value |= CPCAP_BIT_ST_CLK_EN;
			break;

		case CPCAP_AUDIO_STDAC_OFF:
		default:
			break;
		}

		if (state->rat_type != CPCAP_AUDIO_RAT_NONE)
			sdai_changes.value |= CPCAP_BIT_ST_DAC_CLK_IN_SEL;

		if (state->dai_config == CPCAP_AUDIO_DAI_CONFIG_HIFI_DUPLEX_0) {
			/* when using DAI0, follow the codec configuration:
			 * 4-slot network, R on slot 0, L on slot 1 */
			sdai_changes.value |= CPCAP_BIT_ST_DIG_AUD_FS0
					| CPCAP_BIT_ST_L_TIMESLOT0;
		} else {
			/* -True I2S mode
			 * -STDAC is Master of Fsync Bclk
			 * -STDAC uses DAI1 */
			sdai_changes.value |= CPCAP_BIT_DIG_AUD_IN_ST_DAC
					| CPCAP_BIT_ST_DIG_AUD_FS0
					| CPCAP_BIT_ST_DIG_AUD_FS1;
		}

		logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
					stdac_freq_config, SDAC_FREQ_MASK);

		/* Next, write the SDACDI if it's changed */
		if (prev_sdai_data != sdai_changes.value) {
			sdai_changes.mask = sdai_changes.value
						| prev_sdai_data;
			prev_sdai_data = sdai_changes.value;

			logged_cpcap_write(state->cpcap, CPCAP_REG_SDACDI,
					sdai_changes.value, sdai_changes.mask);

			/* Clock tree change -- reset and wait */
			stdac_freq_config |= CPCAP_BIT_ST_CLOCK_TREE_RESET;

			logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
				stdac_freq_config, SDAC_RESET_FREQ_MASK);

			/* Wait for clock tree reset to complete */
			mdelay(CLOCK_TREE_RESET_TIME);
		}

		/* Clear old settings */
		stdac_changes.mask = stdac_changes.value | prev_stdac_data;
		prev_stdac_data = stdac_changes.value;

		logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
			stdac_changes.value, stdac_changes.mask);
	}
}
Ejemplo n.º 4
0
static void cpcap_audio_configure_output(
	struct cpcap_audio_state *state,
	struct cpcap_audio_state *prev)
{
	static unsigned int prev_aud_out_data;

	bool activate_ext_loudspeaker = false;
	struct cpcap_regacc reg_changes = { 0 };

	if (!is_output_changed(prev, state) &&
			!is_codec_changed(prev, state) &&
			!is_stdac_changed(prev, state))
		return;

	cpcap_audio_set_output_amp_switches(state);

	activate_ext_loudspeaker = cpcap_audio_set_bits_for_speaker(
					state->codec_primary_speaker,
					 state->codec_primary_balance,
					 &(reg_changes.value));

	activate_ext_loudspeaker = activate_ext_loudspeaker ||
				cpcap_audio_set_bits_for_speaker(
					state->codec_secondary_speaker,
					 CPCAP_AUDIO_BALANCE_NEUTRAL,
					 &(reg_changes.value));

	activate_ext_loudspeaker = activate_ext_loudspeaker ||
				cpcap_audio_set_bits_for_speaker(
					state->stdac_primary_speaker,
					 state->stdac_primary_balance,
					 &(reg_changes.value));

	activate_ext_loudspeaker = activate_ext_loudspeaker ||
				cpcap_audio_set_bits_for_speaker(
					state->stdac_secondary_speaker,
					 CPCAP_AUDIO_BALANCE_NEUTRAL,
					 &(reg_changes.value));

	activate_ext_loudspeaker = activate_ext_loudspeaker ||
				cpcap_audio_set_bits_for_speaker(
					state->ext_primary_speaker,
					 state->ext_primary_balance,
					 &(reg_changes.value));

	activate_ext_loudspeaker = activate_ext_loudspeaker ||
				cpcap_audio_set_bits_for_speaker(
					state->ext_secondary_speaker,
					 CPCAP_AUDIO_BALANCE_NEUTRAL,
					 &(reg_changes.value));

	reg_changes.mask = reg_changes.value | prev_aud_out_data;

	prev_aud_out_data = reg_changes.value;

	/* Sleep for 300ms if we are getting into a call to allow the switch to
	 * settle.  If we don't do this, it causes a loud pop at the beginning
	 * of the call.
	 */
	if (state->rat_type == CPCAP_AUDIO_RAT_CDMA &&
			state->ext_primary_speaker != CPCAP_AUDIO_OUT_NONE &&
			prev->ext_primary_speaker == CPCAP_AUDIO_OUT_NONE)
		msleep(300);

	logged_cpcap_write(state->cpcap, CPCAP_REG_RXOA,
				reg_changes.value, reg_changes.mask);
}
Ejemplo n.º 5
0
static void cpcap_audio_configure_stdac(struct cpcap_audio_state *state,
				struct cpcap_audio_state *prev)
{
	const unsigned int SDAC_FREQ_MASK = CPCAP_BIT_ST_DAC_CLK0
			| CPCAP_BIT_ST_DAC_CLK1 | CPCAP_BIT_ST_DAC_CLK2;
	const unsigned int SDAC_RESET_FREQ_MASK = SDAC_FREQ_MASK
					| CPCAP_BIT_ST_CLOCK_TREE_RESET;
	static unsigned int prev_stdac_data, prev_sdai_data;

	if (is_stdac_changed(state, prev)) {
		unsigned int temp_stdac_rate = state->stdac_rate;
		struct cpcap_regacc sdai_changes = { 0 };
		struct cpcap_regacc stdac_changes = { 0 };

		int stdac_freq_config = 0;
		if (state->rat_type == CPCAP_AUDIO_RAT_CDMA)
			stdac_freq_config = (CPCAP_BIT_ST_DAC_CLK0
					| CPCAP_BIT_ST_DAC_CLK1) ; /*19.2Mhz*/
		else
			stdac_freq_config = CPCAP_BIT_ST_DAC_CLK2 ; /* 26Mhz */

		/* We need to turn off stdac before changing its settings */
		if (prev->stdac_mode != CPCAP_AUDIO_STDAC_OFF) {
			stdac_changes.mask = prev_stdac_data |
					CPCAP_BIT_DF_RESET_ST_DAC |
					CPCAP_BIT_ST_CLOCK_TREE_RESET;

			logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
				stdac_changes.value, stdac_changes.mask);

			prev_stdac_data = 0;
			prev->stdac_mode = CPCAP_AUDIO_STDAC_OFF;
		}

		temp_stdac_rate &= 0x0000000F;
		temp_stdac_rate = temp_stdac_rate << 4;

		switch (state->stdac_mode) {
		case CPCAP_AUDIO_STDAC_ON:
			stdac_changes.value |= CPCAP_BIT_ST_DAC_EN;
		/* falling through intentionally */
		case CPCAP_AUDIO_STDAC_CLOCK_ONLY:
			stdac_changes.value |= temp_stdac_rate |
				CPCAP_BIT_DF_RESET_ST_DAC | stdac_freq_config;
			sdai_changes.value |= CPCAP_BIT_ST_CLK_EN;
			break;

		case CPCAP_AUDIO_STDAC_OFF:
		default:
			break;
		}

		if (state->rat_type != CPCAP_AUDIO_RAT_NONE)
			sdai_changes.value |= CPCAP_BIT_ST_DAC_CLK_IN_SEL;
		/* begin everest change */
		/*
		sdai_changes.value |= CPCAP_BIT_ST_DIG_AUD_FS0 |
			CPCAP_BIT_DIG_AUD_IN_ST_DAC | CPCAP_BIT_ST_L_TIMESLOT0;
		*/
		/* I2S Mode, ignore timeslots, invert bit clock */
		sdai_changes.value |= CPCAP_BIT_ST_DIG_AUD_FS0 |
			CPCAP_BIT_DIG_AUD_IN_ST_DAC |
			CPCAP_BIT_ST_DIG_AUD_FS1 | CPCAP_BIT_ST_CLK_INV;
		/* end everest change */

		logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
				stdac_freq_config, SDAC_FREQ_MASK);

		/* Next, write the SDACDI if it's changed */
		if (prev_sdai_data != sdai_changes.value) {
			sdai_changes.mask = sdai_changes.value
						| prev_sdai_data;
			prev_sdai_data = sdai_changes.value;

			logged_cpcap_write(state->cpcap, CPCAP_REG_SDACDI,
					sdai_changes.value, sdai_changes.mask);

			/* Clock tree change -- reset and wait */
			stdac_freq_config |= CPCAP_BIT_ST_CLOCK_TREE_RESET;

			logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
				stdac_freq_config, SDAC_RESET_FREQ_MASK);

			/* Wait for clock tree reset to complete */
			mdelay(CLOCK_TREE_RESET_DELAY_MS);
		}

		/* Clear old settings */
		stdac_changes.mask = stdac_changes.value | prev_stdac_data;
		prev_stdac_data = stdac_changes.value;

		if ((stdac_changes.value | CPCAP_BIT_ST_DAC_EN) &&
		    (state->cpcap->vendor == CPCAP_VENDOR_ST)) {
			logged_cpcap_write(state->cpcap, CPCAP_REG_TEST,
					   STM_STDAC_EN_TEST_PRE, 0xFFFF);
			logged_cpcap_write(state->cpcap, CPCAP_REG_ST_TEST1,
					   STM_STDAC_EN_ST_TEST1_PRE, 0xFFFF);
		}

		logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
			stdac_changes.value, stdac_changes.mask);

		if ((stdac_changes.value | CPCAP_BIT_ST_DAC_EN) &&
		    (state->cpcap->vendor == CPCAP_VENDOR_ST)) {
			msleep(STM_STDAC_ACTIVATE_RAMP_TIME);
			logged_cpcap_write(state->cpcap, CPCAP_REG_ST_TEST1,
					   STM_STDAC_EN_ST_TEST1_POST, 0xFFFF);
			logged_cpcap_write(state->cpcap, CPCAP_REG_TEST,
					   STM_STDAC_EN_TEST_POST, 0xFFFF);
		}
	}
}
Ejemplo n.º 6
0
static void cpcap_audio_configure_output(
	struct cpcap_audio_state *state,
	struct cpcap_audio_state *previous_state)
{
	static unsigned int prev_aud_out_data;

	if (is_output_changed(previous_state, state) ||
	    is_codec_changed(previous_state, state) ||
	    is_stdac_changed(previous_state, state)) {
		bool activate_ext_loudspeaker = false;
		struct cpcap_regacc reg_changes = { 0 };

		if (is_output_headset(state) &&
			!is_output_headset(previous_state)) {
			/* Charge pump should be enabled first
			 * and wait a minimum of 750 uSec
			 * to allow for settling of the negative supply.
			 */
			logged_cpcap_write(state->cpcap, CPCAP_REG_RXOA,
					CPCAP_BIT_ST_HS_CP_EN,
					CPCAP_BIT_ST_HS_CP_EN);
			/* HS plug-in noise */
			/*mdelay(1);*/
			mdelay(200);
		}

		cpcap_audio_set_output_amp_switches(state);

		activate_ext_loudspeaker = cpcap_audio_set_bits_for_speaker(
						state->codec_primary_speaker,
						 state->codec_primary_balance,
						 &(reg_changes.value));

		activate_ext_loudspeaker = activate_ext_loudspeaker ||
					cpcap_audio_set_bits_for_speaker(
						state->codec_secondary_speaker,
						 CPCAP_AUDIO_BALANCE_NEUTRAL,
						 &(reg_changes.value));

		activate_ext_loudspeaker = activate_ext_loudspeaker ||
					 cpcap_audio_set_bits_for_speaker(
						state->stdac_primary_speaker,
						 state->stdac_primary_balance,
						 &(reg_changes.value));

		activate_ext_loudspeaker = activate_ext_loudspeaker ||
					cpcap_audio_set_bits_for_speaker(
						state->stdac_secondary_speaker,
						 CPCAP_AUDIO_BALANCE_NEUTRAL,
						 &(reg_changes.value));

		activate_ext_loudspeaker = activate_ext_loudspeaker ||
					cpcap_audio_set_bits_for_speaker(
						state->ext_primary_speaker,
						 state->ext_primary_balance,
						 &(reg_changes.value));

		activate_ext_loudspeaker = activate_ext_loudspeaker ||
					cpcap_audio_set_bits_for_speaker(
						state->ext_secondary_speaker,
						 CPCAP_AUDIO_BALANCE_NEUTRAL,
						 &(reg_changes.value));

		reg_changes.mask = reg_changes.value | prev_aud_out_data;

		prev_aud_out_data = reg_changes.value;

		logged_cpcap_write(state->cpcap, CPCAP_REG_RXOA,
				reg_changes.value, reg_changes.mask);

		if (!is_output_headset(state)
			&& is_output_headset(previous_state)) {
			/* When disabling HS output amp,
			 * HS_CP should be turned off after output
			 * amp goes down. */
			mdelay(1);
			logged_cpcap_write(state->cpcap, CPCAP_REG_RXOA,
					0, CPCAP_BIT_ST_HS_CP_EN);
		}
	}
}
Ejemplo n.º 7
0
static void cpcap_audio_configure_stdac(struct cpcap_audio_state *state,
				struct cpcap_audio_state *previous_state)
{
	const unsigned int SDAC_FREQ_MASK = CPCAP_BIT_ST_DAC_CLK0
		| CPCAP_BIT_ST_DAC_CLK1 | CPCAP_BIT_ST_DAC_CLK2;
	const unsigned int SDAC_RESET_FREQ_MASK = SDAC_FREQ_MASK
		| CPCAP_BIT_ST_CLOCK_TREE_RESET;
	static unsigned int prev_stdac_data, prev_sdai_data;

	if (is_stdac_changed(state, previous_state)) {
		unsigned int temp_stdac_rate = state->stdac_rate;
		struct cpcap_regacc sdai_changes = { 0 };
		struct cpcap_regacc stdac_changes = { 0 };
		int stdac_freq_config = 0;

		if (state->rat_type == CPCAP_AUDIO_RAT_CDMA)
			stdac_freq_config = (CPCAP_BIT_ST_DAC_CLK0
					| CPCAP_BIT_ST_DAC_CLK1) ; /*19.2Mhz*/
		else
			stdac_freq_config = CPCAP_BIT_ST_DAC_CLK2 ; /* 26Mhz */

		/* We need to turn off stdac before changing its settings */
		if (previous_state->stdac_mode != CPCAP_AUDIO_STDAC_OFF) {
			stdac_changes.mask = prev_stdac_data |
					CPCAP_BIT_DF_RESET_ST_DAC |
					CPCAP_BIT_ST_CLOCK_TREE_RESET;

			logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
				stdac_changes.value, stdac_changes.mask);

			prev_stdac_data = 0;
			previous_state->stdac_mode = CPCAP_AUDIO_STDAC_OFF;
		}

		temp_stdac_rate &= 0x0000000F;
		temp_stdac_rate = temp_stdac_rate << 4;

		switch (state->stdac_mode) {
		case CPCAP_AUDIO_STDAC_ON:
			stdac_changes.value |= CPCAP_BIT_ST_DAC_EN;
			/* falling through intentionally */
		case CPCAP_AUDIO_STDAC_CLOCK_ONLY:
			stdac_changes.value |= temp_stdac_rate |
						 CPCAP_BIT_DF_RESET_ST_DAC |
						 stdac_freq_config;
			sdai_changes.value |= CPCAP_BIT_ST_CLK_EN;
			break;

		case CPCAP_AUDIO_STDAC_OFF:
		default:
			break;
		}

		if (state->rat_type != CPCAP_AUDIO_RAT_NONE)
			sdai_changes.value |= CPCAP_BIT_ST_DAC_CLK_IN_SEL;

		/* -True I2S mode
		-STDAC is Master of Fsync Bclk
		-STDAC uses DAI1
		*/
#ifdef AUDIO_I2S_MODE
		sdai_changes.value |= CPCAP_BIT_DIG_AUD_IN_ST_DAC |
			CPCAP_BIT_ST_DIG_AUD_FS0 | CPCAP_BIT_ST_DIG_AUD_FS1;
#else
		sdai_changes.value |= CPCAP_BIT_ST_DIG_AUD_FS0 |
			CPCAP_BIT_DIG_AUD_IN_ST_DAC | CPCAP_BIT_ST_L_TIMESLOT0;
#endif
		/* OK, now start paranoid stdac sequence */
		/* TODO: optimize - make less paranoid */
		/* FIRST, make sure the frequency config is right... */
		logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
			stdac_freq_config, SDAC_FREQ_MASK);

		/* Next, write the SDACDI if it's changed */
		if (prev_sdai_data != sdai_changes.value) {
			sdai_changes.mask = sdai_changes.value
				| prev_sdai_data;
			prev_sdai_data = sdai_changes.value;

			logged_cpcap_write(state->cpcap,
				CPCAP_REG_SDACDI, sdai_changes.value,
				sdai_changes.mask);

			/* Clock tree change -- reset and wait */
			stdac_freq_config |= CPCAP_BIT_ST_CLOCK_TREE_RESET;
			logged_cpcap_write(state->cpcap,
					CPCAP_REG_SDAC,
					stdac_freq_config,
					SDAC_RESET_FREQ_MASK);

			/* Wait for clock tree reset to complete */
			mdelay(CLOCK_TREE_RESET_TIME);
		}

		/* Clear old settings */
		stdac_changes.mask = stdac_changes.value | prev_stdac_data;
		prev_stdac_data = stdac_changes.value;

		logged_cpcap_write(state->cpcap, CPCAP_REG_SDAC,
			stdac_changes.value, stdac_changes.mask);
	}
}
Ejemplo n.º 8
0
void cpcap_audio_set_audio_state(struct cpcap_audio_state *state)
{
    struct cpcap_audio_state *previous_state = &previous_state_struct;

    if (state->codec_mute == CPCAP_AUDIO_CODEC_BYPASS_LOOP)
        state->codec_mode = CPCAP_AUDIO_CODEC_ON;

    if (state->codec_mode == CPCAP_AUDIO_CODEC_OFF ||
            state->codec_mode == CPCAP_AUDIO_CODEC_CLOCK_ONLY)
        state->codec_mute = CPCAP_AUDIO_CODEC_MUTE;
    else
        state->codec_mute = CPCAP_AUDIO_CODEC_UNMUTE;

    if (state->stdac_mode != CPCAP_AUDIO_STDAC_ON)
        state->stdac_mute = CPCAP_AUDIO_STDAC_MUTE;
    else
        state->stdac_mute = CPCAP_AUDIO_STDAC_UNMUTE;

    /* @TODO: STDAC_CLOCK_ONLY can be used when AUX_I2S is the
     * only speaker to save some current.  AUX_I2S is to stdac
     * as BT_MONO is to phone codec.
     */
    if (state->stdac_mode == CPCAP_AUDIO_STDAC_CLOCK_ONLY)
        state->stdac_mode = CPCAP_AUDIO_STDAC_ON;

    if ((state->codec_mode != CPCAP_AUDIO_CODEC_OFF &&
            state->codec_mode != CPCAP_AUDIO_CODEC_CLOCK_ONLY) ||
            state->stdac_mode != CPCAP_AUDIO_STDAC_OFF ||
            (state->codec_primary_speaker != CPCAP_AUDIO_OUT_NONE &&
             state->codec_primary_speaker != CPCAP_AUDIO_OUT_BT_MONO) ||
            state->stdac_primary_speaker != CPCAP_AUDIO_OUT_NONE ||
            state->ext_primary_speaker != CPCAP_AUDIO_OUT_NONE ||
            (state->microphone != CPCAP_AUDIO_IN_NONE &&
             state->microphone != CPCAP_AUDIO_IN_BT_MONO))
        cpcap_audio_configure_power(1);

    if (is_speaker_turning_off(state, previous_state))
        cpcap_audio_configure_output(state, previous_state);

    if (is_codec_changed(state, previous_state)) {
        int codec_mute = state->codec_mute;

        state->codec_mute = CPCAP_AUDIO_CODEC_MUTE;

        cpcap_audio_configure_aud_mute(state, previous_state);

        previous_state->codec_mute = state->codec_mute;

        state->codec_mute = codec_mute;

        cpcap_audio_configure_codec(state, previous_state);
    }
    if (is_stdac_changed(state, previous_state)) {
        int stdac_mute = state->stdac_mute;

        state->stdac_mute = CPCAP_AUDIO_STDAC_MUTE;

        cpcap_audio_configure_aud_mute(state, previous_state);

        previous_state->stdac_mute = state->stdac_mute;

        state->stdac_mute = stdac_mute;

        cpcap_audio_configure_stdac(state, previous_state);
    }


    cpcap_audio_configure_analog_source(state, previous_state);

    cpcap_audio_configure_input(state, previous_state);

    cpcap_audio_configure_input_gains(state, previous_state);

    cpcap_audio_configure_output(state, previous_state);

    cpcap_audio_configure_output_gains(state, previous_state);

    cpcap_audio_configure_aud_mute(state, previous_state);

    if ((state->codec_mode == CPCAP_AUDIO_CODEC_OFF ||
            state->codec_mode == CPCAP_AUDIO_CODEC_CLOCK_ONLY) &&
            state->stdac_mode == CPCAP_AUDIO_STDAC_OFF &&
            (state->codec_primary_speaker == CPCAP_AUDIO_OUT_NONE ||
             state->codec_primary_speaker == CPCAP_AUDIO_OUT_BT_MONO) &&
            state->stdac_primary_speaker == CPCAP_AUDIO_OUT_NONE &&
            state->ext_primary_speaker == CPCAP_AUDIO_OUT_NONE &&
            (state->microphone == CPCAP_AUDIO_IN_NONE ||
             state->microphone == CPCAP_AUDIO_IN_BT_MONO))
        cpcap_audio_configure_power(0);

    previous_state_struct = *state;

    cpcap_audio_reguister_dump(state);
}