Lines Matching +full:headset +full:- +full:detect +full:- +full:gpios
1 // SPDX-License-Identifier: GPL-2.0-only
3 * bytcr_rt5651.c - ASoc Machine driver for Intel Byt CR platform
29 #include <sound/soc-acpi.h>
31 #include "../atom/sst-atom-controls.h"
32 #include "../common/soc-intel-quirks.h"
80 /* jack-detect-source + inv + dmic-en + ovcd-th + -sf + terminating entry */
92 /* Default: jack-detect on JD1_1, internal mic on in2, headsetmic on in3 */
96 static int quirk_override = -1;
98 MODULE_PARM_DESC(quirk, "Board-specific quirk override");
111 dev_info(dev, "quirk realtek,jack-detect-source %ld\n", in log_quirks()
113 dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n", in log_quirks()
115 dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n", in log_quirks()
136 #define BYT_CODEC_DAI1 "rt5651-aif1"
137 #define BYT_CODEC_DAI2 "rt5651-aif2"
157 dev_err(codec_dai->component->dev, "can't set pll: %d\n", ret); in byt_rt5651_prepare_and_enable_pll1()
164 dev_err(codec_dai->component->dev, "can't set clock %d\n", ret); in byt_rt5651_prepare_and_enable_pll1()
174 struct snd_soc_dapm_context *dapm = w->dapm; in platform_clock_control()
175 struct snd_soc_card *card = dapm->card; in platform_clock_control()
184 dev_err(card->dev, in platform_clock_control()
186 return -EIO; in platform_clock_control()
191 ret = clk_prepare_enable(priv->mclk); in platform_clock_control()
193 dev_err(card->dev, in platform_clock_control()
210 clk_disable_unprepare(priv->mclk); in platform_clock_control()
214 dev_err(card->dev, "can't set codec sysclk: %d\n", ret); in platform_clock_control()
224 struct snd_soc_card *card = w->dapm->card; in rt5651_ext_amp_power_event()
228 gpiod_set_value_cansleep(priv->ext_amp_gpio, 1); in rt5651_ext_amp_power_event()
230 gpiod_set_value_cansleep(priv->ext_amp_gpio, 0); in rt5651_ext_amp_power_event()
237 SND_SOC_DAPM_MIC("Headset Mic", NULL),
251 {"Headset Mic", NULL, "Platform Clock"},
257 {"Headset Mic", NULL, "micbias1"}, /* lowercase for rt5651 */
270 {"IN2P", NULL, "Headset Mic"},
276 {"IN3P", NULL, "Headset Mic"},
282 {"IN3P", NULL, "Headset Mic"},
289 {"IN3P", NULL, "Headset Mic"},
330 SOC_DAPM_PIN_SWITCH("Headset Mic"),
342 .pin = "Headset Mic",
368 { "hp-detect-gpios", &pov_p1006w_hp_detect, 1, },
369 { "ext-amp-enable-gpios", &pov_p1006w_ext_amp_en, 1, },
375 byt_rt5651_quirk = (unsigned long)id->driver_data; in byt_rt5651_pov_p1006w_quirk_cb()
382 byt_rt5651_quirk = (unsigned long)id->driver_data; in byt_rt5651_quirk_cb()
424 /* I.T.Works TW701, Ployer Momo7w and Trekstor ST70416-6
522 props[cnt++] = PROPERTY_ENTRY_U32("realtek,jack-detect-source", in byt_rt5651_add_codec_device_props()
525 props[cnt++] = PROPERTY_ENTRY_U32("realtek,over-current-threshold-microamp", in byt_rt5651_add_codec_device_props()
528 props[cnt++] = PROPERTY_ENTRY_U32("realtek,over-current-scale-factor", in byt_rt5651_add_codec_device_props()
532 props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,dmic-en"); in byt_rt5651_add_codec_device_props()
535 props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted"); in byt_rt5651_add_codec_device_props()
542 struct snd_soc_card *card = runtime->card; in byt_rt5651_init()
543 struct snd_soc_component *codec = asoc_rtd_to_codec(runtime, 0)->component; in byt_rt5651_init()
550 card->dapm.idle_bias_off = true; in byt_rt5651_init()
552 /* Start with RC clk for jack-detect (we disable MCLK below) */ in byt_rt5651_init()
574 ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes); in byt_rt5651_init()
579 ret = snd_soc_dapm_add_routes(&card->dapm, in byt_rt5651_init()
583 ret = snd_soc_dapm_add_routes(&card->dapm, in byt_rt5651_init()
587 ret = snd_soc_dapm_add_routes(&card->dapm, in byt_rt5651_init()
591 ret = snd_soc_dapm_add_routes(&card->dapm, in byt_rt5651_init()
601 dev_err(card->dev, "unable to add card controls\n"); in byt_rt5651_init()
616 ret = clk_prepare_enable(priv->mclk); in byt_rt5651_init()
618 clk_disable_unprepare(priv->mclk); in byt_rt5651_init()
621 ret = clk_set_rate(priv->mclk, 25000000); in byt_rt5651_init()
623 ret = clk_set_rate(priv->mclk, 19200000); in byt_rt5651_init()
626 dev_err(card->dev, "unable to set MCLK rate\n"); in byt_rt5651_init()
632 else if (priv->hp_detect) in byt_rt5651_init()
636 ret = snd_soc_card_jack_new(runtime->card, "Headset", in byt_rt5651_init()
637 report, &priv->jack, bytcr_jack_pins, in byt_rt5651_init()
640 dev_err(runtime->dev, "jack creation failed %d\n", ret); in byt_rt5651_init()
645 snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0, in byt_rt5651_init()
648 ret = snd_soc_component_set_jack(codec, &priv->jack, in byt_rt5651_init()
649 priv->hp_detect); in byt_rt5651_init()
667 rate->min = rate->max = 48000; in byt_rt5651_codec_fixup()
668 channels->min = channels->max = 2; in byt_rt5651_codec_fixup()
672 /* set SSP0 to 16-bit */ in byt_rt5651_codec_fixup()
676 /* set SSP2 to 24-bit */ in byt_rt5651_codec_fixup()
693 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); in byt_rt5651_codec_fixup()
699 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); in byt_rt5651_codec_fixup()
717 return snd_pcm_hw_constraint_list(substream->runtime, 0, in byt_rt5651_aif1_startup()
734 DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
737 DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
740 DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
742 DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5651:00", "rt5651-aif1")));
745 DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
759 .name = "Deep-Buffer Audio Port",
760 .stream_name = "Deep-Buffer Audio",
767 /* CODEC<->CODEC link */
770 .name = "SSP2-Codec",
788 static char byt_rt5651_long_name[50]; /* = "bytcr-rt5651-*-spk-*-mic[-swapped-hp]" */
790 static char byt_rt5651_components[50]; /* = "cfg-spk:* cfg-mic:*" */
800 if (!strcmp(component->name, byt_rt5651_codec_name)) { in byt_rt5651_suspend()
801 dev_dbg(component->dev, "disabling jack detect before suspend\n"); in byt_rt5651_suspend()
819 if (!strcmp(component->name, byt_rt5651_codec_name)) { in byt_rt5651_resume()
820 dev_dbg(component->dev, "re-enabling jack detect after resume\n"); in byt_rt5651_resume()
821 snd_soc_component_set_jack(component, &priv->jack, in byt_rt5651_resume()
822 priv->hp_detect); in byt_rt5651_resume()
832 #define CARD_NAME "bytcht rt5651" /* card name will be 'sof-bytcht rt5651' */
835 #define CARD_NAME "bytcr-rt5651"
860 * We want the GpioIo one for the ext-amp-enable-gpio.
862 { "ext-amp-enable-gpios", &ext_amp_enable_gpios, 1, ACPI_GPIO_QUIRK_ONLY_GPIOIO },
884 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in snd_byt_rt5651_mc_probe()
886 return -ENOMEM; in snd_byt_rt5651_mc_probe()
889 byt_rt5651_card.dev = &pdev->dev; in snd_byt_rt5651_mc_probe()
891 mach = byt_rt5651_card.dev->platform_data; in snd_byt_rt5651_mc_probe()
896 if (!strcmp(byt_rt5651_dais[i].codecs->name, in snd_byt_rt5651_mc_probe()
897 "i2c-10EC5651:00")) { in snd_byt_rt5651_mc_probe()
904 adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1); in snd_byt_rt5651_mc_probe()
907 "i2c-%s", acpi_dev_name(adev)); in snd_byt_rt5651_mc_probe()
908 put_device(&adev->dev); in snd_byt_rt5651_mc_probe()
909 byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name; in snd_byt_rt5651_mc_probe()
911 dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id); in snd_byt_rt5651_mc_probe()
912 return -ENODEV; in snd_byt_rt5651_mc_probe()
918 return -EPROBE_DEFER; in snd_byt_rt5651_mc_probe()
925 if (mach->mach_params.acpi_ipc_irq_index == 0) in snd_byt_rt5651_mc_probe()
935 * with the codec driver/pdata are non-existent in snd_byt_rt5651_mc_probe()
940 /* format specified: 2 64-bit integers */ in snd_byt_rt5651_mc_probe()
955 pkg_found = snd_soc_acpi_find_package_from_hid(mach->id, in snd_byt_rt5651_mc_probe()
959 dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n"); in snd_byt_rt5651_mc_probe()
962 dev_info(&pdev->dev, "BIOS Routing: AIF2 connected\n"); in snd_byt_rt5651_mc_probe()
965 dev_info(&pdev->dev, "BIOS Routing isn't valid, ignored\n"); in snd_byt_rt5651_mc_probe()
971 /* no BIOS indications, assume SSP0-AIF2 connection */ in snd_byt_rt5651_mc_probe()
979 if (quirk_override != -1) { in snd_byt_rt5651_mc_probe()
980 dev_info(&pdev->dev, "Overriding quirk 0x%lx => 0x%x\n", in snd_byt_rt5651_mc_probe()
998 priv->ext_amp_gpio = devm_fwnode_gpiod_get(&pdev->dev, in snd_byt_rt5651_mc_probe()
999 codec_dev->fwnode, in snd_byt_rt5651_mc_probe()
1000 "ext-amp-enable", in snd_byt_rt5651_mc_probe()
1002 "speaker-amp"); in snd_byt_rt5651_mc_probe()
1003 if (IS_ERR(priv->ext_amp_gpio)) { in snd_byt_rt5651_mc_probe()
1004 ret_val = PTR_ERR(priv->ext_amp_gpio); in snd_byt_rt5651_mc_probe()
1006 case -ENOENT: in snd_byt_rt5651_mc_probe()
1007 priv->ext_amp_gpio = NULL; in snd_byt_rt5651_mc_probe()
1010 dev_err(&pdev->dev, "Failed to get ext-amp-enable GPIO: %d\n", in snd_byt_rt5651_mc_probe()
1013 case -EPROBE_DEFER: in snd_byt_rt5651_mc_probe()
1018 priv->hp_detect = devm_fwnode_gpiod_get(&pdev->dev, in snd_byt_rt5651_mc_probe()
1019 codec_dev->fwnode, in snd_byt_rt5651_mc_probe()
1020 "hp-detect", in snd_byt_rt5651_mc_probe()
1022 "hp-detect"); in snd_byt_rt5651_mc_probe()
1023 if (IS_ERR(priv->hp_detect)) { in snd_byt_rt5651_mc_probe()
1024 ret_val = PTR_ERR(priv->hp_detect); in snd_byt_rt5651_mc_probe()
1026 case -ENOENT: in snd_byt_rt5651_mc_probe()
1027 priv->hp_detect = NULL; in snd_byt_rt5651_mc_probe()
1030 dev_err(&pdev->dev, "Failed to get hp-detect GPIO: %d\n", in snd_byt_rt5651_mc_probe()
1033 case -EPROBE_DEFER: in snd_byt_rt5651_mc_probe()
1042 log_quirks(&pdev->dev); in snd_byt_rt5651_mc_probe()
1046 byt_rt5651_dais[dai_index].codecs->dai_name = "rt5651-aif2"; in snd_byt_rt5651_mc_probe()
1050 byt_rt5651_dais[dai_index].cpus->dai_name = "ssp0-port"; in snd_byt_rt5651_mc_probe()
1053 priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); in snd_byt_rt5651_mc_probe()
1054 if (IS_ERR(priv->mclk)) { in snd_byt_rt5651_mc_probe()
1055 ret_val = PTR_ERR(priv->mclk); in snd_byt_rt5651_mc_probe()
1056 dev_err(&pdev->dev, in snd_byt_rt5651_mc_probe()
1060 * Fall back to bit clock usage for -ENOENT (clock not in snd_byt_rt5651_mc_probe()
1062 * for all other errors, including -EPROBE_DEFER in snd_byt_rt5651_mc_probe()
1064 if (ret_val != -ENOENT) in snd_byt_rt5651_mc_probe()
1071 "cfg-spk:%s cfg-mic:%s%s", in snd_byt_rt5651_mc_probe()
1075 " cfg-hp:lrswap" : ""); in snd_byt_rt5651_mc_probe()
1079 "bytcr-rt5651-%s-spk-%s-mic%s", in snd_byt_rt5651_mc_probe()
1084 "-hp-swapped" : ""); in snd_byt_rt5651_mc_probe()
1089 platform_name = mach->mach_params.platform; in snd_byt_rt5651_mc_probe()
1096 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5651_card); in snd_byt_rt5651_mc_probe()
1099 dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n", in snd_byt_rt5651_mc_probe()
1120 MODULE_AUTHOR("Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>");