+static void rt5640_hp_gpio_ctrl(struct rt5640_priv *rt5640, bool enable)
+{
+ dev_dbg(rt5640->codec->dev, "hp-con-gpio enable=%d\n", enable);
+ if (line_in_status && (false == enable))
+ return;
+ if (enable)
+ gpio_set_value(rt5640->hp_con_gpio,
+ rt5640->hp_con_gpio_active_high ? 1 : 0);
+ else
+ gpio_set_value(rt5640->hp_con_gpio,
+ rt5640->hp_con_gpio_active_high ? 0 : 1);
+}
+
+static void rt5640_set_linein(struct rt5640_priv *rt5640)//struct snd_soc_codec *code/)
+{
+ printk("%s enter\n",__func__);
+ //regmap_write(rt5640->regmap, RT5640_RESET, 0);
+ regmap_write(rt5640->regmap, RT5640_PWR_ANLG1, 0xfdfc); //63
+ regmap_update_bits(rt5640->regmap, RT5640_REC_L2_MIXER, //3c
+ 1<<5 | 1<<4,
+ 0<<5 | 1<<4);
+ regmap_update_bits(rt5640->regmap, RT5640_REC_R2_MIXER, //3e
+ 1<<5 | 1<<4,
+ 0<<5 | 1<<4);
+
+ regmap_update_bits(rt5640->regmap, RT5640_OUT_L3_MIXER, //4f
+ 1<<3 , 0<<3);
+ regmap_update_bits(rt5640->regmap, RT5640_OUT_R3_MIXER, //52
+ 1<<3 , 0<<3);
+
+ regmap_write(rt5640->regmap, RT5640_HP_VOL, 0x0808); //02
+ regmap_update_bits(rt5640->regmap, RT5640_HPO_MIXER, //45
+ 1<<13 | 1<<12,
+ 0<<13 | 1<<12);
+
+ regmap_update_bits(rt5640->regmap, RT5640_PWR_MIXER, //65
+ 1<<10 | 1<<11 | 1<<14 | 1<<15,
+ 1<<10 | 1<<11 | 1<<14 | 1<<15);
+ regmap_update_bits(rt5640->regmap, RT5640_PWR_VOL, //66
+ 1<<8 | 1<<9 | 1<<10 | 1<<11,
+ 1<<8 | 1<<9 | 1<<10 | 1<<11);
+
+ regmap_write(rt5640->regmap, RT5640_DEPOP_M1, 0x8019); //8e
+ regmap_write(rt5640->regmap, RT5640_DEPOP_M2, 0x3100); //8f
+
+ regmap_write(rt5640->regmap, RT5640_DUMMY1, 0x3401); //fa
+
+ rt5640_hp_gpio_ctrl(rt5640, 1);
+}
+
+static void aux_det_work_func(struct work_struct *work)
+{
+ struct rt5640_priv *rt5640 = container_of(work, struct rt5640_priv, aux_det_work.work);
+ line_in_status = gpio_get_value(rt5640->aux_det_gpio);
+ printk("%s", __func__);
+
+ if (line_in_status == LINE_IN_OKAY){
+ printk(" [on] \n");
+ rt5640_set_linein(rt5640);
+ }
+ else if (line_in_status == LINE_IN_NO)
+ {
+ printk(" [off]\n");
+ }
+
+ if(!aux_irq_flag) {
+ enable_irq(rt5640->aux_det_irq);
+ aux_irq_flag = true;
+ }
+}
+
+static irqreturn_t aux_det_isr(int irq, void *data)
+{
+ struct rt5640_priv *rt5640 = data;
+
+ printk("%s\n", __func__);
+
+ line_in_status = gpio_get_value(rt5640->aux_det_gpio);
+ if(aux_irq_flag) {
+ disable_irq_nosync(rt5640->aux_det_irq);
+ aux_irq_flag = false;
+ }
+
+ if (line_in_status == LINE_IN_OKAY) {
+ //set line in on
+ printk(" line_in: [on] \n");
+ line_in_status = LINE_IN_OKAY;
+ schedule_delayed_work(&rt5640->aux_det_work, msecs_to_jiffies(0));
+ //rt5640_set_linein(rt5640);
+ }
+ else if (line_in_status == LINE_IN_NO) {
+ //set line in off
+ printk(" line_in: [off] \n");
+ if (!aux_irq_flag) {
+ enable_irq(rt5640->aux_det_irq);
+ aux_irq_flag = true;
+ }
+ line_in_status = LINE_IN_NO;
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void rt5640_delay_workq(struct work_struct *work)
+{
+ int ret;
+ struct rt5640_priv *rt5640 = container_of(work, struct rt5640_priv, init_delayed_work.work);
+ printk("%s\n", __func__);
+
+ rt5640->aux_det_irq = gpio_to_irq(rt5640->aux_det_gpio);
+ if (rt5640->aux_det_irq < 0) {
+ gpio_free(rt5640->aux_det_gpio);
+ printk("aux_det_irq req fail\n");
+ }
+ else {
+ ret = request_irq(rt5640->aux_det_irq, aux_det_isr, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "irq_aux_det", rt5640);
+ if (ret)
+ printk(KERN_ALERT "Cannot allocate linein INT!ERRNO:%d\n", ret);
+ else {
+ if (aux_irq_flag) {
+ disable_irq(rt5640->aux_det_irq);
+ aux_irq_flag = false;
+ }
+ }
+ }
+
+ schedule_delayed_work(&rt5640->aux_det_work, msecs_to_jiffies(100));
+}
+