コード例 #1
0
static void sc881x_ext_control(struct snd_soc_dapm_context *dapm)
{
	int i;
	for (i = 0; i < SC881X_FUNC_LINEINREC; i++) {
		if (sc881x.func[i] == SWITCH_FUN_ON)
			snd_soc_dapm_enable_pin(dapm, func_name[i]);
		else
			snd_soc_dapm_disable_pin(dapm, func_name[i]);
	}

	if (sc881x.func[SC881X_FUNC_LINEINREC] == SWITCH_FUN_ON) {
		arch_audio_codec_lineinrec_enable();
		snd_soc_dapm_enable_pin(dapm, func_name[SC881X_FUNC_HP_MIC]);
	} else {
		arch_audio_codec_lineinrec_disable();
	}

	if (sc881x.func[SC881X_FUNC_MIC] == SWITCH_FUN_ON)
		snd_soc_dapm_disable_pin(dapm, func_name[SC881X_FUNC_HP_MIC]);

	if (sc881x.func[SC881X_FUNC_MIC_BIAS] == SWITCH_FUN_ON)
		snd_soc_dapm_force_enable_pin(dapm,
					      func_name[SC881X_FUNC_MIC_BIAS]);
	else
		snd_soc_dapm_disable_pin(dapm, func_name[SC881X_FUNC_MIC_BIAS]);

	/* signal a DAPM event */
	snd_soc_dapm_sync(dapm);
}
コード例 #2
0
ファイル: arizona-micsupp.c プロジェクト: BozkurTR/kernel
static void arizona_micsupp_check_cp(struct work_struct *work)
{
	struct arizona_micsupp *micsupp =
		container_of(work, struct arizona_micsupp, check_cp_work);
	struct snd_soc_dapm_context *dapm = micsupp->arizona->dapm;
	struct arizona *arizona = micsupp->arizona;
	struct regmap *regmap = arizona->regmap;
	unsigned int reg;
	int ret;

	ret = regmap_read(regmap, ARIZONA_MIC_CHARGE_PUMP_1, &reg);
	if (ret != 0) {
		dev_err(arizona->dev, "Failed to read CP state: %d\n", ret);
		return;
	}

	if (dapm) {
		if ((reg & (ARIZONA_CPMIC_ENA | ARIZONA_CPMIC_BYPASS)) ==
		    ARIZONA_CPMIC_ENA)
			snd_soc_dapm_force_enable_pin(dapm, "MICSUPP");
		else
			snd_soc_dapm_disable_pin(dapm, "MICSUPP");

		snd_soc_dapm_sync(dapm);
	}
}
コード例 #3
0
ファイル: tegra_wm9712.c プロジェクト: 383530895/linux
static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	struct snd_soc_codec *codec = codec_dai->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;

	return snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
}
コード例 #4
0
ファイル: cht_bsw_max98090_ti.c プロジェクト: avagin/linux
static int cht_ti_jack_event(struct notifier_block *nb,
		unsigned long event, void *data)
{
	struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
	struct snd_soc_dapm_context *dapm = &jack->card->dapm;

	if (event & SND_JACK_MICROPHONE) {
		snd_soc_dapm_force_enable_pin(dapm, "SHDN");
		snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");
		snd_soc_dapm_sync(dapm);
	} else {
		snd_soc_dapm_disable_pin(dapm, "MICBIAS");
		snd_soc_dapm_disable_pin(dapm, "SHDN");
		snd_soc_dapm_sync(dapm);
	}

	return 0;
}
コード例 #5
0
ファイル: bdw-rt5677.c プロジェクト: byxorna/linux-samus
static int bdw_rt5677_init(struct snd_soc_pcm_runtime *rtd)
{
	struct bdw_rt5677_priv *bdw_rt5677 =
			snd_soc_card_get_drvdata(rtd->card);
	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;

	/* Enable codec ASRC function for Stereo DAC/Stereo1 ADC/DMIC/I2S1.
	 * The ASRC clock source is clk_i2s1_asrc.
	 */
	rt5677_sel_asrc_clk_src(codec, RT5677_DA_STEREO_FILTER |
			RT5677_AD_STEREO1_FILTER | RT5677_I2S1_SOURCE,
			RT5677_CLK_SEL_I2S1_ASRC);

	/* Request rt5677 GPIO for headphone amp control */
	bdw_rt5677->gpio_hp_en = devm_gpiod_get_index(codec->dev,
		"RT5677_GPIO_HP_AMP_SHDN_L", RT5677_GPIO_HP_AMP_SHDN_L, GPIOD_ASIS);
	if (IS_ERR(bdw_rt5677->gpio_hp_en)) {
		dev_err(codec->dev, "Can't find HP_AMP_SHDN_L gpio\n");
		return PTR_ERR(bdw_rt5677->gpio_hp_en);
	}
	gpiod_direction_output(bdw_rt5677->gpio_hp_en, 0);

	/* Create and initialize headphone jack */
	if (!snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
			&headphone_jack)) {
		if (snd_soc_jack_add_pins(&headphone_jack, 1,
				&headphone_jack_pin))
			dev_err(codec->dev, "Can't add headphone jack pin\n");

		headphone_jack_gpio.gpiod_dev = codec->dev;
		if (snd_soc_jack_add_gpios(&headphone_jack, 1,
				&headphone_jack_gpio))
			dev_err(codec->dev, "Can't add headphone jack gpio\n");
	} else {
		dev_err(codec->dev, "Can't create headphone jack\n");
	}

	/* Create and initialize mic jack */
	if (!snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
			&mic_jack)) {
		if (snd_soc_jack_add_pins(&mic_jack, 1, &mic_jack_pin))
			dev_err(codec->dev, "Can't add mic jack pin\n");

		mic_jack_gpio.gpiod_dev = codec->dev;
		if (snd_soc_jack_add_gpios(&mic_jack, 1, &mic_jack_gpio))
			dev_err(codec->dev, "Can't add mic jack gpio\n");
	} else {
		dev_err(codec->dev, "Can't create mic jack\n");
	}
	bdw_rt5677->codec = codec;

	snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
	return 0;
}
コード例 #6
0
ファイル: soc-utils.c プロジェクト: AlexShiLucky/linux
int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
				       const char *pin)
{
	struct snd_soc_dapm_context *dapm =
		snd_soc_component_get_dapm(component);
	char *full_name;
	int ret;

	if (!component->name_prefix)
		return snd_soc_dapm_force_enable_pin(dapm, pin);

	full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
	if (!full_name)
		return -ENOMEM;

	ret = snd_soc_dapm_force_enable_pin(dapm, full_name);
	kfree(full_name);

	return ret;
}
コード例 #7
0
ファイル: bdw-rt5677.c プロジェクト: byxorna/linux-samus
static int bdw_rt5677_resume_post(struct snd_soc_card *card)
{
	struct bdw_rt5677_priv *bdw_rt5677 = snd_soc_card_get_drvdata(card);
	struct snd_soc_dapm_context *dapm;

	if (bdw_rt5677->codec) {
		dapm = &bdw_rt5677->codec->dapm;
		snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
	}
	return 0;
}
コード例 #8
0
ファイル: msm8x60.c プロジェクト: veirs/UbuntuTouch
static int jack_notifier_event(struct notifier_block *nb, unsigned long event, void *data)
{
	struct snd_soc_codec *codec;
	struct wm8994_priv *wm8994;
	struct snd_soc_jack *jack;

	// Force enable will keep the MICBISA on, even when we stop reording
	jack = data;

	if(jack)
	{
		codec = jack->card->codec;
		wm8994 = snd_soc_codec_get_drvdata(codec);

		if(1 == event){
			// Someone inserted a jack, we need to turn on mic bias2 for headset mic detection
			snd_soc_dapm_force_enable_pin( codec, "MICBIAS2");

			pr_crit("MIC DETECT: ENABLE. Jack inserted\n");
			// This will enable mic detection on 8958
			wm8958_mic_detect( codec, &hp_jack, NULL, NULL);

		}else if (0 == event){
			headphone_plugged = 0;
			if (headphone_switch) {
				switch_set_state(headphone_switch, headphone_plugged);
			}
			pr_crit("MIC DETECT: DISABLE. Jack removed\n");

			// This will disable mic detection on 8958
			wm8958_mic_detect( codec, NULL, NULL, NULL);

			if( wm8994->pdata->jack_is_mic) {
				dev_err(codec->dev, "  Reporting headset removed\n");
				wm8994->pdata->jack_is_mic = false;
				wm8994->micdet[0].jack->jack->type = SND_JACK_MICROPHONE;
				input_report_switch(wm8994->micdet[0].jack->jack->input_dev,
							    SW_MICROPHONE_INSERT,
						        0);
			} else { 
				dev_err(codec->dev, "  Reporting headphone removed\n");
                		input_report_switch(wm8994->micdet[0].jack->jack->input_dev,
							    SW_HEADPHONE_INSERT,
						        0);
			}
			
			input_sync(jack->jack->input_dev);
			snd_soc_dapm_disable_pin( codec, "MICBIAS2");
		}
	}

	return 0;
}
コード例 #9
0
ファイル: adav80x.c プロジェクト: AICP/kernel_moto_shamu
static int adav80x_probe(struct snd_soc_codec *codec)
{
	int ret;
	struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);

	ret = snd_soc_codec_set_cache_io(codec, 7, 9, adav80x->control_type);
	if (ret) {
		dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
		return ret;
	}

	/* Force PLLs on for SYSCLK output */
	snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1");
	snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2");

	/* Power down S/PDIF receiver, since it is currently not supported */
	snd_soc_write(codec, ADAV80X_PLL_OUTE, 0x20);
	/* Disable DAC zero flag */
	snd_soc_write(codec, ADAV80X_DAC_CTRL3, 0x6);

	return adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
}
コード例 #10
0
ファイル: tegra_wm8903.c プロジェクト: FrozenCow/FIRE-ICE
static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	struct snd_soc_codec *codec = codec_dai->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_asoc_platform_data *pdata = machine->pdata;

	machine->bias_level = SND_SOC_BIAS_STANDBY;

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

	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() ? SND_JACK_MICROPHONE : 0);

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

	snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");

	return 0;
}
コード例 #11
0
static int set_mic_bias(struct snd_soc_jack *jack,
			const char *bias_widget, bool enable)
{
	struct snd_soc_codec *codec = jack->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;

	if (enable)
		snd_soc_dapm_force_enable_pin(dapm, bias_widget);
	else
		snd_soc_dapm_disable_pin(dapm, bias_widget);

	snd_soc_dapm_sync(&codec->dapm);

	return 0;
}
コード例 #12
0
static int rk_wm8960_init(struct snd_soc_pcm_runtime *runtime)
{
	struct snd_soc_codec *codec = runtime->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;

	snd_soc_dapm_enable_pin(dapm, "Headset Mic");
	snd_soc_dapm_enable_pin(dapm, "Headphone");
	snd_soc_dapm_enable_pin(dapm, "Ext Spk");
	snd_soc_dapm_enable_pin(dapm, "Int Mic");

	snd_soc_dapm_force_enable_pin(dapm, "MICBIAS");

	snd_soc_dapm_sync(dapm);

	return 0;
}
コード例 #13
0
/* Callback to set volume for *VOLCTRL regs. Needs to be implemented separately
 * since clock and VAUDA need to be on before value can be written to the regs
 */
