Example #1
0
static int ams_delta_cx20442_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_dai *codec_dai = rtd->codec_dai;
	struct snd_soc_card *card = rtd->card;
	int ret;
	/* Codec is ready, now add/activate board specific controls */

	/* Store a pointer to the codec structure for tty ldisc use */
	cx20442_codec = codec;

	/* Set up digital mute if not provided by the codec */
	if (!codec_dai->driver->ops) {
		codec_dai->driver->ops = &ams_delta_dai_ops;
	} 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, dapm, 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(rtd->codec, "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(dapm, 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(dapm, 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(dapm, "Mouthpiece");
	snd_soc_dapm_enable_pin(dapm, "Earpiece");
	snd_soc_dapm_enable_pin(dapm, "Microphone");
	snd_soc_dapm_disable_pin(dapm, "Speaker");
	snd_soc_dapm_disable_pin(dapm, "AGCIN");
	snd_soc_dapm_disable_pin(dapm, "AGCOUT");

	/* 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;
}
Example #2
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 snd_soc_dapm_context *dapm = &codec->dapm;
	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->hw_write)
		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(dapm, "Mouthpiece")) {
		changed = 1;
		if (pin)
			snd_soc_dapm_enable_pin(dapm, "Mouthpiece");
		else
			snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
	}
	pin = !!(pins & (1 << AMS_DELTA_EARPIECE));
	if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) {
		changed = 1;
		if (pin)
			snd_soc_dapm_enable_pin(dapm, "Earpiece");
		else
			snd_soc_dapm_disable_pin(dapm, "Earpiece");
	}
	pin = !!(pins & (1 << AMS_DELTA_MICROPHONE));
	if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) {
		changed = 1;
		if (pin)
			snd_soc_dapm_enable_pin(dapm, "Microphone");
		else
			snd_soc_dapm_disable_pin(dapm, "Microphone");
	}
	pin = !!(pins & (1 << AMS_DELTA_SPEAKER));
	if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) {
		changed = 1;
		if (pin)
			snd_soc_dapm_enable_pin(dapm, "Speaker");
		else
			snd_soc_dapm_disable_pin(dapm, "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(dapm, "AGCIN");
		else
			snd_soc_dapm_disable_pin(dapm, "AGCIN");
	}
	if (changed)
		snd_soc_dapm_sync(dapm);

	mutex_unlock(&codec->mutex);

	return changed;
}
static int sdp4430_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 SDP4430 specific controls */
	ret = snd_soc_add_controls(codec, sdp4430_controls,
				ARRAY_SIZE(sdp4430_controls));
	if (ret)
		return ret;

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

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

	/* SDP4430 connected pins */
	snd_soc_dapm_enable_pin(dapm, "Ext Mic");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk");
	snd_soc_dapm_enable_pin(dapm, "AFML");
	snd_soc_dapm_enable_pin(dapm, "AFMR");
	snd_soc_dapm_enable_pin(dapm, "Headset Mic");
	snd_soc_dapm_enable_pin(dapm, "Headset Stereophone");

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

	if (machine_is_omap_4430sdp() || machine_is_omap_tabletblaze()
		|| machine_is_omap4_panda())
		twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
	else
		snd_soc_jack_report(&hs_jack, SND_JACK_HEADSET, 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;
}
Example #4
0
static int msm8930_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()\n", __func__);

	snd_soc_dapm_new_controls(dapm, msm8930_dapm_widgets,
				ARRAY_SIZE(msm8930_dapm_widgets));

	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE)
		snd_soc_dapm_add_routes(dapm, common_audio_map_sglte,
			ARRAY_SIZE(common_audio_map_sglte));
	else
		snd_soc_dapm_add_routes(dapm, common_audio_map,
			ARRAY_SIZE(common_audio_map));

	snd_soc_dapm_enable_pin(dapm, "Ext Spk Left Pos");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk Left Neg");

	snd_soc_dapm_sync(dapm);

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

	err = snd_soc_jack_new(codec, "Button Jack",
				SITAR_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");

	/*
	 * Switch is present only in 8930 CDP and SGLTE
	 */
	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE ||
		machine_is_msm8930_cdp())
		mbhc_cfg.swap_gnd_mic = msm8930_swap_gnd_mic;

	if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE) {
		mbhc_cfg.gpio = GPIO_HS_DET_SGLTE;
		mbhc_cfg.gpio_level_insert = 0;
	} else
		mbhc_cfg.gpio = GPIO_HS_DET;

	/*
	 * GPIO for headset detect is present in all devices
	 * MTP/Fluid/CDP/SGLTE
	 */
	err = gpio_request(mbhc_cfg.gpio, "HEADSET_DETECT");
	if (err) {
		pr_err("%s: Failed to request gpio %d\n",
				__func__, mbhc_cfg.gpio);
		return err;
	}

	mbhc_cfg.gpio_irq = gpio_to_irq(mbhc_cfg.gpio);
	sitar_hs_detect(codec, &mbhc_cfg);

	if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917) {
		/* Initialize default PMIC speaker gain */
		pm8xxx_spk_gain(DEFAULT_PMIC_SPK_GAIN);
	}

	return 0;
}
Example #5
0
void tegra_ext_control(struct snd_soc_codec *codec, int new_con)
{
	struct tegra_audio_data* audio_data = codec->socdev->codec_data;
#if defined(CONFIG_MACH_ACER_PICASSO) || defined(CONFIG_MACH_ACER_MAYA) || defined(CONFIG_MACH_ACER_VANGOGH)
	int CtrlReg = 0;
#endif

	/* Disconnect old codec routes and connect new routes*/
#ifdef MACH_ACER_AUDIO
	if (new_con & (TEGRA_HEADPHONE | TEGRA_VOIP_RINGTONE))
#else
	if (new_con & TEGRA_HEADPHONE)
#endif
		snd_soc_dapm_enable_pin(codec, "Headphone");
	else
		snd_soc_dapm_disable_pin(codec, "Headphone");

#if defined(CONFIG_MACH_ACER_PICASSO) || defined(CONFIG_MACH_ACER_MAYA) || defined(CONFIG_MACH_ACER_VANGOGH)
	if (new_con & (TEGRA_LINEOUT | TEGRA_EAR_SPK | TEGRA_SPK))
		snd_soc_dapm_enable_pin(codec, "Lineout");
	else
		snd_soc_dapm_disable_pin(codec, "Lineout");
#else
	if (new_con & (TEGRA_LINEOUT | TEGRA_EAR_SPK))
		snd_soc_dapm_enable_pin(codec, "Lineout");
	else
		snd_soc_dapm_disable_pin(codec, "Lineout");

	if (new_con & TEGRA_SPK)
		snd_soc_dapm_enable_pin(codec, "Int Spk");
	else
		snd_soc_dapm_disable_pin(codec, "Int Spk");
#endif

	if (new_con & TEGRA_INT_MIC)
		snd_soc_dapm_enable_pin(codec, "Int Mic");
	else
		snd_soc_dapm_disable_pin(codec, "Int Mic");

	if (new_con & TEGRA_EXT_MIC)
		snd_soc_dapm_enable_pin(codec, "Ext Mic");
	else
		snd_soc_dapm_disable_pin(codec, "Ext Mic");

	if (new_con & TEGRA_LINEIN)
		snd_soc_dapm_enable_pin(codec, "Linein");
	else
		snd_soc_dapm_disable_pin(codec, "Linein");

	if (new_con & TEGRA_HEADSET_OUT)
		snd_soc_dapm_enable_pin(codec, "Headset Out");
	else
		snd_soc_dapm_disable_pin(codec, "Headset Out");

	if (new_con & TEGRA_HEADSET_IN)
		snd_soc_dapm_enable_pin(codec, "Headset In");
	else
		snd_soc_dapm_disable_pin(codec, "Headset In");

#if defined(CONFIG_MACH_ACER_PICASSO) || defined(CONFIG_MACH_ACER_MAYA) || defined(CONFIG_MACH_ACER_VANGOGH)
	if (new_con & TEGRA_MIC_MUTE) {
		CtrlReg = snd_soc_read(codec, WM8903_ANALOGUE_LEFT_INPUT_0);
		CtrlReg |= WM8903_LINMUTE;
		snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_0, CtrlReg);
		snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_0, CtrlReg);
	} else {
		CtrlReg = snd_soc_read(codec, WM8903_ANALOGUE_LEFT_INPUT_0);
		CtrlReg &= ~WM8903_LINMUTE;
		snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_0, CtrlReg);
		snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_0, CtrlReg);
	}

	if (new_con & (TEGRA_HEADPHONE | TEGRA_HEADSET_OUT |
			TEGRA_HEADSET_IN))
		hp_enable(codec, 1);
	else
		hp_enable(codec, 0);
