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); }
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, ®); 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); } }
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"); }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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; }
/* 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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",
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; } }
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; }
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); }
static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd) { return snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "Mic Bias"); }
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; }
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; }
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; }
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; }