int mfld_set_vol_2r(struct snd_kcontrol *kcontrol,
		struct snd_ctl_elem_value *ucontrol)
{
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	unsigned int reg = mc->reg;
	unsigned int reg2 = mc->rreg;
	unsigned int shift = mc->shift;
	int max = mc->max;
	unsigned int mask = (1 << fls(max)) - 1;
	unsigned int invert = mc->invert;
	int err;
	unsigned int val, val2, val_mask;
	int sst_pll_mode_saved;

	val_mask = mask << shift;
	val = (ucontrol->value.integer.value[0] & mask);
	val2 = (ucontrol->value.integer.value[1] & mask);

	if (invert) {
		val = max - val;
		val2 = max - val2;
	}

	val = val << shift;
	val2 = val2 << shift;

	pr_debug("enabling PLL and VAUDA to change volume\n");
	mutex_lock(&codec->mutex);
	sst_pll_mode_saved = intel_scu_ipc_set_osc_clk0(true, CLK0_QUERY);
	intel_scu_ipc_set_osc_clk0(true, CLK0_MSIC);
	snd_soc_dapm_force_enable_pin(&codec->dapm, "VirtBias");
	snd_soc_dapm_sync(&codec->dapm);

	err = snd_soc_update_bits(codec, reg, val_mask, val);
	if (err < 0)
		goto restore_state;

