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); } }
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); }
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); } }
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); }
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); } } }
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); } } }
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); } }
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); }