static void t0_micdet(u16 status, void *data)
{
	struct wm1811_machine_priv *wm1811 = data;
	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(wm1811->codec);
	int report;

	/*
	 * If the jack is inserted abnormally,
	 * The variable puts back to its previous status.
	 */
	if (!wm1811->get_g_det_value_f) {
		dev_err(wm1811->codec->dev, "Do not use the ground detection\n");
	} else {
		if (wm1811->get_g_det_value_f()) {
			dev_info(wm1811->codec->dev, "The jack is inserted abnormally\n");

			wm8994->mic_detecting = false;
		}
	}

	wake_lock_timeout(&wm1811->jackdet_wake_lock, 5 * HZ);

	/* Either nothing present or just starting detection */
	if (!(status & WM8958_MICD_STS)) {
		if (!wm8994->jackdet) {
			/* If nothing present then clear our statuses */
			dev_dbg(wm1811->codec->dev, "Detected open circuit\n");
			wm8994->jack_mic = false;
			wm8994->mic_detecting = true;

			t0_micd_set_rate(wm1811->codec);

			snd_soc_jack_report(wm8994->micdet[0].jack, 0,
					    wm8994->btn_mask |
					     SND_JACK_HEADSET);
		}
		/*ToDo*/
		/*return;*/
	}

	/* If the measurement is showing a high impedence we've got a
	 * microphone.
	 */
	if (wm8994->mic_detecting && (status & 0x400)) {
		dev_info(wm1811->codec->dev, "Detected microphone\n");

		wm8994->mic_detecting = false;
		wm8994->jack_mic = true;

		t0_micd_set_rate(wm1811->codec);

		snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADSET,
				    SND_JACK_HEADSET);
	}

	if (wm8994->mic_detecting && status & 0x4) {
		dev_info(wm1811->codec->dev, "Detected headphone\n");
		wm8994->mic_detecting = false;

		t0_micd_set_rate(wm1811->codec);

		snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
				    SND_JACK_HEADSET);

		/* If we have jackdet that will detect removal */
		if (wm8994->jackdet) {
			mutex_lock(&wm8994->accdet_lock);

			snd_soc_update_bits(wm1811->codec, WM8958_MIC_DETECT_1,
					    WM8958_MICD_ENA, 0);

			if (wm8994->active_refcount) {
				snd_soc_update_bits(wm1811->codec,
					WM8994_ANTIPOP_2,
					WM1811_JACKDET_MODE_MASK,
					WM1811_JACKDET_MODE_AUDIO);
			}

			mutex_unlock(&wm8994->accdet_lock);

			if (wm8994->pdata->jd_ext_cap) {
				mutex_lock(&wm1811->codec->mutex);
				snd_soc_dapm_disable_pin(&wm1811->codec->dapm,
							 "MICBIAS2");
				snd_soc_dapm_sync(&wm1811->codec->dapm);
				mutex_unlock(&wm1811->codec->mutex);
			}
		}
	}

	/* Report short circuit as a button */
	if (wm8994->jack_mic) {
		report = 0;
		if (status & WM1811_JACKDET_BTN0)
			report |= SND_JACK_BTN_0;

		if (status & WM1811_JACKDET_BTN1)
			report |= SND_JACK_BTN_1;

		if (status & WM1811_JACKDET_BTN2)
			report |= SND_JACK_BTN_2;

		dev_info(wm1811->codec->dev, "Detected Button: %08x (%08X)\n",
			report, status);

		snd_soc_jack_report(wm8994->micdet[0].jack, report,
				    wm8994->btn_mask);
	}
}
Exemple #2
0
static int tab3_wm1811_init_paiftx(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	struct wm1811_machine_priv *wm1811
		= snd_soc_card_get_drvdata(codec->card);
	struct snd_soc_dai *aif1_dai = rtd->codec_dai;
	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
	int ret;

	midas_snd_set_mclk(true, false);

	rtd->codec_dai->driver->playback.channels_max =
				rtd->cpu_dai->driver->playback.channels_max;

	ret = snd_soc_add_controls(codec, tab3_controls,
					ARRAY_SIZE(tab3_controls));

#if defined(CONFIG_TAB3_00_BD)
	if(system_rev < 2) {
		ret = snd_soc_dapm_new_controls(&codec->dapm, tab3_dapm_widgets_rev0,
				ARRAY_SIZE(tab3_dapm_widgets_rev0));
		if (ret != 0)
			dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret);

		ret = snd_soc_dapm_add_routes(&codec->dapm, tab3_dapm_routes_rev0,
				ARRAY_SIZE(tab3_dapm_routes_rev0));
		if (ret != 0)
			dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret);
	} else {
		ret = snd_soc_dapm_new_controls(&codec->dapm, tab3_dapm_widgets,
				ARRAY_SIZE(tab3_dapm_widgets));
		if (ret != 0)
			dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret);

		ret = snd_soc_dapm_add_routes(&codec->dapm, tab3_dapm_routes,
				ARRAY_SIZE(tab3_dapm_routes));
		if (ret != 0)
			dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret);
	}
#else
	ret = snd_soc_dapm_new_controls(&codec->dapm, tab3_dapm_widgets,
			ARRAY_SIZE(tab3_dapm_widgets));
	if (ret != 0)
		dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret);

	ret = snd_soc_dapm_add_routes(&codec->dapm, tab3_dapm_routes,
			ARRAY_SIZE(tab3_dapm_routes));
	if (ret != 0)
		dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret);

#endif

	ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2,
				     MIDAS_DEFAULT_MCLK2, SND_SOC_CLOCK_IN);
	if (ret < 0)
		dev_err(codec->dev, "Failed to boot clocking\n");

	/* Force AIF1CLK on as it will be master for jack detection */
	if (wm8994->revision > 1) {
		ret = snd_soc_dapm_force_enable_pin(&codec->dapm, "AIF1CLK");
		if (ret < 0)
			dev_err(codec->dev, "Failed to enable AIF1CLK: %d\n",
					ret);
	}

	ret = snd_soc_dapm_disable_pin(&codec->dapm, "S5P RP");
	if (ret < 0)
		dev_err(codec->dev, "Failed to disable S5P RP: %d\n", ret);

	snd_soc_dapm_ignore_suspend(&codec->dapm, "RCV");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "SPK");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "HP");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "Headset Mic");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "Sub Mic");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "Main Mic");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1DACDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2DACDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3DACDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1ADCDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2ADCDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3ADCDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "FM In");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "LINE");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "HDMI");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "Third Mic");

	wm1811->codec = codec;

	tab3_micd_set_rate(codec);

#ifdef CONFIG_SEC_DEV_JACK
	/* By default use idle_bias_off, will override for WM8994 */
	codec->dapm.idle_bias_off = 0;
#if defined (CONFIG_TAB3_00_BD)
	if(system_rev < 2) {
		ret = snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS2");
		if (ret < 0)
			dev_err(codec->dev, "Failed to enable MICBIAS2: %d\n",
					ret);
	}
#endif
#else /* CONFIG_SEC_DEV_JACK */
	wm1811->jack.status = 0;

	ret = snd_soc_jack_new(codec, "Tab3 Jack",
				SND_JACK_HEADSET | SND_JACK_BTN_0 |
				SND_JACK_BTN_1 | SND_JACK_BTN_2,
				&wm1811->jack);

	if (ret < 0)
		dev_err(codec->dev, "Failed to create jack: %d\n", ret);

	ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_0, KEY_MEDIA);

	if (ret < 0)
		dev_err(codec->dev, "Failed to set KEY_MEDIA: %d\n", ret);

	ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_1,
							KEY_VOLUMEUP);
	if (ret < 0)
		dev_err(codec->dev, "Failed to set KEY_VOLUMEUP: %d\n", ret);

	ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_2,
							KEY_VOLUMEDOWN);

	if (ret < 0)
		dev_err(codec->dev, "Failed to set KEY_VOLUMEDOWN: %d\n", ret);

	if (wm8994->revision > 1) {
		dev_info(codec->dev, "wm1811: Rev %c support mic detection\n",
			'A' + wm8994->revision);
		ret = wm8958_mic_detect(codec, &wm1811->jack, NULL,
				NULL, tab3_mic_id, wm1811);

		if (ret < 0)
			dev_err(codec->dev, "Failed start detection: %d\n",
				ret);
	} else {
		dev_info(codec->dev, "wm1811: Rev %c doesn't support mic detection\n",
			'A' + wm8994->revision);
		codec->dapm.idle_bias_off = 0;
	}
	/* To wakeup for earjack event in suspend mode */
	enable_irq_wake(control->irq);

	wake_lock_init(&wm1811->jackdet_wake_lock,
					WAKE_LOCK_SUSPEND, "Tab3_jackdet");

	/* To support PBA function test */
	jack_class = class_create(THIS_MODULE, "audio");

	if (IS_ERR(jack_class))
		pr_err("Failed to create class\n");

	jack_dev = device_create(jack_class, NULL, 0, codec, "earjack");

	if (device_create_file(jack_dev, &dev_attr_select_jack) < 0)
		pr_err("Failed to create device file (%s)!\n",
			dev_attr_select_jack.attr.name);

	if (device_create_file(jack_dev, &dev_attr_key_state) < 0)
		pr_err("Failed to create device file (%s)!\n",
			dev_attr_key_state.attr.name);

	if (device_create_file(jack_dev, &dev_attr_state) < 0)
		pr_err("Failed to create device file (%s)!\n",
			dev_attr_state.attr.name);

	if (device_create_file(jack_dev, &dev_attr_reselect_jack) < 0)
		pr_err("Failed to create device file (%s)!\n",
			dev_attr_reselect_jack.attr.name);

#endif /* CONFIG_SEC_DEV_JACK */
	return snd_soc_dapm_sync(&codec->dapm);
}
Exemple #3
0
static int archos_omap4_twl6040_init(struct snd_soc_pcm_runtime *rtd)
{
    struct snd_soc_codec *codec = rtd->codec;
    struct twl6040 *twl6040 = codec->control_data;
    struct snd_soc_dapm_context *dapm = &codec->dapm;
    int hsotrim, left_offset, right_offset, mode, ret;


    /* Add specific controls */
    ret = snd_soc_add_controls(codec, archos_omap4_controls,
                               ARRAY_SIZE(archos_omap4_controls));
    if (ret)
        return ret;

    /* Add specific widgets */
    ret = snd_soc_dapm_new_controls(dapm, archos_omap4_twl6040_dapm_widgets,
                                    ARRAY_SIZE(archos_omap4_twl6040_dapm_widgets));
    if (ret)
        return ret;

    /* Set up specific audio path audio_map */
    snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));

    /* 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");

    /* allow audio paths from the audio modem to run during suspend */
    snd_soc_dapm_ignore_suspend(dapm, "Ext Mic");
    snd_soc_dapm_ignore_suspend(dapm, "Ext Spk");
    snd_soc_dapm_ignore_suspend(dapm, "AFML");
    snd_soc_dapm_ignore_suspend(dapm, "AFMR");
    snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
    snd_soc_dapm_ignore_suspend(dapm, "Headset Stereophone");
    snd_soc_dapm_ignore_suspend(dapm, "Digital Mic 0");
    snd_soc_dapm_ignore_suspend(dapm, "Digital Mic 1");
    snd_soc_dapm_ignore_suspend(dapm, "Digital Mic 2");

    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);

    twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);

    /* DC offset cancellation computation */
    hsotrim = snd_soc_read(codec, TWL6040_REG_HSOTRIM);
    right_offset = (hsotrim & TWL6040_HSRO) >> TWL6040_HSRO_OFFSET;
    left_offset = hsotrim & TWL6040_HSLO;

    if (twl6040_get_icrev(twl6040) < TWL6040_REV_1_3)
        /* For ES under ES_1.3 HS step is 2 mV */
        mode = 2;
    else
        /* For ES_1.3 HS step is 1 mV */
        mode = 1;

    abe_dsp_set_hs_offset(left_offset, right_offset, mode);

    /* don't wait before switching of HS power */
    rtd->pmdown_time = 0;

    return ret;
}
Exemple #4
0
static void msm8960_enable_ext_spk_amp_gpio(u32 spk_amp_gpio)
{
	int ret = 0;

	struct pm_gpio param = {
		.direction      = PM_GPIO_DIR_OUT,
		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
		.output_value   = 1,
		.pull      = PM_GPIO_PULL_NO,
		.vin_sel	= PM_GPIO_VIN_S4,
		.out_strength   = PM_GPIO_STRENGTH_MED,
		.
			function       = PM_GPIO_FUNC_NORMAL,
	};

	if (spk_amp_gpio == bottom_spk_pamp_gpio) {

		ret = gpio_request(bottom_spk_pamp_gpio, "BOTTOM_SPK_AMP");
		if (ret) {
			pr_err("%s: Error requesting BOTTOM SPK AMP GPIO %u\n",
				__func__, bottom_spk_pamp_gpio);
			return;
		}
		ret = pm8xxx_gpio_config(bottom_spk_pamp_gpio, &param);
		if (ret)
			pr_err("%s: Failed to configure Bottom Spk Ampl"
				" gpio %u\n", __func__, bottom_spk_pamp_gpio);
		else {
			pr_debug("%s: enable Bottom spkr amp gpio\n", __func__);
			gpio_direction_output(bottom_spk_pamp_gpio, 1);
		}

	} else if (spk_amp_gpio == top_spk_pamp_gpio) {

		ret = gpio_request(top_spk_pamp_gpio, "TOP_SPK_AMP");
		if (ret) {
			pr_err("%s: Error requesting GPIO %d\n", __func__,
				top_spk_pamp_gpio);
			return;
		}
		ret = pm8xxx_gpio_config(top_spk_pamp_gpio, &param);
		if (ret)
			pr_err("%s: Failed to configure Top Spk Ampl"
				" gpio %u\n", __func__, top_spk_pamp_gpio);
		else {
			pr_debug("%s: enable Top spkr amp gpio\n", __func__);
			gpio_direction_output(top_spk_pamp_gpio, 1);
		}
	} else {
		pr_err("%s: ERROR : Invalid External Speaker Ampl GPIO."
			" gpio = %u\n", __func__, spk_amp_gpio);
		return;
	}
}