	err = snd_soc_update_bits(codec, reg2, val_mask, val2);
restore_state:
	snd_soc_dapm_disable_pin(&codec->dapm, "VirtBias");
	if (!(sst_pll_mode_saved & CLK0_MSIC))
		intel_scu_ipc_set_osc_clk0(false, CLK0_MSIC);
	mutex_unlock(&codec->mutex);
	return err;
}
コード例 #14
0
static int midas_card_resume_post(struct snd_soc_card *card)
{
	struct snd_soc_codec *codec = card->rtd->codec;
	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);

#ifdef CONFIG_SND_USE_LINEOUT_SWITCH
	if (lineout_mode == 1 &&
		wm8994->vmid_mode == WM8994_VMID_NORMAL) {
		dev_dbg(codec->dev,
			"%s: entering normal vmid mode\n", __func__);
		wm8994_vmid_mode(codec, WM8994_VMID_FORCE);
		gpio_set_value(GPIO_LINEOUT_EN, 1);
	}
#endif
#ifdef CONFIG_SEC_DEV_JACK
	snd_soc_dapm_force_enable_pin(&codec->dapm, "AIF1CLK");
#endif

	return 0;
}
コード例 #15
0
static int tab3_card_resume_post(struct snd_soc_card *card)
{
	struct snd_soc_codec *codec = card->rtd->codec;
	int reg = 0;

	/* workaround for jack detection
	 * sometimes WM8994_GPIO_1 type changed wrong function type
	 * so if type mismatched, update to IRQ type
	 */
	reg = snd_soc_read(codec, WM8994_GPIO_1);

	if ((reg & WM8994_GPN_FN_MASK) != WM8994_GP_FN_IRQ) {
		dev_err(codec->dev, "%s: GPIO1 type 0x%x\n", __func__, reg);
		snd_soc_write(codec, WM8994_GPIO_1, WM8994_GP_FN_IRQ);
	}

#ifdef CONFIG_SEC_DEV_JACK
	snd_soc_dapm_force_enable_pin(&codec->dapm, "AIF1CLK");
#endif

	return 0;
}
コード例 #16
0
ファイル: tegra_alc5632.c プロジェクト: AshishNamdev/linux
static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
{
	int ret;
	struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(rtd->card);

	ret = snd_soc_card_jack_new(rtd->card, "Headset Jack",
				    SND_JACK_HEADSET,
				    &tegra_alc5632_hs_jack,
				    tegra_alc5632_hs_jack_pins,
				    ARRAY_SIZE(tegra_alc5632_hs_jack_pins));
	if (ret)
		return ret;

	if (gpio_is_valid(machine->gpio_hp_det)) {
		tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
		snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack,
						1,
						&tegra_alc5632_hp_jack_gpio);
	}

	snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "MICBIAS1");

	return 0;
}
コード例 #17
0
static int t0_card_resume_post(struct snd_soc_card *card)
{
	struct snd_soc_codec *codec = card->rtd->codec;
	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);

