static void t0_micdet(u16 status, void *data) { struct wm1811_machine_priv *wm1811 = data; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(wm1811->codec); int report; /* * If the jack is inserted abnormally, * The variable puts back to its previous status. */ if (!wm1811->get_g_det_value_f) { dev_err(wm1811->codec->dev, "Do not use the ground detection\n"); } else { if (wm1811->get_g_det_value_f()) { dev_info(wm1811->codec->dev, "The jack is inserted abnormally\n"); wm8994->mic_detecting = false; } } wake_lock_timeout(&wm1811->jackdet_wake_lock, 5 * HZ); /* Either nothing present or just starting detection */ if (!(status & WM8958_MICD_STS)) { if (!wm8994->jackdet) { /* If nothing present then clear our statuses */ dev_dbg(wm1811->codec->dev, "Detected open circuit\n"); wm8994->jack_mic = false; wm8994->mic_detecting = true; t0_micd_set_rate(wm1811->codec); snd_soc_jack_report(wm8994->micdet[0].jack, 0, wm8994->btn_mask | SND_JACK_HEADSET); } /*ToDo*/ /*return;*/ } /* If the measurement is showing a high impedence we've got a * microphone. */ if (wm8994->mic_detecting && (status & 0x400)) { dev_info(wm1811->codec->dev, "Detected microphone\n"); wm8994->mic_detecting = false; wm8994->jack_mic = true; t0_micd_set_rate(wm1811->codec); snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADSET, SND_JACK_HEADSET); } if (wm8994->mic_detecting && status & 0x4) { dev_info(wm1811->codec->dev, "Detected headphone\n"); wm8994->mic_detecting = false; t0_micd_set_rate(wm1811->codec); snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE, SND_JACK_HEADSET); /* If we have jackdet that will detect removal */ if (wm8994->jackdet) { mutex_lock(&wm8994->accdet_lock); snd_soc_update_bits(wm1811->codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); if (wm8994->active_refcount) { snd_soc_update_bits(wm1811->codec, WM8994_ANTIPOP_2, WM1811_JACKDET_MODE_MASK, WM1811_JACKDET_MODE_AUDIO); } mutex_unlock(&wm8994->accdet_lock); if (wm8994->pdata->jd_ext_cap) { mutex_lock(&wm1811->codec->mutex); snd_soc_dapm_disable_pin(&wm1811->codec->dapm, "MICBIAS2"); snd_soc_dapm_sync(&wm1811->codec->dapm); mutex_unlock(&wm1811->codec->mutex); } } } /* Report short circuit as a button */ if (wm8994->jack_mic) { report = 0; if (status & WM1811_JACKDET_BTN0) report |= SND_JACK_BTN_0; if (status & WM1811_JACKDET_BTN1) report |= SND_JACK_BTN_1; if (status & WM1811_JACKDET_BTN2) report |= SND_JACK_BTN_2; dev_info(wm1811->codec->dev, "Detected Button: %08x (%08X)\n", report, status); snd_soc_jack_report(wm8994->micdet[0].jack, report, wm8994->btn_mask); } }
static int tab3_wm1811_init_paiftx(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct wm1811_machine_priv *wm1811 = snd_soc_card_get_drvdata(codec->card); struct snd_soc_dai *aif1_dai = rtd->codec_dai; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int ret; midas_snd_set_mclk(true, false); rtd->codec_dai->driver->playback.channels_max = rtd->cpu_dai->driver->playback.channels_max; ret = snd_soc_add_controls(codec, tab3_controls, ARRAY_SIZE(tab3_controls)); #if defined(CONFIG_TAB3_00_BD) if(system_rev < 2) { ret = snd_soc_dapm_new_controls(&codec->dapm, tab3_dapm_widgets_rev0, ARRAY_SIZE(tab3_dapm_widgets_rev0)); if (ret != 0) dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret); ret = snd_soc_dapm_add_routes(&codec->dapm, tab3_dapm_routes_rev0, ARRAY_SIZE(tab3_dapm_routes_rev0)); if (ret != 0) dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret); } else { ret = snd_soc_dapm_new_controls(&codec->dapm, tab3_dapm_widgets, ARRAY_SIZE(tab3_dapm_widgets)); if (ret != 0) dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret); ret = snd_soc_dapm_add_routes(&codec->dapm, tab3_dapm_routes, ARRAY_SIZE(tab3_dapm_routes)); if (ret != 0) dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret); } #else ret = snd_soc_dapm_new_controls(&codec->dapm, tab3_dapm_widgets, ARRAY_SIZE(tab3_dapm_widgets)); if (ret != 0) dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret); ret = snd_soc_dapm_add_routes(&codec->dapm, tab3_dapm_routes, ARRAY_SIZE(tab3_dapm_routes)); if (ret != 0) dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret); #endif ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2, MIDAS_DEFAULT_MCLK2, SND_SOC_CLOCK_IN); if (ret < 0) dev_err(codec->dev, "Failed to boot clocking\n"); /* Force AIF1CLK on as it will be master for jack detection */ if (wm8994->revision > 1) { ret = snd_soc_dapm_force_enable_pin(&codec->dapm, "AIF1CLK"); if (ret < 0) dev_err(codec->dev, "Failed to enable AIF1CLK: %d\n", ret); } ret = snd_soc_dapm_disable_pin(&codec->dapm, "S5P RP"); if (ret < 0) dev_err(codec->dev, "Failed to disable S5P RP: %d\n", ret); snd_soc_dapm_ignore_suspend(&codec->dapm, "RCV"); snd_soc_dapm_ignore_suspend(&codec->dapm, "SPK"); snd_soc_dapm_ignore_suspend(&codec->dapm, "HP"); snd_soc_dapm_ignore_suspend(&codec->dapm, "Headset Mic"); snd_soc_dapm_ignore_suspend(&codec->dapm, "Sub Mic"); snd_soc_dapm_ignore_suspend(&codec->dapm, "Main Mic"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1DACDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2DACDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3DACDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1ADCDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2ADCDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3ADCDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "FM In"); snd_soc_dapm_ignore_suspend(&codec->dapm, "LINE"); snd_soc_dapm_ignore_suspend(&codec->dapm, "HDMI"); snd_soc_dapm_ignore_suspend(&codec->dapm, "Third Mic"); wm1811->codec = codec; tab3_micd_set_rate(codec); #ifdef CONFIG_SEC_DEV_JACK /* By default use idle_bias_off, will override for WM8994 */ codec->dapm.idle_bias_off = 0; #if defined (CONFIG_TAB3_00_BD) if(system_rev < 2) { ret = snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS2"); if (ret < 0) dev_err(codec->dev, "Failed to enable MICBIAS2: %d\n", ret); } #endif #else /* CONFIG_SEC_DEV_JACK */ wm1811->jack.status = 0; ret = snd_soc_jack_new(codec, "Tab3 Jack", SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, &wm1811->jack); if (ret < 0) dev_err(codec->dev, "Failed to create jack: %d\n", ret); ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_0, KEY_MEDIA); if (ret < 0) dev_err(codec->dev, "Failed to set KEY_MEDIA: %d\n", ret); ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); if (ret < 0) dev_err(codec->dev, "Failed to set KEY_VOLUMEUP: %d\n", ret); ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); if (ret < 0) dev_err(codec->dev, "Failed to set KEY_VOLUMEDOWN: %d\n", ret); if (wm8994->revision > 1) { dev_info(codec->dev, "wm1811: Rev %c support mic detection\n", 'A' + wm8994->revision); ret = wm8958_mic_detect(codec, &wm1811->jack, NULL, NULL, tab3_mic_id, wm1811); if (ret < 0) dev_err(codec->dev, "Failed start detection: %d\n", ret); } else { dev_info(codec->dev, "wm1811: Rev %c doesn't support mic detection\n", 'A' + wm8994->revision); codec->dapm.idle_bias_off = 0; } /* To wakeup for earjack event in suspend mode */ enable_irq_wake(control->irq); wake_lock_init(&wm1811->jackdet_wake_lock, WAKE_LOCK_SUSPEND, "Tab3_jackdet"); /* To support PBA function test */ jack_class = class_create(THIS_MODULE, "audio"); if (IS_ERR(jack_class)) pr_err("Failed to create class\n"); jack_dev = device_create(jack_class, NULL, 0, codec, "earjack"); if (device_create_file(jack_dev, &dev_attr_select_jack) < 0) pr_err("Failed to create device file (%s)!\n", dev_attr_select_jack.attr.name); if (device_create_file(jack_dev, &dev_attr_key_state) < 0) pr_err("Failed to create device file (%s)!\n", dev_attr_key_state.attr.name); if (device_create_file(jack_dev, &dev_attr_state) < 0) pr_err("Failed to create device file (%s)!\n", dev_attr_state.attr.name); if (device_create_file(jack_dev, &dev_attr_reselect_jack) < 0) pr_err("Failed to create device file (%s)!\n", dev_attr_reselect_jack.attr.name); #endif /* CONFIG_SEC_DEV_JACK */ return snd_soc_dapm_sync(&codec->dapm); }
static int archos_omap4_twl6040_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct twl6040 *twl6040 = codec->control_data; struct snd_soc_dapm_context *dapm = &codec->dapm; int hsotrim, left_offset, right_offset, mode, ret; /* Add specific controls */ ret = snd_soc_add_controls(codec, archos_omap4_controls, ARRAY_SIZE(archos_omap4_controls)); if (ret) return ret; /* Add specific widgets */ ret = snd_soc_dapm_new_controls(dapm, archos_omap4_twl6040_dapm_widgets, ARRAY_SIZE(archos_omap4_twl6040_dapm_widgets)); if (ret) return ret; /* Set up specific audio path audio_map */ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* Connected pins */ snd_soc_dapm_enable_pin(dapm, "Ext Mic"); snd_soc_dapm_enable_pin(dapm, "Ext Spk"); snd_soc_dapm_enable_pin(dapm, "AFML"); snd_soc_dapm_enable_pin(dapm, "AFMR"); snd_soc_dapm_enable_pin(dapm, "Headset Mic"); snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); /* allow audio paths from the audio modem to run during suspend */ snd_soc_dapm_ignore_suspend(dapm, "Ext Mic"); snd_soc_dapm_ignore_suspend(dapm, "Ext Spk"); snd_soc_dapm_ignore_suspend(dapm, "AFML"); snd_soc_dapm_ignore_suspend(dapm, "AFMR"); snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); snd_soc_dapm_ignore_suspend(dapm, "Headset Stereophone"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic 0"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic 1"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic 2"); ret = snd_soc_dapm_sync(dapm); if (ret) return ret; /* Headset jack detection */ ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &hs_jack); if (ret) return ret; ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), hs_jack_pins); twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); /* DC offset cancellation computation */ hsotrim = snd_soc_read(codec, TWL6040_REG_HSOTRIM); right_offset = (hsotrim & TWL6040_HSRO) >> TWL6040_HSRO_OFFSET; left_offset = hsotrim & TWL6040_HSLO; if (twl6040_get_icrev(twl6040) < TWL6040_REV_1_3) /* For ES under ES_1.3 HS step is 2 mV */ mode = 2; else /* For ES_1.3 HS step is 1 mV */ mode = 1; abe_dsp_set_hs_offset(left_offset, right_offset, mode); /* don't wait before switching of HS power */ rtd->pmdown_time = 0; return ret; }
static void msm8960_enable_ext_spk_amp_gpio(u32 spk_amp_gpio) { int ret = 0; struct pm_gpio param = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .output_value = 1, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_MED, . function = PM_GPIO_FUNC_NORMAL, }; if (spk_amp_gpio == bottom_spk_pamp_gpio) { ret = gpio_request(bottom_spk_pamp_gpio, "BOTTOM_SPK_AMP"); if (ret) { pr_err("%s: Error requesting BOTTOM SPK AMP GPIO %u\n", __func__, bottom_spk_pamp_gpio); return; } ret = pm8xxx_gpio_config(bottom_spk_pamp_gpio, ¶m); if (ret) pr_err("%s: Failed to configure Bottom Spk Ampl" " gpio %u\n", __func__, bottom_spk_pamp_gpio); else { pr_debug("%s: enable Bottom spkr amp gpio\n", __func__); gpio_direction_output(bottom_spk_pamp_gpio, 1); } } else if (spk_amp_gpio == top_spk_pamp_gpio) { ret = gpio_request(top_spk_pamp_gpio, "TOP_SPK_AMP"); if (ret) { pr_err("%s: Error requesting GPIO %d\n", __func__, top_spk_pamp_gpio); return; } ret = pm8xxx_gpio_config(top_spk_pamp_gpio, ¶m); if (ret) pr_err("%s: Failed to configure Top Spk Ampl" " gpio %u\n", __func__, top_spk_pamp_gpio); else { pr_debug("%s: enable Top spkr amp gpio\n", __func__); gpio_direction_output(top_spk_pamp_gpio, 1); } } else { pr_err("%s: ERROR : Invalid External Speaker Ampl GPIO." " gpio = %u\n", __func__, spk_amp_gpio); return; } } static void msm8960_ext_single_ended_spk_power_amp_on(u32 spk) { if (spk & BOTTOM_SPK_AMP) { if (msm8960_ext_bottom_spk_pamp) { pr_debug("%s() External Bottom Speaker Ampl already " "turned on. spk = 0x%08x\n", __func__, spk); return; } pr_debug("%s: wait 50 ms before turning on " " external Bottom Speaker Ampl\n", __func__); usleep_range(50000, 50000); msm8960_enable_ext_spk_amp_gpio(bottom_spk_pamp_gpio); msm8960_ext_bottom_spk_pamp = 1; pr_debug("%s: sleeping 4 ms after turning on external " " Bottom Speaker Ampl\n", __func__); usleep_range(4000, 4000); } else if (spk & TOP_SPK_AMP) { if (msm8960_ext_top_spk_pamp) { pr_debug("%s() External Top Speaker Ampl already" "turned on. spk = 0x%08x\n", __func__, spk); return; } pr_debug("%s: wait 50 ms before turning on " " external Top Speaker Ampl\n", __func__); usleep_range(50000, 50000); msm8960_enable_ext_spk_amp_gpio(top_spk_pamp_gpio); msm8960_ext_top_spk_pamp = 1; pr_debug("%s: sleeping 4 ms after turning on " " external Top Speaker Ampl\n", __func__); usleep_range(4000, 4000); } else { pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n", __func__, spk); return; } } static void msm8960_ext_spk_power_amp_on(u32 spk) { if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) { if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) && (msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) { pr_debug("%s() External Bottom Speaker Ampl already " "turned on. spk = 0x%08x\n", __func__, spk); return; } msm8960_ext_bottom_spk_pamp |= spk; if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) && (msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) { msm8960_enable_ext_spk_amp_gpio(bottom_spk_pamp_gpio); pr_debug("%s: slepping 4 ms after turning on external " " Bottom Speaker Ampl\n", __func__); usleep_range(4000, 4000); } } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) { if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) && (msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) { pr_debug("%s() External Top Speaker Ampl already" "turned on. spk = 0x%08x\n", __func__, spk); return; } msm8960_ext_top_spk_pamp |= spk; if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) && (msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) { msm8960_enable_ext_spk_amp_gpio(top_spk_pamp_gpio); pr_debug("%s: sleeping 4 ms after turning on " " external Top Speaker Ampl\n", __func__); usleep_range(4000, 4000); } } else { pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n", __func__, spk); return; } } static void msm8960_ext_single_ended_spk_power_amp_off(u32 spk) { if (spk & BOTTOM_SPK_AMP) { if (!msm8960_ext_bottom_spk_pamp) return; gpio_direction_output(bottom_spk_pamp_gpio, 0); gpio_free(bottom_spk_pamp_gpio); msm8960_ext_bottom_spk_pamp = 0; pr_debug("%s: sleeping 4 ms after turning off external Bottom" " Speaker Ampl\n", __func__); usleep_range(4000, 4000); } else if (spk & TOP_SPK_AMP) { if (!msm8960_ext_top_spk_pamp) return; gpio_direction_output(top_spk_pamp_gpio, 0); gpio_free(top_spk_pamp_gpio); msm8960_ext_top_spk_pamp = 0; pr_debug("%s: sleeping 4 ms after turning off external Top" " Spkaker Ampl\n", __func__); usleep_range(4000, 4000); } else { pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n", __func__, spk); return; } } static void msm8960_ext_spk_power_amp_off(u32 spk) { if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) { if (!msm8960_ext_bottom_spk_pamp) return; gpio_direction_output(bottom_spk_pamp_gpio, 0); gpio_free(bottom_spk_pamp_gpio); msm8960_ext_bottom_spk_pamp = 0; pr_debug("%s: sleeping 4 ms after turning off external Bottom" " Speaker Ampl\n", __func__); usleep_range(4000, 4000); } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) { if (!msm8960_ext_top_spk_pamp) return; gpio_direction_output(top_spk_pamp_gpio, 0); gpio_free(top_spk_pamp_gpio); msm8960_ext_top_spk_pamp = 0; pr_debug("%s: sleeping 4 ms after turning off external Top" " Spkaker Ampl\n", __func__); usleep_range(4000, 4000); } else { pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n", __func__, spk); return; } } static void msm8960_ext_single_ended_control(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = &codec->dapm; mutex_lock(&dapm->codec->mutex); pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control); if (msm8960_spk_control == MSM8960_SPK_ON) { snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top"); } else { snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom"); snd_soc_dapm_disable_pin(dapm, "Ext Spk Top"); } snd_soc_dapm_sync(dapm); mutex_unlock(&dapm->codec->mutex); } /* QCT reference code assumes differential speaker */ /* static void msm8960_ext_control(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = &codec->dapm; mutex_lock(&dapm->codec->mutex); pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control); if (msm8960_spk_control == MSM8960_SPK_ON) { snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg"); } else { snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Pos"); snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Neg"); snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Pos"); snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Neg"); } snd_soc_dapm_sync(dapm); mutex_unlock(&dapm->codec->mutex); } */ static int msm8960_get_spk(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control); ucontrol->value.integer.value[0] = msm8960_spk_control; return 0; }
static int ams_delta_cx20442_init(struct snd_soc_codec *codec) { struct snd_soc_dai *codec_dai = codec->dai; struct snd_soc_card *card = codec->socdev->card; int ret; /* Codec is ready, now add/activate board specific controls */ /* Set up digital mute if not provided by the codec */ if (!codec_dai->ops) { codec_dai->ops = &ams_delta_dai_ops; } else if (!codec_dai->ops->digital_mute) { codec_dai->ops->digital_mute = ams_delta_digital_mute; } else { ams_delta_ops.startup = ams_delta_startup; ams_delta_ops.shutdown = ams_delta_shutdown; } /* Set codec bias level */ ams_delta_set_bias_level(card, SND_SOC_BIAS_STANDBY); /* Add hook switch - can be used to control the codec from userspace * even if line discipline fails */ ret = snd_soc_jack_new(card, "hook_switch", SND_JACK_HEADSET, &ams_delta_hook_switch); if (ret) dev_warn(card->dev, "Failed to allocate resources for hook switch, " "will continue without one.\n"); else { ret = snd_soc_jack_add_gpios(&ams_delta_hook_switch, ARRAY_SIZE(ams_delta_hook_switch_gpios), ams_delta_hook_switch_gpios); if (ret) dev_warn(card->dev, "Failed to set up hook switch GPIO line, " "will continue with hook switch inactive.\n"); } /* Register optional line discipline for over the modem control */ ret = tty_register_ldisc(N_V253, &cx81801_ops); if (ret) { dev_warn(card->dev, "Failed to register line discipline, " "will continue without any controls.\n"); return 0; } /* Add board specific DAPM widgets and routes */ ret = snd_soc_dapm_new_controls(codec, ams_delta_dapm_widgets, ARRAY_SIZE(ams_delta_dapm_widgets)); if (ret) { dev_warn(card->dev, "Failed to register DAPM controls, " "will continue without any.\n"); return 0; } ret = snd_soc_dapm_add_routes(codec, ams_delta_audio_map, ARRAY_SIZE(ams_delta_audio_map)); if (ret) { dev_warn(card->dev, "Failed to set up DAPM routes, " "will continue with codec default map.\n"); return 0; } /* Set up initial pin constellation */ snd_soc_dapm_disable_pin(codec, "Mouthpiece"); snd_soc_dapm_enable_pin(codec, "Earpiece"); snd_soc_dapm_enable_pin(codec, "Microphone"); snd_soc_dapm_disable_pin(codec, "Speaker"); snd_soc_dapm_disable_pin(codec, "AGCIN"); snd_soc_dapm_disable_pin(codec, "AGCOUT"); snd_soc_dapm_sync(codec); /* Add virtual switch */ ret = snd_soc_add_controls(codec, ams_delta_audio_controls, ARRAY_SIZE(ams_delta_audio_controls)); if (ret) dev_warn(card->dev, "Failed to register audio mode control, " "will continue without it.\n"); return 0; }
static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); struct tegra_wm8903_platform_data *pdata = machine->pdata; int ret; machine->bias_level = SND_SOC_BIAS_STANDBY; if (gpio_is_valid(pdata->gpio_spkr_en)) { ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); if (ret) { dev_err(card->dev, "cannot get spkr_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_SPKR_EN; gpio_direction_output(pdata->gpio_spkr_en, 0); } if (gpio_is_valid(pdata->gpio_hp_mute)) { ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); if (ret) { dev_err(card->dev, "cannot get hp_mute gpio\n"); return ret; } machine->gpio_requested |= GPIO_HP_MUTE; gpio_direction_output(pdata->gpio_hp_mute, 0); } if (gpio_is_valid(pdata->gpio_int_mic_en)) { ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); if (ret) { dev_err(card->dev, "cannot get int_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_INT_MIC_EN; /* Disable int mic; enable signal is active-high */ gpio_direction_output(pdata->gpio_int_mic_en, 0); } if (gpio_is_valid(pdata->gpio_ext_mic_en)) { ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); if (ret) { dev_err(card->dev, "cannot get ext_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_EXT_MIC_EN; /* Enable ext mic; enable signal is active-low */ gpio_direction_output(pdata->gpio_ext_mic_en, 0); } if (machine_is_cardhu() || machine_is_ventana() || machine_is_rambo() || machine_is_eva()) { ret = snd_soc_add_controls(codec, cardhu_controls, ARRAY_SIZE(cardhu_controls)); if (ret < 0) return ret; snd_soc_dapm_new_controls(dapm, cardhu_dapm_widgets, ARRAY_SIZE(cardhu_dapm_widgets)); } else { ret = snd_soc_add_controls(codec, tegra_wm8903_default_controls, ARRAY_SIZE(tegra_wm8903_default_controls)); if (ret < 0) return ret; snd_soc_dapm_new_controls(dapm, tegra_wm8903_default_dapm_widgets, ARRAY_SIZE(tegra_wm8903_default_dapm_widgets)); } if (machine_is_harmony()) { snd_soc_dapm_add_routes(dapm, harmony_audio_map, ARRAY_SIZE(harmony_audio_map)); } else if (machine_is_cardhu() || machine_is_ventana() || machine_is_rambo() || machine_is_eva()) { snd_soc_dapm_add_routes(dapm, cardhu_audio_map, ARRAY_SIZE(cardhu_audio_map)); } else if (machine_is_seaboard()) { snd_soc_dapm_add_routes(dapm, seaboard_audio_map, ARRAY_SIZE(seaboard_audio_map)); } else if (machine_is_kaen()) { snd_soc_dapm_add_routes(dapm, kaen_audio_map, ARRAY_SIZE(kaen_audio_map)); } else { snd_soc_dapm_add_routes(dapm, aebl_audio_map, ARRAY_SIZE(aebl_audio_map)); } if (gpio_is_valid(pdata->gpio_hp_det)) { tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; if (pdata->hp_det_active_high) tegra_wm8903_hp_jack_gpio.invert = 0; else tegra_wm8903_hp_jack_gpio.invert = 1; snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, &tegra_wm8903_hp_jack); #ifndef CONFIG_SWITCH snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, ARRAY_SIZE(tegra_wm8903_hp_jack_pins), tegra_wm8903_hp_jack_pins); #else snd_soc_jack_notifier_register(&tegra_wm8903_hp_jack, &tegra_wm8903_jack_detect_nb); #endif snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, 1, &tegra_wm8903_hp_jack_gpio); machine->gpio_requested |= GPIO_HP_DET; } snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, &tegra_wm8903_mic_jack); #ifndef CONFIG_SWITCH snd_soc_jack_add_pins(&tegra_wm8903_mic_jack, ARRAY_SIZE(tegra_wm8903_mic_jack_pins), tegra_wm8903_mic_jack_pins); #else snd_soc_jack_notifier_register(&tegra_wm8903_mic_jack, &tegra_wm8903_jack_detect_nb); #endif wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE, machine_is_cardhu() || machine_is_rambo() ? SND_JACK_MICROPHONE : 0); snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); /* FIXME: Calculate automatically based on DAPM routes? */ if (!machine_is_harmony() && !machine_is_ventana() && !machine_is_cardhu() && !machine_is_rambo() && !machine_is_eva()) snd_soc_dapm_nc_pin(dapm, "IN1L"); if (!machine_is_seaboard() && !machine_is_aebl() && !machine_is_cardhu() && !machine_is_rambo()) snd_soc_dapm_nc_pin(dapm, "IN1R"); snd_soc_dapm_nc_pin(dapm, "IN2L"); if (!machine_is_kaen()) snd_soc_dapm_nc_pin(dapm, "IN2R"); snd_soc_dapm_nc_pin(dapm, "IN3L"); snd_soc_dapm_nc_pin(dapm, "IN3R"); if (machine_is_aebl()) { snd_soc_dapm_nc_pin(dapm, "LON"); snd_soc_dapm_nc_pin(dapm, "RON"); snd_soc_dapm_nc_pin(dapm, "ROP"); snd_soc_dapm_nc_pin(dapm, "LOP"); } else { snd_soc_dapm_nc_pin(dapm, "LINEOUTR"); snd_soc_dapm_nc_pin(dapm, "LINEOUTL"); } snd_soc_dapm_sync(dapm); return 0; }
static int tegra_aic326x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card); struct tegra_asoc_platform_data *pdata = machine->pdata; #ifndef CONFIG_ARCH_TEGRA_2x_SOC struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai); #endif int ret; #ifndef CONFIG_ARCH_TEGRA_2x_SOC if (machine->codec_info[BASEBAND].i2s_id != -1) i2s->is_dam_used = true; #endif if (machine->init_done) return 0; machine->init_done = true; #ifndef CONFIG_ARCH_TEGRA_2x_SOC machine->pcard = card; #endif if (machine_is_whistler()) { machine->audio_reg = regulator_get(NULL, "avddio_audio"); if (IS_ERR(machine->audio_reg)) { dev_err(card->dev, "cannot get avddio_audio reg\n"); ret = PTR_ERR(machine->audio_reg); return ret; } ret = regulator_enable(machine->audio_reg); if (ret) { dev_err(card->dev, "cannot enable avddio_audio reg\n"); regulator_put(machine->audio_reg); machine->audio_reg = NULL; return ret; } } if (gpio_is_valid(pdata->gpio_spkr_en)) { ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); if (ret) { dev_err(card->dev, "cannot get spkr_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_SPKR_EN; gpio_direction_output(pdata->gpio_spkr_en, 0); } if (gpio_is_valid(pdata->gpio_hp_mute)) { ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); if (ret) { dev_err(card->dev, "cannot get hp_mute gpio\n"); return ret; } machine->gpio_requested |= GPIO_HP_MUTE; gpio_direction_output(pdata->gpio_hp_mute, 0); } if (gpio_is_valid(pdata->gpio_int_mic_en)) { ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); if (ret) { dev_err(card->dev, "cannot get int_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_INT_MIC_EN; /* Disable int mic; enable signal is active-high */ gpio_direction_output(pdata->gpio_int_mic_en, 0); } if (gpio_is_valid(pdata->gpio_ext_mic_en)) { ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); if (ret) { dev_err(card->dev, "cannot get ext_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_EXT_MIC_EN; /* Enable ext mic; enable signal is active-low */ gpio_direction_output(pdata->gpio_ext_mic_en, 0); } ret = snd_soc_add_controls(codec, tegra_aic326x_controls, ARRAY_SIZE(tegra_aic326x_controls)); if (ret < 0) return ret; snd_soc_dapm_new_controls(dapm, tegra_aic326x_dapm_widgets, ARRAY_SIZE(tegra_aic326x_dapm_widgets)); snd_soc_dapm_add_routes(dapm, aic326x_audio_map, ARRAY_SIZE(aic326x_audio_map)); ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &tegra_aic326x_hp_jack); if (ret < 0) return ret; #ifdef CONFIG_SWITCH snd_soc_jack_notifier_register(&tegra_aic326x_hp_jack, &aic326x_headset_switch_nb); #else /*gpio based headset detection*/ snd_soc_jack_add_pins(&tegra_aic326x_hp_jack, ARRAY_SIZE(tegra_aic326x_hp_jack_pins), tegra_aic326x_hp_jack_pins); #endif aic326x_headset_detect(codec, &tegra_aic326x_hp_jack, SND_JACK_HEADSET); /* Add call mode switch control */ ret = snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&tegra_aic326x_call_mode_control, machine)); if (ret < 0) return ret; snd_soc_dapm_force_enable_pin(dapm, "MICBIAS_EXT ON"); snd_soc_dapm_force_enable_pin(dapm,"MICBIAS_INT ON"); snd_soc_dapm_sync(dapm); return 0; }
static int msm8960_audrx_init(struct snd_soc_pcm_runtime *rtd) { int err; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct pm_gpio jack_gpio_cfg = { .direction = PM_GPIO_DIR_IN, .pull = PM_GPIO_PULL_UP_1P5, .function = PM_GPIO_FUNC_NORMAL, .vin_sel = 2, .inv_int_pol = 0, }; pr_debug("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev)); if (machine_is_msm8960_liquid()) { top_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(19)); bottom_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(18)); } snd_soc_dapm_new_controls(dapm, msm8960_dapm_widgets, ARRAY_SIZE(msm8960_dapm_widgets)); snd_soc_dapm_add_routes(dapm, common_audio_map, ARRAY_SIZE(common_audio_map)); snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg"); snd_soc_dapm_sync(dapm); err = snd_soc_jack_new(codec, "Headset Jack", (SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR | SND_JACK_UNSUPPORTED), &hs_jack); if (err) { pr_err("failed to create new jack\n"); return err; } err = snd_soc_jack_new(codec, "Button Jack", TABLA_JACK_BUTTON_MASK, &button_jack); if (err) { pr_err("failed to create new jack\n"); return err; } codec_clk = clk_get(cpu_dai->dev, "osr_clk"); if (machine_is_msm8960_cdp()) mbhc_cfg.swap_gnd_mic = msm8960_swap_gnd_mic; if (hs_detect_use_gpio) { mbhc_cfg.gpio = PM8921_GPIO_PM_TO_SYS(JACK_DETECT_GPIO); mbhc_cfg.gpio_irq = JACK_DETECT_INT; } if (mbhc_cfg.gpio) { err = pm8xxx_gpio_config(mbhc_cfg.gpio, &jack_gpio_cfg); if (err) { pr_err("%s: pm8xxx_gpio_config JACK_DETECT failed %d\n", __func__, err); return err; } } mbhc_cfg.read_fw_bin = hs_detect_use_firmware; err = tabla_hs_detect(codec, &mbhc_cfg); return err; } static int msm8960_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); pr_debug("%s()\n", __func__); rate->min = rate->max = 48000; channels->min = channels->max = msm8960_slim_0_rx_ch; return 0; } static int msm8960_slim_0_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); pr_debug("%s()\n", __func__); rate->min = rate->max = 48000; channels->min = channels->max = msm8960_slim_0_tx_ch; return 0; } static int msm8960_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); pr_debug("%s()\n", __func__); rate->min = rate->max = 48000; return 0; } static int msm8960_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); pr_debug("%s channels->min %u channels->max %u ()\n", __func__, channels->min, channels->max); rate->min = rate->max = 48000; return 0; } static int msm8960_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); rate->min = rate->max = msm8960_btsco_rate; channels->min = channels->max = msm8960_btsco_ch; return 0; } static int msm8960_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); rate->min = rate->max = msm8960_auxpcm_rate; /* PCM only supports mono output */ channels->min = channels->max = 1; return 0; } static int msm8960_proxy_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); pr_debug("%s()\n", __func__); rate->min = rate->max = 48000; return 0; } static int msm8960_aux_pcm_get_gpios(void) { int ret = 0; pr_debug("%s\n", __func__); ret = gpio_request(GPIO_AUX_PCM_DOUT, "AUX PCM DOUT"); if (ret < 0) { pr_err("%s: Failed to request gpio(%d): AUX PCM DOUT", __func__, GPIO_AUX_PCM_DOUT); goto fail_dout; } ret = gpio_request(GPIO_AUX_PCM_DIN, "AUX PCM DIN"); if (ret < 0) { pr_err("%s: Failed to request gpio(%d): AUX PCM DIN", __func__, GPIO_AUX_PCM_DIN); goto fail_din; } ret = gpio_request(GPIO_AUX_PCM_SYNC, "AUX PCM SYNC"); if (ret < 0) { pr_err("%s: Failed to request gpio(%d): AUX PCM SYNC", __func__, GPIO_AUX_PCM_SYNC); goto fail_sync; } ret = gpio_request(GPIO_AUX_PCM_CLK, "AUX PCM CLK"); if (ret < 0) { pr_err("%s: Failed to request gpio(%d): AUX PCM CLK", __func__, GPIO_AUX_PCM_CLK); goto fail_clk; } return 0; fail_clk: gpio_free(GPIO_AUX_PCM_SYNC); fail_sync: gpio_free(GPIO_AUX_PCM_DIN); fail_din: gpio_free(GPIO_AUX_PCM_DOUT); fail_dout: return ret; }
static int hkdkc110_wm8991_init(struct snd_soc_codec *codec) { int err, ret; /* Setup Default Route */ g_current_out = WM8991_NONE; if (gpio_is_valid(GPIO_HPJACK)) { err = gpio_request( GPIO_HPJACK, GPIO_HPJACK_NAME); if(err) { printk(KERN_ERR "failed to request GPJ0 for wm8991 i2c clk..\n"); return err; } gpio_direction_input(GPIO_HPJACK); s3c_gpio_setpull(GPIO_HPJACK, S3C_GPIO_PULL_UP); if(gpio_get_value(GPIO_HPJACK)) g_current_out=WM8991_SPK; else g_current_out=WM8991_HP; gpio_free(GPIO_HPJACK); } err = request_irq(IRQ_HPJACK, hkdkc110_hpjack_isr, IRQF_DISABLED, "hpjack-irq", NULL); if(err) printk("\nDEBUG -> IRQ_HPJACK request error!!!\n\n"); set_irq_type(IRQ_HPJACK, IRQ_TYPE_EDGE_FALLING); INIT_DELAYED_WORK(&dwork_ear_detect, hkdkc110_hpjack_detect); #if defined(CONFIG_TOUCHSCREEN_X10) || defined(CONFIG_FB_S3C_SMD1024x600) g_btvout = false; wm8991_set_outpath(g_current_out); #else if(get_hdmi_onoff_status()) { g_btvout = true; wm8991_set_outpath(WM8991_NONE); } else { g_btvout = false; wm8991_set_outpath(g_current_out); } #endif /* add iDMA controls */ ret = snd_soc_add_controls(codec, &s5p_idma_control, 1); if (ret < 0) return ret; /* signal a DAPM event */ snd_soc_dapm_sync(codec); /* Set the Codec DAI configuration */ ret = snd_soc_dai_set_fmt(&wm8991_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; /* Set the AP DAI configuration */ ret = snd_soc_dai_set_fmt(&s3c64xx_i2s_dai[0], SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); if (ret < 0) return ret; return 0; }
static void codec_poweramp_on(void) { int ret = 0; struct pm_gpio param = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .output_value = 1, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_MED, .function = PM_GPIO_FUNC_NORMAL, }; if (msm8960_pamp_on) return; pr_debug("%s: enable stereo spkr amp\n", __func__); ret = gpio_request(MSM_CDC_PAMPL, "CDC PAMP1"); if (ret) { pr_err("%s: Error requesting GPIO %d\n", __func__, MSM_CDC_PAMPL); return; } ret = pm8xxx_gpio_config(MSM_CDC_PAMPL, ¶m); if (ret) pr_err("%s: Failed to configure gpio %d\n", __func__, MSM_CDC_PAMPL); else gpio_direction_output(MSM_CDC_PAMPL, 1); ret = gpio_request(MSM_CDC_PAMPR, "CDC PAMPL"); if (ret) { pr_err("%s: Error requesting GPIO %d\n", __func__, MSM_CDC_PAMPR); gpio_free(MSM_CDC_PAMPL); return; } ret = pm8xxx_gpio_config(MSM_CDC_PAMPR, ¶m); if (ret) pr_err("%s: Failed to configure gpio %d\n", __func__, MSM_CDC_PAMPR); else gpio_direction_output(MSM_CDC_PAMPR, 1); msm8960_pamp_on = 1; } static void codec_poweramp_off(void) { if (!msm8960_pamp_on) return; pr_debug("%s: disable stereo spkr amp\n", __func__); gpio_direction_output(MSM_CDC_PAMPL, 0); gpio_free(MSM_CDC_PAMPL); gpio_direction_output(MSM_CDC_PAMPR, 0); gpio_free(MSM_CDC_PAMPR); msm8960_pamp_on = 0; } static void msm8960_ext_control(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = &codec->dapm; pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control); if (msm8960_spk_control == MSM8960_SPK_ON) snd_soc_dapm_enable_pin(dapm, "Ext Spk"); else snd_soc_dapm_disable_pin(dapm, "Ext Spk"); snd_soc_dapm_sync(dapm); } static int msm8960_get_spk(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control); ucontrol->value.integer.value[0] = msm8960_spk_control; return 0; }
static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; int ret; /* Add SDP3430 specific widgets */ ret = snd_soc_dapm_new_controls(codec->dapm, sdp3430_twl4030_dapm_widgets, ARRAY_SIZE(sdp3430_twl4030_dapm_widgets)); if (ret) return ret; #ifdef CONFIG_SND_SOC_MAX97000 /* add MAX97000 specific controls */ ret = max97000_add_controls(codec); #elif CONFIG_SND_SOC_MAX9877 printk(KERN_NOTICE "MAX 9877 AMPLIFIER\n"); ret = max9877_add_controls(codec); #elif CONFIG_SND_SOC_YDA165 printk(KERN_NOTICE "YDA165 AMPLIFIER\n"); ret = yda165_add_controls(codec); #endif if (ret) { printk( "********** max audio amp add controls , %d\n", ret); } /* Set up SDP3430 specific audio path audio_map */ snd_soc_dapm_add_routes(codec->dapm, audio_map, ARRAY_SIZE(audio_map)); /* SDP3430 connected pins */ snd_soc_dapm_enable_pin(codec->dapm, "Ext Mic"); snd_soc_dapm_enable_pin(codec->dapm, "Ext Spk"); snd_soc_dapm_disable_pin(codec->dapm, "Headset Mic"); snd_soc_dapm_disable_pin(codec->dapm, "Headset Stereophone"); snd_soc_dapm_enable_pin(codec->dapm, "EARPIECE"); // reciever snd_soc_dapm_enable_pin(codec->dapm, "PREDRIVEL"); snd_soc_dapm_enable_pin(codec->dapm, "PREDRIVER"); /* TWL4030 not connected pins */ snd_soc_dapm_nc_pin(codec->dapm, "AUXL"); snd_soc_dapm_nc_pin(codec->dapm, "AUXR"); snd_soc_dapm_nc_pin(codec->dapm, "CARKITMIC"); snd_soc_dapm_nc_pin(codec->dapm, "DIGIMIC0"); snd_soc_dapm_nc_pin(codec->dapm, "DIGIMIC1"); //snd_soc_dapm_nc_pin(codec->dapm, "OUTL"); //snd_soc_dapm_nc_pin(codec->dapm, "OUTR"); snd_soc_dapm_nc_pin(codec->dapm, "EARPIECE"); snd_soc_dapm_nc_pin(codec->dapm, "PREDRIVEL"); snd_soc_dapm_nc_pin(codec->dapm, "PREDRIVER"); snd_soc_dapm_nc_pin(codec->dapm, "CARKITL"); snd_soc_dapm_nc_pin(codec->dapm, "CARKITR"); snd_soc_dapm_nc_pin(codec->dapm, "Ext Spk"); ret = snd_soc_dapm_sync(codec->dapm); if (ret) return ret; if (gpio_request(ZEUS_PCM_SELECT_GPIO, "PCM_SEL") == 0) { gpio_direction_output(ZEUS_PCM_SELECT_GPIO, 0); } return ret; }
static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); struct tegra_wm8903_platform_data *pdata = machine->pdata; int ret; if (gpio_is_valid(pdata->gpio_spkr_en)) { ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); if (ret) { dev_err(card->dev, "cannot get spkr_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_SPKR_EN; gpio_direction_output(pdata->gpio_spkr_en, 0); } if (gpio_is_valid(pdata->gpio_hp_mute)) { ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); if (ret) { dev_err(card->dev, "cannot get hp_mute gpio\n"); return ret; } machine->gpio_requested |= GPIO_HP_MUTE; gpio_direction_output(pdata->gpio_hp_mute, 1); } if (gpio_is_valid(pdata->gpio_int_mic_en)) { ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); if (ret) { dev_err(card->dev, "cannot get int_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_INT_MIC_EN; /* Disable int mic; enable signal is active-high */ gpio_direction_output(pdata->gpio_int_mic_en, 0); } if (gpio_is_valid(pdata->gpio_ext_mic_en)) { ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); if (ret) { dev_err(card->dev, "cannot get ext_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_EXT_MIC_EN; /* Enable ext mic; enable signal is active-low */ gpio_direction_output(pdata->gpio_ext_mic_en, 0); } if (gpio_is_valid(pdata->gpio_hp_det)) { tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, &tegra_wm8903_hp_jack); snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, ARRAY_SIZE(tegra_wm8903_hp_jack_pins), tegra_wm8903_hp_jack_pins); snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, 1, &tegra_wm8903_hp_jack_gpio); machine->gpio_requested |= GPIO_HP_DET; } snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, &tegra_wm8903_mic_jack); snd_soc_jack_add_pins(&tegra_wm8903_mic_jack, ARRAY_SIZE(tegra_wm8903_mic_jack_pins), tegra_wm8903_mic_jack_pins); wm8903_mic_detect(codec, &tegra_wm8903_mic_jack, SND_JACK_MICROPHONE, 0); snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); /* FIXME: Calculate automatically based on DAPM routes? */ if (!machine_is_harmony() && !machine_is_ventana()) snd_soc_dapm_nc_pin(dapm, "IN1L"); if (!machine_is_seaboard() && !machine_is_aebl()) snd_soc_dapm_nc_pin(dapm, "IN1R"); snd_soc_dapm_nc_pin(dapm, "IN2L"); if (!machine_is_kaen()) snd_soc_dapm_nc_pin(dapm, "IN2R"); snd_soc_dapm_nc_pin(dapm, "IN3L"); snd_soc_dapm_nc_pin(dapm, "IN3R"); if (machine_is_aebl()) { snd_soc_dapm_nc_pin(dapm, "LON"); snd_soc_dapm_nc_pin(dapm, "RON"); snd_soc_dapm_nc_pin(dapm, "ROP"); snd_soc_dapm_nc_pin(dapm, "LOP"); } else { snd_soc_dapm_nc_pin(dapm, "LINEOUTR"); snd_soc_dapm_nc_pin(dapm, "LINEOUTL"); } snd_soc_dapm_sync(dapm); return 0; }
static void midas_micdet(u16 status, void *data) { struct wm1811_machine_priv *wm1811 = data; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(wm1811->codec); int report; int reg; bool present; wake_lock_timeout(&wm1811->jackdet_wake_lock, 5 * HZ); /* Either nothing present or just starting detection */ if (!(status & WM8958_MICD_STS)) { if (!wm8994->jackdet) { /* If nothing present then clear our statuses */ dev_dbg(wm1811->codec->dev, "Detected open circuit\n"); wm8994->jack_mic = false; wm8994->mic_detecting = true; midas_micd_set_rate(wm1811->codec); snd_soc_jack_report(wm8994->micdet[0].jack, 0, wm8994->btn_mask | SND_JACK_HEADSET); } /*ToDo*/ /*return;*/ } /* If the measurement is showing a high impedence we've got a * microphone. */ if (wm8994->mic_detecting && (status & 0x400)) { dev_info(wm1811->codec->dev, "Detected microphone\n"); wm8994->mic_detecting = false; wm8994->jack_mic = true; midas_micd_set_rate(wm1811->codec); snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADSET, SND_JACK_HEADSET); } if (wm8994->mic_detecting && status & 0x4) { dev_info(wm1811->codec->dev, "Detected headphone\n"); wm8994->mic_detecting = false; midas_micd_set_rate(wm1811->codec); snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE, SND_JACK_HEADSET); /* If we have jackdet that will detect removal */ if (wm8994->jackdet) { mutex_lock(&wm8994->accdet_lock); snd_soc_update_bits(wm1811->codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); if (wm8994->active_refcount) { snd_soc_update_bits(wm1811->codec, WM8994_ANTIPOP_2, WM1811_JACKDET_MODE_MASK, WM1811_JACKDET_MODE_AUDIO); } mutex_unlock(&wm8994->accdet_lock); if (wm8994->pdata->jd_ext_cap) { mutex_lock(&wm1811->codec->mutex); snd_soc_dapm_disable_pin(&wm1811->codec->dapm, "MICBIAS2"); snd_soc_dapm_sync(&wm1811->codec->dapm); mutex_unlock(&wm1811->codec->mutex); } } } /* Report short circuit as a button */ if (wm8994->jack_mic) { report = 0; if (status & WM1811_JACKDET_BTN0) report |= SND_JACK_BTN_0; if (status & WM1811_JACKDET_BTN1) report |= SND_JACK_BTN_1; if (status & WM1811_JACKDET_BTN2) report |= SND_JACK_BTN_2; reg = snd_soc_read(wm1811->codec, WM1811_JACKDET_CTRL); if (reg < 0) { pr_err("%s: Failed to read jack status: %d\n", __func__, reg); return; } pr_err("%s: JACKDET %x\n", __func__, reg); present = reg & WM1811_JACKDET_LVL; if (!present) { pr_err("%s: button is ignored!!!\n", __func__); return; } dev_dbg(wm1811->codec->dev, "Detected Button: %08x (%08X)\n", report, status); snd_soc_jack_report(wm8994->micdet[0].jack, report, wm8994->btn_mask); } }
static int ctp_wm5102_init(struct snd_soc_pcm_runtime *runtime) { int ret; struct snd_soc_card *card = runtime->card; struct ctp_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); struct snd_soc_codec *codec; struct snd_soc_dapm_context *dapm; codec = ctp_get_codec(card, "wm5102-codec"); if (!codec) return -EIO; dapm = &codec->dapm; /* Set codec bias level */ ctp_set_bias_level(card, dapm, SND_SOC_BIAS_OFF); card->dapm.idle_bias_off = true; /* Disable MICBIAS3 bypass mode and set CAP mode. * Capacitors are connected to DMIC on 1525-EV1 board */ snd_soc_update_bits(codec, ARIZONA_MIC_BIAS_CTRL_3, ARIZONA_MICB1_BYPASS_MASK | ARIZONA_MICB1_EXT_CAP_MASK, ARIZONA_MICB1_EXT_CAP); /* Set codec clock */ ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, ARIZONA_CLK_SRC_FLL1, SYSCLK_RATE, SND_SOC_CLOCK_IN); if (ret != 0) { pr_err("failed: %d\n", ret); return ret; } /* Add Jack specific widgets */ ret = snd_soc_dapm_new_controls(dapm, ctp_dapm_widgets, ARRAY_SIZE(ctp_dapm_widgets)); if (ret) return ret; /* Set up Jack specific audio path audio_map */ snd_soc_dapm_add_routes(dapm, ctp_audio_map, ARRAY_SIZE(ctp_audio_map)); /* Add Comms specefic controls */ ctx->comms_ctl.ssp_bt_sco_master_mode = false; ctx->comms_ctl.ssp_voip_master_mode = false; ctx->comms_ctl.ssp_modem_master_mode = false; ret = snd_soc_add_card_controls(card, ssp_comms_controls, ARRAY_SIZE(ssp_comms_controls)); if (ret) { pr_err("Add Comms Controls failed %d", ret); return ret; } /* Keep the voice call paths active during suspend. Mark the end points ignore_suspend */ snd_soc_dapm_ignore_suspend(dapm, "HPOUT1R"); snd_soc_dapm_ignore_suspend(dapm, "HPOUT1L"); snd_soc_dapm_disable_pin(dapm, "MICBIAS1"); snd_soc_dapm_disable_pin(dapm, "SPKOUTLP"); snd_soc_dapm_disable_pin(dapm, "SPKOUTLN"); snd_soc_dapm_ignore_suspend(dapm, "SPKOUTRP"); snd_soc_dapm_ignore_suspend(dapm, "SPKOUTRN"); mutex_lock(&codec->mutex); snd_soc_dapm_sync(dapm); mutex_unlock(&codec->mutex); return ret; }
static int tegra_codec_init(struct snd_soc_codec *codec) { struct adam_audio_priv* ctx = codec->socdev->codec_data; int ret = 0; if (!ctx->init_done) { /* Get and enable the DAP clock */ ctx->dap_mclk = tegra_das_get_dap_mclk(); if (!ctx->dap_mclk) { pr_err("Failed to get dap mclk \n"); return -ENODEV; } clk_enable(ctx->dap_mclk); /* Add the controls used to route audio to bluetooth/voice */ tegra_das_controls_init(codec); /* Store the GPIO used to detect headphone */ tegra_jack_gpios[0].gpio = ctx->gpio_hp_det; /* Add tegra specific widgets */ snd_soc_dapm_new_controls(codec, tegra_dapm_widgets, ARRAY_SIZE(tegra_dapm_widgets)); #ifdef ADAM_MANUAL_CONTROL_OF_OUTPUTDEVICE /* Add specific adam controls */ ret = snd_soc_add_controls(codec, tegra_controls, ARRAY_SIZE(tegra_controls)); if (ret < 0) { pr_err("Failed to register controls\n"); return ret; } #endif /* Set up tegra specific audio path audio_map */ snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); /* make sure to register the dapm widgets */ snd_soc_dapm_new_widgets(codec); /* Set endpoints to not connected */ snd_soc_dapm_nc_pin(codec, "LINEL"); snd_soc_dapm_nc_pin(codec, "LINER"); snd_soc_dapm_nc_pin(codec, "PHONEIN"); snd_soc_dapm_nc_pin(codec, "MIC2"); snd_soc_dapm_nc_pin(codec, "MONO"); /* Set endpoints to default off mode */ snd_soc_dapm_enable_pin(codec, "Internal Speaker"); snd_soc_dapm_enable_pin(codec, "Internal Mic"); snd_soc_dapm_disable_pin(codec, "Headphone Jack"); ret = snd_soc_dapm_sync(codec); if (ret) { pr_err("Failed to sync\n"); return ret; } #ifndef ADAM_MANUAL_CONTROL_OF_OUTPUTDEVICE /* Headphone jack detection */ ret = snd_soc_jack_new(codec->socdev->card, "Headphone Jack", SND_JACK_HEADPHONE, &ctx->tegra_jack); if (ret) return ret; ret = snd_soc_jack_add_pins(&ctx->tegra_jack, ARRAY_SIZE(tegra_jack_pins), tegra_jack_pins); if (ret) return ret; ret = snd_soc_jack_add_gpios(&ctx->tegra_jack, ARRAY_SIZE(tegra_jack_gpios), tegra_jack_gpios); if (ret) return ret; #endif ctx->init_done = 1; } return ret; }
static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) { int err; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai *codec_dai = rtd->codec_dai; /* Taiko SLIMBUS configuration * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13 * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13 * TX14, TX15, TX16 */ unsigned int rx_ch[TAIKO_RX_MAX] = {144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156}; unsigned int tx_ch[TAIKO_TX_MAX] = {128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143}; pr_info("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev)); if (machine_is_msm8960_liquid()) { top_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(19)); bottom_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(18)); } rtd->pmdown_time = 0; err = snd_soc_add_codec_controls(codec, msm_snd_controls, ARRAY_SIZE(msm_snd_controls)); if (err < 0) return err; snd_soc_dapm_new_controls(dapm, msm_dapm_widgets, ARRAY_SIZE(msm_dapm_widgets)); snd_soc_dapm_add_routes(dapm, common_audio_map, ARRAY_SIZE(common_audio_map)); snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg"); snd_soc_dapm_sync(dapm); err = snd_soc_jack_new(codec, "Headset Jack", (SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR | SND_JACK_UNSUPPORTED), &hs_jack); if (err) { pr_err("failed to create new jack\n"); return err; } snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch), tx_ch, ARRAY_SIZE(rx_ch), rx_ch); err = snd_soc_jack_new(codec, "Button Jack", TAIKO_JACK_BUTTON_MASK, &button_jack); if (err) { pr_err("failed to create new jack\n"); return err; } return err; }
/* Blocs will be powered dynamically, input routes could be set using WM8589 DAPM controls but we will activate them here to to be sure */ static void archos_ext_control(struct snd_soc_codec *codec) { /* First Input stuff */ switch (archos_input_func) { case 0: /* None */ wm8985_connect_pga(codec, OFF); wm8985_select_pga_inputs(codec, INPUT_LIP|INPUT_RIP|INPUT_LINE|INPUT_LIN|INPUT_RIN, OFF); snd_soc_dapm_disable_pin(codec, "Mic"); snd_soc_dapm_disable_pin(codec, "Jack Mic"); snd_soc_dapm_disable_pin(codec, "Line In"); break; case 1: /* Mic */ wm8985_select_pga_inputs(codec, INPUT_RIP|INPUT_LINE, OFF); wm8985_select_pga_inputs(codec, INPUT_LIN|INPUT_RIN|INPUT_LIP, ON); wm8985_connect_pga(codec, ON); snd_soc_dapm_enable_pin(codec, "Mic"); snd_soc_dapm_disable_pin(codec, "Jack Mic"); snd_soc_dapm_disable_pin(codec, "Line In"); break; case 2: /* Jack Mic */ wm8985_select_pga_inputs(codec, INPUT_LIP|INPUT_LINE, OFF); wm8985_select_pga_inputs(codec, INPUT_LIN|INPUT_RIN|INPUT_RIP, ON); wm8985_connect_pga(codec, ON); snd_soc_dapm_enable_pin(codec, "Jack Mic"); snd_soc_dapm_disable_pin(codec, "Mic"); snd_soc_dapm_disable_pin(codec, "Line In"); break; case 3: /* Line */ wm8985_select_pga_inputs(codec, INPUT_LIP|INPUT_RIP, OFF); wm8985_select_pga_inputs(codec, INPUT_LIN|INPUT_RIN|INPUT_LINE, ON); wm8985_connect_pga(codec, ON); snd_soc_dapm_enable_pin(codec, "Line In"); snd_soc_dapm_disable_pin(codec, "Mic"); snd_soc_dapm_disable_pin(codec, "Jack Mic"); break; default: break; } /* Then SPDIF */ if (archos_spdif_func) { /* Use SPDIF sample rates */ snd_soc_dapm_disable_pin(codec, "Speaker"); snd_soc_dapm_disable_pin(codec, "Headphone"); sample_info = spdif_sample_info; sample_count = spdif_sample_count; _enable_spdif_ampli(); /* Nothing else has to be enabled if SPDIF is active */ snd_soc_dapm_sync(codec); return; } else { /* Use analogic sample rates */ sample_info = analog_sample_info; sample_count = analog_sample_count; _disable_spdif_ampli(); } /* Finally, if SPDIF is OFF, Speaker, Headphone and Out4*/ if (archos_spk_func) snd_soc_dapm_enable_pin(codec, "Speaker"); else snd_soc_dapm_disable_pin(codec, "Speaker"); if (archos_hp_func) snd_soc_dapm_enable_pin(codec, "Headphone"); else snd_soc_dapm_disable_pin(codec, "Headphone"); if (archos_out4_func) snd_soc_dapm_enable_pin(codec, "HSDPA Mic"); else snd_soc_dapm_disable_pin(codec, "HSDPA Mic"); snd_soc_dapm_sync(codec); }
static int adav80x_set_pll(struct snd_soc_codec *codec, int pll_id, int source, unsigned int freq_in, unsigned int freq_out) { struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); unsigned int pll_ctrl1 = 0; unsigned int pll_ctrl2 = 0; unsigned int pll_src; switch (source) { case ADAV80X_PLL_SRC_XTAL: case ADAV80X_PLL_SRC_XIN: case ADAV80X_PLL_SRC_MCLKI: break; default: return -EINVAL; } if (!freq_out) return 0; switch (freq_in) { case 27000000: break; case 54000000: if (source == ADAV80X_PLL_SRC_XIN) { pll_ctrl1 |= ADAV80X_PLL_CTRL1_PLLDIV; break; } default: return -EINVAL; } if (freq_out > 12288000) { pll_ctrl2 |= ADAV80X_PLL_CTRL2_DOUB(pll_id); freq_out /= 2; } /* freq_out = sample_rate * 256 */ switch (freq_out) { case 8192000: pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_32(pll_id); break; case 11289600: pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_44(pll_id); break; case 12288000: pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_48(pll_id); break; default: return -EINVAL; } regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CTRL1, ADAV80X_PLL_CTRL1_PLLDIV, pll_ctrl1); regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CTRL2, ADAV80X_PLL_CTRL2_PLL_MASK(pll_id), pll_ctrl2); if (source != adav80x->pll_src) { if (source == ADAV80X_PLL_SRC_MCLKI) pll_src = ADAV80X_PLL_CLK_SRC_PLL_MCLKI(pll_id); else pll_src = ADAV80X_PLL_CLK_SRC_PLL_XIN(pll_id); regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CLK_SRC, ADAV80X_PLL_CLK_SRC_PLL_MASK(pll_id), pll_src); adav80x->pll_src = source; snd_soc_dapm_sync(&codec->dapm); } return 0; }
static int msm8960_audrx_init(struct snd_soc_pcm_runtime *rtd) { int err; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; u8 tabla_version; pr_aud_info("%s()\n", __func__); rtd->pmdown_time = 0; err = snd_soc_add_controls(codec, tabla_msm8960_controls, ARRAY_SIZE(tabla_msm8960_controls)); if (err < 0) return err; snd_soc_dapm_new_controls(dapm, msm8960_dapm_widgets, ARRAY_SIZE(msm8960_dapm_widgets)); snd_soc_dapm_new_controls(dapm, fighter_dapm_widgets, ARRAY_SIZE(fighter_dapm_widgets)); snd_soc_dapm_add_routes(dapm, common_audio_map, ARRAY_SIZE(common_audio_map)); /* determine HW connection based on codec revision */ tabla_version = snd_soc_read(codec, TABLA_A_CHIP_VERSION); tabla_version &= 0x1F; pr_aud_info("%s : Tabla version %u\n", __func__, (u32)tabla_version); if ((tabla_version == TABLA_VERSION_1_0) || (tabla_version == TABLA_VERSION_1_1)) { snd_soc_dapm_add_routes(dapm, tabla_1_x_audio_map, ARRAY_SIZE(tabla_1_x_audio_map)); } else { snd_soc_dapm_add_routes(dapm, tabla_2_x_audio_map, ARRAY_SIZE(tabla_2_x_audio_map)); } snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg"); snd_soc_dapm_enable_pin(dapm, "Ext USB AMP Pos"); snd_soc_dapm_enable_pin(dapm, "Ext USB AMP Neg"); snd_soc_dapm_sync(dapm); err = snd_soc_jack_new(codec, "Headset Jack", (SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR), &hs_jack); if (err) { pr_aud_err("failed to create new jack\n"); return err; } err = snd_soc_jack_new(codec, "Button Jack", SND_JACK_BTN_0, &button_jack); if (err) { pr_aud_err("failed to create new jack\n"); return err; } /* Do not pass MBHC calibration data to disable HS detection. * Otherwise, sending project-based cal-data to enable * MBHC mechanism that tabla provides */ tabla_hs_detect(codec, &hs_jack, &button_jack, NULL, TABLA_MICBIAS2, msm8960_enable_codec_ext_clk, 0, TABLA_EXT_CLK_RATE); return 0; }
static int adc3101_set_scenario_endpoints(struct tt_scenario_context *c) { struct snd_kcontrol *kcontrol = (struct snd_kcontrol *) c->data; struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); /* check whether the new scenario is already active, if so, don't set it again as this has been seen to result in non wanted register changes e.g. setting scenario TT_SCENARIO_ASR twice result in non ASR scenario registers being set. */ if (c->tt_current_scenario == c->tt_scenario) return 0; /* scenario routing switching */ switch(c->tt_scenario) { default: case TT_SCENARIO_AUDIO_INIT: /* enable mic bias (not if we use mic pre-amp) */ adc3101_mic_bias_enable(codec); case TT_SCENARIO_AUDIO_OFF: c->tt_volume = 0; switch(c->tt_current_scenario) { case TT_SCENARIO_VR: adc3101_alc_disable(codec); case TT_SCENARIO_NOISE: case TT_SCENARIO_ASR: case TT_SCENARIO_HF_LINEOUT: case TT_SCENARIO_HF_FM: case TT_SCENARIO_HF_SPEAKER: adc3101_mic_disable(codec); break; case TT_SCENARIO_SPEAKER: case TT_SCENARIO_LINEOUT: case TT_SCENARIO_FM: break; adc3101_mic_disable(codec); break; case TT_SCENARIO_iPod: adc3101_line_in_disable(codec); adc3101_mic_bias_enable(codec); break; case TT_SCENARIO_iPod_SPEAKER: adc3101_line_in_disable(codec); adc3101_mic_bias_enable(codec); break; case TT_SCENARIO_iPod_LINEOUT: case TT_SCENARIO_iPod_FM: adc3101_line_in_disable(codec); adc3101_mic_bias_enable(codec); break; default: snd_soc_dapm_disable_pin(codec, "MicIn"); break; } break; case TT_SCENARIO_ASR: adc3101_mic_enable(codec, 25, 1); break; case TT_SCENARIO_VR: adc3101_mic_enable(codec, 25, 1); break; case TT_SCENARIO_NOISE: adc3101_mic_enable(codec, 15, 1); break; case TT_SCENARIO_iPod: adc3101_line_in_enable(codec); break; case TT_SCENARIO_SPEAKER: break; case TT_SCENARIO_LINEOUT: break; case TT_SCENARIO_FM: break; case TT_SCENARIO_iPod_SPEAKER: adc3101_line_in_enable(codec); break; case TT_SCENARIO_iPod_LINEOUT: case TT_SCENARIO_iPod_FM: adc3101_line_in_enable(codec); break; case TT_SCENARIO_HF_SPEAKER: adc3101_mic_enable(codec, 13, 1); break; case TT_SCENARIO_HF_LINEOUT: case TT_SCENARIO_HF_FM: adc3101_mic_enable(codec, 13, 1); break; } c->tt_current_scenario = c->tt_scenario; snd_soc_dapm_sync(codec); switch(c->tt_scenario) { case TT_SCENARIO_LINEOUT: case TT_SCENARIO_iPod_LINEOUT: case TT_SCENARIO_FM: case TT_SCENARIO_iPod_FM: break; default: case TT_SCENARIO_AUDIO_INIT: case TT_SCENARIO_AUDIO_OFF: break; case TT_SCENARIO_SPEAKER: case TT_SCENARIO_iPod_SPEAKER: case TT_SCENARIO_HF_SPEAKER: break; } return 1; }
static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd) { int err; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; pr_debug("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev)); /*if (machine_is_msm_liquid()) { top_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(19)); bottom_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(18)); }*/ rtd->pmdown_time = 0; err = snd_soc_add_controls(codec, tabla_msm_controls, ARRAY_SIZE(tabla_msm_controls)); if (err < 0) return err; snd_soc_dapm_new_controls(dapm, apq8064_dapm_widgets, ARRAY_SIZE(apq8064_dapm_widgets)); snd_soc_dapm_add_routes(dapm, apq8064_common_audio_map, ARRAY_SIZE(apq8064_common_audio_map)); if (machine_is_apq8064_mtp()) { snd_soc_dapm_add_routes(dapm, apq8064_mtp_audio_map, ARRAY_SIZE(apq8064_mtp_audio_map)); } else { snd_soc_dapm_add_routes(dapm, apq8064_liquid_cdp_audio_map, ARRAY_SIZE(apq8064_liquid_cdp_audio_map)); } snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg"); snd_soc_dapm_sync(dapm); err = snd_soc_jack_new(codec, "Headset Jack", (SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR), &hs_jack); if (err) { pr_err("failed to create new jack\n"); return err; } err = snd_soc_jack_new(codec, "Button Jack", TABLA_JACK_BUTTON_MASK, &button_jack); if (err) { pr_err("failed to create new jack\n"); return err; } codec_clk = clk_get(cpu_dai->dev, "osr_clk"); err = tabla_hs_detect(codec, &mbhc_cfg); return err; }
static int aml_asoc_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct snd_soc_codec *codec = rtd->codec; //struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_dapm_context *dapm = &codec->dapm; struct aml_audio_private_data * p_aml_audio; int ret = 0; printk(KERN_DEBUG "enter %s \n", __func__); p_aml_audio = snd_soc_card_get_drvdata(card); /* Add specific widgets */ // snd_soc_dapm_new_controls(dapm, aml_asoc_dapm_widgets, // ARRAY_SIZE(aml_asoc_dapm_widgets)); /* set ADCLRC/GPIO1 Pin Function Select */ snd_soc_update_bits(codec, WM8960_IFACE2, (1 << 6), (1 << 6)); /* not connected */ snd_soc_dapm_nc_pin(dapm, "LINPUT3"); snd_soc_dapm_nc_pin(dapm, "RINPUT3"); snd_soc_dapm_nc_pin(dapm, "OUT3"); /* always connected */ snd_soc_dapm_enable_pin(dapm, "Ext Spk"); snd_soc_dapm_enable_pin(dapm, "Mic"); /* disable connected */ snd_soc_dapm_disable_pin(dapm, "HP"); snd_soc_dapm_sync(dapm); ret = snd_soc_jack_new(codec, "hp switch", SND_JACK_HEADPHONE, &p_aml_audio->jack); if (ret) { printk(KERN_WARNING "Failed to alloc resource for hp switch\n"); } else { ret = snd_soc_jack_add_pins(&p_aml_audio->jack, ARRAY_SIZE(jack_pins), jack_pins); if (ret) { printk(KERN_WARNING "Failed to setup hp pins\n"); } } #if HP_IRQ p_aml_audio->gpio_hp_det = of_get_named_gpio(card->dev->of_node,"wm8960_gpio",0); if (gpio_is_valid(p_aml_audio->gpio_hp_det)) { aml_audio_hp_jack_gpio.gpio = p_aml_audio->gpio_hp_det; snd_soc_jack_add_gpios(&p_aml_audio->jack, 1, &aml_audio_hp_jack_gpio); } #endif #if HP_DET init_timer(&p_aml_audio->timer); p_aml_audio->timer.function = aml_asoc_timer_func; p_aml_audio->timer.data = (unsigned long)p_aml_audio; p_aml_audio->data= (void*)card; INIT_WORK(&p_aml_audio->work, aml_asoc_work_func); mutex_init(&p_aml_audio->lock); mutex_lock(&p_aml_audio->lock); if (!p_aml_audio->timer_en) { aml_audio_start_timer(p_aml_audio, msecs_to_jiffies(100)); } mutex_unlock(&p_aml_audio->lock); #endif //p_aml_audio->dis_hp_det = of_property_read_bool(card->dev->of_node,"dis_hp_det"); ret = of_property_read_u32(card->dev->of_node,"dis_hp_det",(u32 *)&p_aml_audio->dis_hp_det); printk("******p_aml_audio->dis_hp_det=%d***\n",p_aml_audio->dis_hp_det); if(ret){ printk("don't find match dis_hp_det\n"); goto out1; } if(!p_aml_audio->dis_hp_det){ printk("****mm**p_aml_audio->dis_hp_det\n"); //JD2 as headphone detect snd_soc_update_bits(codec,27, 0x008, 0x008);// OUT3 buffer Enabled and disabled with HPL and HPR jack detect //INSERT_DELAY [1] mdelay(1); ///GPIO1 output the "jack detect output" snd_soc_update_bits(codec,48, 0x03A, 0x03A);// JD2 used for Jack Detect Input, GPIO function = jack detect output snd_soc_update_bits(codec,24, 0x040, 0x040);// HPDETECT LOW = Speaker snd_soc_update_bits(codec, 23, 0x1D1, 0x1D1); mdelay(500); } out1: return 0; }
static int msm8960_audrx_init(struct snd_soc_pcm_runtime *rtd) { int err, use_pmic; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct pm_gpio jack_gpio_cfg = { .direction = PM_GPIO_DIR_IN, .pull = PM_GPIO_PULL_NO, .function = PM_GPIO_FUNC_NORMAL, .vin_sel = 2, .inv_int_pol = 0, }; pr_debug("%s()\n", __func__); if (machine_is_msm8960_liquid()) { top_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(19)); bottom_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(18)); } rtd->pmdown_time = 0; err = snd_soc_add_controls(codec, tabla_msm8960_controls, ARRAY_SIZE(tabla_msm8960_controls)); if (err < 0) return err; #ifdef CONFIG_INPUT_SIMPLE_REMOTE use_pmic = 1; #else use_pmic = 0; #endif /* CONFIG_INPUT_SIMPLE_REMOTE */ #ifdef CONFIG_INPUT_MBHC_MIC_BIAS_SWITCHING_GPIO use_pmic = msm8960_read_is_pmic_used(); #endif /* CONFIG_INPUT_MBHC_MIC_BIAS_SWITCHING_GPIO */ if (use_pmic) { pr_debug("%s: Enables PMIC.\n", __func__); snd_soc_dapm_new_controls(dapm, blue_msm8960_dapm_widgets, ARRAY_SIZE(blue_msm8960_dapm_widgets)); } else { pr_debug("%s: Does NOT enable PMIC.\n", __func__); snd_soc_dapm_new_controls(dapm, blue_msm8960_dapm_widgets_no_pmic, ARRAY_SIZE(blue_msm8960_dapm_widgets_no_pmic)); } snd_soc_dapm_add_routes(dapm, blue_audio_map, ARRAY_SIZE(blue_audio_map)); snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top"); snd_soc_dapm_sync(dapm); err = snd_soc_jack_new(codec, "Headset Jack", (SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR), &hs_jack); if (err) { pr_err("failed to create new jack\n"); return err; } err = snd_soc_jack_new(codec, "Button Jack", TABLA_JACK_BUTTON_MASK, &button_jack); if (err) { pr_err("failed to create new jack\n"); return err; } if (hs_detect_use_gpio && !use_pmic) { pr_debug("%s: Using MBHC+GPIO-detect on gpio %d", __func__, JACK_DETECT_GPIO); mbhc_cfg.gpio = PM8921_GPIO_PM_TO_SYS(JACK_DETECT_GPIO); mbhc_cfg.gpio_irq = JACK_DETECT_INT; } else { pr_debug("%s: Does not use MBHC+GPIO-detect", __func__); } if (mbhc_cfg.gpio) { err = pm8xxx_gpio_config(mbhc_cfg.gpio, &jack_gpio_cfg); if (err) { pr_err("%s: pm8xxx_gpio_config failed %d\n", __func__, err); return err; } } #ifdef CONFIG_INPUT_MBHC_HEADSET_CONTROL if (!use_pmic) { mbhc_cfg.read_fw_bin = hs_detect_use_firmware; err = tabla_hs_detect(codec, &mbhc_cfg); } #endif /* CONFIG_INPUT_MBHC_HEADSET_CONTROL */ return err; } static struct snd_soc_dsp_link lpa_fe_media = { .playback = true, .trigger = { SND_SOC_DSP_TRIGGER_POST, SND_SOC_DSP_TRIGGER_POST }, }; static struct snd_soc_dsp_link fe_media = { .playback = true, .capture = true, .trigger = { SND_SOC_DSP_TRIGGER_POST, SND_SOC_DSP_TRIGGER_POST }, }; /* bi-directional media definition for hostless PCM device */ static struct snd_soc_dsp_link bidir_hl_media = { .playback = true, .capture = true, .trigger = { SND_SOC_DSP_TRIGGER_POST, SND_SOC_DSP_TRIGGER_POST }, }; static struct snd_soc_dsp_link hdmi_rx_hl = { .playback = true, .trigger = { SND_SOC_DSP_TRIGGER_POST, SND_SOC_DSP_TRIGGER_POST }, }; static int msm8960_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); pr_debug("%s()\n", __func__); rate->min = rate->max = 48000; channels->min = channels->max = msm8960_slim_0_rx_ch; return 0; } static int msm8960_slim_0_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); pr_debug("%s()\n", __func__); rate->min = rate->max = 48000; channels->min = channels->max = msm8960_slim_0_tx_ch; return 0; } static int msm8960_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); pr_debug("%s()\n", __func__); rate->min = rate->max = 48000; return 0; } static int msm8960_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); pr_debug("%s channels->min %u channels->max %u ()\n", __func__, channels->min, channels->max); rate->min = rate->max = 48000; return 0; } static int msm8960_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); rate->min = rate->max = msm8960_btsco_rate; channels->min = channels->max = msm8960_btsco_ch; return 0; } static int msm8960_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); /* PCM only supports mono output with 8khz sample rate */ rate->min = rate->max = 8000; channels->min = channels->max = 1; return 0; } static int msm8960_aux_pcm_get_gpios(void) { int ret = 0; pr_debug("%s\n", __func__); ret = gpio_request(GPIO_AUX_PCM_DOUT, "AUX PCM DOUT"); if (ret < 0) { pr_err("%s: Failed to request gpio(%d): AUX PCM DOUT", __func__, GPIO_AUX_PCM_DOUT); goto fail_dout; } ret = gpio_request(GPIO_AUX_PCM_DIN, "AUX PCM DIN"); if (ret < 0) { pr_err("%s: Failed to request gpio(%d): AUX PCM DIN", __func__, GPIO_AUX_PCM_DIN); goto fail_din; } ret = gpio_request(GPIO_AUX_PCM_SYNC, "AUX PCM SYNC"); if (ret < 0) { pr_err("%s: Failed to request gpio(%d): AUX PCM SYNC", __func__, GPIO_AUX_PCM_SYNC); goto fail_sync; } ret = gpio_request(GPIO_AUX_PCM_CLK, "AUX PCM CLK"); if (ret < 0) { pr_err("%s: Failed to request gpio(%d): AUX PCM CLK", __func__, GPIO_AUX_PCM_CLK); goto fail_clk; } return 0; fail_clk: gpio_free(GPIO_AUX_PCM_SYNC); fail_sync: gpio_free(GPIO_AUX_PCM_DIN); fail_din: gpio_free(GPIO_AUX_PCM_DOUT); fail_dout: return ret; } static int msm8960_aux_pcm_free_gpios(void) { gpio_free(GPIO_AUX_PCM_DIN); gpio_free(GPIO_AUX_PCM_DOUT); gpio_free(GPIO_AUX_PCM_SYNC); gpio_free(GPIO_AUX_PCM_CLK); return 0; } static int msm8960_startup(struct snd_pcm_substream *substream) { pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); return 0; } static int msm8960_auxpcm_startup(struct snd_pcm_substream *substream) { int ret = 0; pr_debug("%s(): substream = %s\n", __func__, substream->name); ret = msm8960_aux_pcm_get_gpios(); if (ret < 0) { pr_err("%s: Aux PCM GPIO request failed\n", __func__); return -EINVAL; } return 0; } static void msm8960_auxpcm_shutdown(struct snd_pcm_substream *substream) { pr_debug("%s(): substream = %s\n", __func__, substream->name); msm8960_aux_pcm_free_gpios(); }
static int machine_init(struct snd_soc_codec *codec) { snd_soc_dapm_sync(codec); return 0; }
static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct soc_enum *control = (struct soc_enum *)kcontrol->private_value; unsigned short pins; int pin, changed = 0; /* Refuse any mode changes if we are not able to control the codec. */ if (!codec->control_data) return -EUNATCH; if (ucontrol->value.enumerated.item[0] >= control->max) return -EINVAL; mutex_lock(&codec->mutex); /* Translate selection to bitmap */ pins = ams_delta_audio_mode_pins[ucontrol->value.enumerated.item[0]]; /* Setup pins after corresponding bits if changed */ pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE)); if (pin != snd_soc_dapm_get_pin_status(codec, "Mouthpiece")) { changed = 1; if (pin) snd_soc_dapm_enable_pin(codec, "Mouthpiece"); else snd_soc_dapm_disable_pin(codec, "Mouthpiece"); } pin = !!(pins & (1 << AMS_DELTA_EARPIECE)); if (pin != snd_soc_dapm_get_pin_status(codec, "Earpiece")) { changed = 1; if (pin) snd_soc_dapm_enable_pin(codec, "Earpiece"); else snd_soc_dapm_disable_pin(codec, "Earpiece"); } pin = !!(pins & (1 << AMS_DELTA_MICROPHONE)); if (pin != snd_soc_dapm_get_pin_status(codec, "Microphone")) { changed = 1; if (pin) snd_soc_dapm_enable_pin(codec, "Microphone"); else snd_soc_dapm_disable_pin(codec, "Microphone"); } pin = !!(pins & (1 << AMS_DELTA_SPEAKER)); if (pin != snd_soc_dapm_get_pin_status(codec, "Speaker")) { changed = 1; if (pin) snd_soc_dapm_enable_pin(codec, "Speaker"); else snd_soc_dapm_disable_pin(codec, "Speaker"); } pin = !!(pins & (1 << AMS_DELTA_AGC)); if (pin != ams_delta_audio_agc) { ams_delta_audio_agc = pin; changed = 1; if (pin) snd_soc_dapm_enable_pin(codec, "AGCIN"); else snd_soc_dapm_disable_pin(codec, "AGCIN"); } if (changed) snd_soc_dapm_sync(codec); mutex_unlock(&codec->mutex); return changed; }
static int tegra_max98095_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_card *card = codec->card; struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card); struct tegra_asoc_platform_data *pdata = machine->pdata; #ifndef CONFIG_ARCH_TEGRA_2x_SOC struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai); #endif int ret; #ifndef CONFIG_ARCH_TEGRA_2x_SOC if (machine->codec_info[BASEBAND].i2s_id != -1) i2s->is_dam_used = true; #endif if (machine->init_done) return 0; machine->init_done = true; if (gpio_is_valid(pdata->gpio_spkr_en)) { ret = gpio_request(pdata->gpio_spkr_en, "spkr_en"); if (ret) { dev_err(card->dev, "cannot get spkr_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_SPKR_EN; gpio_direction_output(pdata->gpio_spkr_en, 0); } if (gpio_is_valid(pdata->gpio_hp_mute)) { ret = gpio_request(pdata->gpio_hp_mute, "hp_mute"); if (ret) { dev_err(card->dev, "cannot get hp_mute gpio\n"); return ret; } machine->gpio_requested |= GPIO_HP_MUTE; gpio_direction_output(pdata->gpio_hp_mute, 0); } if (gpio_is_valid(pdata->gpio_int_mic_en)) { ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en"); if (ret) { dev_err(card->dev, "cannot get int_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_INT_MIC_EN; /* Disable int mic; enable signal is active-high */ gpio_direction_output(pdata->gpio_int_mic_en, 0); } if (gpio_is_valid(pdata->gpio_ext_mic_en)) { ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en"); if (ret) { dev_err(card->dev, "cannot get ext_mic_en gpio\n"); return ret; } machine->gpio_requested |= GPIO_EXT_MIC_EN; /* Enable ext mic; enable signal is active-low */ gpio_direction_output(pdata->gpio_ext_mic_en, 0); } ret = snd_soc_add_card_controls(card, tegra_max98095_controls, ARRAY_SIZE(tegra_max98095_controls)); if (ret < 0) return ret; snd_soc_dapm_new_controls(dapm, tegra_max98095_dapm_widgets, ARRAY_SIZE(tegra_max98095_dapm_widgets)); snd_soc_dapm_add_routes(dapm, enterprise_audio_map, ARRAY_SIZE(enterprise_audio_map)); ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &tegra_max98095_hp_jack); if (ret < 0) return ret; #ifdef CONFIG_SWITCH snd_soc_jack_notifier_register(&tegra_max98095_hp_jack, &headset_switch_nb); #else /*gpio based headset detection*/ snd_soc_jack_add_pins(&tegra_max98095_hp_jack, ARRAY_SIZE(tegra_max98095_hp_jack_pins), tegra_max98095_hp_jack_pins); #endif ret = tegra_asoc_utils_register_ctls(&machine->util_data); if (ret < 0) return ret; /* max98095_headset_detect(codec, &tegra_max98095_hp_jack, SND_JACK_HEADSET); */ snd_soc_dapm_nc_pin(dapm, "INA1"); snd_soc_dapm_nc_pin(dapm, "INA2"); snd_soc_dapm_nc_pin(dapm, "INB1"); snd_soc_dapm_nc_pin(dapm, "INB2"); snd_soc_dapm_sync(dapm); return 0; }
static void tab3_mic_id(void *data, u16 status) { struct wm1811_machine_priv *wm1811 = data; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(wm1811->codec); int report; int reg; bool present; wake_lock_timeout(&wm1811->jackdet_wake_lock, 5 * HZ); /* Either nothing present or just starting detection */ if (!(status & WM8958_MICD_STS)) { if (!wm8994->jackdet) { /* If nothing present then clear our statuses */ dev_dbg(wm1811->codec->dev, "Detected open circuit\n"); wm8994->jack_mic = false; wm8994->mic_detecting = true; tab3_micd_set_rate(wm1811->codec); snd_soc_jack_report(wm8994->micdet[0].jack, 0, wm8994->btn_mask | SND_JACK_HEADSET); } /*ToDo*/ /*return;*/ } /* If the measurement is showing a high impedence we've got a * microphone. */ if (wm8994->mic_detecting && (status & 0x400)) { dev_info(wm1811->codec->dev, "Detected microphone\n"); wm8994->mic_detecting = false; wm8994->jack_mic = true; tab3_micd_set_rate(wm1811->codec); snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADSET, SND_JACK_HEADSET); } if (wm8994->mic_detecting && status & 0x4) { dev_info(wm1811->codec->dev, "Detected headphone\n"); wm8994->mic_detecting = false; tab3_micd_set_rate(wm1811->codec); snd_soc_jack_report(wm8994->micdet[0].jack, SND_JACK_HEADPHONE, SND_JACK_HEADSET); /* If we have jackdet that will detect removal */ if (wm8994->jackdet) { mutex_lock(&wm8994->accdet_lock); snd_soc_update_bits(wm1811->codec, WM8958_MIC_DETECT_1, WM8958_MICD_ENA, 0); if (wm8994->active_refcount) { snd_soc_update_bits(wm1811->codec, WM8994_ANTIPOP_2, WM1811_JACKDET_MODE_MASK, WM1811_JACKDET_MODE_AUDIO); } mutex_unlock(&wm8994->accdet_lock); if (wm8994->pdata->jd_ext_cap) { mutex_lock(&wm1811->codec->mutex); snd_soc_dapm_disable_pin(&wm1811->codec->dapm, "MICBIAS2"); snd_soc_dapm_sync(&wm1811->codec->dapm); mutex_unlock(&wm1811->codec->mutex); } } } }
static void msm_enable_ext_spk_amp_gpio(u32 spk_amp_gpio) { int ret = 0; struct pm_gpio param = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .output_value = 1, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_MED, .function = PM_GPIO_FUNC_NORMAL, }; if (spk_amp_gpio == bottom_spk_pamp_gpio) { ret = gpio_request(bottom_spk_pamp_gpio, "BOTTOM_SPK_AMP"); if (ret) { pr_err("%s: Error requesting BOTTOM SPK AMP GPIO %u\n", __func__, bottom_spk_pamp_gpio); return; } ret = pm8xxx_gpio_config(bottom_spk_pamp_gpio, ¶m); if (ret) pr_err("%s: Failed to configure Bottom Spk Ampl" " gpio %u\n", __func__, bottom_spk_pamp_gpio); else { pr_debug("%s: enable Bottom spkr amp gpio\n", __func__); gpio_direction_output(bottom_spk_pamp_gpio, 1); } } else if (spk_amp_gpio == top_spk_pamp_gpio) { ret = gpio_request(top_spk_pamp_gpio, "TOP_SPK_AMP"); if (ret) { pr_err("%s: Error requesting GPIO %d\n", __func__, top_spk_pamp_gpio); return; } ret = pm8xxx_gpio_config(top_spk_pamp_gpio, ¶m); if (ret) pr_err("%s: Failed to configure Top Spk Ampl" " gpio %u\n", __func__, top_spk_pamp_gpio); else { pr_debug("%s: enable Top spkr amp gpio\n", __func__); gpio_direction_output(top_spk_pamp_gpio, 1); } } else if (spk_amp_gpio == DOCK_SPK_PAMP_GPIO) { ret = gpio_request(DOCK_SPK_PAMP_GPIO, "DOCK_SPK_AMP"); if (ret) { pr_err("%s: Error requesting GPIO %d\n", __func__, DOCK_SPK_PAMP_GPIO); return; } ret = pm8xxx_gpio_config(DOCK_SPK_PAMP_GPIO, ¶m); if (ret) pr_err("%s: Failed to configure Dock Spk Ampl" " gpio %u\n", __func__, DOCK_SPK_PAMP_GPIO); else { pr_debug("%s: enable dock amp gpio\n", __func__); gpio_direction_output(DOCK_SPK_PAMP_GPIO, 1); } ret = gpio_request(USB_ID_ADC_GPIO, "USB_ID_ADC"); if (ret) { pr_err("%s: Error requesting USB_ID_ADC PMIC GPIO %u\n", __func__, USB_ID_ADC_GPIO); return; } ret = pm8xxx_gpio_config(USB_ID_ADC_GPIO, ¶m); if (ret) pr_err("%s: Failed to configure USB_ID_ADC PMIC" " gpio %u\n", __func__, USB_ID_ADC_GPIO); } else { pr_err("%s: ERROR : Invalid External Speaker Ampl GPIO." " gpio = %u\n", __func__, spk_amp_gpio); return; } } static void msm_ext_spk_power_amp_on(u32 spk) { if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) { if ((msm_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) && (msm_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) { pr_debug("%s() External Bottom Speaker Ampl already " "turned on. spk = 0x%08x\n", __func__, spk); return; } msm_ext_bottom_spk_pamp |= spk; if ((msm_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) && (msm_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) { msm_enable_ext_spk_amp_gpio(bottom_spk_pamp_gpio); pr_debug("%s: slepping 4 ms after turning on external " " Bottom Speaker Ampl\n", __func__); usleep_range(4000, 4000); } } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) { if ((msm_ext_top_spk_pamp & TOP_SPK_AMP_POS) && (msm_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) { pr_debug("%s() External Top Speaker Ampl already" "turned on. spk = 0x%08x\n", __func__, spk); return; } msm_ext_top_spk_pamp |= spk; if ((msm_ext_top_spk_pamp & TOP_SPK_AMP_POS) && (msm_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) { msm_enable_ext_spk_amp_gpio(top_spk_pamp_gpio); pr_debug("%s: sleeping 4 ms after turning on " " external HAC Ampl\n", __func__); usleep_range(4000, 4000); } } else if (spk & (DOCK_SPK_AMP_POS | DOCK_SPK_AMP_NEG)) { mutex_lock(&audio_notifier_lock); if ((msm_ext_dock_spk_pamp & DOCK_SPK_AMP_POS) && (msm_ext_dock_spk_pamp & DOCK_SPK_AMP_NEG)) { pr_debug("%s() External Dock Speaker Ampl already" "turned on. spk = 0x%08x\n", __func__, spk); return; } msm_ext_dock_spk_pamp |= spk; if ((msm_ext_dock_spk_pamp & DOCK_SPK_AMP_POS) && (msm_ext_dock_spk_pamp & DOCK_SPK_AMP_NEG)) { msm_enable_ext_spk_amp_gpio(DOCK_SPK_PAMP_GPIO); pr_debug("%s: sleeping 4 ms after turning on " " external DOCK Ampl\n", __func__); usleep_range(4000, 4000); } mutex_unlock(&audio_notifier_lock); } else { pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n", __func__, spk); return; } } static void msm_ext_spk_power_amp_off(u32 spk) { struct pm_gpio param = { .direction = PM_GPIO_DIR_IN, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_MED, .function = PM_GPIO_FUNC_NORMAL, }; pr_debug("%s, spk = %d\n", __func__, spk); if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) { if (!msm_ext_bottom_spk_pamp) return; gpio_direction_output(bottom_spk_pamp_gpio, 0); gpio_free(bottom_spk_pamp_gpio); msm_ext_bottom_spk_pamp = 0; pr_debug("%s: sleeping 4 ms after turning off external Bottom" " Speaker Ampl\n", __func__); usleep_range(4000, 4000); } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) { if (!msm_ext_top_spk_pamp) return; gpio_direction_output(top_spk_pamp_gpio, 0); gpio_free(top_spk_pamp_gpio); msm_ext_top_spk_pamp = 0; pr_debug("%s: sleeping 4 ms after turning off external" " HAC Ampl\n", __func__); usleep_range(4000, 4000); } else if (spk & (DOCK_SPK_AMP_POS | DOCK_SPK_AMP_NEG)) { mutex_lock(&audio_notifier_lock); if (!msm_ext_dock_spk_pamp) { mutex_unlock(&audio_notifier_lock); return; } gpio_direction_input(DOCK_SPK_PAMP_GPIO); gpio_free(DOCK_SPK_PAMP_GPIO); gpio_direction_input(USB_ID_ADC_GPIO); if (pm8xxx_gpio_config(USB_ID_ADC_GPIO, ¶m)) pr_err("%s: Failed to configure USB_ID_ADC PMIC" " gpio %u\n", __func__, USB_ID_ADC_GPIO); gpio_free(USB_ID_ADC_GPIO); msm_ext_dock_spk_pamp = 0; mutex_unlock(&audio_notifier_lock); pr_debug("%s: sleeping 4 ms after turning off external" " DOCK Ampl\n", __func__); usleep_range(4000, 4000); } else { pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n", __func__, spk); return; } } static void msm_ext_control(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = &codec->dapm; mutex_lock(&dapm->codec->mutex); pr_debug("%s: msm_spk_control = %d", __func__, msm_spk_control); if (msm_spk_control == MSM_SPK_ON) { snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg"); snd_soc_dapm_enable_pin(dapm, "Dock Spk Pos"); snd_soc_dapm_enable_pin(dapm, "Dock Spk Neg"); } else { snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Pos"); snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Neg"); snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Pos"); snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Neg"); snd_soc_dapm_disable_pin(dapm, "Dock Spk Pos"); snd_soc_dapm_disable_pin(dapm, "Dock Spk Neg"); } snd_soc_dapm_sync(dapm); mutex_unlock(&dapm->codec->mutex); } static int msm_get_spk(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { pr_debug("%s: msm_spk_control = %d", __func__, msm_spk_control); ucontrol->value.integer.value[0] = msm_spk_control; return 0; }
static int adav80x_set_sysclk(struct snd_soc_codec *codec, int clk_id, unsigned int freq, int dir) { struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); if (dir == SND_SOC_CLOCK_IN) { switch (clk_id) { case ADAV80X_CLK_XIN: case ADAV80X_CLK_XTAL: case ADAV80X_CLK_MCLKI: case ADAV80X_CLK_PLL1: case ADAV80X_CLK_PLL2: break; default: return -EINVAL; } adav80x->sysclk = freq; if (adav80x->clk_src != clk_id) { unsigned int iclk_ctrl1, iclk_ctrl2; adav80x->clk_src = clk_id; if (clk_id == ADAV80X_CLK_XTAL) clk_id = ADAV80X_CLK_XIN; iclk_ctrl1 = ADAV80X_ICLK_CTRL1_DAC_SRC(clk_id) | ADAV80X_ICLK_CTRL1_ADC_SRC(clk_id) | ADAV80X_ICLK_CTRL1_ICLK2_SRC(clk_id); iclk_ctrl2 = ADAV80X_ICLK_CTRL2_ICLK1_SRC(clk_id); snd_soc_write(codec, ADAV80X_ICLK_CTRL1, iclk_ctrl1); snd_soc_write(codec, ADAV80X_ICLK_CTRL2, iclk_ctrl2); snd_soc_dapm_sync(&codec->dapm); } } else { unsigned int mask; switch (clk_id) { case ADAV80X_CLK_SYSCLK1: case ADAV80X_CLK_SYSCLK2: case ADAV80X_CLK_SYSCLK3: break; default: return -EINVAL; } clk_id -= ADAV80X_CLK_SYSCLK1; mask = ADAV80X_PLL_OUTE_SYSCLKPD(clk_id); if (freq == 0) { snd_soc_update_bits(codec, ADAV80X_PLL_OUTE, mask, mask); adav80x->sysclk_pd[clk_id] = true; } else { snd_soc_update_bits(codec, ADAV80X_PLL_OUTE, mask, 0); adav80x->sysclk_pd[clk_id] = false; } if (adav80x->sysclk_pd[0]) snd_soc_dapm_disable_pin(&codec->dapm, "PLL1"); else snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL1"); if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2]) snd_soc_dapm_disable_pin(&codec->dapm, "PLL2"); else snd_soc_dapm_force_enable_pin(&codec->dapm, "PLL2"); snd_soc_dapm_sync(&codec->dapm); } return 0; }
/* * omap4_aic31xx_init * This function is to initialize the machine Driver. */ static int omap4_aic31xx_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; int ret = 0; int gpiostatus; printk(KERN_INFO "entered the omap4_aic31xx_init function....\n"); #ifdef DRIVER_DAPM_SUPPORT /* Add OMAP4 specific widgets */ ret = snd_soc_dapm_new_controls(codec->dapm, omap4_aic31xx_dapm_widgets, ARRAY_SIZE(omap4_aic31xx_dapm_widgets)); if (ret) { printk (KERN_INFO "snd_soc_dapm_new_controls call failed. returning...\n"); return ret; } DBG ("snd_soc_dapm_new_controls passed..\n"); DBG ("Disabling the DAPM Routes for now...\n"); /* Set up OMAP4 specific audio path audio_map */ ret = snd_soc_dapm_add_routes(codec->dapm, audio_map, ARRAY_SIZE(audio_map)); if (ret != 0) { printk (KERN_INFO "snd_soc_dapm_add_routes failed... %d\n", ret); } /* OMAP4 connected pins */ snd_soc_dapm_enable_pin(codec->dapm, "Ext Mic"); snd_soc_dapm_enable_pin(codec->dapm, "Ext Spk"); snd_soc_dapm_disable_pin(codec->dapm, "Headset Mic"); snd_soc_dapm_disable_pin(codec->dapm, "Headset Stereophone"); /* AIC31XX not connected pins */ snd_soc_dapm_nc_pin(codec->dapm, "AUXL"); snd_soc_dapm_nc_pin(codec->dapm, "AUXR"); snd_soc_dapm_nc_pin(codec->dapm, "CARKITMIC"); snd_soc_dapm_nc_pin(codec->dapm, "DIGIMIC0"); snd_soc_dapm_nc_pin(codec->dapm, "DIGIMIC1");mcbsp_be_hw_params_fixup snd_soc_dapm_nc_pin(codec->dapm, "OUTL"); snd_soc_dapm_nc_pin(codec->dapm, "OUTR"); snd_soc_dapm_nc_pin(codec->dapm, "EARPIECE"); snd_soc_dapm_nc_pin(codec->dapm, "PREDRIVEL"); snd_soc_dapm_nc_pin(codec->dapm, "PREDRIVER"); snd_soc_dapm_nc_pin(codec->dapm, "CARKITL"); snd_soc_dapm_nc_pin(codec->dapm, "CARKITR"); ret = snd_soc_dapm_sync(codec->dapm); if (ret != 0) { printk (KERN_INFO "snd_soc_dapm_sync failed... %d\n", ret); return ret; } printk (KERN_INFO "snd_soc_dapm_sync passed..\n");mcbsp_be_hw_params_fixup /* Headset jack detection */ ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &hs_jack); if (ret != 0) { printk (KERN_INFO "snd_soc_jack_new failed...\n"); return ret; } ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), hs_jack_pins); if (ret != 0) { printk (KERN_INFO "snd_soc_jack_add_pins failed... %d\n", ret); return ret; } ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), hs_jack_gpios); #endif /* Headset jack detection */ gpiostatus = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &hs_jack); if (gpiostatus != 0) { printk (KERN_INFO "snd_soc_jack_new failed. %d..\n", gpiostatus); } gpiostatus = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), hs_jack_pins); if (gpiostatus != 0) { printk (KERN_INFO "snd_soc_jack_add_pins failed... %d\n", gpiostatus); } gpiostatus = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), hs_jack_gpios); if (gpiostatus != 0) printk (KERN_INFO "snd_soc_jack_add_gpios failed..%d\n", gpiostatus); DBG ("%s: Exiting \n", __func__); return ret; }