static void vote_power(unsigned long *addr, enum AMP_POWER_MASK bit) { pr_info("%s: mask %d\n",__func__,bit); set_bit(bit,addr); if(need_power(addr) && rt5506_query.gpiostatus == AMP_GPIO_OFF) { pr_info("%s: enable gpio %d\n",__func__,pdata->gpio_rt5506_enable); if(rt5506_query.regstatus == REG_AUTO_MODE) { set_rt5506_regulator(REG_PWM_MODE); rt5506_query.regstatus = REG_PWM_MODE; msleep(1); } gpio_set_value(pdata->gpio_rt5506_enable, 1); rt5506_query.gpiostatus = AMP_GPIO_ON; usleep_range(20000,20000); } }
static int rt5506_headset_detect(void *private_data, int on) { if(!rt5506Connect) return 0; if(on) { pr_info("%s: headset in ++\n",__func__); cancel_delayed_work_sync(&rt5506_query.hs_imp_detec_work); mutex_lock(&rt5506_query.gpiolock); mutex_lock(&rt5506_query.mlock); rt5506_query.hs_qstatus = RT55XX_QUERY_HEADSET; rt5506_query.headsetom = HEADSET_OM_UNDER_DETECT; if(rt5506_query.rt5506_status == RT55XX_PLAYBACK) { if(high_imp) { rt5506_write_reg(1,0x7); rt5506_write_reg(0xb1,0x81); } else { rt5506_write_reg(1,0xc7); } last_spkamp_state = 0; pr_info("%s: OFF\n", __func__); rt5506_query.rt5506_status = RT55XX_SUSPEND; } pr_info("%s: headset in --\n",__func__); mutex_unlock(&rt5506_query.mlock); mutex_unlock(&rt5506_query.gpiolock); queue_delayed_work(hs_wq,&rt5506_query.hs_imp_detec_work,msecs_to_jiffies(5)); pr_info("%s: headset in --2\n",__func__); } else { pr_info("%s: headset remove ++\n",__func__); cancel_delayed_work_sync(&rt5506_query.hs_imp_detec_work); flush_work(&rt5506_query.volume_ramp_work.work); mutex_lock(&rt5506_query.gpiolock); mutex_lock(&rt5506_query.mlock); rt5506_query.hs_qstatus = RT55XX_QUERY_OFF; rt5506_query.headsetom = HEADSET_OM_UNDER_DETECT; if(rt5506_query.regstatus == REG_AUTO_MODE) { set_rt5506_regulator(REG_PWM_MODE); rt5506_query.regstatus = REG_PWM_MODE; } if(rt5506_query.rt5506_status == RT55XX_PLAYBACK) { if(high_imp) { rt5506_write_reg(1,0x7); rt5506_write_reg(0xb1,0x81); } else { rt5506_write_reg(1,0xc7); } last_spkamp_state = 0; pr_info("%s: OFF\n", __func__); rt5506_query.rt5506_status = RT55XX_SUSPEND; } if(high_imp) { int closegpio = 0; if(rt5506_query.gpiostatus == AMP_GPIO_OFF) { pr_info("%s: enable gpio %d\n", __func__, pdata->gpio_rt55xx_enable); if(rt5506_query.regstatus == REG_AUTO_MODE) { set_rt5506_regulator(REG_PWM_MODE); rt5506_query.regstatus = REG_PWM_MODE; msleep(1); } gpio_set_value(pdata->gpio_rt55xx_enable, 1); closegpio = 1; usleep_range(20000,20000); } pr_info("%s: reset rt5501\n",__func__); rt5506_write_reg(0x0,0x4); mdelay(1); rt5506_write_reg(0x1,0xc7); high_imp = 0; if(closegpio) { pr_info("%s: disable gpio %d\n", __func__, pdata->gpio_rt55xx_enable); gpio_set_value(pdata->gpio_rt55xx_enable, 0); if(rt5506_query.regstatus == REG_PWM_MODE) { set_rt5506_regulator(REG_AUTO_MODE); rt5506_query.regstatus = REG_AUTO_MODE; } } } rt5506_query.curmode = RT55XX_MODE_OFF; pr_info("%s: headset remove --1\n",__func__); mutex_unlock(&rt5506_query.mlock); mutex_unlock(&rt5506_query.gpiolock); pr_info("%s: headset remove --2\n",__func__); } return 0; }
static int rt5506_headset_detect(void *private_data, int on) { if(!rt5506Connect) return 0; if(on) { mutex_lock(&rt5506_query.mlock); if(rt5506_query.hs_connec) { pr_info("%s: headset exist, ignore\n",__func__); mutex_unlock(&rt5506_query.mlock); return 0; } mutex_unlock(&rt5506_query.mlock); pr_info("%s: headset in ++\n",__func__); cancel_delayed_work_sync(&rt5506_query.hs_imp_detec_work); mutex_lock(&rt5506_query.gpiolock); mutex_lock(&rt5506_query.mlock); rt5506_query.hs_qstatus = QUERY_HEADSET; rt5506_query.headsetom = HEADSET_OM_UNDER_DETECT; if(rt5506_query.rt5506_status == STATUS_PLAYBACK) { if(high_imp) { rt5506_write_reg(1,0x7); rt5506_write_reg(0xb1,0x81); } else { rt5506_write_reg(1,0xc7); } last_spkamp_state = 0; pr_info("%s: OFF\n", __func__); rt5506_query.rt5506_status = STATUS_SUSPEND; } rt5506_query.hs_connec = 1; pr_info("%s: headset in --\n",__func__); mutex_unlock(&rt5506_query.mlock); mutex_unlock(&rt5506_query.gpiolock); queue_delayed_work(hs_wq,&rt5506_query.hs_imp_detec_work,msecs_to_jiffies(5)); pr_info("%s: headset in --2\n",__func__); } else { mutex_lock(&rt5506_query.mlock); if(!rt5506_query.hs_connec) { pr_info("%s: headset isn't exist, ignore\n",__func__); mutex_unlock(&rt5506_query.mlock); return 0; } mutex_unlock(&rt5506_query.mlock); pr_info("%s: headset remove ++\n",__func__); cancel_delayed_work_sync(&rt5506_query.hs_imp_detec_work); flush_work_sync(&rt5506_query.volume_ramp_work.work); mutex_lock(&rt5506_query.gpiolock); mutex_lock(&rt5506_query.mlock); rt5506_query.hs_qstatus = QUERY_OFF; rt5506_query.headsetom = HEADSET_OM_UNDER_DETECT; if(rt5506_query.regstatus == REG_AUTO_MODE) { set_rt5506_regulator(REG_PWM_MODE); rt5506_query.regstatus = REG_PWM_MODE; } if(rt5506_query.rt5506_status == STATUS_PLAYBACK) { if(high_imp) { rt5506_write_reg(1,0x7); rt5506_write_reg(0xb1,0x81); } else { rt5506_write_reg(1,0xc7); } last_spkamp_state = 0; pr_info("%s: OFF\n", __func__); rt5506_query.rt5506_status = STATUS_SUSPEND; } if(high_imp) { vote_power(&rt5506_query.power_mask, POWER_HIGH_IMP_RESET); pr_info("%s: reset rt5501\n",__func__); rt5506_write_reg(0x0,0x4); mdelay(1); rt5506_write_reg(0x1,0xc7); high_imp = 0; unvote_power(&rt5506_query.power_mask, POWER_HIGH_IMP_RESET); } rt5506_query.curmode = PLAYBACK_MODE_OFF; rt5506_query.hs_connec = 0; pr_info("%s: headset remove --1\n",__func__); mutex_unlock(&rt5506_query.mlock); mutex_unlock(&rt5506_query.gpiolock); pr_info("%s: headset remove --2\n",__func__); } return 0; }