static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_card *card = rtd->card; int ret; /* Codec is ready, now add/activate board specific controls */ /* Store a pointer to the codec structure for tty ldisc use */ cx20442_codec = codec; /* Set up digital mute if not provided by the codec */ if (!codec_dai->driver->ops) { codec_dai->driver->ops = &ams_delta_dai_ops; } else { ams_delta_ops.startup = ams_delta_startup; ams_delta_ops.shutdown = ams_delta_shutdown; } /* Set codec bias level */ ams_delta_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY); /* Add hook switch - can be used to control the codec from userspace * even if line discipline fails */ ret = snd_soc_jack_new(rtd->codec, "hook_switch", SND_JACK_HEADSET, &ams_delta_hook_switch); if (ret) dev_warn(card->dev, "Failed to allocate resources for hook switch, " "will continue without one.\n"); else { ret = snd_soc_jack_add_gpios(&ams_delta_hook_switch, ARRAY_SIZE(ams_delta_hook_switch_gpios), ams_delta_hook_switch_gpios); if (ret) dev_warn(card->dev, "Failed to set up hook switch GPIO line, " "will continue with hook switch inactive.\n"); } /* Register optional line discipline for over the modem control */ ret = tty_register_ldisc(N_V253, &cx81801_ops); if (ret) { dev_warn(card->dev, "Failed to register line discipline, " "will continue without any controls.\n"); return 0; } /* Add board specific DAPM widgets and routes */ ret = snd_soc_dapm_new_controls(dapm, ams_delta_dapm_widgets, ARRAY_SIZE(ams_delta_dapm_widgets)); if (ret) { dev_warn(card->dev, "Failed to register DAPM controls, " "will continue without any.\n"); return 0; } ret = snd_soc_dapm_add_routes(dapm, ams_delta_audio_map, ARRAY_SIZE(ams_delta_audio_map)); if (ret) { dev_warn(card->dev, "Failed to set up DAPM routes, " "will continue with codec default map.\n"); return 0; } /* Set up initial pin constellation */ snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); snd_soc_dapm_enable_pin(dapm, "Earpiece"); snd_soc_dapm_enable_pin(dapm, "Microphone"); snd_soc_dapm_disable_pin(dapm, "Speaker"); snd_soc_dapm_disable_pin(dapm, "AGCIN"); snd_soc_dapm_disable_pin(dapm, "AGCOUT"); /* Add virtual switch */ ret = snd_soc_add_controls(codec, ams_delta_audio_controls, ARRAY_SIZE(ams_delta_audio_controls)); if (ret) dev_warn(card->dev, "Failed to register audio mode control, " "will continue without it.\n"); return 0; }
static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct snd_soc_dapm_context *dapm = &codec->dapm; struct soc_enum *control = (struct soc_enum *)kcontrol->private_value; unsigned short pins; int pin, changed = 0; /* Refuse any mode changes if we are not able to control the codec. */ if (!codec->hw_write) return -EUNATCH; if (ucontrol->value.enumerated.item[0] >= control->max) return -EINVAL; mutex_lock(&codec->mutex); /* Translate selection to bitmap */ pins = ams_delta_audio_mode_pins[ucontrol->value.enumerated.item[0]]; /* Setup pins after corresponding bits if changed */ pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE)); if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) { changed = 1; if (pin) snd_soc_dapm_enable_pin(dapm, "Mouthpiece"); else snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); } pin = !!(pins & (1 << AMS_DELTA_EARPIECE)); if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) { changed = 1; if (pin) snd_soc_dapm_enable_pin(dapm, "Earpiece"); else snd_soc_dapm_disable_pin(dapm, "Earpiece"); } pin = !!(pins & (1 << AMS_DELTA_MICROPHONE)); if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) { changed = 1; if (pin) snd_soc_dapm_enable_pin(dapm, "Microphone"); else snd_soc_dapm_disable_pin(dapm, "Microphone"); } pin = !!(pins & (1 << AMS_DELTA_SPEAKER)); if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) { changed = 1; if (pin) snd_soc_dapm_enable_pin(dapm, "Speaker"); else snd_soc_dapm_disable_pin(dapm, "Speaker"); } pin = !!(pins & (1 << AMS_DELTA_AGC)); if (pin != ams_delta_audio_agc) { ams_delta_audio_agc = pin; changed = 1; if (pin) snd_soc_dapm_enable_pin(dapm, "AGCIN"); else snd_soc_dapm_disable_pin(dapm, "AGCIN"); } if (changed) snd_soc_dapm_sync(dapm); mutex_unlock(&codec->mutex); return changed; }
static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct twl6040 *twl6040 = codec->control_data; struct snd_soc_dapm_context *dapm = &codec->dapm; int hsotrim, left_offset, right_offset, mode, ret; /* Add SDP4430 specific controls */ ret = snd_soc_add_controls(codec, sdp4430_controls, ARRAY_SIZE(sdp4430_controls)); if (ret) return ret; /* Add SDP4430 specific widgets */ ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets, ARRAY_SIZE(sdp4430_twl6040_dapm_widgets)); if (ret) return ret; /* Set up SDP4430 specific audio path audio_map */ snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* SDP4430 connected pins */ snd_soc_dapm_enable_pin(dapm, "Ext Mic"); snd_soc_dapm_enable_pin(dapm, "Ext Spk"); snd_soc_dapm_enable_pin(dapm, "AFML"); snd_soc_dapm_enable_pin(dapm, "AFMR"); snd_soc_dapm_enable_pin(dapm, "Headset Mic"); snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); /* allow audio paths from the audio modem to run during suspend */ snd_soc_dapm_ignore_suspend(dapm, "Ext Mic"); snd_soc_dapm_ignore_suspend(dapm, "Ext Spk"); snd_soc_dapm_ignore_suspend(dapm, "AFML"); snd_soc_dapm_ignore_suspend(dapm, "AFMR"); snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); snd_soc_dapm_ignore_suspend(dapm, "Headset Stereophone"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic 0"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic 1"); snd_soc_dapm_ignore_suspend(dapm, "Digital Mic 2"); ret = snd_soc_dapm_sync(dapm); if (ret) return ret; /* Headset jack detection */ ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, &hs_jack); if (ret) return ret; ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), hs_jack_pins); if (machine_is_omap_4430sdp() || machine_is_omap_tabletblaze() || machine_is_omap4_panda()) twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); else snd_soc_jack_report(&hs_jack, SND_JACK_HEADSET, SND_JACK_HEADSET); /* DC offset cancellation computation */ hsotrim = snd_soc_read(codec, TWL6040_REG_HSOTRIM); right_offset = (hsotrim & TWL6040_HSRO) >> TWL6040_HSRO_OFFSET; left_offset = hsotrim & TWL6040_HSLO; if (twl6040_get_icrev(twl6040) < TWL6040_REV_1_3) /* For ES under ES_1.3 HS step is 2 mV */ mode = 2; else /* For ES_1.3 HS step is 1 mV */ mode = 1; abe_dsp_set_hs_offset(left_offset, right_offset, mode); /* don't wait before switching of HS power */ rtd->pmdown_time = 0; return ret; }
static int msm8930_audrx_init(struct snd_soc_pcm_runtime *rtd) { int err; struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; pr_debug("%s()\n", __func__); snd_soc_dapm_new_controls(dapm, msm8930_dapm_widgets, ARRAY_SIZE(msm8930_dapm_widgets)); if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE) snd_soc_dapm_add_routes(dapm, common_audio_map_sglte, ARRAY_SIZE(common_audio_map_sglte)); else snd_soc_dapm_add_routes(dapm, common_audio_map, ARRAY_SIZE(common_audio_map)); snd_soc_dapm_enable_pin(dapm, "Ext Spk Left Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Left Neg"); snd_soc_dapm_sync(dapm); err = snd_soc_jack_new(codec, "Headset Jack", MSM8930_JACK_TYPES, &hs_jack); if (err) { pr_err("failed to create new jack\n"); return err; } err = snd_soc_jack_new(codec, "Button Jack", SITAR_JACK_BUTTON_MASK, &button_jack); if (err) { pr_err("failed to create new jack\n"); return err; } codec_clk = clk_get(cpu_dai->dev, "osr_clk"); /* * Switch is present only in 8930 CDP and SGLTE */ if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE || machine_is_msm8930_cdp()) mbhc_cfg.swap_gnd_mic = msm8930_swap_gnd_mic; if (socinfo_get_platform_subtype() == PLATFORM_SUBTYPE_SGLTE) { mbhc_cfg.gpio = GPIO_HS_DET_SGLTE; mbhc_cfg.gpio_level_insert = 0; } else mbhc_cfg.gpio = GPIO_HS_DET; /* * GPIO for headset detect is present in all devices * MTP/Fluid/CDP/SGLTE */ err = gpio_request(mbhc_cfg.gpio, "HEADSET_DETECT"); if (err) { pr_err("%s: Failed to request gpio %d\n", __func__, mbhc_cfg.gpio); return err; } mbhc_cfg.gpio_irq = gpio_to_irq(mbhc_cfg.gpio); sitar_hs_detect(codec, &mbhc_cfg); if (socinfo_get_pmic_model() != PMIC_MODEL_PM8917) { /* Initialize default PMIC speaker gain */ pm8xxx_spk_gain(DEFAULT_PMIC_SPK_GAIN); } return 0; }
void tegra_ext_control(struct snd_soc_codec *codec, int new_con) { struct tegra_audio_data* audio_data = codec->socdev->codec_data; #if defined(CONFIG_MACH_ACER_PICASSO) || defined(CONFIG_MACH_ACER_MAYA) || defined(CONFIG_MACH_ACER_VANGOGH) int CtrlReg = 0; #endif /* Disconnect old codec routes and connect new routes*/ #ifdef MACH_ACER_AUDIO if (new_con & (TEGRA_HEADPHONE | TEGRA_VOIP_RINGTONE)) #else if (new_con & TEGRA_HEADPHONE) #endif snd_soc_dapm_enable_pin(codec, "Headphone"); else snd_soc_dapm_disable_pin(codec, "Headphone"); #if defined(CONFIG_MACH_ACER_PICASSO) || defined(CONFIG_MACH_ACER_MAYA) || defined(CONFIG_MACH_ACER_VANGOGH) if (new_con & (TEGRA_LINEOUT | TEGRA_EAR_SPK | TEGRA_SPK)) snd_soc_dapm_enable_pin(codec, "Lineout"); else snd_soc_dapm_disable_pin(codec, "Lineout"); #else if (new_con & (TEGRA_LINEOUT | TEGRA_EAR_SPK)) snd_soc_dapm_enable_pin(codec, "Lineout"); else snd_soc_dapm_disable_pin(codec, "Lineout"); if (new_con & TEGRA_SPK) snd_soc_dapm_enable_pin(codec, "Int Spk"); else snd_soc_dapm_disable_pin(codec, "Int Spk"); #endif if (new_con & TEGRA_INT_MIC) snd_soc_dapm_enable_pin(codec, "Int Mic"); else snd_soc_dapm_disable_pin(codec, "Int Mic"); if (new_con & TEGRA_EXT_MIC) snd_soc_dapm_enable_pin(codec, "Ext Mic"); else snd_soc_dapm_disable_pin(codec, "Ext Mic"); if (new_con & TEGRA_LINEIN) snd_soc_dapm_enable_pin(codec, "Linein"); else snd_soc_dapm_disable_pin(codec, "Linein"); if (new_con & TEGRA_HEADSET_OUT) snd_soc_dapm_enable_pin(codec, "Headset Out"); else snd_soc_dapm_disable_pin(codec, "Headset Out"); if (new_con & TEGRA_HEADSET_IN) snd_soc_dapm_enable_pin(codec, "Headset In"); else snd_soc_dapm_disable_pin(codec, "Headset In"); #if defined(CONFIG_MACH_ACER_PICASSO) || defined(CONFIG_MACH_ACER_MAYA) || defined(CONFIG_MACH_ACER_VANGOGH) if (new_con & TEGRA_MIC_MUTE) { CtrlReg = snd_soc_read(codec, WM8903_ANALOGUE_LEFT_INPUT_0); CtrlReg |= WM8903_LINMUTE; snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_0, CtrlReg); snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_0, CtrlReg); } else { CtrlReg = snd_soc_read(codec, WM8903_ANALOGUE_LEFT_INPUT_0); CtrlReg &= ~WM8903_LINMUTE; snd_soc_write(codec, WM8903_ANALOGUE_LEFT_INPUT_0, CtrlReg); snd_soc_write(codec, WM8903_ANALOGUE_RIGHT_INPUT_0, CtrlReg); } if (new_con & (TEGRA_HEADPHONE | TEGRA_HEADSET_OUT | TEGRA_HEADSET_IN)) hp_enable(codec, 1); else hp_enable(codec, 0); #endif /* signal a DAPM event */ snd_soc_dapm_sync(codec); audio_data->codec_con = new_con; }
static void pavo_ext_control(struct snd_soc_codec *codec) { int spk = 0, mic = 0, line = 0, hp = 0, hs = 0; /* set up jack connection */ switch (pavo_jack_func) { case PAVO_HP: hp = 1; /* set = unmute headphone */ //set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); //set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); break; case PAVO_MIC: mic = 1; /* reset = mute headphone */ //reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); //reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); break; case PAVO_LINE: line = 1; //reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); //reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); break; case PAVO_HEADSET: hs = 1; mic = 1; //reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); //set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); break; } if (pavo_spk_func == PAVO_SPK_ON) spk = 1; /* set the enpoints to their new connetion states */ if (spk) snd_soc_dapm_enable_pin(codec, "Ext Spk"); else snd_soc_dapm_disable_pin(codec, "Ext Spk"); if (mic) snd_soc_dapm_enable_pin(codec, "Mic Jack"); else snd_soc_dapm_disable_pin(codec, "Mic Jack"); if (line) snd_soc_dapm_enable_pin(codec, "Line Jack"); else snd_soc_dapm_disable_pin(codec, "Line Jack"); if (hp) snd_soc_dapm_enable_pin(codec, "Headphone Jack"); else snd_soc_dapm_disable_pin(codec, "Headphone Jack"); if (hp) snd_soc_dapm_enable_pin(codec, "Headset Jack"); else snd_soc_dapm_disable_pin(codec, "Headset Jack"); /* signal a DAPM event */ snd_soc_dapm_sync(codec);}
static void mdm9615_enable_ext_spk_amp_gpio(u32 spk_amp_gpio) { int ret = 0; struct pm_gpio param = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_CMOS, .output_value = 1, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_MED, .function = PM_GPIO_FUNC_NORMAL, }; if (spk_amp_gpio == bottom_spk_pamp_gpio) { ret = gpio_request(bottom_spk_pamp_gpio, "BOTTOM_SPK_AMP"); if (ret) { pr_err("%s: Error requesting BOTTOM SPK AMP GPIO %u\n", __func__, bottom_spk_pamp_gpio); return; } ret = pm8xxx_gpio_config(bottom_spk_pamp_gpio, ¶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 mdm9615_ext_spk_power_amp_on(u32 spk) { if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) { if ((mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) && (mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) { pr_debug("%s() External Bottom Speaker Ampl already " "turned on. spk = 0x%08x\n", __func__, spk); return; } mdm9615_ext_bottom_spk_pamp |= spk; if ((mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) && (mdm9615_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) { mdm9615_enable_ext_spk_amp_gpio(bottom_spk_pamp_gpio); pr_debug("%s: slepping 4 ms after turning on external " " Bottom Speaker Ampl\n", __func__); usleep_range(4000, 4000); } } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) { if ((mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_POS) && (mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) { pr_debug("%s() External Top Speaker Ampl already" "turned on. spk = 0x%08x\n", __func__, spk); return; } mdm9615_ext_top_spk_pamp |= spk; if ((mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_POS) && (mdm9615_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) { mdm9615_enable_ext_spk_amp_gpio(top_spk_pamp_gpio); pr_debug("%s: sleeping 4 ms after turning on " " external Top Speaker Ampl\n", __func__); usleep_range(4000, 4000); } } else { pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n", __func__, spk); return; } } static void mdm9615_ext_spk_power_amp_off(u32 spk) { if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) { if (!mdm9615_ext_bottom_spk_pamp) return; gpio_direction_output(bottom_spk_pamp_gpio, 0); gpio_free(bottom_spk_pamp_gpio); mdm9615_ext_bottom_spk_pamp = 0; pr_debug("%s: sleeping 4 ms after turning off external Bottom" " Speaker Ampl\n", __func__); usleep_range(4000, 4000); } else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) { if (!mdm9615_ext_top_spk_pamp) return; gpio_direction_output(top_spk_pamp_gpio, 0); gpio_free(top_spk_pamp_gpio); mdm9615_ext_top_spk_pamp = 0; pr_debug("%s: sleeping 4 ms after turning off external Top" " Spkaker Ampl\n", __func__); usleep_range(4000, 4000); } else { pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n", __func__, spk); return; } } static void mdm9615_ext_control(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = &codec->dapm; pr_debug("%s: mdm9615_spk_control = %d", __func__, mdm9615_spk_control); if (mdm9615_spk_control == MDM9615_SPK_ON) { snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg"); } else { snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Pos"); snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Neg"); snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Pos"); snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Neg"); } snd_soc_dapm_sync(dapm); } static int mdm9615_get_spk(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { pr_debug("%s: mdm9615_spk_control = %d", __func__, mdm9615_spk_control); ucontrol->value.integer.value[0] = mdm9615_spk_control; return 0; }
static int msm8960_audrx_init(struct snd_soc_pcm_runtime *rtd) { int err; #ifdef CONFIG_PANTECH_SND //kdkim #if defined(T_EF44S) int ret = 0; #elif defined(T_VEGAPVW) int ret = 0; int hw_rev; #endif #endif struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; #if !(defined(T_EF44S) || defined(T_VEGAPVW)) //Qualcomm original...kdkim other model struct pm_gpio jack_gpio_cfg = { .direction = PM_GPIO_DIR_IN, .pull = PM_GPIO_PULL_DN, .function = PM_GPIO_FUNC_NORMAL, .vin_sel = 2, .inv_int_pol = 0, }; #endif pr_debug("%s()\n", __func__); if (machine_is_msm8960_liquid()) { top_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(19)); bottom_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(18)); } rtd->pmdown_time = 0; err = snd_soc_add_controls(codec, tabla_msm8960_controls, ARRAY_SIZE(tabla_msm8960_controls)); if (err < 0) return err; snd_soc_dapm_new_controls(dapm, msm8960_dapm_widgets, ARRAY_SIZE(msm8960_dapm_widgets)); snd_soc_dapm_add_routes(dapm, common_audio_map, ARRAY_SIZE(common_audio_map)); snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos"); snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg"); snd_soc_dapm_sync(dapm); err = snd_soc_jack_new(codec, "Headset Jack", (SND_JACK_HEADSET | SND_JACK_OC_HPHL | SND_JACK_OC_HPHR), &hs_jack); if (err) { pr_err("failed to create new jack\n"); return err; } err = snd_soc_jack_new(codec, "Button Jack", TABLA_JACK_BUTTON_MASK, &button_jack); if (err) { pr_err("failed to create new jack\n"); return err; } #if defined(T_VEGAPVW) //kdkim hw_rev = get_hw_revision(); pr_debug("########### msm8960 hw_rev : %d\n", hw_rev); if(hw_rev < 4) { mbhc_cfg.gpio = 0; mbhc_cfg.gpio_irq = 0; } #endif #ifdef CONFIG_PANTECH_SND //kdkim #if defined(T_EF44S) || defined(T_VEGAPVW) if (mbhc_cfg.gpio) { ret = gpio_request(JACK_DETECT_GPIO, "headset_detect"); if(ret){ pr_err("%s: gpio_request failed %d\n", __func__, ret); headset_gpio_config = false; gpio_free(JACK_DETECT_GPIO); } ret = gpio_direction_input(mbhc_cfg.gpio); if(ret){ pr_err("%s: gpio_direction_input failed %d\n", __func__, ret); headset_gpio_config = false; gpio_free(JACK_DETECT_GPIO); } mbhc_cfg.gpio_irq = gpio_to_irq(mbhc_cfg.gpio); } #else //Qualcomm original and other model temp if (hs_detect_use_gpio) { mbhc_cfg.gpio = PM8921_GPIO_PM_TO_SYS(JACK_DETECT_GPIO); mbhc_cfg.gpio_irq = JACK_DETECT_INT; } #if defined(T_MAGNUS) mbhc_cfg.gpio = PM8921_GPIO_PM_TO_SYS(JACK_DETECT_GPIO); mbhc_cfg.gpio_irq = JACK_DETECT_INT; #endif if (mbhc_cfg.gpio) { err = pm8xxx_gpio_config(mbhc_cfg.gpio, &jack_gpio_cfg); if (err) { pr_err("%s: pm8xxx_gpio_config failed %d\n", __func__, err); return err; } } #endif #endif mbhc_cfg.read_fw_bin = hs_detect_use_firmware; err = tabla_hs_detect(codec, &mbhc_cfg); return err; } static struct snd_soc_dsp_link lpa_fe_media = { .playback = true, .trigger = { SND_SOC_DSP_TRIGGER_POST, SND_SOC_DSP_TRIGGER_POST }, }; static struct snd_soc_dsp_link fe_media = { .playback = true, .capture = true, .trigger = { SND_SOC_DSP_TRIGGER_POST, SND_SOC_DSP_TRIGGER_POST }, }; /* bi-directional media definition for hostless PCM device */ static struct snd_soc_dsp_link bidir_hl_media = { .playback = true, .capture = true, .trigger = { SND_SOC_DSP_TRIGGER_POST, SND_SOC_DSP_TRIGGER_POST }, }; static struct snd_soc_dsp_link hdmi_rx_hl = { .playback = true, .trigger = { SND_SOC_DSP_TRIGGER_POST, SND_SOC_DSP_TRIGGER_POST }, }; static int msm8960_slim_0_rx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); pr_debug("%s()\n", __func__); rate->min = rate->max = 48000; channels->min = channels->max = msm8960_slim_0_rx_ch; return 0; } static int msm8960_slim_0_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); pr_debug("%s()\n", __func__); rate->min = rate->max = 48000; channels->min = channels->max = msm8960_slim_0_tx_ch; return 0; } static int msm8960_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); pr_debug("%s()\n", __func__); rate->min = rate->max = 48000; return 0; } static int msm8960_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); pr_debug("%s channels->min %u channels->max %u ()\n", __func__, channels->min, channels->max); rate->min = rate->max = 48000; return 0; } static int msm8960_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); rate->min = rate->max = msm8960_btsco_rate; channels->min = channels->max = msm8960_btsco_ch; return 0; } static int msm8960_auxpcm_be_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); /* PCM only supports mono output with 8khz sample rate */ rate->min = rate->max = 8000; channels->min = channels->max = 1; return 0; } static int msm8960_aux_pcm_get_gpios(void) { int ret = 0; pr_debug("%s\n", __func__); ret = gpio_request(GPIO_AUX_PCM_DOUT, "AUX PCM DOUT"); if (ret < 0) { pr_err("%s: Failed to request gpio(%d): AUX PCM DOUT", __func__, GPIO_AUX_PCM_DOUT); goto fail_dout; } ret = gpio_request(GPIO_AUX_PCM_DIN, "AUX PCM DIN"); if (ret < 0) { pr_err("%s: Failed to request gpio(%d): AUX PCM DIN", __func__, GPIO_AUX_PCM_DIN); goto fail_din; } ret = gpio_request(GPIO_AUX_PCM_SYNC, "AUX PCM SYNC"); if (ret < 0) { pr_err("%s: Failed to request gpio(%d): AUX PCM SYNC", __func__, GPIO_AUX_PCM_SYNC); goto fail_sync; } ret = gpio_request(GPIO_AUX_PCM_CLK, "AUX PCM CLK"); if (ret < 0) { pr_err("%s: Failed to request gpio(%d): AUX PCM CLK", __func__, GPIO_AUX_PCM_CLK); goto fail_clk; } return 0; fail_clk: gpio_free(GPIO_AUX_PCM_SYNC); fail_sync: gpio_free(GPIO_AUX_PCM_DIN); fail_din: gpio_free(GPIO_AUX_PCM_DOUT); fail_dout: return ret; } static int msm8960_aux_pcm_free_gpios(void) { gpio_free(GPIO_AUX_PCM_DIN); gpio_free(GPIO_AUX_PCM_DOUT); gpio_free(GPIO_AUX_PCM_SYNC); gpio_free(GPIO_AUX_PCM_CLK); return 0; } static int msm8960_startup(struct snd_pcm_substream *substream) { pr_debug("%s(): substream = %s stream = %d\n", __func__, substream->name, substream->stream); return 0; } static int msm8960_auxpcm_startup(struct snd_pcm_substream *substream) { int ret = 0; pr_debug("%s(): substream = %s\n", __func__, substream->name); ret = msm8960_aux_pcm_get_gpios(); if (ret < 0) { pr_err("%s: Aux PCM GPIO request failed\n", __func__); return -EINVAL; } return 0; } static void msm8960_auxpcm_shutdown(struct snd_pcm_substream *substream) { pr_debug("%s(): substream = %s\n", __func__, substream->name); msm8960_aux_pcm_free_gpios(); }
static int imx_wm8962_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct imx_priv *priv = &card_priv; struct platform_device *pdev = priv->pdev; struct mxc_audio_platform_data *plat = pdev->dev.platform_data; int ret = 0; gcodec = rtd->codec; /* Add imx specific widgets */ snd_soc_dapm_new_controls(&codec->dapm, imx_dapm_widgets, ARRAY_SIZE(imx_dapm_widgets)); /* Set up imx specific audio path audio_map */ snd_soc_dapm_add_routes(&codec->dapm, audio_map, ARRAY_SIZE(audio_map)); snd_soc_dapm_enable_pin(&codec->dapm, "Headphone Jack"); snd_soc_dapm_enable_pin(&codec->dapm, "AMIC"); snd_soc_dapm_sync(&codec->dapm); if (plat->hp_gpio != -1) { priv->hp_irq = gpio_to_irq(plat->hp_gpio); ret = request_irq(priv->hp_irq, imx_headphone_detect_handler, IRQ_TYPE_EDGE_BOTH, pdev->name, priv); if (ret < 0) { ret = -EINVAL; return ret; } ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone); if (ret < 0) { ret = -EINVAL; return ret; } priv->hp_status = gpio_get_value(plat->hp_gpio); /* if headphone is inserted, disable speaker */ if (priv->hp_status != plat->hp_active_low) snd_soc_dapm_nc_pin(&codec->dapm, "Ext Spk"); else snd_soc_dapm_enable_pin(&codec->dapm, "Ext Spk"); } if (plat->mic_gpio != -1) { priv->amic_irq = gpio_to_irq(plat->mic_gpio); ret = request_irq(priv->amic_irq, imx_amic_detect_handler, IRQ_TYPE_EDGE_BOTH, pdev->name, priv); if (ret < 0) { ret = -EINVAL; return ret; } ret = driver_create_file(pdev->dev.driver, &driver_attr_amic); if (ret < 0) { ret = -EINVAL; return ret; } priv->amic_status = gpio_get_value(plat->mic_gpio); /* if amic is inserted, disable DMIC */ if (priv->amic_status != plat->mic_active_low) snd_soc_dapm_nc_pin(&codec->dapm, "DMIC"); else snd_soc_dapm_enable_pin(&codec->dapm, "DMIC"); } else if (!snd_soc_dapm_get_pin_status(&codec->dapm, "DMICDAT")) snd_soc_dapm_nc_pin(&codec->dapm, "DMIC"); return 0; }