static void msm8960_ext_single_ended_spk_power_amp_on(u32 spk)
{
	if (spk & BOTTOM_SPK_AMP) {

		if (msm8960_ext_bottom_spk_pamp) {

			pr_debug("%s() External Bottom Speaker Ampl already "
				"turned on. spk = 0x%08x\n", __func__, spk);
			return;
		}

		pr_debug("%s: wait 50 ms before turning on "
			" external Bottom Speaker Ampl\n", __func__);
		usleep_range(50000, 50000);

		msm8960_enable_ext_spk_amp_gpio(bottom_spk_pamp_gpio);
		msm8960_ext_bottom_spk_pamp = 1;
		pr_debug("%s: sleeping 4 ms after turning on external "
			" Bottom Speaker Ampl\n", __func__);
		usleep_range(4000, 4000);

	} else if (spk & TOP_SPK_AMP) {

		if (msm8960_ext_top_spk_pamp) {

			pr_debug("%s() External Top Speaker Ampl already"
				"turned on. spk = 0x%08x\n", __func__, spk);
			return;
		}

		pr_debug("%s: wait 50 ms before turning on "
			" external Top Speaker Ampl\n", __func__);
		usleep_range(50000, 50000);

		msm8960_enable_ext_spk_amp_gpio(top_spk_pamp_gpio);
		msm8960_ext_top_spk_pamp = 1;
		pr_debug("%s: sleeping 4 ms after turning on "
			" external Top Speaker Ampl\n", __func__);
		usleep_range(4000, 4000);
	} else  {

		pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n",
			__func__, spk);
		return;
	}
}

static void msm8960_ext_spk_power_amp_on(u32 spk)
{
	if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {

		if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
			(msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) {

			pr_debug("%s() External Bottom Speaker Ampl already "
				"turned on. spk = 0x%08x\n", __func__, spk);
			return;
		}

		msm8960_ext_bottom_spk_pamp |= spk;

		if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
			(msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) {

			msm8960_enable_ext_spk_amp_gpio(bottom_spk_pamp_gpio);
			pr_debug("%s: slepping 4 ms after turning on external "
				" Bottom Speaker Ampl\n", __func__);
			usleep_range(4000, 4000);
		}

	} else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {

		if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
			(msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {

			pr_debug("%s() External Top Speaker Ampl already"
				"turned on. spk = 0x%08x\n", __func__, spk);
			return;
		}

		msm8960_ext_top_spk_pamp |= spk;

		if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
			(msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {

			msm8960_enable_ext_spk_amp_gpio(top_spk_pamp_gpio);
			pr_debug("%s: sleeping 4 ms after turning on "
				" external Top Speaker Ampl\n", __func__);
			usleep_range(4000, 4000);
		}
	} else  {

		pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n",
			__func__, spk);
		return;
	}
}

static void msm8960_ext_single_ended_spk_power_amp_off(u32 spk)
{
	if (spk & BOTTOM_SPK_AMP) {

		if (!msm8960_ext_bottom_spk_pamp)
			return;

		gpio_direction_output(bottom_spk_pamp_gpio, 0);
		gpio_free(bottom_spk_pamp_gpio);
		msm8960_ext_bottom_spk_pamp = 0;

		pr_debug("%s: sleeping 4 ms after turning off external Bottom"
			" Speaker Ampl\n", __func__);

		usleep_range(4000, 4000);

	} else if (spk & TOP_SPK_AMP) {

		if (!msm8960_ext_top_spk_pamp)
			return;

		gpio_direction_output(top_spk_pamp_gpio, 0);
		gpio_free(top_spk_pamp_gpio);
		msm8960_ext_top_spk_pamp = 0;

		pr_debug("%s: sleeping 4 ms after turning off external Top"
			" Spkaker Ampl\n", __func__);

		usleep_range(4000, 4000);
	} else  {

		pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n",
			__func__, spk);
		return;
	}
}

static void msm8960_ext_spk_power_amp_off(u32 spk)
{
	if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {

		if (!msm8960_ext_bottom_spk_pamp)
			return;

		gpio_direction_output(bottom_spk_pamp_gpio, 0);
		gpio_free(bottom_spk_pamp_gpio);
		msm8960_ext_bottom_spk_pamp = 0;

		pr_debug("%s: sleeping 4 ms after turning off external Bottom"
			" Speaker Ampl\n", __func__);

		usleep_range(4000, 4000);

	} else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {

		if (!msm8960_ext_top_spk_pamp)
			return;

		gpio_direction_output(top_spk_pamp_gpio, 0);
		gpio_free(top_spk_pamp_gpio);
		msm8960_ext_top_spk_pamp = 0;

		pr_debug("%s: sleeping 4 ms after turning off external Top"
			" Spkaker Ampl\n", __func__);

		usleep_range(4000, 4000);
	} else  {

		pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n",
			__func__, spk);
		return;
	}
}

static void msm8960_ext_single_ended_control(struct snd_soc_codec *codec)
{
	struct snd_soc_dapm_context *dapm = &codec->dapm;

	mutex_lock(&dapm->codec->mutex);

	pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control);
	if (msm8960_spk_control == MSM8960_SPK_ON) {
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom");
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Top");
	} else {
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom");
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Top");
	}

	snd_soc_dapm_sync(dapm);
	mutex_unlock(&dapm->codec->mutex);
}

/* QCT reference code assumes differential speaker */
/*
static void msm8960_ext_control(struct snd_soc_codec *codec)
{
	struct snd_soc_dapm_context *dapm = &codec->dapm;

	mutex_lock(&dapm->codec->mutex);

	pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control);
	if (msm8960_spk_control == MSM8960_SPK_ON) {
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
	} else {
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Pos");
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Neg");
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Pos");
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Neg");
	}

	snd_soc_dapm_sync(dapm);
	mutex_unlock(&dapm->codec->mutex);
}
*/

static int msm8960_get_spk(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control);
	ucontrol->value.integer.value[0] = msm8960_spk_control;
	return 0;
}
Exemple #5
0
static int ams_delta_cx20442_init(struct snd_soc_codec *codec)
{
	struct snd_soc_dai *codec_dai = codec->dai;
	struct snd_soc_card *card = codec->socdev->card;
	int ret;
	/* Codec is ready, now add/activate board specific controls */

	/* Set up digital mute if not provided by the codec */
	if (!codec_dai->ops) {
		codec_dai->ops = &ams_delta_dai_ops;
	} else if (!codec_dai->ops->digital_mute) {
		codec_dai->ops->digital_mute = ams_delta_digital_mute;
	} else {
		ams_delta_ops.startup = ams_delta_startup;
		ams_delta_ops.shutdown = ams_delta_shutdown;
	}

	/* Set codec bias level */
	ams_delta_set_bias_level(card, SND_SOC_BIAS_STANDBY);

	/* Add hook switch - can be used to control the codec from userspace
	 * even if line discipline fails */
	ret = snd_soc_jack_new(card, "hook_switch",
				SND_JACK_HEADSET, &ams_delta_hook_switch);
	if (ret)
		dev_warn(card->dev,
				"Failed to allocate resources for hook switch, "
				"will continue without one.\n");
	else {
		ret = snd_soc_jack_add_gpios(&ams_delta_hook_switch,
					ARRAY_SIZE(ams_delta_hook_switch_gpios),
					ams_delta_hook_switch_gpios);
		if (ret)
			dev_warn(card->dev,
				"Failed to set up hook switch GPIO line, "
				"will continue with hook switch inactive.\n");
	}

	/* Register optional line discipline for over the modem control */
	ret = tty_register_ldisc(N_V253, &cx81801_ops);
	if (ret) {
		dev_warn(card->dev,
				"Failed to register line discipline, "
				"will continue without any controls.\n");
		return 0;
	}

	/* Add board specific DAPM widgets and routes */
	ret = snd_soc_dapm_new_controls(codec, ams_delta_dapm_widgets,
					ARRAY_SIZE(ams_delta_dapm_widgets));
	if (ret) {
		dev_warn(card->dev,
				"Failed to register DAPM controls, "
				"will continue without any.\n");
		return 0;
	}

	ret = snd_soc_dapm_add_routes(codec, ams_delta_audio_map,
					ARRAY_SIZE(ams_delta_audio_map));
	if (ret) {
		dev_warn(card->dev,
				"Failed to set up DAPM routes, "
				"will continue with codec default map.\n");
		return 0;
	}

	/* Set up initial pin constellation */
	snd_soc_dapm_disable_pin(codec, "Mouthpiece");
	snd_soc_dapm_enable_pin(codec, "Earpiece");
	snd_soc_dapm_enable_pin(codec, "Microphone");
	snd_soc_dapm_disable_pin(codec, "Speaker");
	snd_soc_dapm_disable_pin(codec, "AGCIN");
	snd_soc_dapm_disable_pin(codec, "AGCOUT");
	snd_soc_dapm_sync(codec);

	/* Add virtual switch */
	ret = snd_soc_add_controls(codec, ams_delta_audio_controls,
					ARRAY_SIZE(ams_delta_audio_controls));
	if (ret)
		dev_warn(card->dev,
				"Failed to register audio mode control, "
				"will continue without it.\n");

	return 0;
}
Exemple #6
0
static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	struct snd_soc_card *card = codec->card;
	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
	struct tegra_wm8903_platform_data *pdata = machine->pdata;
	int ret;

	machine->bias_level = SND_SOC_BIAS_STANDBY;

	if (gpio_is_valid(pdata->gpio_spkr_en)) {
		ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
		if (ret) {
			dev_err(card->dev, "cannot get spkr_en gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_SPKR_EN;

		gpio_direction_output(pdata->gpio_spkr_en, 0);
	}

	if (gpio_is_valid(pdata->gpio_hp_mute)) {
		ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
		if (ret) {
			dev_err(card->dev, "cannot get hp_mute gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_HP_MUTE;

		gpio_direction_output(pdata->gpio_hp_mute, 0);
	}

	if (gpio_is_valid(pdata->gpio_int_mic_en)) {
		ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
		if (ret) {
			dev_err(card->dev, "cannot get int_mic_en gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_INT_MIC_EN;

		/* Disable int mic; enable signal is active-high */
		gpio_direction_output(pdata->gpio_int_mic_en, 0);
	}

	if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
		ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
		if (ret) {
			dev_err(card->dev, "cannot get ext_mic_en gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_EXT_MIC_EN;

		/* Enable ext mic; enable signal is active-low */
		gpio_direction_output(pdata->gpio_ext_mic_en, 0);
	}

	if (machine_is_cardhu() || machine_is_ventana() || machine_is_rambo() ||
		machine_is_eva()) {
		ret = snd_soc_add_controls(codec, cardhu_controls,
				ARRAY_SIZE(cardhu_controls));
		if (ret < 0)
			return ret;

		snd_soc_dapm_new_controls(dapm, cardhu_dapm_widgets,
				ARRAY_SIZE(cardhu_dapm_widgets));
	}
	else {
		ret = snd_soc_add_controls(codec,
				tegra_wm8903_default_controls,
				ARRAY_SIZE(tegra_wm8903_default_controls));
		if (ret < 0)
			return ret;

		snd_soc_dapm_new_controls(dapm,
				tegra_wm8903_default_dapm_widgets,
				ARRAY_SIZE(tegra_wm8903_default_dapm_widgets));
	}

	if (machine_is_harmony()) {
		snd_soc_dapm_add_routes(dapm, harmony_audio_map,
					ARRAY_SIZE(harmony_audio_map));
	} else if (machine_is_cardhu() || machine_is_ventana() || machine_is_rambo() ||
		machine_is_eva()) {
		snd_soc_dapm_add_routes(dapm, cardhu_audio_map,
					ARRAY_SIZE(cardhu_audio_map));
	} else if (machine_is_seaboard()) {
		snd_soc_dapm_add_routes(dapm, seaboard_audio_map,
					ARRAY_SIZE(seaboard_audio_map));
	} else if (machine_is_kaen()) {
		snd_soc_dapm_add_routes(dapm, kaen_audio_map,
					ARRAY_SIZE(kaen_audio_map));
	} else {
		snd_soc_dapm_add_routes(dapm, aebl_audio_map,
					ARRAY_SIZE(aebl_audio_map));
	}

	if (gpio_is_valid(pdata->gpio_hp_det)) {
		tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det;

		if (pdata->hp_det_active_high)
			tegra_wm8903_hp_jack_gpio.invert = 0;
		else
			tegra_wm8903_hp_jack_gpio.invert = 1;

		snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
				&tegra_wm8903_hp_jack);
#ifndef CONFIG_SWITCH
		snd_soc_jack_add_pins(&tegra_wm8903_hp_jack,
					ARRAY_SIZE(tegra_wm8903_hp_jack_pins),
					tegra_wm8903_hp_jack_pins);
#else
		snd_soc_jack_notifier_register(&tegra_wm8903_hp_jack,
					&tegra_wm8903_jack_detect_nb);
#endif
		snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack,
					1,
					&tegra_wm8903_hp_jack_gpio);
		machine->gpio_requested |= GPIO_HP_DET;
	}

	snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
			 &tegra_wm8903_mic_jack);
#ifndef CONFIG_SWITCH
	snd_soc_jack_add_pins(&tegra_wm8903_mic_jack,
			      ARRAY_SIZE(tegra_wm8903_mic_jack_pins),
			      tegra_wm8903_mic_jack_pins);
#else
	snd_soc_jack_notifier_register(&tegra_wm8903_mic_jack,
				&tegra_wm8903_jack_detect_nb);
#endif
	wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
			  machine_is_cardhu() || machine_is_rambo() ? SND_JACK_MICROPHONE : 0);

	snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");

	/* FIXME: Calculate automatically based on DAPM routes? */
	if (!machine_is_harmony() && !machine_is_ventana() &&
	    !machine_is_cardhu() && !machine_is_rambo() && !machine_is_eva())
		snd_soc_dapm_nc_pin(dapm, "IN1L");
	if (!machine_is_seaboard() && !machine_is_aebl() &&
	    !machine_is_cardhu() && !machine_is_rambo())
		snd_soc_dapm_nc_pin(dapm, "IN1R");
	snd_soc_dapm_nc_pin(dapm, "IN2L");
	if (!machine_is_kaen())
		snd_soc_dapm_nc_pin(dapm, "IN2R");
	snd_soc_dapm_nc_pin(dapm, "IN3L");
	snd_soc_dapm_nc_pin(dapm, "IN3R");

	if (machine_is_aebl()) {
		snd_soc_dapm_nc_pin(dapm, "LON");
		snd_soc_dapm_nc_pin(dapm, "RON");
		snd_soc_dapm_nc_pin(dapm, "ROP");
		snd_soc_dapm_nc_pin(dapm, "LOP");
	} else {
		snd_soc_dapm_nc_pin(dapm, "LINEOUTR");
		snd_soc_dapm_nc_pin(dapm, "LINEOUTL");
	}

	snd_soc_dapm_sync(dapm);

	return 0;
}
static int tegra_aic326x_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	struct snd_soc_card *card = codec->card;
	struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card);
	struct tegra_asoc_platform_data *pdata = machine->pdata;
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai);
#endif
	int ret;

