static void aml_asoc_work_func(struct work_struct *work) { struct aml_audio_private_data *p_aml_audio = NULL; struct snd_soc_card *card = NULL; int jack_type = 0; int flag = -1; int status = SND_JACK_HEADPHONE; p_aml_audio = container_of(work, struct aml_audio_private_data, work); card = (struct snd_soc_card *)p_aml_audio->data; flag = aml_audio_hp_detect(p_aml_audio); // printk("******%s***flag=%d**\n",__func__,flag); if(p_aml_audio->detect_flag != flag) { if (flag == 1) { switch_set_state(&p_aml_audio->sdev, 2); // 1 :have mic ; 2 no mic printk(KERN_INFO "aml aduio hp pluged jack_type: %d\n", jack_type); snd_soc_jack_report(&p_aml_audio->jack, status, SND_JACK_HEADPHONE); } else { printk(KERN_INFO "aml audio hp unpluged\n"); switch_set_state(&p_aml_audio->sdev, 0); snd_soc_jack_report(&p_aml_audio->jack, 0, SND_JACK_HEADPHONE); } p_aml_audio->detect_flag = flag; } }
void sn95031_jack_detection(struct mfld_jack_data *jack_data) { unsigned int status; unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET; pr_debug("interrupt id read in sram = 0x%x\n", jack_data->intr_id); if (jack_data->intr_id & 0x1) { pr_debug("short_push detected\n"); status = SND_JACK_HEADSET | SND_JACK_BTN_0; } else if (jack_data->intr_id & 0x2) { pr_debug("long_push detected\n"); status = SND_JACK_HEADSET | SND_JACK_BTN_1; } else if (jack_data->intr_id & 0x4) { pr_debug("headset or headphones inserted\n"); status = sn95031_get_headset_state(jack_data->mfld_jack); } else if (jack_data->intr_id & 0x8) { pr_debug("headset or headphones removed\n"); status = 0; sn95031_disable_jack_btn(jack_data->mfld_jack->codec); } else { pr_err("unidentified interrupt\n"); return; } snd_soc_jack_report(jack_data->mfld_jack, status, mask); /*button pressed and released so we send explicit button release */ if ((status & SND_JACK_BTN_0) | (status & SND_JACK_BTN_1)) snd_soc_jack_report(jack_data->mfld_jack, SND_JACK_HEADSET, mask); }
static void aml_asoc_work_func(struct work_struct *work) { struct aml_audio_private_data *p_aml_audio = NULL; struct snd_soc_card *card = NULL; // int jack_type = 0; int flag = -1; int status = SND_JACK_HEADPHONE; p_aml_audio = container_of(work, struct aml_audio_private_data, work); card = (struct snd_soc_card *)p_aml_audio->data; flag = aml_audio_hp_detect(p_aml_audio); if(p_aml_audio->detect_flag != flag) { p_aml_audio->detect_flag = flag; if (flag & 0x1) { //amlogic_set_value(p_aml_audio->gpio_mute, 0, "mute_spk"); switch_set_state(&p_aml_audio->sdev, 2); // 1 :have mic ; 2 no mic adac_wr_reg (71, 0x0101); // use board mic printk(KERN_INFO "aml aduio hp pluged 3 jack_type: %d\n", SND_JACK_HEADPHONE); snd_soc_jack_report(&p_aml_audio->jack, status, SND_JACK_HEADPHONE); // mic port detect if(p_aml_audio->mic_det){ if(flag & 0x8){ switch_set_state(&p_aml_audio->mic_sdev, 1); adac_wr_reg (71, 0x0005); // use hp mic printk(KERN_INFO "aml aduio mic pluged jack_type: %d\n", SND_JACK_MICROPHONE); //snd_soc_jack_report(&p_aml_audio->jack, status, SND_JACK_HEADPHONE); } } } else if(flag & 0x2){ //amlogic_set_value(p_aml_audio->gpio_mute, 0, "mute_spk"); switch_set_state(&p_aml_audio->sdev, 1); // 1 :have mic ; 2 no mic adac_wr_reg (71, 0x0005); // use hp mic printk(KERN_INFO "aml aduio hp pluged 4 jack_type: %d\n", SND_JACK_HEADSET); snd_soc_jack_report(&p_aml_audio->jack, status, SND_JACK_HEADPHONE); } else { printk(KERN_INFO "aml audio hp unpluged\n"); //amlogic_set_value(p_aml_audio->gpio_mute, 1, "mute_spk"); adac_wr_reg (71, 0x0101); // use board mic switch_set_state(&p_aml_audio->sdev, 0); snd_soc_jack_report(&p_aml_audio->jack, 0, SND_JACK_HEADPHONE); // mic port detect if(p_aml_audio->mic_det){ if(flag & 0x8){ switch_set_state(&p_aml_audio->mic_sdev, 1); adac_wr_reg (71, 0x0005); // use hp mic printk(KERN_INFO "aml aduio mic pluged jack_type: %d\n", SND_JACK_MICROPHONE); //snd_soc_jack_report(&p_aml_audio->jack, status, SND_JACK_HEADPHONE); } } } } p_aml_audio->hp_det_status = true; }
static void cs42l52_hp_detect_queue(struct work_struct* work) { int level = 0x0; struct cs42l52_work_t* pwork = container_of(work,struct cs42l52_work_t, cs42l52_workqueue); struct snd_soc_codec* codec = (struct snd_soc_codec*)(pwork->data); if ((soc_cs42l52_dai.ac97_pdata) && ((struct cs42l52_platform_data *) (soc_cs42l52_dai.ac97_pdata))->is_hp_pluged) level = ((struct cs42l52_platform_data *) (soc_cs42l52_dai.ac97_pdata))->is_hp_pluged(); //printk("level = %x, hp_detect_flag = %x\n", level, hp_detect_flag); if(level == 0x1 && hp_detect_flag!= 0x1){ // HP printk("Headphone pluged in\n"); snd_soc_dapm_disable_pin(codec, "Ext Spk"); snd_soc_dapm_enable_pin(codec, "MIC IN"); snd_soc_dapm_sync(codec); // pull down the gpio to mute spk mute_spk(codec, 1); snd_soc_jack_report(&hp_jack, SND_JACK_HEADSET, SND_JACK_HEADSET); hp_detect_flag = level; }else if(level != hp_detect_flag){ // HDMI printk("Headphone unpluged\n"); snd_soc_dapm_enable_pin(codec, "Ext Spk"); snd_soc_dapm_enable_pin(codec, "MIC IN"); snd_soc_dapm_sync(codec); snd_soc_jack_report(&hp_jack,0, SND_JACK_HEADSET); hp_detect_flag = level; mute_spk(codec, 0); } }
static void rt5631_work_func(struct work_struct *work) { struct rt5631_private_data *pdata = NULL; struct snd_soc_codec *codec = NULL; int jack_type = 0; int flag = -1; int status = SND_JACK_HEADPHONE; pdata = container_of(work, struct rt5631_private_data, work); codec = (struct snd_soc_codec *)pdata->data; flag = rt5631_detect_hp(); if(pdata->detect_flag != flag) { if (flag == 1) { switch_set_state(&pdata->sdev, 2); // 1 :have mic ; 2 no mic jack_type = rt5631_headset_detect(codec, 1); printk(KERN_INFO "rt5631 hp pluged jack_type: %d\n", jack_type); snd_soc_jack_report(&pdata->jack, status, SND_JACK_HEADPHONE); } else { printk(KERN_INFO "rt5631 hp unpluged\n"); switch_set_state(&pdata->sdev, 0); rt5631_headset_detect(codec, 0); snd_soc_jack_report(&pdata->jack, 0, SND_JACK_HEADPHONE); } pdata->detect_flag = flag; } }
static void max97236_report_jack_state(struct max97236_priv *max97236, unsigned int *status_reg) { char string[MAX_STRING]; int state; if ((status_reg[0] & 0x88) == 0x88) { state = SND_JACK_HEADSET; string_copy(string, "HEADSET", MAX_STRING); } else if ((status_reg[0] & 0x80) == 0x80) { state = SND_JACK_HEADPHONE; string_copy(string, "HEADPHONES", MAX_STRING); } else if ((status_reg[1] == 0xCC) && (status_reg[2] == 0xCC)) { state = M97236_JACK_STATE_UNKNOWN; string_copy(string, "UNKNOWN", MAX_STRING); } else if ((status_reg[1] & 0xCC) == 0xCC) { state = SND_JACK_LINEOUT; string_copy(string, "LINEOUT", MAX_STRING); } else { state = M97236_JACK_STATE_NONE; string_copy(string, "NOTHING", MAX_STRING); } if (verbosity) dev_info(max97236->codec->dev, "0x%02X, 0x%02X, 0x%02X - %s\n", status_reg[0], status_reg[1], status_reg[2], string); /* unmute left and right volume */ if ((state == SND_JACK_HEADSET) || (state == SND_JACK_HEADPHONE)) { regmap_update_bits(max97236->regmap, M97236_REG_07_LEFT_VOLUME, M97236_MUTEL_MASK, 0); regmap_update_bits(max97236->regmap, M97236_REG_08_RIGHT_VOLUME, M97236_MUTER_MASK, 0); } if (max97236->jack_state != state) { snd_soc_jack_report(max97236->jack, state, SND_JACK_HEADSET | SND_JACK_LINEOUT); max97236->jack_state = state; } if (state == M97236_JACK_STATE_NONE) snd_soc_jack_report(max97236->jack, state, SND_JACK_HEADSET | SND_JACK_LINEOUT); }
static int max97236_pm_resume(struct device *dev) { struct max97236_priv *max97236 = dev_get_drvdata(dev); struct snd_soc_codec *codec = max97236->codec; struct snd_soc_card *card = codec->card; struct snd_soc_dai_link *dai_link = card->dai_link; int i = 0; for (i = 0; i < card->num_links; i++) if (card->dai_link[i].ignore_suspend) return 0; if (pm_delay_enable) { pr_info("%s: enter, setting extclk to %d\n", __func__, extclk_freq); msleep(3000); } cancel_delayed_work(&max97236->jack_work); regcache_cache_only(max97236->regmap, false); /* max97236_reset(max97236); */ regcache_sync(max97236->regmap); max97236_set_clk_dividers(max97236); max97236->jack_state = M97236_JACK_STATE_NONE; if (test_jack_presence(max97236, 10)) snd_soc_jack_report(max97236->jack, max97236->jack_state, 0x7E00); return 0; }
static void test_jack_presence(struct max97236_priv *max97236, int delay) { unsigned int reg; int test_value; regmap_read(max97236->regmap, M97236_REG_00_STATUS1, ®); #ifdef M97236_JACK_SWITCH_NORMALLY_CLOSED test_value = 4; #else test_value = 0; #endif if ((reg & M97236_JACKSW_MASK) == test_value) { schedule_delayed_work(&max97236->jack_work, msecs_to_jiffies(delay)); } else { /* report there is no headset */ snd_soc_jack_report(max97236->jack, M97236_JACK_STATE_NONE, SND_JACK_HEADSET | SND_JACK_LINEOUT); /* Clear any interrupts then enable jack detection */ regmap_read(max97236->regmap, M97236_REG_00_STATUS1, ®); regmap_read(max97236->regmap, M97236_REG_01_STATUS2, ®); #ifdef MAX97236_AUTOMODE1_JACK_DETECTION max97236_configure_for_detection(max97236, M97236_AUTO_MODE_1); #else regmap_write(max97236->regmap, M97236_REG_19_STATE_FORCING, M97236_STATE_FLOAT); max97236_configure_for_detection(max97236, M97236_AUTO_MODE_0); #endif } }
static int es8316_resume_post(struct snd_soc_card *card) { struct snd_soc_codec *codec = es8316; int jack = jack_gpio.gpio; int invert = jack_gpio.invert; int level = gpio_get_value_cansleep(jack); PM_DBGOUT("%s BAIAS=%d, PRE=%d\n", __func__, codec->dapm.bias_level, codec_bias_level); if (!codec) return -1; if (SND_SOC_BIAS_OFF != codec_bias_level) codec->driver->resume(codec); if (invert) level = !level; pr_debug("%s: hp jack %s\n", __func__, level?"IN":"OUT"); if (!level) { es8316_jack_insert = 0; } else { es8316_jack_insert = 1; } pr_debug("%s: jack_insert %d\n", __func__, es8316_jack_insert); snd_soc_jack_report(&hp_jack, level, jack_gpio.report); return 0; }
static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; int ret; /* Add SDP4430 specific controls */ ret = snd_soc_add_controls(codec, sdp4430_controls, ARRAY_SIZE(sdp4430_controls)); if (ret) return ret; /* Add SDP4430 specific widgets */ ret = snd_soc_dapm_new_controls(codec->dapm, sdp4430_twl6040_dapm_widgets, ARRAY_SIZE(sdp4430_twl6040_dapm_widgets)); if (ret) return ret; /* Set up SDP4430 specific audio path audio_map */ snd_soc_dapm_add_routes(codec->dapm, audio_map, ARRAY_SIZE(audio_map)); /* SDP4430 connected pins */ snd_soc_dapm_enable_pin(codec->dapm, "Ext Mic"); snd_soc_dapm_enable_pin(codec->dapm, "Ext Spk"); snd_soc_dapm_enable_pin(codec->dapm, "AFML"); snd_soc_dapm_enable_pin(codec->dapm, "AFMR"); snd_soc_dapm_disable_pin(codec->dapm, "Headset Mic"); snd_soc_dapm_disable_pin(codec->dapm, "Headset Stereophone"); /* allow audio paths from the audio modem to run during suspend */ snd_soc_dapm_ignore_suspend(codec, "Ext Mic"); snd_soc_dapm_ignore_suspend(codec, "Ext Spk"); snd_soc_dapm_ignore_suspend(codec, "AFML"); snd_soc_dapm_ignore_suspend(codec, "AFMR"); snd_soc_dapm_ignore_suspend(codec, "Headset Mic"); snd_soc_dapm_ignore_suspend(codec, "Headset Stereophone"); ret = snd_soc_dapm_sync(codec->dapm); if (ret) return ret; /*Headset jack detection */ ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &hs_jack); if (ret) return ret; ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), hs_jack_pins); if (machine_is_omap_4430sdp()) twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); else snd_soc_jack_report(&hs_jack, SND_JACK_HEADSET, SND_JACK_HEADSET); /* wait 500 ms before switching of HS power */ rtd->pmdown_time = 500; return ret; }
int acer_soc_resume_post(struct snd_soc_card *card) { int state = (int) is_hp_plugged(); if (!is_debug_on()) snd_soc_jack_report(&tegra_wm8903_hp_jack, state, 1); return 0; }
/* headset key feature WJ 22/11/13 */ static void max97236_keypress(struct max97236_priv *max97236, unsigned int *status_reg) { unsigned char keystr[MAX_STRING] = ""; unsigned int key = 0; unsigned int reg; int press; /* headset key feature WJ 22/11/13 */ wake_lock(&jack_key_lock); g_max97236 = max97236; /* headset key feature WJ 22/11/13 */ regmap_read(max97236->regmap, M97236_REG_17_PASSIVE_MBH_KEYSCAN_DATA, ®); press = (reg & M97236_PRESS_MASK) == M97236_PRESS_MASK; printk("Ivan max97236_keypress keydata = %x, status_reg[0] = %x, status_reg[1] = %x\n",reg,status_reg[0],status_reg[1]); if (press) { if (status_reg[0] & M97236_MCSW_MASK) { string_copy(keystr, "SND_JACK_BTN_0", MAX_STRING); key = SND_JACK_BTN_0; } else if (status_reg[1] & M97236_KEY_MASK) { reg &= 0x3F; if (reg < M97236_KEY_THRESH_1) { string_copy(keystr, "SND_JACK_BTN_1", MAX_STRING); key = SND_JACK_BTN_1; } else if (reg < M97236_KEY_THRESH_2) { string_copy(keystr, "SND_JACK_BTN_2", MAX_STRING); key = SND_JACK_BTN_2; } else if (reg < M97236_KEY_THRESH_3) { string_copy(keystr, "SND_JACK_BTN_3", MAX_STRING); key = SND_JACK_BTN_3; } else { string_copy(keystr, "SND_JACK_BTN_4", MAX_STRING); key = SND_JACK_BTN_4; } } else { dev_err(max97236->codec->dev, "Unknown key interrupt s1 %02X, s2 %02X\n", status_reg[0], status_reg[1]); } } if (verbosity) dev_info(max97236->codec->dev, "%s %s\n", press ? (char *) keystr : "BUTTON", press ? "PRESS" : "RELEASE"); #ifdef CONFIG_SWITCH switch_set_state(&tegra_max97236_button_switch, press ? 1:0); #endif snd_soc_jack_report(max97236->jack, key, 0x7E00); wake_unlock(&jack_key_lock); }
int ctp_soc_jack_gpio_detect_bp(void) { struct snd_soc_jack_gpio *gpio = &hs_gpio[CTP_BTN_GPIO]; int enable, hs_status, status; struct snd_soc_jack *jack = gpio->jack; struct snd_soc_codec *codec = jack->codec; unsigned int mask = SND_JACK_BTN_0 | SND_JACK_HEADSET; struct ctp_mc_private *ctx = container_of(jack, struct ctp_mc_private, ctp_jack); status = 0; enable = gpio_get_value(gpio->gpio); if (gpio->invert) enable = !enable; pr_debug("%s: gpio->%d=0x%x\n", __func__, gpio->gpio, enable); /* Check for headset status before processing interrupt */ gpio = &hs_gpio[CTP_HSDET_GPIO]; hs_status = gpio_get_value(gpio->gpio); if (gpio->invert) hs_status = !hs_status; pr_debug("%s: gpio->%d=0x%x\n", __func__, gpio->gpio, hs_status); pr_debug("Jack status = %x\n", jack->status); if (((jack->status & SND_JACK_HEADSET) == SND_JACK_HEADSET) && (!hs_status)) { /* HS present, process the interrupt */ if (!enable) { /* Jack removal might be in progress, check interrupt status * before proceeding for button press detection */ if (!atomic_dec_return(&ctx->bpirq_flag)) { status = ctx->ops->bp_detection(codec, jack, enable); if (status == mask) { ctx->btn_press_flag = true; } else { if (!(ctx->btn_press_flag)) snd_soc_jack_report(jack, mask, mask); ctx->btn_press_flag = false; } atomic_inc(&ctx->bpirq_flag); } else atomic_inc(&ctx->bpirq_flag); } else { status = jack->status; pr_debug("%s:Invalid BP interrupt\n", __func__); } } else { pr_debug("%s:Spurious BP interrupt : jack_status 0x%x, HS_status 0x%x\n", __func__, jack->status, hs_status); set_mic_bias(jack, ctx->ops->mic_bias, false); /* Disable Button_press interrupt if no Headset */ set_bp_interrupt(ctx, false); } pr_debug("%s: status 0x%x\n", __func__, status); return status; }
static void rt5616_work_func(struct work_struct *work) { struct rt5616_private_data *pdata = NULL; struct snd_soc_codec *codec = NULL; int jack_type = 0; int flag = -1; int status = SND_JACK_HEADPHONE; pdata = container_of(work, struct rt5616_private_data, work); codec = (struct snd_soc_codec *)pdata->data; flag = rt5616_detect_hp(); if(pdata->detect_flag != flag) { //printk("*****flag=%d,detect_flag=%d****\n",flag,pdata->detect_flag); if (flag == 1) { if ((&pdata->sdev!=NULL)&&(pdata->sdev.dev!=NULL)) switch_set_state(&pdata->sdev, 2); // 1 :have mic 2: no mic else printk(KERN_INFO "rt5616 kernel NULL pointer error\n"); // jack_type = rt5616_headset_detect(codec, 1); printk(KERN_INFO "rt5616 hp pluged jack_type: %d\n", jack_type); snd_soc_jack_report(&pdata->jack, status, SND_JACK_HEADPHONE); // if ((&pdata->sdev!=NULL)&&(pdata->sdev.dev!=NULL)) // switch_set_state(&pdata->sdev, 1); // else // printk(KERN_INFO "rt5616 kernel NULL pointer error\n"); } else { printk(KERN_INFO "rt5616 hp unpluged\n"); if ((&pdata->sdev!=NULL)&&(pdata->sdev.dev!=NULL)) switch_set_state(&pdata->sdev, 0); else printk(KERN_INFO "rt5616 kernel NULL pointer error\n"); // rt5616_headset_detect(codec, 0); snd_soc_jack_report(&pdata->jack, 0, SND_JACK_HEADPHONE); // if ((&pdata->sdev!=NULL)&&(pdata->sdev.dev!=NULL)) // switch_set_state(&pdata->sdev, 0); // else // printk(KERN_INFO "rt5616 kernel NULL pointer error\n"); } pdata->detect_flag = flag; } }
void tegra_wm8903_jack_resume(void) { int val; val = gpio_get_value(tegra_wm8903_hp_jack_gpio.gpio); val = tegra_wm8903_hp_jack_gpio.invert ? !val : val; val = val ? tegra_wm8903_hp_jack_gpio.report : 0; snd_soc_jack_report(&tegra_wm8903_hp_jack, val, tegra_wm8903_hp_jack_gpio.report); //enable_irq(gpio_to_irq(tegra_wm8903_hp_jack_gpio.gpio)); val = gpio_get_value(tegra_wm8903_lineout_jack_gpio.gpio); val = tegra_wm8903_lineout_jack_gpio.invert ? !val : val; val = val ? tegra_wm8903_lineout_jack_gpio.report : 0; snd_soc_jack_report(&tegra_wm8903_lineout_jack, val, tegra_wm8903_lineout_jack_gpio.report); //enable_irq(gpio_to_irq(tegra_wm8903_lineout_jack_gpio.gpio)); //tegra_headphone_check(); }
void cs42l73_hp_detection(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int plug_status) { unsigned int status = 0; unsigned int micbias = 0; int hs_status = 0; unsigned int reg; unsigned int mask = SND_JACK_BTN_0 | SND_JACK_HEADSET; if (plug_status) { pr_debug("%s: Jack removed - disable micbias\n", __func__); cs42l73_set_mic_bias(codec, MIC_BIAS_DISABLE); } else { micbias = snd_soc_read(codec, CS42L73_PWRCTL2); micbias &= 0xC0; if (micbias) { cs42l73_set_mic_bias(codec, MIC_BIAS_ENABLE); hs_status = 1; } snd_soc_update_bits(codec, CS42L73_IM1, MIC2_SDET, MIC2_SDET); reg = snd_soc_read(codec, CS42L73_IS1); pr_debug("Mic detect = %x ISI =%x\n", micbias, reg); if (hs_status) { if ((reg & MIC2_SDET)) { status = SND_JACK_HEADPHONE; cs42l73_set_mic_bias(codec, MIC_BIAS_DISABLE); pr_debug("Headphone detected\n"); } else { status = SND_JACK_HEADSET; pr_debug("Headset detected\n"); } } } snd_soc_jack_report(jack, status, mask); #ifdef CONFIG_SWITCH_MID if (status) { if (status == SND_JACK_HEADPHONE) mid_headset_report((1<<1)); else if (status == SND_JACK_HEADSET) mid_headset_report(1); } else { mid_headset_report(0); } #endif pr_debug("Plug Status = %x\n", plug_status); pr_debug("Jack Status = %x\n", status); }
static irqreturn_t t0_g_det_thread(int irq, void *data) { struct wm1811_machine_priv *wm1811 = data; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(wm1811->codec); struct snd_soc_codec *codec = wm8994->codec; if (wm1811->get_g_det_value_f()) { pr_info("%s: G_DET_N GPIO is High!!!!", __func__); mutex_lock(&wm8994->accdet_lock); snd_soc_update_bits(codec, WM8958_MICBIAS2, WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); /* Enable debounce while removed */ snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, WM1811_JACKDET_DB, WM1811_JACKDET_DB); wm8994->mic_detecting = false; wm8994->jack_mic = false; snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); t0_jackdet_set_mode(codec, WM1811_JACKDET_MODE_JACK); mutex_unlock(&wm8994->accdet_lock); mutex_lock(&codec->mutex); snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS2"); snd_soc_dapm_sync(&codec->dapm); mutex_unlock(&codec->mutex); snd_soc_jack_report(wm8994->micdet[0].jack, 0, SND_JACK_MECHANICAL | SND_JACK_HEADSET | wm8994->btn_mask); } else { pr_info("%s: G_DET_N GPIO is Low!!!!", __func__); handle_nested_irq(WM1811_JACKDET_IRQ_NUM); msleep(100); handle_nested_irq(WM1811_MIC_IRQ_NUM); } return IRQ_HANDLED; }
/* Jack insert delayed work */ void headset_insert_poll(struct work_struct *work) { struct snd_soc_jack_gpio *gpio = &hs_gpio[CTP_HSDET_GPIO]; struct snd_soc_jack *jack = gpio->jack; struct snd_soc_codec *codec = jack->codec; struct ctp_mc_private *ctx = container_of(jack, struct ctp_mc_private, ctp_jack); int enable, status; unsigned int mask = SND_JACK_HEADSET; enable = gpio_get_value(gpio->gpio); if (enable != 0) { pr_err("%s:gpio status = 0x%d\n", __func__, enable); return; } pr_debug("%s: Current jack status = 0x%x\n", __func__, jack->status); set_mic_bias(jack, ctx->ops->mic_bias, true); msleep(ctx->ops->micsdet_debounce); status = ctx->ops->hp_detection(codec, jack, enable); if (status == SND_JACK_HEADSET) { set_bp_interrupt(ctx, true); ctx->headset_plug_flag = true; } if (jack->status != status) snd_soc_jack_report(jack, status, mask); /* * At this point the HS may be half inserted and still be * detected as HP, so recheck after HPDETECT_POLL_INTERVAL */ if (!atomic_dec_and_test(&ctx->hs_det_retry) && status != SND_JACK_HEADSET) { pr_debug("HS Jack detect Retry %d\n", atomic_read(&ctx->hs_det_retry)); #ifdef CONFIG_HAS_WAKELOCK /* Give sufficient time for the detection to propagate*/ wake_lock_timeout(ctx->jack_wake_lock, HPDETECT_POLL_INTERVAL + msecs_to_jiffies(50)); #endif schedule_delayed_work(&ctx->jack_work_insert, HPDETECT_POLL_INTERVAL); } if (!atomic_read(&ctx->hs_det_retry) && status == SND_JACK_HEADPHONE) set_mic_bias(jack, "MIC2 Bias", false); pr_debug("%s: status 0x%x\n", __func__, status); }
void tegra_wm8903_resume_pre(struct snd_soc_card *card) { int val; struct snd_soc_jack_gpio *gpio = &tegra_wm8903_hp_jack_gpio; if (gpio_is_valid(gpio->gpio)) { val = gpio_get_value(gpio->gpio); val = gpio->invert ? !val : val; snd_soc_jack_report(gpio->jack, val, gpio->report); if(!hp_irq_enb){ enable_irq(gpio_to_irq(gpio->gpio)); hp_irq_enb = 1; } } }
static int tegra_wm8903_resume_pre(struct snd_soc_card *card) { int val; struct snd_soc_jack_gpio *gpio = &tegra_wm8903_hp_jack_gpio; if (gpio_is_valid(gpio->gpio)) { val = gpio_get_value(gpio->gpio); val = gpio->invert ? !val : val; snd_soc_jack_report(gpio->jack, val, gpio->report); enable_irq(gpio_to_irq(gpio->gpio)); } return 0; }
/* Jack remove delayed work */ void headset_remove_poll(struct work_struct *work) { struct snd_soc_jack_gpio *gpio = &hs_gpio[CTP_HSDET_GPIO]; struct snd_soc_jack *jack = gpio->jack; struct snd_soc_codec *codec = jack->codec; struct ctp_mc_private *ctx = container_of(jack, struct ctp_mc_private, ctp_jack); int enable, status; unsigned int mask = SND_JACK_HEADSET; enable = gpio_get_value(gpio->gpio); if (enable == 0) { pr_err("%s:gpio status = 0x%d\n", __func__, enable); return; } pr_debug("%s: Current jack status = 0x%x\n", __func__, jack->status); status = ctx->ops->hp_detection(codec, jack, enable); set_bp_interrupt(ctx, false); ctx->headset_plug_flag = false; set_mic_bias(jack, ctx->ops->mic_bias, false); /* If the jack is removed while the button status is pressed */ pr_debug("button press flag:%d status:%x\n", ctx->btn_press_flag, status); if (ctx->btn_press_flag) { snd_soc_jack_report(jack, SND_JACK_HEADSET, SND_JACK_BTN_0 | SND_JACK_HEADSET); ctx->btn_press_flag = false; } if (jack->status != status) snd_soc_jack_report(jack, status, mask); pr_debug("%s: status 0x%x\n", __func__, status); }
static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* Add SDP4430 specific controls */ ret = snd_soc_add_controls(codec, sdp4430_controls, ARRAY_SIZE(sdp4430_controls)); if (ret) return ret; /* Add SDP4430 specific widgets */ ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets, ARRAY_SIZE(sdp4430_twl6040_dapm_widgets)); if (ret) return ret; /* Set up SDP4430 specific audio path audio_map */ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* SDP4430 connected pins */ snd_soc_dapm_enable_pin(dapm, "Ext Mic"); snd_soc_dapm_enable_pin(dapm, "Ext Spk"); snd_soc_dapm_enable_pin(dapm, "AFML"); snd_soc_dapm_enable_pin(dapm, "AFMR"); snd_soc_dapm_enable_pin(dapm, "Headset Mic"); snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); ret = snd_soc_dapm_sync(dapm); if (ret) return ret; /* Headset jack detection */ ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &hs_jack); if (ret) return ret; ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), hs_jack_pins); if (machine_is_omap_4430sdp()) twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); else snd_soc_jack_report(&hs_jack, SND_JACK_HEADSET, SND_JACK_HEADSET); return ret; }
static void aml_m3_hp_detect_queue(struct work_struct* work) { int level = 0x0; //u16 reg; struct aml_m3_work_t* pwork = container_of(work,struct aml_m3_work_t, aml_m3_workqueue); struct snd_soc_codec* codec = (struct snd_soc_codec*)(pwork->data); //if ((aml_dai[1].ac97_pdata) && ((struct aml_m3_pdata *) (aml_dai[1].ac97_pdata))->is_hp_pluged) //level = ((struct aml_m3_pdata *) (aml_dai[1].ac97_pdata))->is_hp_pluged(); level = aml_m3_is_hp_pluged(); //printk("level = %x, hp_detect_flag = %x\n", level, hp_detect_flag); if(level == 0x1 && hp_detect_flag!= 0x1){ // HP printk("Headphone pluged in\n"); snd_soc_jack_report(&hp_jack, SND_JACK_HEADSET, SND_JACK_HEADSET); //reg = snd_soc_read(codec, ADAC_MUTE_CTRL_REG1); //reg &= ~0xc0; //snd_soc_write(codec, ADAC_MUTE_CTRL_REG1, reg); //unmute HP mute_headphone(codec, 0); //unmute HP mute_spk(codec, 1); latch_(codec); hp_detect_flag = level; switch_set_state(&sdev, 1); }else if(level != hp_detect_flag){ // HDMI printk("Headphone unpluged\n"); snd_soc_jack_report(&hp_jack,0, SND_JACK_HEADSET); //reg = snd_soc_read(codec, ADAC_MUTE_CTRL_REG1); //reg |= 0xc0; //snd_soc_write(codec, ADAC_MUTE_CTRL_REG1, reg);//mute HP mute_headphone(codec,1); //mute HP mute_spk(codec, 0); latch_(codec); hp_detect_flag = level; switch_set_state(&sdev, 0); } }
static ssize_t earjack_select_jack_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct snd_soc_codec *codec = dev_get_drvdata(dev); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); wm8994->mic_detecting = false; wm8994->jack_mic = true; midas_micd_set_rate(codec); if ((!size) || (buf[0] != '1')) { snd_soc_jack_report(wm8994->micdet[0].jack, 0, SND_JACK_HEADSET); dev_info(codec->dev, "Forced remove microphone\n"); } else { snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADSET, SND_JACK_HEADSET); dev_info(codec->dev, "Forced detect microphone\n"); } return size; }
static void max97236_report_jack_state(struct max97236_priv *max97236, unsigned int *status_reg) { char string[MAX_STRING]; int state; if ((status_reg[0] & 0x88) == 0x88) { state = SND_JACK_HEADSET; string_copy(string, "HEADSET", MAX_STRING); } else if ((status_reg[0] & 0x84) == 0x84) { if ((status_reg[1] & 0xC0) == 0xC0) { state = SND_JACK_DATA; string_copy(string, "SERIAL CABLE", MAX_STRING); } else if ((status_reg[1] & 0x30) == 0x30) { state = SND_JACK_HEADPHONE; string_copy(string, "HEADPHONES", MAX_STRING); } } else if ((status_reg[0] & 0x80) == 0x80) { state = SND_JACK_HEADPHONE; string_copy(string, "HEADPHONES", MAX_STRING); } else if ((status_reg[1] == 0xCC) && (status_reg[2] == 0xCC)) { #if 0 state = M97236_JACK_STATE_UNKNOWN; string_copy(string, "UNKNOWN", MAX_STRING); #else state = SND_JACK_HEADSET; string_copy(string, "HEADSET", MAX_STRING); #endif } else if ((status_reg[1] & 0xCC) == 0xCC) { state = SND_JACK_LINEOUT; string_copy(string, "LINEOUT", MAX_STRING); } else { state = M97236_JACK_STATE_NONE; string_copy(string, "NOTHING", MAX_STRING); } dev_info(max97236->codec->dev, "0x%02X, 0x%02X, 0x%02X - %s\n", status_reg[0], status_reg[1], status_reg[2], string); if (max97236->jack_state != state) { snd_soc_jack_report(max97236->jack, state, SND_JACK_HEADSET | SND_JACK_LINEOUT); max97236->jack_state = state; } }
static irqreturn_t wm8350_mic_handler(int irq, void *data) { struct wm8350_data *priv = data; struct wm8350 *wm8350 = priv->codec.control_data; u16 reg; int report = 0; reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); if (reg & WM8350_JACK_MICSCD_LVL) report |= priv->mic.short_report; if (reg & WM8350_JACK_MICSD_LVL) report |= priv->mic.report; snd_soc_jack_report(priv->mic.jack, report, priv->mic.report | priv->mic.short_report); return IRQ_HANDLED; }
static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) { struct wm8350_data *priv = data; struct wm8350 *wm8350 = priv->codec.control_data; u16 reg; int report; int mask; struct wm8350_jack_data *jack = NULL; switch (irq - wm8350->irq_base) { case WM8350_IRQ_CODEC_JCK_DET_L: jack = &priv->hpl; mask = WM8350_JACK_L_LVL; break; case WM8350_IRQ_CODEC_JCK_DET_R: jack = &priv->hpr; mask = WM8350_JACK_R_LVL; break; default: BUG(); } if (!jack->jack) { dev_warn(wm8350->dev, "Jack interrupt called with no jack\n"); return IRQ_NONE; } /* Debounce */ msleep(200); reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); if (reg & mask) report = jack->report; else report = 0; snd_soc_jack_report(jack->jack, report, jack->report); return IRQ_HANDLED; }
static int tegra_aic326x_resume_pre(struct snd_soc_card *card) { int val; struct snd_soc_jack_gpio *gpio = &tegra_aic326x_hp_jack_gpio; struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card); if (gpio_is_valid(gpio->gpio)) { val = gpio_get_value(gpio->gpio); val = gpio->invert ? !val : val; snd_soc_jack_report(gpio->jack, val, gpio->report); enable_irq(gpio_to_irq(gpio->gpio)); } if (!machine->clock_enabled) { machine->clock_enabled = 1; tegra_asoc_utils_clk_enable(&machine->util_data); } return 0; }
static void twl6040_hs_jack_report(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int report) { struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); int status, state; mutex_lock(&priv->mutex); /* Sync status */ status = twl6040_read_reg_volatile(codec, TWL6040_REG_STATUS); if (status & TWL6040_PLUGCOMP) state = report; else state = 0; mutex_unlock(&priv->mutex); snd_soc_jack_report(jack, state, report); switch_set_state(&priv->hs_jack.sdev, !!state); }
static ssize_t reselect_jack_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct snd_soc_codec *codec = dev_get_drvdata(dev); struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int reg = 0; reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); if (reg == 0x402) { dev_info(codec->dev, "Detected open circuit\n"); snd_soc_update_bits(codec, WM8958_MICBIAS2, WM8958_MICB2_DISCH, WM8958_MICB2_DISCH); /* Enable debounce while removed */ snd_soc_update_bits(codec, WM1811_JACKDET_CTRL, WM1811_JACKDET_DB, WM1811_JACKDET_DB); wm8994->mic_detecting = false; wm8994->jack_mic = false; snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); if (wm8994->active_refcount) { snd_soc_update_bits(codec, WM8994_ANTIPOP_2, WM1811_JACKDET_MODE_MASK, WM1811_JACKDET_MODE_AUDIO); } else { snd_soc_update_bits(codec, WM8994_ANTIPOP_2, WM1811_JACKDET_MODE_MASK, WM1811_JACKDET_MODE_JACK); } snd_soc_jack_report(wm8994->micdet[0].jack, 0, SND_JACK_MECHANICAL | SND_JACK_HEADSET | wm8994->btn_mask); } return size; }