#ifdef CONFIG_SND_USE_LINEOUT_SWITCH
	struct wm1811_machine_priv *wm1811
		= snd_soc_card_get_drvdata(codec->card);

	if (lineout_mode == 1 &&
		wm8994->vmid_mode == WM8994_VMID_NORMAL) {
		dev_info(codec->dev,
			"%s: entering normal vmid mode\n", __func__);
		wm8994_vmid_mode(codec, WM8994_VMID_FORCE);
		if (wm1811->lineout_switch_f)
			wm1811->lineout_switch_f(1);
	}
#endif
#ifdef CONFIG_SEC_DEV_JACK
	snd_soc_dapm_force_enable_pin(&codec->dapm, "AIF1CLK");
#endif

	return 0;
}
コード例 #18
0
ファイル: tegra_alc5632.c プロジェクト: 383530895/linux
static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	struct snd_soc_codec *codec = codec_dai->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(rtd->card);

	snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
			 &tegra_alc5632_hs_jack);
	snd_soc_jack_add_pins(&tegra_alc5632_hs_jack,
			ARRAY_SIZE(tegra_alc5632_hs_jack_pins),
			tegra_alc5632_hs_jack_pins);

	if (gpio_is_valid(machine->gpio_hp_det)) {
		tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
		snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack,
						1,
						&tegra_alc5632_hp_jack_gpio);
	}

	snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");

	return 0;
}
コード例 #19
0
static int seaboard_asoc_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_seaboard *seaboard = snd_soc_card_get_drvdata(card);
	struct seaboard_audio_platform_data *pdata = seaboard->pdata;
	int ret;

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

	gpio_direction_output(pdata->gpio_spkr_en, 0);

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

		gpio_direction_output(pdata->gpio_hp_mute, 1);
	}

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

	snd_soc_dapm_new_controls(dapm, seaboard_dapm_widgets,
					ARRAY_SIZE(seaboard_dapm_widgets));

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

	seaboard_hp_jack_gpios[0].gpio = pdata->gpio_hp_det;
	snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
			 &seaboard_hp_jack);
	snd_soc_jack_add_pins(&seaboard_hp_jack,
			      ARRAY_SIZE(seaboard_hp_jack_pins),
			      seaboard_hp_jack_pins);
	snd_soc_jack_add_gpios(&seaboard_hp_jack,
			       ARRAY_SIZE(seaboard_hp_jack_gpios),
			       seaboard_hp_jack_gpios);

	snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
			 &seaboard_mic_jack);
	snd_soc_jack_add_pins(&seaboard_mic_jack,
			      ARRAY_SIZE(seaboard_mic_jack_pins),
			      seaboard_mic_jack_pins);
	wm8903_mic_detect(codec, &seaboard_mic_jack, SND_JACK_MICROPHONE, 0);

	snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");

	snd_soc_dapm_nc_pin(dapm, "IN1L");
	if (machine_is_kaen())
		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, "IN2L");
	snd_soc_dapm_nc_pin(dapm, "IN3R");
	snd_soc_dapm_nc_pin(dapm, "IN3L");

	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;
}
コード例 #20
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 defined(CONFIG_ARCH_ACER_T30)
	/* bypass switch enable gpio */
	if (gpio_is_valid(pdata->gpio_bypass_switch_en)) {
		tegra_gpio_enable(pdata->gpio_bypass_switch_en);
		ret = gpio_request(pdata->gpio_bypass_switch_en, "bypass_switch_en");
		if (ret) {
			dev_err(card->dev, "cannot get bypass_switch_en gpio\n");
			return ret;
		}
		machine->gpio_requested |= GPIO_BYBASS_EN;

		/* Enable bypass switch; enable signal is active-high */
		gpio_direction_output(pdata->gpio_bypass_switch_en, 0);
	}