#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	if (machine->codec_info[BASEBAND].i2s_id != -1)
		i2s->is_dam_used = true;
#endif

	if (machine->init_done)
		return 0;

	machine->init_done = true;

#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	machine->pcard = card;
#endif

	if (machine_is_whistler()) {
		machine->audio_reg = regulator_get(NULL, "avddio_audio");
		if (IS_ERR(machine->audio_reg)) {
			dev_err(card->dev, "cannot get avddio_audio reg\n");
			ret = PTR_ERR(machine->audio_reg);
			return ret;
		}

		ret = regulator_enable(machine->audio_reg);
		if (ret) {
			dev_err(card->dev, "cannot enable avddio_audio reg\n");
			regulator_put(machine->audio_reg);
			machine->audio_reg = NULL;
			return ret;
		}
	}

	if (gpio_is_valid(pdata->gpio_spkr_en)) {
		ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
		if (ret) {
			dev_err(card->dev, "cannot get spkr_en gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_SPKR_EN;

		gpio_direction_output(pdata->gpio_spkr_en, 0);
	}

	if (gpio_is_valid(pdata->gpio_hp_mute)) {
		ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
		if (ret) {
			dev_err(card->dev, "cannot get hp_mute gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_HP_MUTE;

		gpio_direction_output(pdata->gpio_hp_mute, 0);
	}

	if (gpio_is_valid(pdata->gpio_int_mic_en)) {
		ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
		if (ret) {
			dev_err(card->dev, "cannot get int_mic_en gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_INT_MIC_EN;

		/* Disable int mic; enable signal is active-high */
		gpio_direction_output(pdata->gpio_int_mic_en, 0);
	}

	if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
		ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
		if (ret) {
			dev_err(card->dev, "cannot get ext_mic_en gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_EXT_MIC_EN;

		/* Enable ext mic; enable signal is active-low */
		gpio_direction_output(pdata->gpio_ext_mic_en, 0);
	}

	ret = snd_soc_add_controls(codec, tegra_aic326x_controls,
				   ARRAY_SIZE(tegra_aic326x_controls));
	if (ret < 0)
		return ret;

	snd_soc_dapm_new_controls(dapm, tegra_aic326x_dapm_widgets,
					ARRAY_SIZE(tegra_aic326x_dapm_widgets));

	snd_soc_dapm_add_routes(dapm, aic326x_audio_map,
					ARRAY_SIZE(aic326x_audio_map));

	ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
			&tegra_aic326x_hp_jack);
	if (ret < 0)
		return ret;

#ifdef CONFIG_SWITCH
	snd_soc_jack_notifier_register(&tegra_aic326x_hp_jack,
		&aic326x_headset_switch_nb);
#else /*gpio based headset detection*/
	snd_soc_jack_add_pins(&tegra_aic326x_hp_jack,
		ARRAY_SIZE(tegra_aic326x_hp_jack_pins),
		tegra_aic326x_hp_jack_pins);
#endif

	aic326x_headset_detect(codec, &tegra_aic326x_hp_jack,
		SND_JACK_HEADSET);

	/* Add call mode switch control */
	ret = snd_ctl_add(codec->card->snd_card,
			snd_ctl_new1(&tegra_aic326x_call_mode_control,
				machine));
	if (ret < 0)
		return ret;

	snd_soc_dapm_force_enable_pin(dapm, "MICBIAS_EXT ON");
	snd_soc_dapm_force_enable_pin(dapm,"MICBIAS_INT ON");
	snd_soc_dapm_sync(dapm);

	return 0;
}
Exemple #8
0
static int msm8960_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
	int err;
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	struct pm_gpio jack_gpio_cfg = {
		.direction = PM_GPIO_DIR_IN,
		.pull = PM_GPIO_PULL_UP_1P5,
		.function = PM_GPIO_FUNC_NORMAL,
		.vin_sel = 2,
		.inv_int_pol = 0,
	};

	pr_debug("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));

	if (machine_is_msm8960_liquid()) {
		top_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(19));
		bottom_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(18));
	}

	snd_soc_dapm_new_controls(dapm, msm8960_dapm_widgets,
				ARRAY_SIZE(msm8960_dapm_widgets));

	snd_soc_dapm_add_routes(dapm, common_audio_map,
		ARRAY_SIZE(common_audio_map));

	snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");

	snd_soc_dapm_sync(dapm);

	err = snd_soc_jack_new(codec, "Headset Jack",
			       (SND_JACK_HEADSET | SND_JACK_OC_HPHL |
				SND_JACK_OC_HPHR | SND_JACK_UNSUPPORTED),
			       &hs_jack);
	if (err) {
		pr_err("failed to create new jack\n");
		return err;
	}

	err = snd_soc_jack_new(codec, "Button Jack",
			       TABLA_JACK_BUTTON_MASK, &button_jack);
	if (err) {
		pr_err("failed to create new jack\n");
		return err;
	}

	codec_clk = clk_get(cpu_dai->dev, "osr_clk");

	if (machine_is_msm8960_cdp())
		mbhc_cfg.swap_gnd_mic = msm8960_swap_gnd_mic;

	if (hs_detect_use_gpio) {
		mbhc_cfg.gpio = PM8921_GPIO_PM_TO_SYS(JACK_DETECT_GPIO);
		mbhc_cfg.gpio_irq = JACK_DETECT_INT;
	}

	if (mbhc_cfg.gpio) {
		err = pm8xxx_gpio_config(mbhc_cfg.gpio, &jack_gpio_cfg);
		if (err) {
			pr_err("%s: pm8xxx_gpio_config JACK_DETECT failed %d\n",
			       __func__, err);
			return err;
		}
	}

	mbhc_cfg.read_fw_bin = hs_detect_use_firmware;

	err = tabla_hs_detect(codec, &mbhc_cfg);

	return err;
}

static int msm8960_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
			struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
	SNDRV_PCM_HW_PARAM_RATE);

	struct snd_interval *channels = hw_param_interval(params,
			SNDRV_PCM_HW_PARAM_CHANNELS);

	pr_debug("%s()\n", __func__);
	rate->min = rate->max = 48000;
	channels->min = channels->max = msm8960_slim_0_rx_ch;

	return 0;
}

static int msm8960_slim_0_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
			struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
	SNDRV_PCM_HW_PARAM_RATE);

	struct snd_interval *channels = hw_param_interval(params,
			SNDRV_PCM_HW_PARAM_CHANNELS);

	pr_debug("%s()\n", __func__);
	rate->min = rate->max = 48000;
	channels->min = channels->max = msm8960_slim_0_tx_ch;

	return 0;
}

static int msm8960_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
			struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
	SNDRV_PCM_HW_PARAM_RATE);

	pr_debug("%s()\n", __func__);
	rate->min = rate->max = 48000;

	return 0;
}

static int msm8960_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
					struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_RATE);

	struct snd_interval *channels = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_CHANNELS);

	pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
			channels->min, channels->max);

	rate->min = rate->max = 48000;

	return 0;
}

static int msm8960_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
					struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_RATE);

	struct snd_interval *channels = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_CHANNELS);

	rate->min = rate->max = msm8960_btsco_rate;
	channels->min = channels->max = msm8960_btsco_ch;

	return 0;
}
static int msm8960_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
					struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_RATE);

	struct snd_interval *channels = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_CHANNELS);

	rate->min = rate->max = msm8960_auxpcm_rate;
	/* PCM only supports mono output */
	channels->min = channels->max = 1;

	return 0;
}
static int msm8960_proxy_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
			struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
	SNDRV_PCM_HW_PARAM_RATE);

	pr_debug("%s()\n", __func__);
	rate->min = rate->max = 48000;

	return 0;
}
static int msm8960_aux_pcm_get_gpios(void)
{
	int ret = 0;

	pr_debug("%s\n", __func__);

	ret = gpio_request(GPIO_AUX_PCM_DOUT, "AUX PCM DOUT");
	if (ret < 0) {
		pr_err("%s: Failed to request gpio(%d): AUX PCM DOUT",
				__func__, GPIO_AUX_PCM_DOUT);
		goto fail_dout;
	}

	ret = gpio_request(GPIO_AUX_PCM_DIN, "AUX PCM DIN");
	if (ret < 0) {
		pr_err("%s: Failed to request gpio(%d): AUX PCM DIN",
				__func__, GPIO_AUX_PCM_DIN);
		goto fail_din;
	}

	ret = gpio_request(GPIO_AUX_PCM_SYNC, "AUX PCM SYNC");
	if (ret < 0) {
		pr_err("%s: Failed to request gpio(%d): AUX PCM SYNC",
				__func__, GPIO_AUX_PCM_SYNC);
		goto fail_sync;
	}
	ret = gpio_request(GPIO_AUX_PCM_CLK, "AUX PCM CLK");
	if (ret < 0) {
		pr_err("%s: Failed to request gpio(%d): AUX PCM CLK",
				__func__, GPIO_AUX_PCM_CLK);
		goto fail_clk;
	}

	return 0;

fail_clk:
	gpio_free(GPIO_AUX_PCM_SYNC);
fail_sync:
	gpio_free(GPIO_AUX_PCM_DIN);
fail_din:
	gpio_free(GPIO_AUX_PCM_DOUT);
fail_dout:

	return ret;
}
Exemple #9
0
static int hkdkc110_wm8991_init(struct snd_soc_codec *codec)
{
	int err, ret;

	/* Setup Default Route */
	g_current_out = WM8991_NONE;

	if (gpio_is_valid(GPIO_HPJACK))
	{
		err = gpio_request( GPIO_HPJACK, GPIO_HPJACK_NAME);
		if(err)
		{
			printk(KERN_ERR "failed to request GPJ0 for wm8991 i2c clk..\n");
			return err;
		}
		gpio_direction_input(GPIO_HPJACK);
		s3c_gpio_setpull(GPIO_HPJACK, S3C_GPIO_PULL_UP);
		
		if(gpio_get_value(GPIO_HPJACK)) g_current_out=WM8991_SPK;
		else 							g_current_out=WM8991_HP;
		
		gpio_free(GPIO_HPJACK);
	}
	err = request_irq(IRQ_HPJACK, hkdkc110_hpjack_isr, IRQF_DISABLED, "hpjack-irq", NULL);
	if(err) printk("\nDEBUG -> IRQ_HPJACK request error!!!\n\n");
	set_irq_type(IRQ_HPJACK, IRQ_TYPE_EDGE_FALLING);

	INIT_DELAYED_WORK(&dwork_ear_detect, hkdkc110_hpjack_detect);

#if defined(CONFIG_TOUCHSCREEN_X10) || defined(CONFIG_FB_S3C_SMD1024x600)
	g_btvout = false;
	wm8991_set_outpath(g_current_out);
#else
	if(get_hdmi_onoff_status()) {
		g_btvout = true;
		wm8991_set_outpath(WM8991_NONE);
	} else {
		g_btvout = false;
		wm8991_set_outpath(g_current_out);
	}
#endif

	/* add iDMA controls */
	ret = snd_soc_add_controls(codec, &s5p_idma_control, 1);
	if (ret < 0)
		return ret;

	/* signal a DAPM event */
	snd_soc_dapm_sync(codec);

	/* Set the Codec DAI configuration */
	ret = snd_soc_dai_set_fmt(&wm8991_dai, SND_SOC_DAIFMT_I2S
					 | SND_SOC_DAIFMT_NB_NF
					 | SND_SOC_DAIFMT_CBS_CFS);
	if (ret < 0)
		return ret;

	/* Set the AP DAI configuration */
	ret = snd_soc_dai_set_fmt(&s3c64xx_i2s_dai[0], SND_SOC_DAIFMT_I2S
					 | SND_SOC_DAIFMT_NB_NF
					 | SND_SOC_DAIFMT_CBS_CFS);
	if (ret < 0)
		return ret;

	return 0;
}
Exemple #10
0
static void codec_poweramp_on(void)
{
	int ret = 0;

	struct pm_gpio param = {
		.direction      = PM_GPIO_DIR_OUT,
		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
		.output_value   = 1,
		.pull      = PM_GPIO_PULL_NO,
		.vin_sel	= PM_GPIO_VIN_S4,
		.out_strength   = PM_GPIO_STRENGTH_MED,
		.function       = PM_GPIO_FUNC_NORMAL,
	};

	if (msm8960_pamp_on)
		return;

	pr_debug("%s: enable stereo spkr amp\n", __func__);
	ret = gpio_request(MSM_CDC_PAMPL, "CDC PAMP1");
	if (ret) {
		pr_err("%s: Error requesting GPIO %d\n", __func__,
			MSM_CDC_PAMPL);
		return;
	}
	ret = pm8xxx_gpio_config(MSM_CDC_PAMPL, &param);
	if (ret)
		pr_err("%s: Failed to configure gpio %d\n", __func__,
			MSM_CDC_PAMPL);
	else
		gpio_direction_output(MSM_CDC_PAMPL, 1);

	ret = gpio_request(MSM_CDC_PAMPR, "CDC PAMPL");
	if (ret) {
		pr_err("%s: Error requesting GPIO %d\n", __func__,
			MSM_CDC_PAMPR);
		gpio_free(MSM_CDC_PAMPL);
		return;
	}
	ret = pm8xxx_gpio_config(MSM_CDC_PAMPR, &param);
	if (ret)
		pr_err("%s: Failed to configure gpio %d\n", __func__,
			MSM_CDC_PAMPR);
	else
		gpio_direction_output(MSM_CDC_PAMPR, 1);

	msm8960_pamp_on = 1;
}
static void codec_poweramp_off(void)
{
	if (!msm8960_pamp_on)
		return;

	pr_debug("%s: disable stereo spkr amp\n", __func__);
	gpio_direction_output(MSM_CDC_PAMPL, 0);
	gpio_free(MSM_CDC_PAMPL);
	gpio_direction_output(MSM_CDC_PAMPR, 0);
	gpio_free(MSM_CDC_PAMPR);
	msm8960_pamp_on = 0;
}
static void msm8960_ext_control(struct snd_soc_codec *codec)
{
	struct snd_soc_dapm_context *dapm = &codec->dapm;

	pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control);
	if (msm8960_spk_control == MSM8960_SPK_ON)
		snd_soc_dapm_enable_pin(dapm, "Ext Spk");
	else
		snd_soc_dapm_disable_pin(dapm, "Ext Spk");

	snd_soc_dapm_sync(dapm);
}