#endif

	/* signal a DAPM event */
	snd_soc_dapm_sync(codec);
	audio_data->codec_con = new_con;
}
Example #6
0
static void pavo_ext_control(struct snd_soc_codec *codec)
{
	int spk = 0, mic = 0, line = 0, hp = 0, hs = 0;

	/* set up jack connection */
	switch (pavo_jack_func) {
	case PAVO_HP:
		hp = 1;
		/* set = unmute headphone */
		//set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
		//set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
		break;
	case PAVO_MIC:
		mic = 1;
		/* reset = mute headphone */
		//reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
		//reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
		break;
	case PAVO_LINE:
		line = 1;
		//reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
		//reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
		break;
	case PAVO_HEADSET:
		hs = 1;
		mic = 1;
		//reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
		//set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
		break;
	}

	if (pavo_spk_func == PAVO_SPK_ON)
		spk = 1;

	/* set the enpoints to their new connetion states */
	if (spk)
		snd_soc_dapm_enable_pin(codec, "Ext Spk");
	else 
		snd_soc_dapm_disable_pin(codec, "Ext Spk");

	if (mic) 
		snd_soc_dapm_enable_pin(codec, "Mic Jack");
	else
		snd_soc_dapm_disable_pin(codec, "Mic Jack");
	
	if (line)
		snd_soc_dapm_enable_pin(codec, "Line Jack");
	else
		snd_soc_dapm_disable_pin(codec, "Line Jack");
	
	if (hp) 
		snd_soc_dapm_enable_pin(codec, "Headphone Jack");
	else
		snd_soc_dapm_disable_pin(codec, "Headphone Jack");
	
	if (hp)
		snd_soc_dapm_enable_pin(codec, "Headset Jack");
	else
		snd_soc_dapm_disable_pin(codec, "Headset Jack");

	/* signal a DAPM event */
	snd_soc_dapm_sync(codec);}