#endif

#if defined(CONFIG_ARCH_ACER_T20) || defined(CONFIG_ARCH_ACER_T30)
	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));

	snd_soc_dapm_add_routes(dapm, cardhu_audio_map,
			ARRAY_SIZE(cardhu_audio_map));
#else
	if (machine_is_cardhu() || machine_is_ventana()) {
		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()) {
		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));
	}
#endif

#if defined(CONFIG_ARCH_ACER_T20) || defined(CONFIG_ARCH_ACER_T30)
	audio_data.gpio.debug_en = pdata->gpio_debug_switch_en;
	/* if debug on, will not enable headset */
	if (gpio_is_valid(pdata->gpio_hp_det) && !is_debug_on()) {
		pr_info("[Audio]register headphone jack\n");
		audio_data.gpio.hp_det = pdata->gpio_hp_det;
#else
	if (gpio_is_valid(pdata->gpio_hp_det)) {
#endif
		tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det;
		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);

#if !defined(CONFIG_ARCH_ACER_T20) && !defined(CONFIG_ARCH_ACER_T30)
#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
#endif
	wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE,
			  machine_is_cardhu() ? SND_JACK_MICROPHONE : 0);

	snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");

	/* Disable Spk,Headphone,Line Out when wm8903 init */
#if defined(CONFIG_ARCH_ACER_T20) || defined(CONFIG_ARCH_ACER_T30)
	snd_soc_dapm_disable_pin(dapm, "Int Spk");
	snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
	snd_soc_dapm_disable_pin(dapm, "LineOut");

	snd_soc_dapm_disable_pin(dapm, "Mic Jack");
	snd_soc_dapm_disable_pin(dapm, "Int Mic");