static int msm8960_get_spk(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control);
	ucontrol->value.integer.value[0] = msm8960_spk_control;
	return 0;
}
Exemple #11
0
static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	int ret;

	/* Add SDP3430 specific widgets */
	ret = snd_soc_dapm_new_controls(codec->dapm, sdp3430_twl4030_dapm_widgets,
				ARRAY_SIZE(sdp3430_twl4030_dapm_widgets));
	if (ret)
		return ret;

#ifdef CONFIG_SND_SOC_MAX97000
       /* add MAX97000 specific controls */
	ret = max97000_add_controls(codec);
#elif CONFIG_SND_SOC_MAX9877
	printk(KERN_NOTICE "MAX 9877 AMPLIFIER\n");
	ret = max9877_add_controls(codec);
#elif CONFIG_SND_SOC_YDA165
	printk(KERN_NOTICE "YDA165 AMPLIFIER\n");
	ret = yda165_add_controls(codec);
#endif

	if (ret)
	{
		printk( "********** max audio amp add controls , %d\n", ret);
	}

	/* Set up SDP3430 specific audio path audio_map */
	snd_soc_dapm_add_routes(codec->dapm, audio_map, ARRAY_SIZE(audio_map));

	/* SDP3430 connected pins */
	snd_soc_dapm_enable_pin(codec->dapm, "Ext Mic");
	snd_soc_dapm_enable_pin(codec->dapm, "Ext Spk");
	snd_soc_dapm_disable_pin(codec->dapm, "Headset Mic");
	snd_soc_dapm_disable_pin(codec->dapm, "Headset Stereophone");
	snd_soc_dapm_enable_pin(codec->dapm, "EARPIECE"); // reciever
	snd_soc_dapm_enable_pin(codec->dapm, "PREDRIVEL");
	snd_soc_dapm_enable_pin(codec->dapm, "PREDRIVER");

	/* TWL4030 not connected pins */
	snd_soc_dapm_nc_pin(codec->dapm, "AUXL");
	snd_soc_dapm_nc_pin(codec->dapm, "AUXR");
	snd_soc_dapm_nc_pin(codec->dapm, "CARKITMIC");
	snd_soc_dapm_nc_pin(codec->dapm, "DIGIMIC0");
	snd_soc_dapm_nc_pin(codec->dapm, "DIGIMIC1");

	//snd_soc_dapm_nc_pin(codec->dapm, "OUTL");
	//snd_soc_dapm_nc_pin(codec->dapm, "OUTR");
	snd_soc_dapm_nc_pin(codec->dapm, "EARPIECE");
	snd_soc_dapm_nc_pin(codec->dapm, "PREDRIVEL");
	snd_soc_dapm_nc_pin(codec->dapm, "PREDRIVER");
	snd_soc_dapm_nc_pin(codec->dapm, "CARKITL");
	snd_soc_dapm_nc_pin(codec->dapm, "CARKITR");
	snd_soc_dapm_nc_pin(codec->dapm, "Ext Spk");

	ret = snd_soc_dapm_sync(codec->dapm);
	if (ret)
		return ret;

	if (gpio_request(ZEUS_PCM_SELECT_GPIO, "PCM_SEL") == 0)
	{
		gpio_direction_output(ZEUS_PCM_SELECT_GPIO, 0);
	}

	return ret;
}
Exemple #12
0
static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	struct snd_soc_card *card = codec->card;
	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
	struct tegra_wm8903_platform_data *pdata = machine->pdata;
	int ret;

	if (gpio_is_valid(pdata->gpio_spkr_en)) {
		ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
		if (ret) {
			dev_err(card->dev, "cannot get spkr_en gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_SPKR_EN;

		gpio_direction_output(pdata->gpio_spkr_en, 0);
	}

	if (gpio_is_valid(pdata->gpio_hp_mute)) {
		ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
		if (ret) {
			dev_err(card->dev, "cannot get hp_mute gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_HP_MUTE;

		gpio_direction_output(pdata->gpio_hp_mute, 1);
	}

	if (gpio_is_valid(pdata->gpio_int_mic_en)) {
		ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
		if (ret) {
			dev_err(card->dev, "cannot get int_mic_en gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_INT_MIC_EN;

		/* Disable int mic; enable signal is active-high */
		gpio_direction_output(pdata->gpio_int_mic_en, 0);
	}

	if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
		ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
		if (ret) {
			dev_err(card->dev, "cannot get ext_mic_en gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_EXT_MIC_EN;

		/* Enable ext mic; enable signal is active-low */
		gpio_direction_output(pdata->gpio_ext_mic_en, 0);
	}

	if (gpio_is_valid(pdata->gpio_hp_det)) {
		tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det;
		snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
				&tegra_wm8903_hp_jack);
		snd_soc_jack_add_pins(&tegra_wm8903_hp_jack,
					ARRAY_SIZE(tegra_wm8903_hp_jack_pins),
					tegra_wm8903_hp_jack_pins);
		snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack,
					1,
					&tegra_wm8903_hp_jack_gpio);
		machine->gpio_requested |= GPIO_HP_DET;
	}

	snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
			 &tegra_wm8903_mic_jack);
	snd_soc_jack_add_pins(&tegra_wm8903_mic_jack,
			      ARRAY_SIZE(tegra_wm8903_mic_jack_pins),
			      tegra_wm8903_mic_jack_pins);
	wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
				0);

	snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");

	/* FIXME: Calculate automatically based on DAPM routes? */
	if (!machine_is_harmony() && !machine_is_ventana())
		snd_soc_dapm_nc_pin(dapm, "IN1L");
	if (!machine_is_seaboard() && !machine_is_aebl())
		snd_soc_dapm_nc_pin(dapm, "IN1R");
	snd_soc_dapm_nc_pin(dapm, "IN2L");
	if (!machine_is_kaen())
		snd_soc_dapm_nc_pin(dapm, "IN2R");
	snd_soc_dapm_nc_pin(dapm, "IN3L");
	snd_soc_dapm_nc_pin(dapm, "IN3R");

	if (machine_is_aebl()) {
		snd_soc_dapm_nc_pin(dapm, "LON");
		snd_soc_dapm_nc_pin(dapm, "RON");
		snd_soc_dapm_nc_pin(dapm, "ROP");
		snd_soc_dapm_nc_pin(dapm, "LOP");
	} else {
		snd_soc_dapm_nc_pin(dapm, "LINEOUTR");
		snd_soc_dapm_nc_pin(dapm, "LINEOUTL");
	}

	snd_soc_dapm_sync(dapm);

	return 0;
}
Exemple #13
0
static void midas_micdet(u16 status, void *data)
{
	struct wm1811_machine_priv *wm1811 = data;
	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(wm1811->codec);
	int report;
	int reg;
	bool present;

	wake_lock_timeout(&wm1811->jackdet_wake_lock, 5 * HZ);

	/* Either nothing present or just starting detection */
	if (!(status & WM8958_MICD_STS)) {
		if (!wm8994->jackdet) {
			/* If nothing present then clear our statuses */
			dev_dbg(wm1811->codec->dev, "Detected open circuit\n");
			wm8994->jack_mic = false;
			wm8994->mic_detecting = true;

			midas_micd_set_rate(wm1811->codec);

			snd_soc_jack_report(wm8994->micdet[0].jack, 0,
					    wm8994->btn_mask |
					     SND_JACK_HEADSET);
		}
		/*ToDo*/
		/*return;*/
	}

	/* If the measurement is showing a high impedence we've got a
	 * microphone.
	 */
	if (wm8994->mic_detecting && (status & 0x400)) {
		dev_info(wm1811->codec->dev, "Detected microphone\n");

		wm8994->mic_detecting = false;
		wm8994->jack_mic = true;

		midas_micd_set_rate(wm1811->codec);

		snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADSET,
				    SND_JACK_HEADSET);
	}

	if (wm8994->mic_detecting && status & 0x4) {
		dev_info(wm1811->codec->dev, "Detected headphone\n");
		wm8994->mic_detecting = false;

		midas_micd_set_rate(wm1811->codec);

		snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
				    SND_JACK_HEADSET);

		/* If we have jackdet that will detect removal */
		if (wm8994->jackdet) {
			mutex_lock(&wm8994->accdet_lock);

			snd_soc_update_bits(wm1811->codec, WM8958_MIC_DETECT_1,
					    WM8958_MICD_ENA, 0);

			if (wm8994->active_refcount) {
				snd_soc_update_bits(wm1811->codec,
					WM8994_ANTIPOP_2,
					WM1811_JACKDET_MODE_MASK,
					WM1811_JACKDET_MODE_AUDIO);
			}

			mutex_unlock(&wm8994->accdet_lock);

			if (wm8994->pdata->jd_ext_cap) {
				mutex_lock(&wm1811->codec->mutex);
				snd_soc_dapm_disable_pin(&wm1811->codec->dapm,
							 "MICBIAS2");
				snd_soc_dapm_sync(&wm1811->codec->dapm);
				mutex_unlock(&wm1811->codec->mutex);
			}
		}
	}

	/* Report short circuit as a button */
	if (wm8994->jack_mic) {
		report = 0;
		if (status & WM1811_JACKDET_BTN0)
			report |= SND_JACK_BTN_0;

		if (status & WM1811_JACKDET_BTN1)
			report |= SND_JACK_BTN_1;

		if (status & WM1811_JACKDET_BTN2)
			report |= SND_JACK_BTN_2;

		reg = snd_soc_read(wm1811->codec, WM1811_JACKDET_CTRL);
		if (reg < 0) {
			pr_err("%s: Failed to read jack status: %d\n",
					__func__, reg);
			return;
		}

		pr_err("%s: JACKDET %x\n", __func__, reg);

		present = reg & WM1811_JACKDET_LVL;
		if (!present) {
			pr_err("%s: button is ignored!!!\n", __func__);
			return;
		}

		dev_dbg(wm1811->codec->dev, "Detected Button: %08x (%08X)\n",
			report, status);

		snd_soc_jack_report(wm8994->micdet[0].jack, report,
				    wm8994->btn_mask);
	}
}
static int ctp_wm5102_init(struct snd_soc_pcm_runtime *runtime)
{
	int ret;
	struct snd_soc_card *card = runtime->card;
	struct ctp_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card);
	struct snd_soc_codec *codec;
	struct snd_soc_dapm_context *dapm;

	codec = ctp_get_codec(card, "wm5102-codec");
	if (!codec)
		return -EIO;
	dapm = &codec->dapm;

	/* Set codec bias level */
	ctp_set_bias_level(card, dapm, SND_SOC_BIAS_OFF);
	card->dapm.idle_bias_off = true;

	/* Disable MICBIAS3 bypass mode and set CAP mode.
	* Capacitors are connected to DMIC on 1525-EV1 board */
	snd_soc_update_bits(codec, ARIZONA_MIC_BIAS_CTRL_3,
			ARIZONA_MICB1_BYPASS_MASK | ARIZONA_MICB1_EXT_CAP_MASK,
			ARIZONA_MICB1_EXT_CAP);

	/* Set codec clock */
	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
				ARIZONA_CLK_SRC_FLL1,
				SYSCLK_RATE,
				SND_SOC_CLOCK_IN);
	if (ret != 0) {
		pr_err("failed: %d\n", ret);
		return ret;
	}

	/* Add Jack specific widgets */
	ret = snd_soc_dapm_new_controls(dapm, ctp_dapm_widgets,
					ARRAY_SIZE(ctp_dapm_widgets));
	if (ret)
		return ret;

	/* Set up Jack specific audio path audio_map */
	snd_soc_dapm_add_routes(dapm, ctp_audio_map,
					ARRAY_SIZE(ctp_audio_map));
	/* Add Comms specefic controls */
	ctx->comms_ctl.ssp_bt_sco_master_mode = false;
	ctx->comms_ctl.ssp_voip_master_mode = false;
	ctx->comms_ctl.ssp_modem_master_mode = false;

	ret = snd_soc_add_card_controls(card, ssp_comms_controls,
				ARRAY_SIZE(ssp_comms_controls));
	if (ret) {
		pr_err("Add Comms Controls failed %d",
				ret);
		return ret;
	}
	/* Keep the voice call paths active during
	suspend. Mark the end points ignore_suspend */
	snd_soc_dapm_ignore_suspend(dapm, "HPOUT1R");
	snd_soc_dapm_ignore_suspend(dapm, "HPOUT1L");

	snd_soc_dapm_disable_pin(dapm, "MICBIAS1");
	snd_soc_dapm_disable_pin(dapm, "SPKOUTLP");
	snd_soc_dapm_disable_pin(dapm, "SPKOUTLN");
	snd_soc_dapm_ignore_suspend(dapm, "SPKOUTRP");
	snd_soc_dapm_ignore_suspend(dapm, "SPKOUTRN");
	mutex_lock(&codec->mutex);
	snd_soc_dapm_sync(dapm);
	mutex_unlock(&codec->mutex);
	return ret;
}
Exemple #15
0
static int tegra_codec_init(struct snd_soc_codec *codec)
{
	struct adam_audio_priv* ctx = codec->socdev->codec_data;
	int ret = 0;

	if (!ctx->init_done) {
		
		/* Get and enable the DAP clock */
		ctx->dap_mclk = tegra_das_get_dap_mclk();
		if (!ctx->dap_mclk) {
			pr_err("Failed to get dap mclk \n");
			return -ENODEV;
		}
		clk_enable(ctx->dap_mclk);

		/* Add the controls used to route audio to bluetooth/voice */
		tegra_das_controls_init(codec);
		
		/* Store the GPIO used to detect headphone */
		tegra_jack_gpios[0].gpio = ctx->gpio_hp_det;

		/* Add tegra specific widgets */
		snd_soc_dapm_new_controls(codec, tegra_dapm_widgets,
					ARRAY_SIZE(tegra_dapm_widgets));

#ifdef ADAM_MANUAL_CONTROL_OF_OUTPUTDEVICE
		/* Add specific adam controls */
		ret = snd_soc_add_controls(codec, tegra_controls,
					ARRAY_SIZE(tegra_controls));
		if (ret < 0) {
			pr_err("Failed to register controls\n");
			return ret;
		}
#endif
					
		/* Set up tegra specific audio path audio_map */
		snd_soc_dapm_add_routes(codec, audio_map,
					ARRAY_SIZE(audio_map));

		/* make sure to register the dapm widgets */
		snd_soc_dapm_new_widgets(codec);
					
		/* Set endpoints to not connected */
		snd_soc_dapm_nc_pin(codec, "LINEL");
		snd_soc_dapm_nc_pin(codec, "LINER");
		snd_soc_dapm_nc_pin(codec, "PHONEIN");
		snd_soc_dapm_nc_pin(codec, "MIC2");
		snd_soc_dapm_nc_pin(codec, "MONO");

		/* Set endpoints to default off mode */
		snd_soc_dapm_enable_pin(codec, "Internal Speaker");
		snd_soc_dapm_enable_pin(codec, "Internal Mic");
		snd_soc_dapm_disable_pin(codec, "Headphone Jack");
	
		ret = snd_soc_dapm_sync(codec);
		if (ret) {
			pr_err("Failed to sync\n");
			return ret;
		}

#ifndef ADAM_MANUAL_CONTROL_OF_OUTPUTDEVICE
		/* Headphone jack detection */		
		ret = snd_soc_jack_new(codec->socdev->card, "Headphone Jack", SND_JACK_HEADPHONE,
				 &ctx->tegra_jack);
		if (ret)
			return ret;
			 
		ret = snd_soc_jack_add_pins(&ctx->tegra_jack,
			      ARRAY_SIZE(tegra_jack_pins),
			      tegra_jack_pins);
		if (ret)
			return ret;
				  
		ret = snd_soc_jack_add_gpios(&ctx->tegra_jack,
			       ARRAY_SIZE(tegra_jack_gpios),
			       tegra_jack_gpios);
		if (ret)
			return ret;
#endif

		ctx->init_done = 1;
	}

	return ret;
}
static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
	int err;
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;

	/* Taiko SLIMBUS configuration
	 * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
	 * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
	 * TX14, TX15, TX16
	 */
	unsigned int rx_ch[TAIKO_RX_MAX] = {144, 145, 146, 147, 148, 149, 150,
					    151, 152, 153, 154, 155, 156};
	unsigned int tx_ch[TAIKO_TX_MAX]  = {128, 129, 130, 131, 132, 133,
					     134, 135, 136, 137, 138, 139,
					     140, 141, 142, 143};


	pr_info("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));

	if (machine_is_msm8960_liquid()) {
		top_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(19));
		bottom_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(18));
	}

	rtd->pmdown_time = 0;

	err = snd_soc_add_codec_controls(codec, msm_snd_controls,
					 ARRAY_SIZE(msm_snd_controls));
	if (err < 0)
		return err;

	snd_soc_dapm_new_controls(dapm, msm_dapm_widgets,
				ARRAY_SIZE(msm_dapm_widgets));

	snd_soc_dapm_add_routes(dapm, common_audio_map,
		ARRAY_SIZE(common_audio_map));

	snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");

	snd_soc_dapm_sync(dapm);

	err = snd_soc_jack_new(codec, "Headset Jack",
			       (SND_JACK_HEADSET | SND_JACK_OC_HPHL |
				SND_JACK_OC_HPHR | SND_JACK_UNSUPPORTED),
			       &hs_jack);
	if (err) {
		pr_err("failed to create new jack\n");
		return err;
	}

	snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
				    tx_ch, ARRAY_SIZE(rx_ch), rx_ch);

	err = snd_soc_jack_new(codec, "Button Jack",
			       TAIKO_JACK_BUTTON_MASK, &button_jack);
	if (err) {
		pr_err("failed to create new jack\n");
		return err;
	}

	return err;
}
Exemple #17
0
/* Blocs will be powered dynamically, input routes could be set
	using WM8589 DAPM controls but we will activate them here to to be sure */
