diff --git a/kernel/sound/soc/codecs/es8323.c b/kernel/sound/soc/codecs/es8323.c index 1a4401dad6..92a379eeef 100755 --- a/kernel/sound/soc/codecs/es8323.c +++ b/kernel/sound/soc/codecs/es8323.c @@ -62,6 +62,7 @@ int es8323_line_det_gpio = INVALID_GPIO; int es8323_hp_det_action_value = 0; int es8323_hp_mic_only = 0; char es8323_mic_state = 0; +char es8323_earphone_state = 0; static int HP_IRQ=0; static int hp_irq_flag = 0; int LINE_IRQ = 0; @@ -139,6 +140,32 @@ static int es8323_read_gpio(int gpio) return level; } +static void spk_detect_do_switch(int ctrl) +{ + es8323_earphone_state = es8323_read_gpio(es8323_hp_det_gpio); + if(ctrl == 1) { + if(es8323_earphone_state == 1) + { + if(es8323_earphone_con_gpio != INVALID_GPIO) + gpio_set_value(es8323_earphone_con_gpio, es8323_earphone_con_gpio_active); + if(es8323_spk_con_gpio != INVALID_GPIO) + gpio_set_value(es8323_spk_con_gpio, !es8323_spk_con_gpio_active); + } + else + { + if(es8323_earphone_con_gpio != INVALID_GPIO) + gpio_set_value(es8323_earphone_con_gpio, !es8323_earphone_con_gpio_active); + if(es8323_spk_con_gpio != INVALID_GPIO) + gpio_set_value(es8323_spk_con_gpio, es8323_spk_con_gpio_active); + } + }else { + if(es8323_earphone_con_gpio != INVALID_GPIO) + gpio_set_value(es8323_earphone_con_gpio, !es8323_earphone_con_gpio_active); + if(es8323_spk_con_gpio != INVALID_GPIO) + gpio_set_value(es8323_spk_con_gpio, !es8323_spk_con_gpio_active); + } +} + static void line_detect_do_switch(struct work_struct *work) { int ret; @@ -147,29 +174,54 @@ static void line_detect_do_switch(struct work_struct *work) unsigned int type; level = es8323_read_gpio(es8323_line_det_gpio); - printk("line_detect_do_switch level: %d\n",level); - - - if(level == 1) //line in in + + if(level == 0) //line in in { line_in_state = 1; + printk("%s Enter line in mode\n",__func__); + spk_detect_do_switch(1); + /**** Add line in to earphone directly ****/ snd_soc_write(es8323_codec, 0x26, 0x00); + snd_soc_write(es8323_codec, 0x27, 0x40); + snd_soc_write(es8323_codec, 0x2a, 0x40); + snd_soc_write(es8323_codec, 0x0b, 0x02); //line1 + //power on left analog input N left ADC + snd_soc_write(es8323_codec, 0x03, 0x00); + snd_soc_write(es8323_codec, 0x04, 0x0c); //enable LOUT2 ROUT2 + + snd_soc_write(es8323_codec, 0x09, 0x00); + snd_soc_write(es8323_codec, 0x0a, 0x00); + + /**** Add line in function ****/ + /*snd_soc_write(es8323_codec, 0x26, 0x00); snd_soc_write(es8323_codec, 0x0b, 0x02); //line1 //power on left analog input N left ADC snd_soc_write(es8323_codec, 0x03, 0x00); snd_soc_write(es8323_codec, 0x09, 0x66); - snd_soc_write(es8323_codec, 0x0a, 0x00); + snd_soc_write(es8323_codec, 0x0a, 0x00);*/ - irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING); + irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); } else //line in out { line_in_state = 0; - snd_soc_write(es8323_codec, 0x0b, 0x02); - irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING); + printk("%s Exit line in mode\n",__func__); + snd_soc_write(es8323_codec, 0x26, 0x12); + snd_soc_write(es8323_codec, 0x27, 0xb8); + snd_soc_write(es8323_codec, 0x2a, 0xb8); + snd_soc_write(es8323_codec, 0x0b, 0x82); //line1 + //power on left analog input N left ADC + snd_soc_write(es8323_codec, 0x03, 0x59); + snd_soc_write(es8323_codec, 0x04, 0x3c); //enable LOUT2 ROUT2 + + snd_soc_write(es8323_codec, 0x09, 0x88); + snd_soc_write(es8323_codec, 0x0a, 0xf0); + spk_detect_do_switch(0); + //snd_soc_write(es8323_codec, 0x0b, 0x02); + irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING); } enable_irq(irq); @@ -688,12 +740,8 @@ static void on_off_ext_amp(int i) if (set_spk == 0) { return; } - if(hp_irq_flag == 0) { - if(es8323_earphone_con_gpio != INVALID_GPIO) - gpio_set_value(es8323_earphone_con_gpio, es8323_earphone_con_gpio_active ? i:!i); //delete by hjc - if(es8323_spk_con_gpio != INVALID_GPIO) - gpio_set_value(es8323_spk_con_gpio, es8323_spk_con_gpio_active ? i:!i); //delete by gzl - } + + if(hp_irq_flag == 0) spk_detect_do_switch(i); DBG("*** %s() SPEAKER set SPK_CON %d\n", __FUNCTION__, i); mdelay(50); @@ -958,7 +1006,6 @@ static int es8323_mute(struct snd_soc_dai *dai, int mute) } on_off_ext_amp(!mute); - return 0; } @@ -972,33 +1019,33 @@ static int es8323_set_bias_level(struct snd_soc_codec *codec, DBG("Enter::%s----%d level =%d\n",__FUNCTION__,__LINE__,level); switch (level) { - case SND_SOC_BIAS_ON: - es8323->is_biason = 1; - break; - case SND_SOC_BIAS_PREPARE: - snd_soc_write(codec, ES8323_ANAVOLMANAG, 0x7C); - snd_soc_write(codec, ES8323_CHIPLOPOW1, 0x00); - snd_soc_write(codec, ES8323_CHIPLOPOW2, 0xFF); - snd_soc_write(codec, ES8323_CHIPPOWER, 0x00); - snd_soc_write(codec, ES8323_ADCPOWER, 0x59); - break; - case SND_SOC_BIAS_STANDBY: - snd_soc_write(codec, ES8323_ANAVOLMANAG, 0x7C); - snd_soc_write(codec, ES8323_CHIPLOPOW1, 0x00); - snd_soc_write(codec, ES8323_CHIPLOPOW2, 0xFF); - snd_soc_write(codec, ES8323_CHIPPOWER, 0x00); - snd_soc_write(codec, ES8323_ADCPOWER, 0x59); - break; - case SND_SOC_BIAS_OFF: - snd_soc_write(codec, ES8323_ANAVOLMANAG, 0x7B); - snd_soc_write(codec, ES8323_CHIPLOPOW1, 0xFF); - snd_soc_write(codec, ES8323_CHIPLOPOW2, 0xFF); - snd_soc_write(codec, ES8323_ADCPOWER, 0xFF); - snd_soc_write(codec, ES8323_CHIPPOWER, 0xAA); + case SND_SOC_BIAS_ON: + es8323->is_biason = 1; + break; + case SND_SOC_BIAS_PREPARE: + snd_soc_write(codec, ES8323_ANAVOLMANAG, 0x7C); + snd_soc_write(codec, ES8323_CHIPLOPOW1, 0x00); + snd_soc_write(codec, ES8323_CHIPLOPOW2, 0xFF); + snd_soc_write(codec, ES8323_CHIPPOWER, 0x00); + snd_soc_write(codec, ES8323_ADCPOWER, 0x59); + break; + case SND_SOC_BIAS_STANDBY: + snd_soc_write(codec, ES8323_ANAVOLMANAG, 0x7C); + snd_soc_write(codec, ES8323_CHIPLOPOW1, 0x00); + snd_soc_write(codec, ES8323_CHIPLOPOW2, 0xFF); + snd_soc_write(codec, ES8323_CHIPPOWER, 0x00); + snd_soc_write(codec, ES8323_ADCPOWER, 0x59); + break; + case SND_SOC_BIAS_OFF: + snd_soc_write(codec, ES8323_ANAVOLMANAG, 0x7B); + snd_soc_write(codec, ES8323_CHIPLOPOW1, 0xFF); + snd_soc_write(codec, ES8323_CHIPLOPOW2, 0xFF); + snd_soc_write(codec, ES8323_ADCPOWER, 0xFF); + snd_soc_write(codec, ES8323_CHIPPOWER, 0xAA); - //snd_soc_write(codec, 0x2b, 0x90); - break; - } + //snd_soc_write(codec, 0x2b, 0x90); + break; + } codec->dapm.bias_level = level; return 0; } @@ -1185,10 +1232,8 @@ static int es8323_resume(struct snd_soc_codec *codec) //s8323_set_bias_level(codec, SND_SOC_BIAS_STANDBY); //codec->dapm.bias_level = SND_SOC_BIAS_STANDBY; - if(es8323_earphone_con_gpio != INVALID_GPIO) - gpio_set_value(es8323_earphone_con_gpio, es8323_earphone_con_gpio_active); - if(es8323_spk_con_gpio != INVALID_GPIO) - gpio_set_value(es8323_spk_con_gpio, es8323_spk_con_gpio_active); + spk_detect_do_switch(1); + if(line_in_state == 1) schedule_delayed_work(&line_wakeup_work, msecs_to_jiffies(250)); return 0; } @@ -1238,7 +1283,8 @@ static int es8323_hp_jack_change(struct notifier_block *nb, }else { printk("mic use intern\n"); snd_soc_write(es8323_codec, 0x0b,0x02); - } + } + if(line_in_state == 1) spk_detect_do_switch(1); } return NOTIFY_OK;