#if !defined(CONFIG_ARCH_ACER_T30)
	snd_soc_dapm_disable_pin(dapm, "LineIn");
#endif

	audio_data.codec = codec;
	audio_data.gpio.spkr_en = pdata->gpio_spkr_en;
	audio_data.gpio.int_mic_en = pdata->gpio_int_mic_en;
	audio_data.gpio.bypass_en = pdata->gpio_bypass_switch_en;
#else
	/* FIXME: Calculate automatically based on DAPM routes? */
	if (!machine_is_harmony() && !machine_is_ventana() &&
	    !machine_is_cardhu())
		snd_soc_dapm_nc_pin(dapm, "IN1L");
	if (!machine_is_seaboard() && !machine_is_aebl() &&
	    !machine_is_cardhu())
		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");
	}
#endif

	snd_soc_dapm_sync(dapm);

	return 0;
}

static int tegra30_soc_set_bias_level(struct snd_soc_card *card,
					enum snd_soc_bias_level level)
{
	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);

	if (machine->bias_level == SND_SOC_BIAS_OFF &&
		level != SND_SOC_BIAS_OFF)
		tegra_asoc_utils_clk_enable(&machine->util_data);

	return 0;
}

static int tegra30_soc_set_bias_level_post(struct snd_soc_card *card,
					enum snd_soc_bias_level level)
{
	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);

	if (machine->bias_level != SND_SOC_BIAS_OFF &&
		level == SND_SOC_BIAS_OFF)
		tegra_asoc_utils_clk_disable(&machine->util_data);

	machine->bias_level = level;

	return 0 ;
}