static void archos_ext_control(struct snd_soc_codec *codec)
{
    /* First Input stuff */
    switch (archos_input_func) {
    case 0:		/* None */
        wm8985_connect_pga(codec, OFF);
        wm8985_select_pga_inputs(codec, INPUT_LIP|INPUT_RIP|INPUT_LINE|INPUT_LIN|INPUT_RIN, OFF);
        snd_soc_dapm_disable_pin(codec, "Mic");
        snd_soc_dapm_disable_pin(codec, "Jack Mic");
        snd_soc_dapm_disable_pin(codec, "Line In");
        break;
    case 1:		/* Mic */
        wm8985_select_pga_inputs(codec, INPUT_RIP|INPUT_LINE, OFF);
        wm8985_select_pga_inputs(codec, INPUT_LIN|INPUT_RIN|INPUT_LIP, ON);
        wm8985_connect_pga(codec, ON);
        snd_soc_dapm_enable_pin(codec, "Mic");
        snd_soc_dapm_disable_pin(codec, "Jack Mic");
        snd_soc_dapm_disable_pin(codec, "Line In");
        break;
    case 2:		/* Jack Mic */
        wm8985_select_pga_inputs(codec, INPUT_LIP|INPUT_LINE, OFF);
        wm8985_select_pga_inputs(codec, INPUT_LIN|INPUT_RIN|INPUT_RIP, ON);
        wm8985_connect_pga(codec, ON);
        snd_soc_dapm_enable_pin(codec, "Jack Mic");
        snd_soc_dapm_disable_pin(codec, "Mic");
        snd_soc_dapm_disable_pin(codec, "Line In");
        break;
    case 3:		/* Line */
        wm8985_select_pga_inputs(codec, INPUT_LIP|INPUT_RIP, OFF);
        wm8985_select_pga_inputs(codec, INPUT_LIN|INPUT_RIN|INPUT_LINE, ON);
        wm8985_connect_pga(codec, ON);
        snd_soc_dapm_enable_pin(codec, "Line In");
        snd_soc_dapm_disable_pin(codec, "Mic");
        snd_soc_dapm_disable_pin(codec, "Jack Mic");
        break;
    default:
        break;
    }

    /* Then SPDIF */
    if (archos_spdif_func) {
        /* Use SPDIF sample rates */
        snd_soc_dapm_disable_pin(codec, "Speaker");
        snd_soc_dapm_disable_pin(codec, "Headphone");
        sample_info = spdif_sample_info;
        sample_count = spdif_sample_count;
        _enable_spdif_ampli();

        /* Nothing else has to be enabled if SPDIF is active */
        snd_soc_dapm_sync(codec);
        return;
    } else {
        /* Use analogic sample rates */
        sample_info = analog_sample_info;
        sample_count = analog_sample_count;
        _disable_spdif_ampli();
    }

    /* Finally, if SPDIF is OFF, Speaker, Headphone and Out4*/
    if (archos_spk_func)
        snd_soc_dapm_enable_pin(codec, "Speaker");
    else
        snd_soc_dapm_disable_pin(codec, "Speaker");

    if (archos_hp_func)
        snd_soc_dapm_enable_pin(codec, "Headphone");
    else
        snd_soc_dapm_disable_pin(codec, "Headphone");

    if (archos_out4_func)
        snd_soc_dapm_enable_pin(codec, "HSDPA Mic");
    else
        snd_soc_dapm_disable_pin(codec, "HSDPA Mic");

    snd_soc_dapm_sync(codec);
}
Exemple #18
0
static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id,
		int source, unsigned int freq_in, unsigned int freq_out)
{
	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
	unsigned int pll_ctrl1 = 0;
	unsigned int pll_ctrl2 = 0;
	unsigned int pll_src;

	switch (source) {
	case ADAV80X_PLL_SRC_XTAL:
	case ADAV80X_PLL_SRC_XIN:
	case ADAV80X_PLL_SRC_MCLKI:
		break;
	default:
		return -EINVAL;
	}

	if (!freq_out)
		return 0;

	switch (freq_in) {
	case 27000000:
		break;
	case 54000000:
		if (source == ADAV80X_PLL_SRC_XIN) {
			pll_ctrl1 |= ADAV80X_PLL_CTRL1_PLLDIV;
			break;
		}
	default:
		return -EINVAL;
	}

	if (freq_out > 12288000) {
		pll_ctrl2 |= ADAV80X_PLL_CTRL2_DOUB(pll_id);
		freq_out /= 2;
	}

	/* freq_out = sample_rate * 256 */
	switch (freq_out) {
	case 8192000:
		pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_32(pll_id);
		break;
	case 11289600:
		pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_44(pll_id);
		break;
	case 12288000:
		pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_48(pll_id);
		break;
	default:
		return -EINVAL;
	}

	regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CTRL1,
			ADAV80X_PLL_CTRL1_PLLDIV, pll_ctrl1);
	regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CTRL2,
			ADAV80X_PLL_CTRL2_PLL_MASK(pll_id), pll_ctrl2);

	if (source != adav80x->pll_src) {
		if (source == ADAV80X_PLL_SRC_MCLKI)
			pll_src = ADAV80X_PLL_CLK_SRC_PLL_MCLKI(pll_id);
		else
			pll_src = ADAV80X_PLL_CLK_SRC_PLL_XIN(pll_id);

		regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CLK_SRC,
				ADAV80X_PLL_CLK_SRC_PLL_MASK(pll_id), pll_src);

		adav80x->pll_src = source;

		snd_soc_dapm_sync(&codec->dapm);
	}

	return 0;
}
static int msm8960_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
	int err;
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	u8 tabla_version;

	pr_aud_info("%s()\n", __func__);

	rtd->pmdown_time = 0;
	err = snd_soc_add_controls(codec, tabla_msm8960_controls,
				ARRAY_SIZE(tabla_msm8960_controls));

	if (err < 0)
		return err;

	snd_soc_dapm_new_controls(dapm, msm8960_dapm_widgets,
				ARRAY_SIZE(msm8960_dapm_widgets));

	snd_soc_dapm_new_controls(dapm, fighter_dapm_widgets,
				ARRAY_SIZE(fighter_dapm_widgets));


	snd_soc_dapm_add_routes(dapm, common_audio_map,
		ARRAY_SIZE(common_audio_map));

	/* determine HW connection based on codec revision */
	tabla_version = snd_soc_read(codec, TABLA_A_CHIP_VERSION);
	tabla_version &=  0x1F;
	pr_aud_info("%s : Tabla version %u\n", __func__, (u32)tabla_version);

	if ((tabla_version == TABLA_VERSION_1_0) ||
		(tabla_version == TABLA_VERSION_1_1)) {
		snd_soc_dapm_add_routes(dapm, tabla_1_x_audio_map,
			 ARRAY_SIZE(tabla_1_x_audio_map));
	} else {
		snd_soc_dapm_add_routes(dapm, tabla_2_x_audio_map,
			 ARRAY_SIZE(tabla_2_x_audio_map));
	}

	snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
	snd_soc_dapm_enable_pin(dapm, "Ext USB AMP Pos");
	snd_soc_dapm_enable_pin(dapm, "Ext USB AMP Neg");

	snd_soc_dapm_sync(dapm);

	err = snd_soc_jack_new(codec, "Headset Jack",
		(SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR),
		&hs_jack);
	if (err) {
		pr_aud_err("failed to create new jack\n");
		return err;
	}

	err = snd_soc_jack_new(codec, "Button Jack",
				SND_JACK_BTN_0, &button_jack);
	if (err) {
		pr_aud_err("failed to create new jack\n");
		return err;
	}

	/* Do not pass MBHC calibration data to disable HS detection.
	 * Otherwise, sending project-based cal-data to enable
	 * MBHC mechanism that tabla provides */
	tabla_hs_detect(codec, &hs_jack, &button_jack, NULL,
			TABLA_MICBIAS2, msm8960_enable_codec_ext_clk, 0,
			TABLA_EXT_CLK_RATE);

	return 0;
}
Exemple #20
0
static int adc3101_set_scenario_endpoints(struct tt_scenario_context *c)
{
	struct snd_kcontrol	*kcontrol = (struct snd_kcontrol *) c->data;
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);

	/* check whether the new scenario is already active, if so,
	   don't set it again as this has been seen to result in non
	   wanted register changes e.g. setting scenario TT_SCENARIO_ASR
	   twice result in non ASR scenario registers being set. */
	if (c->tt_current_scenario == c->tt_scenario)
		return 0;
	
	/* scenario routing switching */
	switch(c->tt_scenario) {
	default:
	case TT_SCENARIO_AUDIO_INIT:
		/* enable mic bias (not if we use mic pre-amp) */
		adc3101_mic_bias_enable(codec);
	case TT_SCENARIO_AUDIO_OFF:
		c->tt_volume = 0;
		switch(c->tt_current_scenario) {
		case TT_SCENARIO_VR:
			adc3101_alc_disable(codec);
		case TT_SCENARIO_NOISE:
		case TT_SCENARIO_ASR:
		case TT_SCENARIO_HF_LINEOUT:
		case TT_SCENARIO_HF_FM:
		case TT_SCENARIO_HF_SPEAKER:
			adc3101_mic_disable(codec);
			break;
		case TT_SCENARIO_SPEAKER:
		case TT_SCENARIO_LINEOUT:
		case TT_SCENARIO_FM:
			break;
			adc3101_mic_disable(codec);
			break;
		case TT_SCENARIO_iPod:
			adc3101_line_in_disable(codec);
			adc3101_mic_bias_enable(codec);
			break;
		case TT_SCENARIO_iPod_SPEAKER:
			adc3101_line_in_disable(codec);
			adc3101_mic_bias_enable(codec);
			break;
		case TT_SCENARIO_iPod_LINEOUT:
		case TT_SCENARIO_iPod_FM:
			adc3101_line_in_disable(codec);
			adc3101_mic_bias_enable(codec);
			break;
		default:
			snd_soc_dapm_disable_pin(codec, "MicIn");
			break;
		}
		break;
	case TT_SCENARIO_ASR:
		adc3101_mic_enable(codec, 25, 1);
		break;
	case TT_SCENARIO_VR:
		adc3101_mic_enable(codec, 25, 1);
		break;
	case TT_SCENARIO_NOISE:
		adc3101_mic_enable(codec, 15, 1);
		break;
	case TT_SCENARIO_iPod:
		adc3101_line_in_enable(codec);
		break;
	case TT_SCENARIO_SPEAKER:
		break;
	case TT_SCENARIO_LINEOUT:
		break;
	case TT_SCENARIO_FM:
		break;
	case TT_SCENARIO_iPod_SPEAKER:
		adc3101_line_in_enable(codec);
		break;
	case TT_SCENARIO_iPod_LINEOUT:
	case TT_SCENARIO_iPod_FM:
		adc3101_line_in_enable(codec);
		break;
	case TT_SCENARIO_HF_SPEAKER:
		adc3101_mic_enable(codec, 13, 1);
		break;
	case TT_SCENARIO_HF_LINEOUT:
	case TT_SCENARIO_HF_FM:
		adc3101_mic_enable(codec, 13, 1);
		break;
	}

	c->tt_current_scenario = c->tt_scenario;
	snd_soc_dapm_sync(codec);

	switch(c->tt_scenario) {
	case TT_SCENARIO_LINEOUT:
	case TT_SCENARIO_iPod_LINEOUT:
	case TT_SCENARIO_FM:
	case TT_SCENARIO_iPod_FM:
		break;
	default:
	case TT_SCENARIO_AUDIO_INIT:
	case TT_SCENARIO_AUDIO_OFF:
		break;
	case TT_SCENARIO_SPEAKER:
	case TT_SCENARIO_iPod_SPEAKER:
	case TT_SCENARIO_HF_SPEAKER:
		break;
	}

	return 1;
}
static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
	int err;
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;

	pr_debug("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));

	/*if (machine_is_msm_liquid()) {
		top_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(19));
		bottom_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(18));
	}*/

	rtd->pmdown_time = 0;

	err = snd_soc_add_controls(codec, tabla_msm_controls,
				ARRAY_SIZE(tabla_msm_controls));
	if (err < 0)
		return err;

	snd_soc_dapm_new_controls(dapm, apq8064_dapm_widgets,
				ARRAY_SIZE(apq8064_dapm_widgets));

	snd_soc_dapm_add_routes(dapm, apq8064_common_audio_map,
		ARRAY_SIZE(apq8064_common_audio_map));

	if (machine_is_apq8064_mtp()) {
		snd_soc_dapm_add_routes(dapm, apq8064_mtp_audio_map,
			ARRAY_SIZE(apq8064_mtp_audio_map));
	} else  {
		snd_soc_dapm_add_routes(dapm, apq8064_liquid_cdp_audio_map,
			ARRAY_SIZE(apq8064_liquid_cdp_audio_map));
	}

	snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");

	snd_soc_dapm_sync(dapm);

	err = snd_soc_jack_new(codec, "Headset Jack",
		(SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR),
		&hs_jack);
	if (err) {
		pr_err("failed to create new jack\n");
		return err;
	}

	err = snd_soc_jack_new(codec, "Button Jack",
			       TABLA_JACK_BUTTON_MASK, &button_jack);
	if (err) {
		pr_err("failed to create new jack\n");
		return err;
	}

	codec_clk = clk_get(cpu_dai->dev, "osr_clk");

	err = tabla_hs_detect(codec, &mbhc_cfg);

	return err;
}
Exemple #22
0
static int aml_asoc_init(struct snd_soc_pcm_runtime *rtd)
{
    struct snd_soc_card *card = rtd->card;
    struct snd_soc_codec *codec = rtd->codec;
    //struct snd_soc_dai *codec_dai = rtd->codec_dai;
    struct snd_soc_dapm_context *dapm = &codec->dapm;
    struct aml_audio_private_data * p_aml_audio;
    int ret = 0;
    
    printk(KERN_DEBUG "enter %s \n", __func__);
    p_aml_audio = snd_soc_card_get_drvdata(card);

    /* Add specific widgets */
  //  snd_soc_dapm_new_controls(dapm, aml_asoc_dapm_widgets,
 //                ARRAY_SIZE(aml_asoc_dapm_widgets));
    /* set ADCLRC/GPIO1 Pin Function Select */
    snd_soc_update_bits(codec, WM8960_IFACE2, (1 << 6), (1 << 6));

    /* not connected */
    snd_soc_dapm_nc_pin(dapm, "LINPUT3");
    snd_soc_dapm_nc_pin(dapm, "RINPUT3");
    
    snd_soc_dapm_nc_pin(dapm, "OUT3");

    /* always connected */
    snd_soc_dapm_enable_pin(dapm, "Ext Spk");
    snd_soc_dapm_enable_pin(dapm, "Mic");

    /* disable connected */
    snd_soc_dapm_disable_pin(dapm, "HP");

    snd_soc_dapm_sync(dapm);
    ret = snd_soc_jack_new(codec, "hp switch", SND_JACK_HEADPHONE, &p_aml_audio->jack);
    if (ret) {
        printk(KERN_WARNING "Failed to alloc resource for hp switch\n");
    } else {
        ret = snd_soc_jack_add_pins(&p_aml_audio->jack, ARRAY_SIZE(jack_pins), jack_pins);
        if (ret) {
            printk(KERN_WARNING "Failed to setup hp pins\n");
        }
    }
#if HP_IRQ  
    p_aml_audio->gpio_hp_det = of_get_named_gpio(card->dev->of_node,"wm8960_gpio",0);

    if (gpio_is_valid(p_aml_audio->gpio_hp_det)) {
        aml_audio_hp_jack_gpio.gpio = p_aml_audio->gpio_hp_det;
        snd_soc_jack_add_gpios(&p_aml_audio->jack,
                        1, &aml_audio_hp_jack_gpio);
    }
#endif
#if HP_DET
    init_timer(&p_aml_audio->timer);
    p_aml_audio->timer.function = aml_asoc_timer_func;
    p_aml_audio->timer.data = (unsigned long)p_aml_audio;
    p_aml_audio->data= (void*)card;

    INIT_WORK(&p_aml_audio->work, aml_asoc_work_func);
    mutex_init(&p_aml_audio->lock);

    mutex_lock(&p_aml_audio->lock);
    if (!p_aml_audio->timer_en) {
        aml_audio_start_timer(p_aml_audio, msecs_to_jiffies(100));
    }
    mutex_unlock(&p_aml_audio->lock);

#endif

//p_aml_audio->dis_hp_det = of_property_read_bool(card->dev->of_node,"dis_hp_det");
     ret = of_property_read_u32(card->dev->of_node,"dis_hp_det",(u32 *)&p_aml_audio->dis_hp_det);
     printk("******p_aml_audio->dis_hp_det=%d***\n",p_aml_audio->dis_hp_det);
    if(ret){
        printk("don't find match dis_hp_det\n");
        goto out1;
    }
  
    if(!p_aml_audio->dis_hp_det){
        printk("****mm**p_aml_audio->dis_hp_det\n");
        //JD2 as headphone detect
        snd_soc_update_bits(codec,27, 0x008, 0x008);// OUT3 buffer Enabled and disabled with HPL and HPR jack detect              
        //INSERT_DELAY    [1] 
        mdelay(1);      
        ///GPIO1 output the "jack detect output"
        snd_soc_update_bits(codec,48, 0x03A, 0x03A);// JD2 used for Jack Detect Input, GPIO function = jack detect output 

        snd_soc_update_bits(codec,24, 0x040, 0x040);// HPDETECT LOW = Speaker 
    
        snd_soc_update_bits(codec, 23, 0x1D1, 0x1D1);
        mdelay(500);

    }
out1:    
   
    return 0;
}
Exemple #23
0
static int msm8960_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
	int err, use_pmic;
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	struct pm_gpio jack_gpio_cfg = {
		.direction = PM_GPIO_DIR_IN,
		.pull = PM_GPIO_PULL_NO,
		.function = PM_GPIO_FUNC_NORMAL,
		.vin_sel = 2,
		.inv_int_pol = 0,
	};

	pr_debug("%s()\n", __func__);

	if (machine_is_msm8960_liquid()) {
		top_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(19));
		bottom_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(18));
	}

	rtd->pmdown_time = 0;

	err = snd_soc_add_controls(codec, tabla_msm8960_controls,
				ARRAY_SIZE(tabla_msm8960_controls));
	if (err < 0)
		return err;