Example #7
0
static void mdm9615_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 mdm9615_ext_spk_power_amp_on(u32 spk)
{
	if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {

		if ((mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
			(mdm9615_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;
		}

		mdm9615_ext_bottom_spk_pamp |= spk;

		if ((mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
			(mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) {

			mdm9615_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 ((mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
			(mdm9615_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;
		}

		mdm9615_ext_top_spk_pamp |= spk;

		if ((mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
			(mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {

			mdm9615_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 mdm9615_ext_spk_power_amp_off(u32 spk)
{
	if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {

		if (!mdm9615_ext_bottom_spk_pamp)
			return;

		gpio_direction_output(bottom_spk_pamp_gpio, 0);
		gpio_free(bottom_spk_pamp_gpio);
		mdm9615_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 (!mdm9615_ext_top_spk_pamp)
			return;

		gpio_direction_output(top_spk_pamp_gpio, 0);
		gpio_free(top_spk_pamp_gpio);
		mdm9615_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 mdm9615_ext_control(struct snd_soc_codec *codec)
{
	struct snd_soc_dapm_context *dapm = &codec->dapm;

	pr_debug("%s: mdm9615_spk_control = %d", __func__, mdm9615_spk_control);
	if (mdm9615_spk_control == MDM9615_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);
}

static int mdm9615_get_spk(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	pr_debug("%s: mdm9615_spk_control = %d", __func__, mdm9615_spk_control);
	ucontrol->value.integer.value[0] = mdm9615_spk_control;
	return 0;
}
Example #8
0
static int msm8960_audrx_init(struct snd_soc_pcm_runtime *rtd)
{
	int err;
#ifdef CONFIG_PANTECH_SND //kdkim
#if defined(T_EF44S)
	int ret = 0; 
#elif defined(T_VEGAPVW)
	int ret = 0;
	int hw_rev;
#endif
#endif
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	
#if !(defined(T_EF44S) || defined(T_VEGAPVW)) //Qualcomm original...kdkim other model
	struct pm_gpio jack_gpio_cfg = {
		.direction = PM_GPIO_DIR_IN,
		.pull = PM_GPIO_PULL_DN,
		.function = PM_GPIO_FUNC_NORMAL,
		.vin_sel = 2,
		.inv_int_pol = 0,
	};
#endif
	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;

	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),
			       &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 defined(T_VEGAPVW) //kdkim
	hw_rev = get_hw_revision();
	pr_debug("########### msm8960 hw_rev : %d\n", hw_rev); 

	if(hw_rev < 4) {
		mbhc_cfg.gpio = 0;
		mbhc_cfg.gpio_irq = 0;
	}
#endif

#ifdef CONFIG_PANTECH_SND //kdkim
#if defined(T_EF44S) || defined(T_VEGAPVW)
	if (mbhc_cfg.gpio) {
		ret = gpio_request(JACK_DETECT_GPIO, "headset_detect");
		if(ret){
			pr_err("%s: gpio_request failed %d\n", __func__,
			       ret);
			headset_gpio_config = false;
			gpio_free(JACK_DETECT_GPIO);
		}

		ret = gpio_direction_input(mbhc_cfg.gpio);
		if(ret){
			pr_err("%s: gpio_direction_input failed %d\n", __func__,
			       ret);
			headset_gpio_config = false;
			gpio_free(JACK_DETECT_GPIO);
		}

		mbhc_cfg.gpio_irq = gpio_to_irq(mbhc_cfg.gpio);
	}
#else //Qualcomm original and other model temp
	if (hs_detect_use_gpio) {
		mbhc_cfg.gpio = PM8921_GPIO_PM_TO_SYS(JACK_DETECT_GPIO);
		mbhc_cfg.gpio_irq = JACK_DETECT_INT;
	}

#if defined(T_MAGNUS)
	mbhc_cfg.gpio = PM8921_GPIO_PM_TO_SYS(JACK_DETECT_GPIO);
	mbhc_cfg.gpio_irq = JACK_DETECT_INT;
#endif

	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;
		}
	}
#endif
#endif

	mbhc_cfg.read_fw_bin = hs_detect_use_firmware;

	err = tabla_hs_detect(codec, &mbhc_cfg);

	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();
}
Example #9
0
static int imx_wm8962_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	struct imx_priv *priv = &card_priv;
	struct platform_device *pdev = priv->pdev;
	struct mxc_audio_platform_data *plat = pdev->dev.platform_data;
	int ret = 0;

	gcodec = rtd->codec;

	/* Add imx specific widgets */
	snd_soc_dapm_new_controls(&codec->dapm, imx_dapm_widgets,
				  ARRAY_SIZE(imx_dapm_widgets));

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

	snd_soc_dapm_enable_pin(&codec->dapm, "Headphone Jack");
	snd_soc_dapm_enable_pin(&codec->dapm, "AMIC");

	snd_soc_dapm_sync(&codec->dapm);

	if (plat->hp_gpio != -1) {
		priv->hp_irq = gpio_to_irq(plat->hp_gpio);

		ret = request_irq(priv->hp_irq,
					imx_headphone_detect_handler,
					IRQ_TYPE_EDGE_BOTH, pdev->name, priv);

		if (ret < 0) {
			ret = -EINVAL;
			return ret;
		}

		ret = driver_create_file(pdev->dev.driver,
						&driver_attr_headphone);
		if (ret < 0) {
			ret = -EINVAL;
			return ret;
		}

		priv->hp_status = gpio_get_value(plat->hp_gpio);

		/* if headphone is inserted, disable speaker */
		if (priv->hp_status != plat->hp_active_low)
			snd_soc_dapm_nc_pin(&codec->dapm, "Ext Spk");
		else
			snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk");
	}

	if (plat->mic_gpio != -1) {
		priv->amic_irq = gpio_to_irq(plat->mic_gpio);

		ret = request_irq(priv->amic_irq,
					imx_amic_detect_handler,
					IRQ_TYPE_EDGE_BOTH, pdev->name, priv);

		if (ret < 0) {
			ret = -EINVAL;
			return ret;
		}

		ret = driver_create_file(pdev->dev.driver, &driver_attr_amic);
		if (ret < 0) {
			ret = -EINVAL;
			return ret;
		}

		priv->amic_status = gpio_get_value(plat->mic_gpio);

		/* if amic is inserted, disable DMIC */
		if (priv->amic_status != plat->mic_active_low)
			snd_soc_dapm_nc_pin(&codec->dapm, "DMIC");
		else
			snd_soc_dapm_enable_pin(&codec->dapm, "DMIC");
	} else if (!snd_soc_dapm_get_pin_status(&codec->dapm, "DMICDAT"))
		snd_soc_dapm_nc_pin(&codec->dapm, "DMIC");

	return 0;
}