Lines Matching +full:clock +full:- +full:error +full:- +full:detect
1 // SPDX-License-Identifier: GPL-2.0-only
3 * byt_cr_dpcm_rt5640.c - ASoc Machine driver for Intel Byt CR platform
30 #include <sound/soc-acpi.h>
31 #include <dt-bindings/sound/rt5640.h>
33 #include "../atom/sst-atom-controls.h"
34 #include "../common/soc-intel-quirks.h"
36 #define BYT_RT5640_FALLBACK_CODEC_DEV_NAME "i2c-rt5640"
78 #define BYT_RT5640_DIFF_MIC BIT(18) /* default is single-ended */
99 /* in-diff or dmic-pin + jdsrc + ovcd-th + -sf + jd-inv + terminating entry */
113 static int quirk_override = -1;
115 MODULE_PARM_DESC(quirk, "Board-specific quirk override");
152 dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
154 dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n",
156 dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n",
190 dev_err(dev, "Invalid routing, bytcr detected but no SSP0-based quirk, audio cannot work with SSP2 on bytcr\n");
241 dev_err(codec_dai->component->dev, "can't set pll: %d\n", ret);
248 dev_err(codec_dai->component->dev, "can't set clock %d\n", ret);
255 #define BYT_CODEC_DAI1 "rt5640-aif1"
256 #define BYT_CODEC_DAI2 "rt5640-aif2"
260 struct snd_soc_card *card = dapm->card;
267 dev_err(card->dev, "Error codec dai not found\n");
275 struct snd_soc_dapm_context *dapm = w->dapm;
276 struct snd_soc_card *card = dapm->card;
283 return -EIO;
286 ret = clk_prepare_enable(priv->mclk);
288 dev_err(card->dev, "could not configure MCLK state\n");
294 * Set codec clock source to internal clock before
295 * turning off the platform clock. Codec needs clock
302 clk_disable_unprepare(priv->mclk);
306 dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
323 * On devices which use line-out as a second headphones output,
324 * the codec's GPIO1 pin is used to enable an external HP-amp.
327 codec_dai = byt_rt5640_get_codec_dai(w->dapm);
329 return -EIO;
334 snd_soc_component_update_bits(codec_dai->component, RT5640_GPIO_CTRL3,
347 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
353 {"Headphone", NULL, "Platform Clock"},
354 {"Headset Mic", NULL, "Platform Clock"},
362 {"Internal Mic", NULL, "Platform Clock"},
367 {"Internal Mic", NULL, "Platform Clock"},
372 {"Internal Mic", NULL, "Platform Clock"},
378 {"Internal Mic", NULL, "Platform Clock"},
384 {"Headset Mic 2", NULL, "Platform Clock"},
426 {"Speaker", NULL, "Platform Clock"},
434 {"Speaker", NULL, "Platform Clock"},
440 {"Line Out", NULL, "Platform Clock"},
467 /* The 2nd headset jack uses lineout with an external HP-amp */
478 .name = "hp-detect",
485 .name = "hp2-detect",
496 { "hp-detect-gpios", &acpi_gpio0, 1, },
497 { "headset-mic-detect-gpios", &acpi_gpio1, 1, },
498 { "hp2-detect-gpios", &acpi_gpio2, 1, },
511 mic_status = gpiod_get_value_cansleep(priv->hsmic_detect);
545 { /* Acer Iconia One 7 B1-750 */
557 { /* Acer Iconia Tab 8 W1-810 */
560 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Iconia W1-810"),
582 { /* Acer Aspire SW3-013 */
585 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-013"),
598 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
608 /* Advantech MICA-071 */
611 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"),
613 /* OVCD Th = 1500uA to reliable detect head-phones vs -set */
720 { /* Chuwi Vi8 dual-boot (CWI506) */
736 DMI_MATCH(DMI_BOARD_NAME, "BYT-PF02"),
752 DMI_MATCH(DMI_BOARD_NAME, "BYT-PA03C"),
809 DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"),
817 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
827 { /* HP Pavilion x2 10-k0XX, 10-n0XX */
829 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
839 { /* HP Pavilion x2 10-p0XX */
842 DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"),
852 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
864 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
875 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
919 { /* Lenovo Miix 3-830 */
922 DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 3-830"),
966 { /* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */
989 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
1041 { /* Point of View Mobii TAB-P800W (V2.0) */
1058 { /* Point of View Mobii TAB-P800W (V2.1) */
1075 { /* Point of View Mobii TAB-P1005W-232 (V2.0) */
1115 { /* Toshiba Satellite Click Mini L9W-B */
1118 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
1127 { /* Toshiba Encore WT8-A */
1130 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TOSHIBA WT8-A"),
1139 { /* Toshiba Encore WT10-A */
1142 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TOSHIBA WT10-A-103"),
1195 { /* Catch-all for generic Insyde tablets, must be last */
1221 props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic1-data-pin",
1225 props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic2-data-pin",
1231 PROPERTY_ENTRY_BOOL("realtek,in1-differential");
1236 PROPERTY_ENTRY_BOOL("realtek,in3-differential");
1243 "realtek,jack-detect-source",
1248 "realtek,over-current-threshold-microamp",
1252 "realtek,over-current-scale-factor",
1257 props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
1276 { "rt5640-jd-gpios", &amcr0f28_jd_gpio, 1 },
1283 struct rt5640_set_jack_data *data = &priv->jack_data;
1287 adev = acpi_dev_get_first_match_dev("AMCR0F28", "1", -1);
1289 dev_err(card->dev, "error cannot find AMCR0F28 adev\n");
1290 return -ENOENT;
1293 data->codec_irq_override = acpi_dev_gpio_irq_get(adev, 0);
1294 if (data->codec_irq_override < 0) {
1295 ret = data->codec_irq_override;
1296 dev_err(card->dev, "error %d getting codec IRQ\n", ret);
1302 data->jd_gpio = devm_fwnode_gpiod_get(card->dev, acpi_fwnode_handle(adev),
1303 "rt5640-jd", GPIOD_IN, "rt5640-jd");
1306 if (IS_ERR(data->jd_gpio)) {
1307 ret = PTR_ERR(data->jd_gpio);
1308 dev_err(card->dev, "error %d getting jd GPIO\n", ret);
1319 struct snd_soc_card *card = runtime->card;
1321 struct rt5640_set_jack_data *jack_data = &priv->jack_data;
1322 struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component;
1327 card->dapm.idle_bias = false;
1328 jack_data->use_platform_clock = true;
1330 /* Start with RC clk for jack-detect (we disable MCLK below) */
1347 dev_err(card->dev, "unable to add card controls\n");
1370 ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
1375 ret = snd_soc_dapm_add_routes(&card->dapm,
1383 ret = snd_soc_dapm_add_routes(&card->dapm,
1387 ret = snd_soc_dapm_add_routes(&card->dapm,
1391 ret = snd_soc_dapm_add_routes(&card->dapm,
1395 ret = snd_soc_dapm_add_routes(&card->dapm,
1403 ret = snd_soc_dapm_add_routes(&card->dapm,
1407 ret = snd_soc_dapm_add_routes(&card->dapm,
1415 ret = snd_soc_dapm_add_routes(&card->dapm,
1423 * The firmware might enable the clock at boot (this information
1424 * may or may not be reflected in the enable clock register).
1425 * To change the rate we must disable the clock first to cover
1426 * these cases. Due to common clock framework restrictions that
1427 * do not allow to disable a clock that has not been enabled,
1428 * we need to enable the clock first.
1430 ret = clk_prepare_enable(priv->mclk);
1432 clk_disable_unprepare(priv->mclk);
1435 ret = clk_set_rate(priv->mclk, 25000000);
1437 ret = clk_set_rate(priv->mclk, 19200000);
1439 dev_err(card->dev, "unable to set MCLK rate\n");
1446 &priv->jack, rt5640_pins,
1449 dev_err(card->dev, "Jack creation failed %d\n", ret);
1452 snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0,
1461 snd_soc_component_set_jack(component, &priv->jack, &priv->jack_data);
1467 &priv->jack, rt5640_pins,
1474 &priv->jack2, rt5640_pins2,
1480 rt5640_jack_gpio.gpiod_dev = priv->codec_dev;
1482 ret = snd_soc_jack_add_gpios(&priv->jack, 1, &rt5640_jack_gpio);
1488 rt5640_jack2_gpio.gpiod_dev = priv->codec_dev;
1490 ret = snd_soc_jack_add_gpios(&priv->jack2, 1, &rt5640_jack2_gpio);
1492 snd_soc_jack_free_gpios(&priv->jack, 1, &rt5640_jack_gpio);
1502 struct snd_soc_card *card = runtime->card;
1506 snd_soc_jack_free_gpios(&priv->jack2, 1, &rt5640_jack2_gpio);
1507 snd_soc_jack_free_gpios(&priv->jack, 1, &rt5640_jack_gpio);
1521 rate->min = rate->max = 48000;
1522 channels->min = channels->max = 2;
1526 /* set SSP0 to 16-bit */
1530 /* set SSP2 to 24-bit */
1545 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
1551 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
1560 return snd_pcm_hw_constraint_single(substream->runtime,
1576 DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
1579 DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
1583 DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
1586 /* overwritten with HID */ "i2c-10EC5640:00",
1587 /* changed w/ quirk */ "rt5640-aif1")));
1590 DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
1602 .name = "Deep-Buffer Audio Port",
1603 .stream_name = "Deep-Buffer Audio",
1612 .name = "SSP2-Codec",
1628 static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
1630 static char byt_rt5640_components[64]; /* = "cfg-spk:* cfg-mic:* ..." */
1640 if (!strcmp(component->name, byt_rt5640_codec_name)) {
1641 dev_dbg(component->dev, "disabling jack detect before suspend\n");
1659 if (!strcmp(component->name, byt_rt5640_codec_name)) {
1660 dev_dbg(component->dev, "re-enabling jack detect after resume\n");
1661 snd_soc_component_set_jack(component, &priv->jack,
1662 &priv->jack_data);
1671 #define SOF_CARD_NAME "bytcht rt5640" /* card name will be 'sof-bytcht rt5640' */
1674 #define CARD_NAME "bytcr-rt5640"
1697 struct device *dev = &pdev->dev;
1717 return -ENOMEM;
1726 !strcmp(byt_rt5640_dais[i].codecs->name,
1727 "i2c-10EC5640:00")) {
1734 adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1);
1737 "i2c-%s", acpi_dev_name(adev));
1738 byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name;
1740 dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
1741 return -ENOENT;
1748 priv->codec_dev = get_device(codec_dev);
1758 return -EPROBE_DEFER;
1761 dev_err(dev, "Error '%s' is not an i2c_client\n",
1771 priv->codec_dev = codec_dev;
1779 if (mach->mach_params.acpi_ipc_irq_index == 0)
1789 * with the codec driver/pdata are non-existent
1794 /* format specified: 2 64-bit integers */
1809 pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
1825 /* no BIOS indications, assume SSP0-AIF2 connection */
1829 /* change defaults for Baytrail-CR capture */
1841 byt_rt5640_quirk = (unsigned long)dmi_id->driver_data;
1842 if (quirk_override != -1) {
1849 acpi_dev_add_driver_gpios(ACPI_COMPANION(priv->codec_dev),
1852 priv->hsmic_detect = devm_fwnode_gpiod_get(dev, codec_dev->fwnode,
1853 "headset-mic-detect", GPIOD_IN,
1854 "headset-mic-detect");
1855 if (IS_ERR(priv->hsmic_detect)) {
1856 ret_val = dev_err_probe(dev, PTR_ERR(priv->hsmic_detect),
1857 "getting hsmic-detect GPIO\n");
1871 byt_rt5640_dais[dai_index].codecs->dai_name = "rt5640-aif2";
1879 byt_rt5640_dais[dai_index].cpus->dai_name = "ssp0-port";
1882 priv->mclk = devm_clk_get_optional(dev, "pmc_plt_clk_3");
1883 if (IS_ERR(priv->mclk)) {
1884 ret_val = dev_err_probe(dev, PTR_ERR(priv->mclk),
1889 * Fall back to bit clock usage when clock is not
1892 if (!priv->mclk)
1912 lineout_string = " cfg-hp2:lineout";
1914 lineout_string = " cfg-lineout:2";
1918 headset2_string = " cfg-hs2:in1";
1921 "cfg-spk:%s cfg-mic:%s aif:%d%s%s", cfg_spk,
1927 "bytcr-rt5640-%s-spk-%s-mic", spk_type,
1933 platform_name = mach->mach_params.platform;
1953 dev->driver->pm = &snd_soc_pm_ops;
1964 device_remove_software_node(priv->codec_dev);
1967 acpi_dev_remove_driver_gpios(ACPI_COMPANION(priv->codec_dev));
1969 put_device(priv->codec_dev);
1979 acpi_dev_remove_driver_gpios(ACPI_COMPANION(priv->codec_dev));
1981 device_remove_software_node(priv->codec_dev);
1982 put_device(priv->codec_dev);