#ifdef CONFIG_INPUT_SIMPLE_REMOTE
	use_pmic = 1;
#else
	use_pmic = 0;
#endif /* CONFIG_INPUT_SIMPLE_REMOTE */

#ifdef CONFIG_INPUT_MBHC_MIC_BIAS_SWITCHING_GPIO
	use_pmic = msm8960_read_is_pmic_used();
#endif /* CONFIG_INPUT_MBHC_MIC_BIAS_SWITCHING_GPIO */

	if (use_pmic) {
		pr_debug("%s: Enables PMIC.\n", __func__);
		snd_soc_dapm_new_controls(dapm, blue_msm8960_dapm_widgets,
					ARRAY_SIZE(blue_msm8960_dapm_widgets));
	} else {
		pr_debug("%s: Does NOT enable PMIC.\n", __func__);
		snd_soc_dapm_new_controls(dapm,
				blue_msm8960_dapm_widgets_no_pmic,
				ARRAY_SIZE(blue_msm8960_dapm_widgets_no_pmic));
	}

	snd_soc_dapm_add_routes(dapm, blue_audio_map,
		ARRAY_SIZE(blue_audio_map));

	snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk Top");

	snd_soc_dapm_sync(dapm);

	err = snd_soc_jack_new(codec, "Headset Jack",
			       (SND_JACK_HEADSET | SND_JACK_OC_HPHL |
				SND_JACK_OC_HPHR),
			       &hs_jack);
	if (err) {
		pr_err("failed to create new jack\n");
		return err;
	}

	err = snd_soc_jack_new(codec, "Button Jack",
			       TABLA_JACK_BUTTON_MASK, &button_jack);
	if (err) {
		pr_err("failed to create new jack\n");
		return err;
	}

	if (hs_detect_use_gpio && !use_pmic) {
		pr_debug("%s: Using MBHC+GPIO-detect on gpio %d", __func__,
				JACK_DETECT_GPIO);
		mbhc_cfg.gpio = PM8921_GPIO_PM_TO_SYS(JACK_DETECT_GPIO);
		mbhc_cfg.gpio_irq = JACK_DETECT_INT;
	} else {
		pr_debug("%s: Does not use MBHC+GPIO-detect", __func__);
	}

	if (mbhc_cfg.gpio) {
		err = pm8xxx_gpio_config(mbhc_cfg.gpio, &jack_gpio_cfg);
		if (err) {
			pr_err("%s: pm8xxx_gpio_config failed %d\n", __func__,
			       err);
			return err;
		}
	}

#ifdef CONFIG_INPUT_MBHC_HEADSET_CONTROL
	if (!use_pmic) {
		mbhc_cfg.read_fw_bin = hs_detect_use_firmware;
		err = tabla_hs_detect(codec, &mbhc_cfg);
	}
#endif /* CONFIG_INPUT_MBHC_HEADSET_CONTROL */

	return err;
}

static struct snd_soc_dsp_link lpa_fe_media = {
	.playback = true,
	.trigger = {
		SND_SOC_DSP_TRIGGER_POST,
		SND_SOC_DSP_TRIGGER_POST
	},
};

static struct snd_soc_dsp_link fe_media = {
	.playback = true,
	.capture = true,
	.trigger = {
		SND_SOC_DSP_TRIGGER_POST,
		SND_SOC_DSP_TRIGGER_POST
	},
};

/* bi-directional media definition for hostless PCM device */
static struct snd_soc_dsp_link bidir_hl_media = {
	.playback = true,
	.capture = true,
	.trigger = {
		SND_SOC_DSP_TRIGGER_POST,
		SND_SOC_DSP_TRIGGER_POST
	},
};

static struct snd_soc_dsp_link hdmi_rx_hl = {
	.playback = true,
	.trigger = {
		SND_SOC_DSP_TRIGGER_POST,
		SND_SOC_DSP_TRIGGER_POST
	},
};

static int msm8960_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
			struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
	SNDRV_PCM_HW_PARAM_RATE);

	struct snd_interval *channels = hw_param_interval(params,
			SNDRV_PCM_HW_PARAM_CHANNELS);

	pr_debug("%s()\n", __func__);
	rate->min = rate->max = 48000;
	channels->min = channels->max = msm8960_slim_0_rx_ch;

	return 0;
}

