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 cht_codec_init(struct snd_soc_pcm_runtime *runtime) { int ret; int jack_type; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); struct snd_soc_jack *jack = &ctx->jack; /** * TI supports 4 butons headset detection * KEY_MEDIA * KEY_VOICECOMMAND * KEY_VOLUMEUP * KEY_VOLUMEDOWN */ if (ctx->ts3a227e_present) jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3; else jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE; ret = snd_soc_card_jack_new(runtime->card, "Headset Jack", jack_type, jack, NULL, 0); if (ret) { dev_err(runtime->dev, "Headset Jack creation failed %d\n", ret); return ret; } if (ctx->ts3a227e_present) snd_soc_jack_notifier_register(jack, &cht_jack_nb); return ret; }
static int cht_codec_init(struct snd_soc_pcm_runtime *runtime) { int ret; int jack_type; struct cht_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); struct snd_soc_jack *jack = &ctx->jack; if (ctx->ts3a227e_present) { /* * The jack has already been created in the * cht_max98090_headset_init() function. */ snd_soc_jack_notifier_register(jack, &cht_jack_nb); return 0; } jack_type = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE; ret = snd_soc_card_jack_new(runtime->card, "Headset Jack", jack_type, jack, hs_jack_pins, ARRAY_SIZE(hs_jack_pins)); if (ret) { dev_err(runtime->dev, "Headset Jack creation failed %d\n", ret); return ret; } ret = snd_soc_jack_add_gpiods(runtime->card->dev->parent, jack, ARRAY_SIZE(hs_jack_gpios), hs_jack_gpios); if (ret) { /* * flag error but don't bail if jack detect is broken * due to platform issues or bad BIOS/configuration */ dev_err(runtime->dev, "jack detection gpios not added, error %d\n", ret); } /* * The firmware might enable the clock at * boot (this information may or may not * be reflected in the enable clock register). * To change the rate we must disable the clock * first to cover these cases. Due to common * clock framework restrictions that do not allow * to disable a clock that has not been enabled, * we need to enable the clock first. */ ret = clk_prepare_enable(ctx->mclk); if (!ret) clk_disable_unprepare(ctx->mclk); ret = clk_set_rate(ctx->mclk, CHT_PLAT_CLK_3_HZ); if (ret) dev_err(runtime->dev, "unable to set MCLK rate\n"); return ret; }
int tegra_jack_init(struct snd_soc_codec *codec) { int ret; if (!codec) return -1; tegra_wired_jack = kzalloc(sizeof(*tegra_wired_jack), GFP_KERNEL); if (!tegra_wired_jack) { pr_err("failed to allocate tegra_wired_jack\n"); return -ENOMEM; } /* Add jack detection */ ret = snd_soc_jack_new(codec->socdev->card, "Headset Jack", SND_JACK_HEADSET, tegra_wired_jack); if (ret < 0) goto failed; ret = snd_soc_jack_add_pins(tegra_wired_jack, ARRAY_SIZE(hs_jack_pins), hs_jack_pins); if (ret < 0) goto failed; /* Addd h2w swith class support */ ret = switch_dev_register(&wired_switch_dev); if (ret < 0) goto switch_dev_failed; snd_soc_jack_notifier_register(tegra_wired_jack, &wired_switch_nb); ret = platform_driver_register(&tegra_wired_jack_driver); if (ret < 0) goto platform_dev_failed; return 0; switch_dev_failed: switch_dev_unregister(&wired_switch_dev); platform_dev_failed: platform_driver_unregister(&tegra_wired_jack_driver); failed: if (tegra_wired_jack) { kfree(tegra_wired_jack); tegra_wired_jack = 0; } return ret; }
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 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_max98095_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card); struct tegra_asoc_platform_data *pdata = machine->pdata; #ifndef CONFIG_ARCH_TEGRA_2x_SOC struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai); #endif int ret; #ifndef CONFIG_ARCH_TEGRA_2x_SOC if (machine->codec_info[BASEBAND].i2s_id != -1) i2s->is_dam_used = true; #endif if (machine->init_done) return 0; machine->init_done = true; if (gpio_is_valid(pdata->gpio_spkr_en)) { ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); if (ret) { dev_err(card->dev, "cannot get spkr_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_SPKR_EN; gpio_direction_output(pdata->gpio_spkr_en, 0); } if (gpio_is_valid(pdata->gpio_hp_mute)) { ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); if (ret) { dev_err(card->dev, "cannot get hp_mute gpio\n"); return ret; } machine->gpio_requested |= GPIO_HP_MUTE; gpio_direction_output(pdata->gpio_hp_mute, 0); } if (gpio_is_valid(pdata->gpio_int_mic_en)) { ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); if (ret) { dev_err(card->dev, "cannot get int_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_INT_MIC_EN; /* Disable int mic; enable signal is active-high */ gpio_direction_output(pdata->gpio_int_mic_en, 0); } if (gpio_is_valid(pdata->gpio_ext_mic_en)) { ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); if (ret) { dev_err(card->dev, "cannot get ext_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_EXT_MIC_EN; /* Enable ext mic; enable signal is active-low */ gpio_direction_output(pdata->gpio_ext_mic_en, 0); } ret = snd_soc_add_controls(codec, tegra_max98095_controls, ARRAY_SIZE(tegra_max98095_controls)); if (ret < 0) return ret; snd_soc_dapm_new_controls(dapm, tegra_max98095_dapm_widgets, ARRAY_SIZE(tegra_max98095_dapm_widgets)); snd_soc_dapm_add_routes(dapm, enterprise_audio_map, ARRAY_SIZE(enterprise_audio_map)); ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &tegra_max98095_hp_jack); if (ret < 0) return ret; #ifdef CONFIG_SWITCH snd_soc_jack_notifier_register(&tegra_max98095_hp_jack, &headset_switch_nb); #else /*gpio based headset detection*/ snd_soc_jack_add_pins(&tegra_max98095_hp_jack, ARRAY_SIZE(tegra_max98095_hp_jack_pins), tegra_max98095_hp_jack_pins); #endif /* max98095_headset_detect(codec, &tegra_max98095_hp_jack, SND_JACK_HEADSET); */ snd_soc_dapm_nc_pin(dapm, "INA1"); snd_soc_dapm_nc_pin(dapm, "INA2"); snd_soc_dapm_nc_pin(dapm, "INB1"); snd_soc_dapm_nc_pin(dapm, "INB2"); snd_soc_dapm_sync(dapm); return 0; }
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 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 msm_soc_dai_init(struct snd_soc_codec *codec) { int ret = 0; struct snd_soc_card *card = codec->socdev->card; struct wm8994_priv *wm8994; ret = msm_new_mixer(codec->card); if (ret < 0) pr_err("%s: ALSA MSM Mixer Fail\n", __func__); wm8994_add_controls(codec); // permanently disable pin snd_soc_dapm_nc_pin(codec, "SPKOUTRN"); snd_soc_dapm_nc_pin(codec, "SPKOUTRP"); snd_soc_dapm_nc_pin(codec, "SPKOUTLN"); snd_soc_dapm_nc_pin(codec, "SPKOUTLP"); snd_soc_dapm_nc_pin(codec, "HPOUT2P"); snd_soc_dapm_nc_pin(codec, "HPOUT2N"); snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP"); snd_soc_dapm_nc_pin(codec, "IN2RN"); snd_soc_dapm_nc_pin(codec, "IN2LN"); snd_soc_dapm_nc_pin(codec, "IN1RN"); snd_soc_dapm_nc_pin(codec, "IN1RP"); snd_soc_dapm_nc_pin(codec, "IN1LN"); #if defined(CONFIG_MACH_TENDERLOIN) snd_soc_dapm_new_controls(codec, tenderloin_dapm_widgets, ARRAY_SIZE(tenderloin_dapm_widgets)); snd_soc_dapm_add_routes(codec, tenderloin_dapm_routes, ARRAY_SIZE(tenderloin_dapm_routes)); #endif // Initially clock from MCLK1 - we will switch over to the FLLs // once we start playing audio but don't have BCLK yet to boot // them. ret = snd_soc_dai_set_sysclk(&codec->dai[0], WM8994_SYSCLK_MCLK1, WM_FLL, 0); if (ret != 0) { pr_err("Failed to set DAI sysclk: %d\n", ret); return ret; } ret = snd_soc_dai_set_sysclk(&codec->dai[1], WM8994_SYSCLK_MCLK1, WM_FLL, 0); if (ret != 0) { pr_err("Failed to set DAI sysclk: %d\n", ret); return ret; } /* Headphone jack detection */ // If we have the HeadSet uart (hs_uart) then we DONT want to detect headphones if ( hs_uart == 1 ) { snd_soc_jack_new(card, "headset", SND_JACK_MICROPHONE | SND_JACK_BTN_0, &hp_jack); } else { snd_soc_jack_new(card, "headset", SND_JACK_HEADPHONE | SND_JACK_MICROPHONE | SND_JACK_BTN_0, &hp_jack); } snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),hp_jack_pins); snd_jack_set_key(hp_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); // mapping button 0 to KEY_PLAYPUASE // Register a notifier with snd_soc_jack jack_notifier.notifier_call = jack_notifier_event; snd_soc_jack_notifier_register(&hp_jack, &jack_notifier); ret = snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), hp_jack_gpios); wm8994 = snd_soc_codec_get_drvdata(codec); if(wm8994) wm8994->soc_jack = &hp_jack; // add headphone switch headphone_switch = kzalloc(sizeof(struct switch_dev), GFP_KERNEL); if (headphone_switch) { headphone_switch->name = "h2w"; headphone_switch->print_name = headphone_switch_print_name; ret = switch_dev_register(headphone_switch); if (ret < 0) { printk(KERN_ERR "Unable to register headphone switch\n"); kfree(headphone_switch); headphone_switch = NULL; } else { headphone_plugged = hp_jack.status ? 1 : 0; printk(KERN_INFO "Headphone switch initialized, plugged=%d\n", headphone_plugged); switch_set_state(headphone_switch, headphone_plugged); } } else { printk(KERN_ERR "Unable to allocate headphone switch\n"); } return ret; }
static int tegra_aic326x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card); struct tegra_asoc_platform_data *pdata = machine->pdata; #ifndef CONFIG_ARCH_TEGRA_2x_SOC struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai); #endif int ret; #ifndef CONFIG_ARCH_TEGRA_2x_SOC if (machine->codec_info[BASEBAND].i2s_id != -1) i2s->is_dam_used = true; #endif if (machine->init_done) return 0; machine->init_done = true; #ifndef CONFIG_ARCH_TEGRA_2x_SOC machine->pcard = card; #endif if (machine_is_whistler()) { machine->audio_reg = regulator_get(NULL, "avddio_audio"); if (IS_ERR(machine->audio_reg)) { dev_err(card->dev, "cannot get avddio_audio reg\n"); ret = PTR_ERR(machine->audio_reg); return ret; } ret = regulator_enable(machine->audio_reg); if (ret) { dev_err(card->dev, "cannot enable avddio_audio reg\n"); regulator_put(machine->audio_reg); machine->audio_reg = NULL; return ret; } } if (gpio_is_valid(pdata->gpio_spkr_en)) { ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); if (ret) { dev_err(card->dev, "cannot get spkr_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_SPKR_EN; gpio_direction_output(pdata->gpio_spkr_en, 0); } if (gpio_is_valid(pdata->gpio_hp_mute)) { ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); if (ret) { dev_err(card->dev, "cannot get hp_mute gpio\n"); return ret; } machine->gpio_requested |= GPIO_HP_MUTE; gpio_direction_output(pdata->gpio_hp_mute, 0); } if (gpio_is_valid(pdata->gpio_int_mic_en)) { ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); if (ret) { dev_err(card->dev, "cannot get int_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_INT_MIC_EN; /* Disable int mic; enable signal is active-high */ gpio_direction_output(pdata->gpio_int_mic_en, 0); } if (gpio_is_valid(pdata->gpio_ext_mic_en)) { ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); if (ret) { dev_err(card->dev, "cannot get ext_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_EXT_MIC_EN; /* Enable ext mic; enable signal is active-low */ gpio_direction_output(pdata->gpio_ext_mic_en, 0); } ret = snd_soc_add_card_controls(card, 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; if (gpio_is_valid(pdata->gpio_hp_det)) { /* Headphone detection */ tegra_aic326x_hp_jack_gpio.gpio = pdata->gpio_hp_det; snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADSET, &tegra_aic326x_hp_jack); #ifndef CONFIG_SWITCH snd_soc_jack_add_pins(&tegra_aic326x_hp_jack, ARRAY_SIZE(tegra_aic326x_hp_jack_pins), tegra_aic326x_hp_jack_pins); #else snd_soc_jack_notifier_register(&tegra_aic326x_hp_jack, &aic326x_headset_switch_nb); #endif snd_soc_jack_add_gpios(&tegra_aic326x_hp_jack, 1, &tegra_aic326x_hp_jack_gpio); machine->gpio_requested |= GPIO_HP_DET; } #ifndef CONFIG_ARCH_TEGRA_11x_SOC /* update jack status during boot */ aic3262_hs_jack_detect(codec, &tegra_aic326x_hp_jack, SND_JACK_HEADSET); #endif /* 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; ret = tegra_asoc_utils_register_ctls(&machine->util_data); if (ret < 0) return ret; return 0; }