static int map_late_probe(struct snd_soc_card *card) { int ret; struct snd_soc_codec *codec = card->rtd[0].codec; ret = snd_soc_jack_new(codec, "Headset", SND_JACK_HEADSET, &hs_jack); if (ret) return ret; if (headset_detect) { ret = headset_detect(&hs_jack); if (ret) return ret; } ret = snd_soc_jack_new(codec, "Hook", SND_JACK_HEADSET, &hk_jack); if (ret) return ret; snd_jack_set_key(hk_jack.jack, SND_JACK_BTN_0, KEY_MEDIA); snd_jack_set_key(hk_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); snd_jack_set_key(hk_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); if (hook_detect) { ret = hook_detect(&hk_jack); if (ret) return ret; } return 0; }
static int sdm845_dai_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_component *component; struct snd_soc_dai_link *dai_link = rtd->dai_link; struct snd_soc_card *card = rtd->card; struct sdm845_snd_data *pdata = snd_soc_card_get_drvdata(card); int i, rval; if (!pdata->jack_setup) { struct snd_jack *jack; rval = snd_soc_card_jack_new(card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_HEADPHONE | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3, &pdata->jack, NULL, 0); if (rval < 0) { dev_err(card->dev, "Unable to add Headphone Jack\n"); return rval; } jack = pdata->jack.jack; snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP); snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); pdata->jack_setup = true; } for (i = 0 ; i < dai_link->num_codecs; i++) { struct snd_soc_dai *dai = rtd->codec_dais[i]; component = dai->component; rval = snd_soc_component_set_jack( component, &pdata->jack, NULL); if (rval != 0 && rval != -ENOTSUPP) { dev_warn(card->dev, "Failed to set jack: %d\n", rval); return rval; } } return 0; }
static int rt5512_headset_keys(struct snd_soc_jack *jack) { int err = 0; err = snd_jack_set_key(jack->jack, SND_JACK_BTN_0, 0x80); if (err) return err; err = snd_jack_set_key(jack->jack, SND_JACK_BTN_1, 0x81); if (err) return err; err = snd_jack_set_key(jack->jack, SND_JACK_BTN_2, 0x82); if (err) return err; return 0; }
/** * snd_hda_jack_add_kctl - Add a kctl for the given pin * @codec: the HDA codec * @nid: pin NID to assign * @name: string name for the jack * @phantom_jack: flag to deal as a phantom jack * @type: jack type bits to be reported, 0 for guessing from pincfg * @keymap: optional jack / key mapping * * This assigns a jack-detection kctl to the given pin. The kcontrol * will have the given name and index. */ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, const char *name, bool phantom_jack, int type, const struct hda_jack_keymap *keymap) { struct hda_jack_tbl *jack; const struct hda_jack_keymap *map; int err, state, buttons; jack = snd_hda_jack_tbl_new(codec, nid); if (!jack) return 0; if (jack->jack) return 0; /* already created */ if (!type) type = get_input_jack_type(codec, nid); buttons = 0; if (keymap) { for (map = keymap; map->type; map++) buttons |= map->type; } err = snd_jack_new(codec->card, name, type | buttons, &jack->jack, true, phantom_jack); if (err < 0) return err; jack->phantom_jack = !!phantom_jack; jack->type = type; jack->button_state = 0; jack->jack->private_data = jack; jack->jack->private_free = hda_free_jack_priv; if (keymap) { for (map = keymap; map->type; map++) snd_jack_set_key(jack->jack, map->type, map->key); } state = snd_hda_jack_detect(codec, nid); snd_jack_report(jack->jack, state ? jack->type : 0); return 0; }
static int snd_ctp_jack_init(struct snd_soc_pcm_runtime *runtime, bool jack_supported) { int ret, irq; struct ctp_mc_private *ctx = snd_soc_card_get_drvdata(runtime->card); struct snd_soc_jack_gpio *gpio = &hs_gpio[CTP_BTN_GPIO]; struct snd_soc_codec *codec = runtime->codec; if (!jack_supported) return 0; /* Setup the HPDET timer */ INIT_DELAYED_WORK(&ctx->jack_work_insert, headset_insert_poll); INIT_DELAYED_WORK(&ctx->jack_work_remove, headset_remove_poll); /* Headset and button jack detection */ ret = snd_soc_jack_new(codec, "Intel MID Audio Jack", SND_JACK_HEADSET | SND_JACK_BTN_0, &ctx->ctp_jack); if (ret) { pr_err("jack creation failed\n"); return ret; } snd_jack_set_key(ctx->ctp_jack.jack, SND_JACK_BTN_0, KEY_MEDIA); ret = snd_soc_jack_add_gpios(&ctx->ctp_jack, 2, ctx->hs_gpio_ops); if (ret) { pr_err("adding jack GPIO failed\n"); return ret; } irq = gpio_to_irq(gpio->gpio); if (irq < 0) { pr_err("%d:Failed to map gpio_to_irq\n", irq); return irq; } /* Disable Button_press interrupt if no Headset */ pr_err("Disable %d interrupt line\n", irq); disable_irq_nosync(irq); atomic_set(&ctx->bpirq_flag, 0); atomic_set(&ctx->hs_det_retry, HS_DET_RETRY); return 0; }
/** * snd_intelmad_jack- to setup jack settings of the card * * @intelmaddata: pointer to internal context * * This function is called send jack events */ static int snd_intelmad_jack(struct snd_intelmad *intelmaddata) { struct snd_jack *jack; int retval; pr_debug("snd_intelmad_jack called\n"); jack = &intelmaddata->jack[0].jack; snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PHONE); retval = snd_jack_new(intelmaddata->card, "Intel(R) MID Audio Jack", SND_JACK_HEADPHONE | SND_JACK_HEADSET | SW_JACK_PHYSICAL_INSERT | SND_JACK_BTN_0 | SND_JACK_BTN_1, &jack); pr_debug("snd_intelmad_jack called\n"); if (retval < 0) return retval; snd_jack_report(jack, 0); jack->private_data = jack; intelmaddata->jack[0].jack = *jack; return retval; }
static int msm8930_audrx_init(struct snd_soc_pcm_runtime *rtd) { int err, ret; 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; } ret = snd_jack_set_key(button_jack.jack, SND_JACK_BTN_0, KEY_MEDIA); if (ret) { pr_err("%s: Failed to set code for btn-0\n", __func__); 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; }
static int midas_wm1811_init_paiftx(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct wm1811_machine_priv *wm1811 = snd_soc_card_get_drvdata(codec->card); struct snd_soc_dai *aif1_dai = rtd->codec_dai; struct wm8994 *control = codec->control_data; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int ret; #ifdef SND_USE_BIAS_LEVEL midas_aif1_dai = aif1_dai; #endif #ifdef CONFIG_MACH_GC1 wm1811_codec = codec; #endif midas_snd_set_mclk(true, false); rtd->codec_dai->driver->playback.channels_max = rtd->cpu_dai->driver->playback.channels_max; ret = snd_soc_add_controls(codec, midas_controls, ARRAY_SIZE(midas_controls)); ret = snd_soc_dapm_new_controls(&codec->dapm, midas_dapm_widgets, ARRAY_SIZE(midas_dapm_widgets)); if (ret != 0) dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret); ret = snd_soc_dapm_add_routes(&codec->dapm, midas_dapm_routes, ARRAY_SIZE(midas_dapm_routes)); if (ret != 0) dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret); ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2, MIDAS_DEFAULT_MCLK2, SND_SOC_CLOCK_IN); if (ret < 0) dev_err(codec->dev, "Failed to boot clocking\n"); /* Force AIF1CLK on as it will be master for jack detection */ if (wm8994->revision > 1) { ret = snd_soc_dapm_force_enable_pin(&codec->dapm, "AIF1CLK"); if (ret < 0) dev_err(codec->dev, "Failed to enable AIF1CLK: %d\n", ret); } ret = snd_soc_dapm_disable_pin(&codec->dapm, "S5P RP"); if (ret < 0) dev_err(codec->dev, "Failed to disable S5P RP: %d\n", ret); snd_soc_dapm_ignore_suspend(&codec->dapm, "RCV"); snd_soc_dapm_ignore_suspend(&codec->dapm, "SPK"); snd_soc_dapm_ignore_suspend(&codec->dapm, "HP"); snd_soc_dapm_ignore_suspend(&codec->dapm, "Headset Mic"); snd_soc_dapm_ignore_suspend(&codec->dapm, "Sub Mic"); snd_soc_dapm_ignore_suspend(&codec->dapm, "Main Mic"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1DACDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2DACDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3DACDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1ADCDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2ADCDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3ADCDAT"); snd_soc_dapm_ignore_suspend(&codec->dapm, "FM In"); snd_soc_dapm_ignore_suspend(&codec->dapm, "LINE"); snd_soc_dapm_ignore_suspend(&codec->dapm, "HDMI"); snd_soc_dapm_ignore_suspend(&codec->dapm, "Third Mic"); wm1811->codec = codec; midas_micd_set_rate(codec); #ifdef CONFIG_SEC_DEV_JACK /* By default use idle_bias_off, will override for WM8994 */ codec->dapm.idle_bias_off = 0; #else /* CONFIG_SEC_DEV_JACK */ wm1811->jack.status = 0; ret = snd_soc_jack_new(codec, "Midas Jack", SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, &wm1811->jack); if (ret < 0) dev_err(codec->dev, "Failed to create jack: %d\n", ret); ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_0, KEY_MEDIA); if (ret < 0) dev_err(codec->dev, "Failed to set KEY_MEDIA: %d\n", ret); ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_1, KEY_VOLUMEDOWN); if (ret < 0) dev_err(codec->dev, "Failed to set KEY_VOLUMEUP: %d\n", ret); ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP); if (ret < 0) dev_err(codec->dev, "Failed to set KEY_VOLUMEDOWN: %d\n", ret); if (wm8994->revision > 1) { dev_info(codec->dev, "wm1811: Rev %c support mic detection\n", 'A' + wm8994->revision); ret = wm8958_mic_detect(codec, &wm1811->jack, midas_micdet, wm1811); if (ret < 0) dev_err(codec->dev, "Failed start detection: %d\n", ret); } else { dev_info(codec->dev, "wm1811: Rev %c doesn't support mic detection\n", 'A' + wm8994->revision); codec->dapm.idle_bias_off = 0; } /* To wakeup for earjack event in suspend mode */ enable_irq_wake(control->irq); wake_lock_init(&wm1811->jackdet_wake_lock, WAKE_LOCK_SUSPEND, "midas_jackdet"); /* To support PBA function test */ jack_class = class_create(THIS_MODULE, "audio"); if (IS_ERR(jack_class)) pr_err("Failed to create class\n"); jack_dev = device_create(jack_class, NULL, 0, codec, "earjack"); if (device_create_file(jack_dev, &dev_attr_select_jack) < 0) pr_err("Failed to create device file (%s)!\n", dev_attr_select_jack.attr.name); if (device_create_file(jack_dev, &dev_attr_key_state) < 0) pr_err("Failed to create device file (%s)!\n", dev_attr_key_state.attr.name); if (device_create_file(jack_dev, &dev_attr_state) < 0) pr_err("Failed to create device file (%s)!\n", dev_attr_state.attr.name); if (device_create_file(jack_dev, &dev_attr_reselect_jack) < 0) pr_err("Failed to create device file (%s)!\n", dev_attr_reselect_jack.attr.name); #endif /* CONFIG_SEC_DEV_JACK */ return snd_soc_dapm_sync(&codec->dapm); }
static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) { struct snd_soc_card *card = runtime->card; struct snd_soc_component *codec = runtime->codec_dai->component; struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card); const struct snd_soc_dapm_route *custom_map; int num_routes; int ret; card->dapm.idle_bias_off = true; /* Start with RC clk for jack-detect (we disable MCLK below) */ if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) snd_soc_component_update_bits(codec, RT5651_GLB_CLK, RT5651_SCLK_SRC_MASK, RT5651_SCLK_SRC_RCCLK); switch (BYT_RT5651_MAP(byt_rt5651_quirk)) { case BYT_RT5651_IN1_MAP: custom_map = byt_rt5651_intmic_in1_map; num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_map); break; case BYT_RT5651_IN2_MAP: custom_map = byt_rt5651_intmic_in2_map; num_routes = ARRAY_SIZE(byt_rt5651_intmic_in2_map); break; case BYT_RT5651_IN1_IN2_MAP: custom_map = byt_rt5651_intmic_in1_in2_map; num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_in2_map); break; default: custom_map = byt_rt5651_intmic_dmic_map; num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic_map); } ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); if (ret) return ret; if (byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) { ret = snd_soc_dapm_add_routes(&card->dapm, byt_rt5651_ssp2_aif2_map, ARRAY_SIZE(byt_rt5651_ssp2_aif2_map)); } else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) { ret = snd_soc_dapm_add_routes(&card->dapm, byt_rt5651_ssp0_aif1_map, ARRAY_SIZE(byt_rt5651_ssp0_aif1_map)); } else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2) { ret = snd_soc_dapm_add_routes(&card->dapm, byt_rt5651_ssp0_aif2_map, ARRAY_SIZE(byt_rt5651_ssp0_aif2_map)); } else { ret = snd_soc_dapm_add_routes(&card->dapm, byt_rt5651_ssp2_aif1_map, ARRAY_SIZE(byt_rt5651_ssp2_aif1_map)); } if (ret) return ret; ret = snd_soc_add_card_controls(card, byt_rt5651_controls, ARRAY_SIZE(byt_rt5651_controls)); if (ret) { dev_err(card->dev, "unable to add card controls\n"); return ret; } snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) { /* * The firmware might enable the clock at * boot (this information may or may not * be reflected in the enable clock register). * To change the rate we must disable the clock * first to cover these cases. Due to common * clock framework restrictions that do not allow * to disable a clock that has not been enabled, * we need to enable the clock first. */ ret = clk_prepare_enable(priv->mclk); if (!ret) clk_disable_unprepare(priv->mclk); if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ) ret = clk_set_rate(priv->mclk, 25000000); else ret = clk_set_rate(priv->mclk, 19200000); if (ret) dev_err(card->dev, "unable to set MCLK rate\n"); } if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) { ret = snd_soc_card_jack_new(runtime->card, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, &priv->jack, bytcr_jack_pins, ARRAY_SIZE(bytcr_jack_pins)); if (ret) { dev_err(runtime->dev, "jack creation failed %d\n", ret); return ret; } snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); ret = snd_soc_component_set_jack(codec, &priv->jack, NULL); if (ret) return ret; } return 0; }
static int msm_soc_dai_init(struct snd_soc_codec *codec) { int ret = 0; struct snd_soc_card *card = codec->socdev->card; struct wm8994_priv *wm8994; ret = msm_new_mixer(codec->card); if (ret < 0) pr_err("%s: ALSA MSM Mixer Fail\n", __func__); wm8994_add_controls(codec); // permanently disable pin snd_soc_dapm_nc_pin(codec, "SPKOUTRN"); snd_soc_dapm_nc_pin(codec, "SPKOUTRP"); snd_soc_dapm_nc_pin(codec, "SPKOUTLN"); snd_soc_dapm_nc_pin(codec, "SPKOUTLP"); snd_soc_dapm_nc_pin(codec, "HPOUT2P"); snd_soc_dapm_nc_pin(codec, "HPOUT2N"); snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP"); snd_soc_dapm_nc_pin(codec, "IN2RN"); snd_soc_dapm_nc_pin(codec, "IN2LN"); snd_soc_dapm_nc_pin(codec, "IN1RN"); snd_soc_dapm_nc_pin(codec, "IN1RP"); snd_soc_dapm_nc_pin(codec, "IN1LN"); #if defined(CONFIG_MACH_TENDERLOIN) snd_soc_dapm_new_controls(codec, tenderloin_dapm_widgets, ARRAY_SIZE(tenderloin_dapm_widgets)); snd_soc_dapm_add_routes(codec, tenderloin_dapm_routes, ARRAY_SIZE(tenderloin_dapm_routes)); #endif // Initially clock from MCLK1 - we will switch over to the FLLs // once we start playing audio but don't have BCLK yet to boot // them. ret = snd_soc_dai_set_sysclk(&codec->dai[0], WM8994_SYSCLK_MCLK1, WM_FLL, 0); if (ret != 0) { pr_err("Failed to set DAI sysclk: %d\n", ret); return ret; } ret = snd_soc_dai_set_sysclk(&codec->dai[1], WM8994_SYSCLK_MCLK1, WM_FLL, 0); if (ret != 0) { pr_err("Failed to set DAI sysclk: %d\n", ret); return ret; } /* Headphone jack detection */ // If we have the HeadSet uart (hs_uart) then we DONT want to detect headphones if ( hs_uart == 1 ) { snd_soc_jack_new(card, "headset", SND_JACK_MICROPHONE | SND_JACK_BTN_0, &hp_jack); } else { snd_soc_jack_new(card, "headset", SND_JACK_HEADPHONE | SND_JACK_MICROPHONE | SND_JACK_BTN_0, &hp_jack); } snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),hp_jack_pins); snd_jack_set_key(hp_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); // mapping button 0 to KEY_PLAYPUASE // Register a notifier with snd_soc_jack jack_notifier.notifier_call = jack_notifier_event; snd_soc_jack_notifier_register(&hp_jack, &jack_notifier); ret = snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), hp_jack_gpios); wm8994 = snd_soc_codec_get_drvdata(codec); if(wm8994) wm8994->soc_jack = &hp_jack; // add headphone switch headphone_switch = kzalloc(sizeof(struct switch_dev), GFP_KERNEL); if (headphone_switch) { headphone_switch->name = "h2w"; headphone_switch->print_name = headphone_switch_print_name; ret = switch_dev_register(headphone_switch); if (ret < 0) { printk(KERN_ERR "Unable to register headphone switch\n"); kfree(headphone_switch); headphone_switch = NULL; } else { headphone_plugged = hp_jack.status ? 1 : 0; printk(KERN_INFO "Headphone switch initialized, plugged=%d\n", headphone_plugged); switch_set_state(headphone_switch, headphone_plugged); } } else { printk(KERN_ERR "Unable to allocate headphone switch\n"); } return ret; }
static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_component *component; struct snd_soc_dai_link *dai_link = rtd->dai_link; struct snd_soc_card *card = rtd->card; struct apq8016_sbc_data *pdata = snd_soc_card_get_drvdata(card); int i, rval; switch (cpu_dai->id) { case MI2S_PRIMARY: writel(readl(pdata->spkr_iomux) | SPKR_CTL_PRI_WS_SLAVE_SEL_11, pdata->spkr_iomux); break; case MI2S_QUATERNARY: /* Configure the Quat MI2S to TLMM */ writel(readl(pdata->mic_iomux) | MIC_CTRL_QUA_WS_SLAVE_SEL_10 | MIC_CTRL_TLMM_SCLK_EN, pdata->mic_iomux); break; case MI2S_TERTIARY: writel(readl(pdata->mic_iomux) | MIC_CTRL_TER_WS_SLAVE_SEL | MIC_CTRL_TLMM_SCLK_EN, pdata->mic_iomux); break; default: dev_err(card->dev, "unsupported cpu dai configuration\n"); return -EINVAL; } if (!pdata->jack_setup) { struct snd_jack *jack; rval = snd_soc_card_jack_new(card, "Headset Jack", SND_JACK_HEADSET | SND_JACK_HEADPHONE | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3 | SND_JACK_BTN_4, &pdata->jack, NULL, 0); if (rval < 0) { dev_err(card->dev, "Unable to add Headphone Jack\n"); return rval; } jack = pdata->jack.jack; snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP); snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); pdata->jack_setup = true; } for (i = 0 ; i < dai_link->num_codecs; i++) { struct snd_soc_dai *dai = rtd->codec_dais[i]; component = dai->component; /* Set default mclk for internal codec */ rval = snd_soc_component_set_sysclk(component, 0, 0, DEFAULT_MCLK_RATE, SND_SOC_CLOCK_IN); if (rval != 0 && rval != -ENOTSUPP) { dev_warn(card->dev, "Failed to set mclk: %d\n", rval); return rval; } rval = snd_soc_component_set_jack(component, &pdata->jack, NULL); if (rval != 0 && rval != -ENOTSUPP) { dev_warn(card->dev, "Failed to set jack: %d\n", rval); return rval; } } return 0; }