static struct snd_soc_dai_link tegra_wm8903_dai[] = {
	{
		.name = "WM8903",
		.stream_name = "WM8903 PCM",
		.codec_name = "wm8903.0-001a",
		.platform_name = "tegra-pcm-audio",
		.cpu_dai_name = "tegra20-i2s.0",
		.codec_dai_name = "wm8903-hifi",
		.init = tegra_wm8903_init,
		.ops = &tegra_wm8903_ops,
	},
	{
		.name = "SPDIF",
コード例 #21
0
static int byt_alc5645_jack_detection(void)
{
	int jack_type, bottun_type;
	int event, status;
	struct snd_soc_codec *codec = alc5645.codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	mutex_lock(&alc5645.mutex);
	event = alc5645_check_event(codec);
	pr_debug("event = %d\n", event);
	switch (event) {
	case JD_EVENT:
		status = gpio_get_value(hs_gpio_common.gpio) ? 0 : 1;
		pr_debug("gpio status is %d\n", status);
		if (status == 1) {
			snd_soc_dapm_force_enable_pin(dapm, "micbias1");
			snd_soc_dapm_force_enable_pin(dapm, "micbias2");

			snd_soc_dapm_sync(dapm);

			jack_type = rt5645_headset_detect(codec, status);
			switch (jack_type) {
			case RT5645_HEADSET_DET:
				alc5645.jack_status = true;
				alc5645.report = SND_JACK_HEADSET;
				mutex_unlock(&alc5645.mutex);
				return SND_JACK_HEADSET;
				break;
			case RT5645_HEADPHO_DET:
				snd_soc_dapm_disable_pin(dapm, "micbias1");
				snd_soc_dapm_disable_pin(dapm, "micbias2");

				snd_soc_dapm_sync(dapm);

				alc5645.jack_status = true;
				alc5645.report = SND_JACK_HEADPHONE;
				mutex_unlock(&alc5645.mutex);
				return SND_JACK_HEADPHONE;
				break;
			default:
				pr_err("No such jack_type %d\n", jack_type);
				mutex_unlock(&alc5645.mutex);
				return alc5645.report;
				break;
			}

		} else {
			snd_soc_dapm_disable_pin(dapm, "micbias1");
			snd_soc_dapm_disable_pin(dapm, "micbias2");
			snd_soc_dapm_sync(dapm);

			alc5645.jack_status = false;
			alc5645.report = 0;
			mutex_unlock(&alc5645.mutex);
			return 0;
		}
		break;
	case BOT_EVENT:
		bottun_type = rt5645_button_detect(codec);
		pr_debug("TODO: BOT_event: %d\n", bottun_type);
		pr_debug("TODO: all bottom events report as BTN_0\n");
		if (bottun_type)
			alc5645.report |= SND_JACK_BTN_0;
		else
			alc5645.report &= ~SND_JACK_BTN_0;
		mutex_unlock(&alc5645.mutex);
		return alc5645.report;
		break;
	default:
		mutex_unlock(&alc5645.mutex);
		return alc5645.report;
		break;
	}
}
コード例 #22
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;
	struct device_node *np = card->dev->of_node;
	int ret;

	if (card->dev->platform_data) {
		memcpy(pdata, card->dev->platform_data, sizeof(*pdata));
	} else if (np) {
		pdata->gpio_spkr_en = of_get_named_gpio(np,
						"nvidia,spkr-en-gpios", 0);
		pdata->gpio_hp_mute = of_get_named_gpio(np,
						"nvidia,hp-mute-gpios", 0);
		pdata->gpio_hp_det = of_get_named_gpio(np,
						"nvidia,hp-det-gpios", 0);
		pdata->gpio_int_mic_en = of_get_named_gpio(np,
						"nvidia,int-mic-en-gpios", 0);
		pdata->gpio_ext_mic_en = of_get_named_gpio(np,
						"nvidia,ext-mic-en-gpios", 0);
	} else {
		dev_err(card->dev, "No platform data supplied\n");
		return -EINVAL;
	}

	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;

		
		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;

		
		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, "MICBIAS");

	return 0;
}
コード例 #23
0
static int midas_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 *control = codec->control_data;
	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
	int ret;

#ifdef SND_USE_BIAS_LEVEL
	midas_aif1_dai = aif1_dai;
#endif

#ifdef CONFIG_MACH_GC1
	wm1811_codec = codec;
