Esempio n. 1
0
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;
    }
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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;
}
Esempio n. 8
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, &reg);
#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,
			&reg);
		regmap_read(max97236->regmap, M97236_REG_01_STATUS2,
			&reg);
#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
	}
}
Esempio n. 9
0
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;
}
Esempio n. 12
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,
				&reg);
	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;
}
Esempio n. 14
0
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;
    }
}
Esempio n. 15
0
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();
}
Esempio n. 16
0
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);

}
Esempio n. 17
0
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);
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
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;
}
Esempio n. 25
0
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;
	}
}
Esempio n. 26
0
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;
}
Esempio n. 27
0
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;
}
Esempio n. 29
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;
}