static int msm8960_slim_0_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
			struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
	SNDRV_PCM_HW_PARAM_RATE);

	struct snd_interval *channels = hw_param_interval(params,
			SNDRV_PCM_HW_PARAM_CHANNELS);

	pr_debug("%s()\n", __func__);
	rate->min = rate->max = 48000;
	channels->min = channels->max = msm8960_slim_0_tx_ch;

	return 0;
}

static int msm8960_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
			struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
	SNDRV_PCM_HW_PARAM_RATE);

	pr_debug("%s()\n", __func__);
	rate->min = rate->max = 48000;

	return 0;
}

static int msm8960_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
					struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_RATE);

	struct snd_interval *channels = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_CHANNELS);

	pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
			channels->min, channels->max);

	rate->min = rate->max = 48000;

	return 0;
}

static int msm8960_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
					struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_RATE);

	struct snd_interval *channels = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_CHANNELS);

	rate->min = rate->max = msm8960_btsco_rate;
	channels->min = channels->max = msm8960_btsco_ch;

	return 0;
}
static int msm8960_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd,
					struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_RATE);

	struct snd_interval *channels = hw_param_interval(params,
					SNDRV_PCM_HW_PARAM_CHANNELS);

	/* PCM only supports mono output with 8khz sample rate */
	rate->min = rate->max = 8000;
	channels->min = channels->max = 1;

	return 0;
}
static int msm8960_aux_pcm_get_gpios(void)
{
	int ret = 0;

	pr_debug("%s\n", __func__);

	ret = gpio_request(GPIO_AUX_PCM_DOUT, "AUX PCM DOUT");
	if (ret < 0) {
		pr_err("%s: Failed to request gpio(%d): AUX PCM DOUT",
				__func__, GPIO_AUX_PCM_DOUT);
		goto fail_dout;
	}

	ret = gpio_request(GPIO_AUX_PCM_DIN, "AUX PCM DIN");
	if (ret < 0) {
		pr_err("%s: Failed to request gpio(%d): AUX PCM DIN",
				__func__, GPIO_AUX_PCM_DIN);
		goto fail_din;
	}

	ret = gpio_request(GPIO_AUX_PCM_SYNC, "AUX PCM SYNC");
	if (ret < 0) {
		pr_err("%s: Failed to request gpio(%d): AUX PCM SYNC",
				__func__, GPIO_AUX_PCM_SYNC);
		goto fail_sync;
	}
	ret = gpio_request(GPIO_AUX_PCM_CLK, "AUX PCM CLK");
	if (ret < 0) {
		pr_err("%s: Failed to request gpio(%d): AUX PCM CLK",
				__func__, GPIO_AUX_PCM_CLK);
		goto fail_clk;
	}

	return 0;

fail_clk:
	gpio_free(GPIO_AUX_PCM_SYNC);
fail_sync:
	gpio_free(GPIO_AUX_PCM_DIN);
fail_din:
	gpio_free(GPIO_AUX_PCM_DOUT);
fail_dout:

	return ret;
}

static int msm8960_aux_pcm_free_gpios(void)
{
	gpio_free(GPIO_AUX_PCM_DIN);
	gpio_free(GPIO_AUX_PCM_DOUT);
	gpio_free(GPIO_AUX_PCM_SYNC);
	gpio_free(GPIO_AUX_PCM_CLK);

	return 0;
}
static int msm8960_startup(struct snd_pcm_substream *substream)
{
	pr_debug("%s(): substream = %s  stream = %d\n", __func__,
		 substream->name, substream->stream);
	return 0;
}

static int msm8960_auxpcm_startup(struct snd_pcm_substream *substream)
{
	int ret = 0;

	pr_debug("%s(): substream = %s\n", __func__, substream->name);
	ret = msm8960_aux_pcm_get_gpios();
	if (ret < 0) {
		pr_err("%s: Aux PCM GPIO request failed\n", __func__);
		return -EINVAL;
	}
	return 0;
}

static void msm8960_auxpcm_shutdown(struct snd_pcm_substream *substream)
{

	pr_debug("%s(): substream = %s\n", __func__, substream->name);
	msm8960_aux_pcm_free_gpios();
}
static int machine_init(struct snd_soc_codec *codec)
{
	snd_soc_dapm_sync(codec);
	return 0;
}
Exemple #25
0
static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
	struct soc_enum *control = (struct soc_enum *)kcontrol->private_value;
	unsigned short pins;
	int pin, changed = 0;

	/* Refuse any mode changes if we are not able to control the codec. */
	if (!codec->control_data)
		return -EUNATCH;

	if (ucontrol->value.enumerated.item[0] >= control->max)
		return -EINVAL;

	mutex_lock(&codec->mutex);

	/* Translate selection to bitmap */
	pins = ams_delta_audio_mode_pins[ucontrol->value.enumerated.item[0]];

	/* Setup pins after corresponding bits if changed */
	pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE));
	if (pin != snd_soc_dapm_get_pin_status(codec, "Mouthpiece")) {
		changed = 1;
		if (pin)
			snd_soc_dapm_enable_pin(codec, "Mouthpiece");
		else
			snd_soc_dapm_disable_pin(codec, "Mouthpiece");
	}
	pin = !!(pins & (1 << AMS_DELTA_EARPIECE));
	if (pin != snd_soc_dapm_get_pin_status(codec, "Earpiece")) {
		changed = 1;
		if (pin)
			snd_soc_dapm_enable_pin(codec, "Earpiece");
		else
			snd_soc_dapm_disable_pin(codec, "Earpiece");
	}
	pin = !!(pins & (1 << AMS_DELTA_MICROPHONE));
	if (pin != snd_soc_dapm_get_pin_status(codec, "Microphone")) {
		changed = 1;
		if (pin)
			snd_soc_dapm_enable_pin(codec, "Microphone");
		else
			snd_soc_dapm_disable_pin(codec, "Microphone");
	}
	pin = !!(pins & (1 << AMS_DELTA_SPEAKER));
	if (pin != snd_soc_dapm_get_pin_status(codec, "Speaker")) {
		changed = 1;
		if (pin)
			snd_soc_dapm_enable_pin(codec, "Speaker");
		else
			snd_soc_dapm_disable_pin(codec, "Speaker");
	}
	pin = !!(pins & (1 << AMS_DELTA_AGC));
	if (pin != ams_delta_audio_agc) {
		ams_delta_audio_agc = pin;
		changed = 1;
		if (pin)
			snd_soc_dapm_enable_pin(codec, "AGCIN");
		else
			snd_soc_dapm_disable_pin(codec, "AGCIN");
	}
	if (changed)
		snd_soc_dapm_sync(codec);

	mutex_unlock(&codec->mutex);

	return changed;
}
Exemple #26
0
static int tegra_max98095_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	struct snd_soc_card *card = codec->card;
	struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card);
	struct tegra_asoc_platform_data *pdata = machine->pdata;
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai);
#endif
	int ret;

#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	if (machine->codec_info[BASEBAND].i2s_id != -1)
		i2s->is_dam_used = true;