#endif

	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, midas_controls,
					ARRAY_SIZE(midas_controls));

	ret = snd_soc_dapm_new_controls(&codec->dapm, midas_dapm_widgets,
					   ARRAY_SIZE(midas_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, midas_dapm_routes,
					   ARRAY_SIZE(midas_dapm_routes));
	if (ret != 0)
		dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret);

	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;

	midas_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;
#else /* CONFIG_SEC_DEV_JACK */
	wm1811->jack.status = 0;

	ret = snd_soc_jack_new(codec, "Midas 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_VOLUMEDOWN);
	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_VOLUMEUP);

	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, midas_micdet,
			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, "midas_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);
}
コード例 #24
0
ファイル: tegra_wm9712.c プロジェクト: 020gzh/linux
static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd)
{
	return snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "Mic Bias");
}
コード例 #25
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, 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()) {
		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()) {
		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;
		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,
				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())
		snd_soc_dapm_nc_pin(dapm, "IN1L");
	if (!machine_is_seaboard() && !machine_is_aebl() &&
	    !machine_is_cardhu())
		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;
}
コード例 #26
0
static int tegra_alc5623_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_alc5623 *machine = snd_soc_card_get_drvdata(card);
	struct tegra_alc5623_platform_data *pdata = machine->pdata;
	int ret, i;

	/* Add the controls used to route audio to bluetooth/voice */
	tegra_das_controls_init(codec);
	
	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);
	} else if(pdata->gpio_spkr_en == -2) {
          	snd_soc_update_bits(codec, ALC5623_GPIO_PIN_CONFIG,
                	ALC5623_GPIO_PIN_CONFIG_GPIO_CONF,
                        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);
    }

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

	if (ret < 0)
		return ret;

	snd_soc_dapm_new_controls(dapm, dapm_widgets,
			ARRAY_SIZE(dapm_widgets));

	snd_soc_dapm_add_routes(dapm, audio_map,
				ARRAY_SIZE(audio_map));


	if (gpio_is_valid(pdata->gpio_hp_det)) {
		tegra_alc5623_hp_jack_gpio.gpio = pdata->gpio_hp_det;
		snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
				&machine->tegra_jack);
#ifndef CONFIG_SWITCH
		snd_soc_jack_add_pins(&machine->tegra_jack,
					ARRAY_SIZE(tegra_alc5623_hp_jack_pins),
					tegra_alc5623_hp_jack_pins);
#else
		snd_soc_jack_notifier_register(&machine->tegra_jack,
					&tegra_alc5623_jack_detect_nb);
#endif
		snd_soc_jack_add_gpios(&machine->tegra_jack,
					1,
					&tegra_alc5623_hp_jack_gpio);
		machine->gpio_requested |= GPIO_HP_DET;
	}
	

	/* Set endpoints to not connected */
	for(i = 0; i < ARRAY_SIZE(nc_pins); i++) {
		snd_soc_dapm_nc_pin(dapm, nc_pins[i]);
	}

	/* Set endpoints to default off mode */
	snd_soc_dapm_enable_pin(dapm, "Channel Swap Detect");
	snd_soc_dapm_enable_pin(dapm, "Int Spk");
	snd_soc_dapm_enable_pin(dapm, "Int Mic");
	snd_soc_dapm_enable_pin(dapm, "FM Radio");
	snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
	
	snd_soc_dapm_force_enable_pin(dapm, "Mic Bias1");
	
	ret = snd_soc_dapm_sync(dapm);
	if (ret) {
		dev_err(card->dev,"Failed to sync dapm\n");
		return ret;
	}

	return 0;
}
コード例 #27
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_aic326x_platform_data *pdata = machine->pdata;
	int ret;

	if (machine->init_done)
		return 0;

	machine->init_done = true;

	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;
}
コード例 #28
0
ファイル: adav80x.c プロジェクト: AICP/kernel_moto_shamu
static int adav80x_set_sysclk(struct snd_soc_codec *codec,
			      int clk_id, int source,
			      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;
}