#endif

	if (machine->init_done)
		return 0;

	machine->init_done = true;

	if (gpio_is_valid(pdata->gpio_spkr_en)) {
		ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
		if (ret) {
			dev_err(card->dev, "cannot get spkr_en gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_SPKR_EN;

		gpio_direction_output(pdata->gpio_spkr_en, 0);
	}

	if (gpio_is_valid(pdata->gpio_hp_mute)) {
		ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
		if (ret) {
			dev_err(card->dev, "cannot get hp_mute gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_HP_MUTE;

		gpio_direction_output(pdata->gpio_hp_mute, 0);
	}

	if (gpio_is_valid(pdata->gpio_int_mic_en)) {
		ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
		if (ret) {
			dev_err(card->dev, "cannot get int_mic_en gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_INT_MIC_EN;

		/* Disable int mic; enable signal is active-high */
		gpio_direction_output(pdata->gpio_int_mic_en, 0);
	}

	if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
		ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
		if (ret) {
			dev_err(card->dev, "cannot get ext_mic_en gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_EXT_MIC_EN;

		/* Enable ext mic; enable signal is active-low */
		gpio_direction_output(pdata->gpio_ext_mic_en, 0);
	}

	ret = snd_soc_add_card_controls(card, tegra_max98095_controls,
				   ARRAY_SIZE(tegra_max98095_controls));
	if (ret < 0)
		return ret;

	snd_soc_dapm_new_controls(dapm, tegra_max98095_dapm_widgets,
			ARRAY_SIZE(tegra_max98095_dapm_widgets));

	snd_soc_dapm_add_routes(dapm, enterprise_audio_map,
			ARRAY_SIZE(enterprise_audio_map));

	ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
			&tegra_max98095_hp_jack);
	if (ret < 0)
		return ret;

#ifdef CONFIG_SWITCH
	snd_soc_jack_notifier_register(&tegra_max98095_hp_jack,
		&headset_switch_nb);
#else /*gpio based headset detection*/
	snd_soc_jack_add_pins(&tegra_max98095_hp_jack,
		ARRAY_SIZE(tegra_max98095_hp_jack_pins),
		tegra_max98095_hp_jack_pins);
#endif

	ret = tegra_asoc_utils_register_ctls(&machine->util_data);
	if (ret < 0)
		return ret;

	/* max98095_headset_detect(codec, &tegra_max98095_hp_jack,
		SND_JACK_HEADSET); */

	snd_soc_dapm_nc_pin(dapm, "INA1");
	snd_soc_dapm_nc_pin(dapm, "INA2");
	snd_soc_dapm_nc_pin(dapm, "INB1");
	snd_soc_dapm_nc_pin(dapm, "INB2");
	snd_soc_dapm_sync(dapm);

	return 0;
}
Exemple #27
0
static void tab3_mic_id(void *data, u16 status)
{
	struct wm1811_machine_priv *wm1811 = data;
	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(wm1811->codec);
	int report;
	int reg;
	bool present;

	wake_lock_timeout(&wm1811->jackdet_wake_lock, 5 * HZ);

	/* Either nothing present or just starting detection */
	if (!(status & WM8958_MICD_STS)) {
		if (!wm8994->jackdet) {
			/* If nothing present then clear our statuses */
			dev_dbg(wm1811->codec->dev, "Detected open circuit\n");
			wm8994->jack_mic = false;
			wm8994->mic_detecting = true;

			tab3_micd_set_rate(wm1811->codec);

			snd_soc_jack_report(wm8994->micdet[0].jack, 0,
					    wm8994->btn_mask |
					     SND_JACK_HEADSET);
		}
		/*ToDo*/
		/*return;*/
	}

	/* If the measurement is showing a high impedence we've got a
	 * microphone.
	 */
	if (wm8994->mic_detecting && (status & 0x400)) {
		dev_info(wm1811->codec->dev, "Detected microphone\n");

		wm8994->mic_detecting = false;
		wm8994->jack_mic = true;

		tab3_micd_set_rate(wm1811->codec);

		snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADSET,
				    SND_JACK_HEADSET);
	}

	if (wm8994->mic_detecting && status & 0x4) {
		dev_info(wm1811->codec->dev, "Detected headphone\n");
		wm8994->mic_detecting = false;

		tab3_micd_set_rate(wm1811->codec);

		snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE,
				    SND_JACK_HEADSET);

		/* If we have jackdet that will detect removal */
		if (wm8994->jackdet) {
			mutex_lock(&wm8994->accdet_lock);

			snd_soc_update_bits(wm1811->codec, WM8958_MIC_DETECT_1,
					    WM8958_MICD_ENA, 0);

			if (wm8994->active_refcount) {
				snd_soc_update_bits(wm1811->codec,
					WM8994_ANTIPOP_2,
					WM1811_JACKDET_MODE_MASK,
					WM1811_JACKDET_MODE_AUDIO);
			}

			mutex_unlock(&wm8994->accdet_lock);

			if (wm8994->pdata->jd_ext_cap) {
				mutex_lock(&wm1811->codec->mutex);
				snd_soc_dapm_disable_pin(&wm1811->codec->dapm,
							 "MICBIAS2");
				snd_soc_dapm_sync(&wm1811->codec->dapm);
				mutex_unlock(&wm1811->codec->mutex);
			}
		}
	}
}
Exemple #28
0
static void msm_enable_ext_spk_amp_gpio(u32 spk_amp_gpio)
{
	int ret = 0;

	struct pm_gpio param = {
		.direction      = PM_GPIO_DIR_OUT,
		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
		.output_value   = 1,
		.pull      = PM_GPIO_PULL_NO,
		.vin_sel	= PM_GPIO_VIN_S4,
		.out_strength   = PM_GPIO_STRENGTH_MED,
		.function       = PM_GPIO_FUNC_NORMAL,
	};

	if (spk_amp_gpio == bottom_spk_pamp_gpio) {

		ret = gpio_request(bottom_spk_pamp_gpio, "BOTTOM_SPK_AMP");
		if (ret) {
			pr_err("%s: Error requesting BOTTOM SPK AMP GPIO %u\n",
				__func__, bottom_spk_pamp_gpio);
			return;
		}
		ret = pm8xxx_gpio_config(bottom_spk_pamp_gpio, &param);
		if (ret)
			pr_err("%s: Failed to configure Bottom Spk Ampl"
				" gpio %u\n", __func__, bottom_spk_pamp_gpio);
		else {
			pr_debug("%s: enable Bottom spkr amp gpio\n", __func__);
			gpio_direction_output(bottom_spk_pamp_gpio, 1);
		}

	} else if (spk_amp_gpio == top_spk_pamp_gpio) {

		ret = gpio_request(top_spk_pamp_gpio, "TOP_SPK_AMP");
		if (ret) {
			pr_err("%s: Error requesting GPIO %d\n", __func__,
				top_spk_pamp_gpio);
			return;
		}
		ret = pm8xxx_gpio_config(top_spk_pamp_gpio, &param);
		if (ret)
			pr_err("%s: Failed to configure Top Spk Ampl"
				" gpio %u\n", __func__, top_spk_pamp_gpio);
		else {
			pr_debug("%s: enable Top spkr amp gpio\n", __func__);
			gpio_direction_output(top_spk_pamp_gpio, 1);
		}

	} else if (spk_amp_gpio == DOCK_SPK_PAMP_GPIO) {

		ret = gpio_request(DOCK_SPK_PAMP_GPIO, "DOCK_SPK_AMP");
		if (ret) {
			pr_err("%s: Error requesting GPIO %d\n", __func__,
				DOCK_SPK_PAMP_GPIO);
			return;
		}
		ret = pm8xxx_gpio_config(DOCK_SPK_PAMP_GPIO, &param);
		if (ret)
			pr_err("%s: Failed to configure Dock Spk Ampl"
				" gpio %u\n", __func__, DOCK_SPK_PAMP_GPIO);
		else {
			pr_debug("%s: enable dock amp gpio\n", __func__);
			gpio_direction_output(DOCK_SPK_PAMP_GPIO, 1);
		}

		ret = gpio_request(USB_ID_ADC_GPIO, "USB_ID_ADC");
		if (ret) {
			pr_err("%s: Error requesting USB_ID_ADC PMIC GPIO %u\n",
				__func__, USB_ID_ADC_GPIO);
			return;
		}
		ret = pm8xxx_gpio_config(USB_ID_ADC_GPIO, &param);
		if (ret)
			pr_err("%s: Failed to configure USB_ID_ADC PMIC"
				" gpio %u\n", __func__, USB_ID_ADC_GPIO);

	} else {
		pr_err("%s: ERROR : Invalid External Speaker Ampl GPIO."
			" gpio = %u\n", __func__, spk_amp_gpio);
		return;
	}
}

static void msm_ext_spk_power_amp_on(u32 spk)
{
	if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {

		if ((msm_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
			(msm_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) {

			pr_debug("%s() External Bottom Speaker Ampl already "
				"turned on. spk = 0x%08x\n", __func__, spk);
			return;
		}

		msm_ext_bottom_spk_pamp |= spk;

		if ((msm_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
			(msm_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) {

			msm_enable_ext_spk_amp_gpio(bottom_spk_pamp_gpio);
			pr_debug("%s: slepping 4 ms after turning on external "
				" Bottom Speaker Ampl\n", __func__);
			usleep_range(4000, 4000);
		}

	} else if  (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {

		if ((msm_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
			(msm_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {

			pr_debug("%s() External Top Speaker Ampl already"
				"turned on. spk = 0x%08x\n", __func__, spk);
			return;
		}

		msm_ext_top_spk_pamp |= spk;

		if ((msm_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
			(msm_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {

			msm_enable_ext_spk_amp_gpio(top_spk_pamp_gpio);
			pr_debug("%s: sleeping 4 ms after turning on "
				" external HAC Ampl\n", __func__);
			usleep_range(4000, 4000);
		}

	} else if (spk & (DOCK_SPK_AMP_POS | DOCK_SPK_AMP_NEG)) {

		mutex_lock(&audio_notifier_lock);

		if ((msm_ext_dock_spk_pamp & DOCK_SPK_AMP_POS) &&
			(msm_ext_dock_spk_pamp & DOCK_SPK_AMP_NEG)) {

			pr_debug("%s() External Dock Speaker Ampl already"
				"turned on. spk = 0x%08x\n", __func__, spk);
			return;
		}

		msm_ext_dock_spk_pamp |= spk;

		if ((msm_ext_dock_spk_pamp & DOCK_SPK_AMP_POS) &&
			(msm_ext_dock_spk_pamp & DOCK_SPK_AMP_NEG)) {

			msm_enable_ext_spk_amp_gpio(DOCK_SPK_PAMP_GPIO);

			pr_debug("%s: sleeping 4 ms after turning on "
				" external DOCK Ampl\n", __func__);
			usleep_range(4000, 4000);
		}
		mutex_unlock(&audio_notifier_lock);

	} else  {

		pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n",
			__func__, spk);
		return;
	}
}

static void msm_ext_spk_power_amp_off(u32 spk)
{
	struct pm_gpio param = {
		.direction      = PM_GPIO_DIR_IN,
		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
		.pull      = PM_GPIO_PULL_NO,
		.vin_sel	= PM_GPIO_VIN_S4,
		.out_strength   = PM_GPIO_STRENGTH_MED,
		.function       = PM_GPIO_FUNC_NORMAL,
	};

	pr_debug("%s, spk = %d\n", __func__, spk);

	if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {

		if (!msm_ext_bottom_spk_pamp)
			return;

		gpio_direction_output(bottom_spk_pamp_gpio, 0);
		gpio_free(bottom_spk_pamp_gpio);
		msm_ext_bottom_spk_pamp = 0;

		pr_debug("%s: sleeping 4 ms after turning off external Bottom"
			" Speaker Ampl\n", __func__);

		usleep_range(4000, 4000);

	} else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {

		if (!msm_ext_top_spk_pamp)
			return;

		gpio_direction_output(top_spk_pamp_gpio, 0);
		gpio_free(top_spk_pamp_gpio);
		msm_ext_top_spk_pamp = 0;

		pr_debug("%s: sleeping 4 ms after turning off external"
			" HAC Ampl\n", __func__);

		usleep_range(4000, 4000);

	} else if (spk & (DOCK_SPK_AMP_POS | DOCK_SPK_AMP_NEG)) {

		mutex_lock(&audio_notifier_lock);

		if (!msm_ext_dock_spk_pamp) {
			mutex_unlock(&audio_notifier_lock);
			return;
		}

		gpio_direction_input(DOCK_SPK_PAMP_GPIO);
		gpio_free(DOCK_SPK_PAMP_GPIO);

		gpio_direction_input(USB_ID_ADC_GPIO);
		if (pm8xxx_gpio_config(USB_ID_ADC_GPIO, &param))
			pr_err("%s: Failed to configure USB_ID_ADC PMIC"
				" gpio %u\n", __func__, USB_ID_ADC_GPIO);
		gpio_free(USB_ID_ADC_GPIO);
		msm_ext_dock_spk_pamp = 0;

		mutex_unlock(&audio_notifier_lock);

		pr_debug("%s: sleeping 4 ms after turning off external"
			" DOCK Ampl\n", __func__);

		usleep_range(4000, 4000);

	} else  {

		pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n",
			__func__, spk);
		return;
	}
}

static void msm_ext_control(struct snd_soc_codec *codec)
{
	struct snd_soc_dapm_context *dapm = &codec->dapm;

	mutex_lock(&dapm->codec->mutex);

	pr_debug("%s: msm_spk_control = %d", __func__, msm_spk_control);
	if (msm_spk_control == MSM_SPK_ON) {
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
		snd_soc_dapm_enable_pin(dapm, "Dock Spk Pos");
		snd_soc_dapm_enable_pin(dapm, "Dock Spk Neg");

	} else {
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Pos");
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Neg");
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Pos");
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Neg");
		snd_soc_dapm_disable_pin(dapm, "Dock Spk Pos");
		snd_soc_dapm_disable_pin(dapm, "Dock Spk Neg");
	}

	snd_soc_dapm_sync(dapm);
	mutex_unlock(&dapm->codec->mutex);
}

static int msm_get_spk(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	pr_debug("%s: msm_spk_control = %d", __func__, msm_spk_control);
	ucontrol->value.integer.value[0] = msm_spk_control;
	return 0;
}
Exemple #29
0
static int adav80x_set_sysclk(struct snd_soc_codec *codec,
		int clk_id, unsigned int freq, int dir)
{
	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);

	if (dir == SND_SOC_CLOCK_IN) {
		switch (clk_id) {
		case ADAV80X_CLK_XIN:
		case ADAV80X_CLK_XTAL:
		case ADAV80X_CLK_MCLKI:
		case ADAV80X_CLK_PLL1:
		case ADAV80X_CLK_PLL2:
			break;
		default:
			return -EINVAL;
		}

		adav80x->sysclk = freq;

		if (adav80x->clk_src != clk_id) {
			unsigned int iclk_ctrl1, iclk_ctrl2;

			adav80x->clk_src = clk_id;
			if (clk_id == ADAV80X_CLK_XTAL)
				clk_id = ADAV80X_CLK_XIN;

			iclk_ctrl1 = ADAV80X_ICLK_CTRL1_DAC_SRC(clk_id) |
					ADAV80X_ICLK_CTRL1_ADC_SRC(clk_id) |
					ADAV80X_ICLK_CTRL1_ICLK2_SRC(clk_id);
			iclk_ctrl2 = ADAV80X_ICLK_CTRL2_ICLK1_SRC(clk_id);

			snd_soc_write(codec, ADAV80X_ICLK_CTRL1, iclk_ctrl1);
			snd_soc_write(codec, ADAV80X_ICLK_CTRL2, iclk_ctrl2);

			snd_soc_dapm_sync(&codec->dapm);
		}
	} else {
		unsigned int mask;

		switch (clk_id) {
		case ADAV80X_CLK_SYSCLK1:
		case ADAV80X_CLK_SYSCLK2:
		case ADAV80X_CLK_SYSCLK3:
			break;
		default:
			return -EINVAL;
		}

		clk_id -= ADAV80X_CLK_SYSCLK1;
		mask = ADAV80X_PLL_OUTE_SYSCLKPD(clk_id);

		if (freq == 0) {
			snd_soc_update_bits(codec, ADAV80X_PLL_OUTE, mask, mask);
			adav80x->sysclk_pd[clk_id] = true;
		} else {
			snd_soc_update_bits(codec, ADAV80X_PLL_OUTE, mask, 0);
			adav80x->sysclk_pd[clk_id] = false;
		}

		if (adav80x->sysclk_pd[0])
			snd_soc_dapm_disable_pin(&codec->dapm, "PLL1");
		else
			snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");

		if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2])
			snd_soc_dapm_disable_pin(&codec->dapm, "PLL2");
		else
			snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2");

		snd_soc_dapm_sync(&codec->dapm);
	}

	return 0;
}
/*
 * omap4_aic31xx_init
 * This function is to initialize the machine Driver.
 */
static int omap4_aic31xx_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	int ret = 0;
	int gpiostatus;

	printk(KERN_INFO "entered the omap4_aic31xx_init function....\n");

#ifdef DRIVER_DAPM_SUPPORT
	/* Add OMAP4 specific widgets */
	ret = snd_soc_dapm_new_controls(codec->dapm, omap4_aic31xx_dapm_widgets,
					ARRAY_SIZE(omap4_aic31xx_dapm_widgets));
	if (ret) {
		printk (KERN_INFO "snd_soc_dapm_new_controls call failed. returning...\n");
		return ret;
	}
	DBG ("snd_soc_dapm_new_controls passed..\n");
	DBG ("Disabling the DAPM Routes for now...\n");



	/* Set up OMAP4 specific audio path audio_map */
	ret = snd_soc_dapm_add_routes(codec->dapm, audio_map, ARRAY_SIZE(audio_map));

	if (ret != 0) {
		printk (KERN_INFO "snd_soc_dapm_add_routes failed... %d\n", ret);
	}

	/* OMAP4 connected pins */
	snd_soc_dapm_enable_pin(codec->dapm, "Ext Mic");
	snd_soc_dapm_enable_pin(codec->dapm, "Ext Spk");
	snd_soc_dapm_disable_pin(codec->dapm, "Headset Mic");
	snd_soc_dapm_disable_pin(codec->dapm, "Headset Stereophone");


	/* AIC31XX not connected pins */
	snd_soc_dapm_nc_pin(codec->dapm, "AUXL");
	snd_soc_dapm_nc_pin(codec->dapm, "AUXR");
	snd_soc_dapm_nc_pin(codec->dapm, "CARKITMIC");
	snd_soc_dapm_nc_pin(codec->dapm, "DIGIMIC0");
	snd_soc_dapm_nc_pin(codec->dapm, "DIGIMIC1");mcbsp_be_hw_params_fixup

	snd_soc_dapm_nc_pin(codec->dapm, "OUTL");
	snd_soc_dapm_nc_pin(codec->dapm, "OUTR");
	snd_soc_dapm_nc_pin(codec->dapm, "EARPIECE");
	snd_soc_dapm_nc_pin(codec->dapm, "PREDRIVEL");
	snd_soc_dapm_nc_pin(codec->dapm, "PREDRIVER");
	snd_soc_dapm_nc_pin(codec->dapm, "CARKITL");
	snd_soc_dapm_nc_pin(codec->dapm, "CARKITR");

	ret = snd_soc_dapm_sync(codec->dapm);
	if (ret != 0) {
		printk (KERN_INFO "snd_soc_dapm_sync failed... %d\n", ret);
		return ret;
	}

	printk (KERN_INFO "snd_soc_dapm_sync passed..\n");mcbsp_be_hw_params_fixup

	/* Headset jack detection */
	ret = snd_soc_jack_new(codec, "Headset Jack",
			       SND_JACK_HEADSET, &hs_jack);
	if (ret != 0) {
		printk (KERN_INFO "snd_soc_jack_new failed...\n");
		return ret;
	}

	ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
				    hs_jack_pins);
	if (ret != 0) {
		printk (KERN_INFO "snd_soc_jack_add_pins failed... %d\n", ret);
		return ret;
	}

	ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
				     hs_jack_gpios);
#endif
	/* Headset jack detection */
	gpiostatus = snd_soc_jack_new(codec, "Headset Jack",
			       SND_JACK_HEADSET, &hs_jack);
	if (gpiostatus != 0) {
		printk (KERN_INFO "snd_soc_jack_new failed. %d..\n", gpiostatus);
	}

	gpiostatus = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
				    hs_jack_pins);
	if (gpiostatus != 0) {
		printk (KERN_INFO "snd_soc_jack_add_pins failed... %d\n", gpiostatus);
        }

	gpiostatus = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
				     hs_jack_gpios);

	if (gpiostatus != 0)
		printk (KERN_INFO "snd_soc_jack_add_gpios failed..%d\n", gpiostatus);

	DBG ("%s: Exiting \n", __func__);
	return ret;
}