.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * byt_cr_dpcm_rt5640.c - ASoc Machine driver for Intel Byt CR platform |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2014 Intel Corp |
---|
5 | 6 | * Author: Subhransu S. Prusty <subhransu.s.prusty@intel.com> |
---|
6 | 7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify |
---|
9 | | - * it under the terms of the GNU General Public License as published by |
---|
10 | | - * the Free Software Foundation; version 2 of the License. |
---|
11 | | - * |
---|
12 | | - * This program is distributed in the hope that it will be useful, but |
---|
13 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
15 | | - * General Public License for more details. |
---|
16 | 8 | * |
---|
17 | 9 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
18 | 10 | */ |
---|
.. | .. |
---|
28 | 20 | #include <linux/dmi.h> |
---|
29 | 21 | #include <linux/input.h> |
---|
30 | 22 | #include <linux/slab.h> |
---|
31 | | -#include <asm/cpu_device_id.h> |
---|
32 | | -#include <asm/platform_sst_audio.h> |
---|
33 | 23 | #include <sound/pcm.h> |
---|
34 | 24 | #include <sound/pcm_params.h> |
---|
35 | 25 | #include <sound/soc.h> |
---|
.. | .. |
---|
38 | 28 | #include <dt-bindings/sound/rt5640.h> |
---|
39 | 29 | #include "../../codecs/rt5640.h" |
---|
40 | 30 | #include "../atom/sst-atom-controls.h" |
---|
41 | | -#include "../common/sst-dsp.h" |
---|
| 31 | +#include "../common/soc-intel-quirks.h" |
---|
42 | 32 | |
---|
43 | 33 | enum { |
---|
44 | 34 | BYT_RT5640_DMIC1_MAP, |
---|
.. | .. |
---|
81 | 71 | #define BYT_RT5640_SSP0_AIF2 BIT(21) |
---|
82 | 72 | #define BYT_RT5640_MCLK_EN BIT(22) |
---|
83 | 73 | #define BYT_RT5640_MCLK_25MHZ BIT(23) |
---|
| 74 | +#define BYT_RT5640_NO_SPEAKERS BIT(24) |
---|
84 | 75 | |
---|
85 | 76 | #define BYTCR_INPUT_DEFAULTS \ |
---|
86 | 77 | (BYT_RT5640_IN3_MAP | \ |
---|
.. | .. |
---|
99 | 90 | static bool is_bytcr; |
---|
100 | 91 | |
---|
101 | 92 | static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN; |
---|
102 | | -static unsigned int quirk_override; |
---|
103 | | -module_param_named(quirk, quirk_override, uint, 0444); |
---|
| 93 | +static int quirk_override = -1; |
---|
| 94 | +module_param_named(quirk, quirk_override, int, 0444); |
---|
104 | 95 | MODULE_PARM_DESC(quirk, "Board-specific quirk override"); |
---|
105 | 96 | |
---|
106 | 97 | static void log_quirks(struct device *dev) |
---|
.. | .. |
---|
142 | 133 | dev_info(dev, "quirk JD_NOT_INV enabled\n"); |
---|
143 | 134 | if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) |
---|
144 | 135 | dev_info(dev, "quirk MONO_SPEAKER enabled\n"); |
---|
| 136 | + if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) |
---|
| 137 | + dev_info(dev, "quirk NO_SPEAKERS enabled\n"); |
---|
145 | 138 | if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) |
---|
146 | 139 | dev_info(dev, "quirk DIFF_MIC enabled\n"); |
---|
147 | 140 | if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) { |
---|
.. | .. |
---|
392 | 385 | static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream, |
---|
393 | 386 | struct snd_pcm_hw_params *params) |
---|
394 | 387 | { |
---|
395 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
396 | | - struct snd_soc_dai *dai = rtd->codec_dai; |
---|
| 388 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
| 389 | + struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0); |
---|
397 | 390 | |
---|
398 | 391 | return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params)); |
---|
399 | 392 | } |
---|
400 | 393 | |
---|
401 | 394 | /* Please keep this list alphabetically sorted */ |
---|
402 | 395 | static const struct dmi_system_id byt_rt5640_quirk_table[] = { |
---|
| 396 | + { /* Acer Iconia One 7 B1-750 */ |
---|
| 397 | + .matches = { |
---|
| 398 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"), |
---|
| 399 | + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "VESPA2"), |
---|
| 400 | + }, |
---|
| 401 | + .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | |
---|
| 402 | + BYT_RT5640_JD_SRC_JD1_IN4P | |
---|
| 403 | + BYT_RT5640_OVCD_TH_1500UA | |
---|
| 404 | + BYT_RT5640_OVCD_SF_0P75 | |
---|
| 405 | + BYT_RT5640_SSP0_AIF1 | |
---|
| 406 | + BYT_RT5640_MCLK_EN), |
---|
| 407 | + }, |
---|
403 | 408 | { /* Acer Iconia Tab 8 W1-810 */ |
---|
404 | 409 | .matches = { |
---|
405 | 410 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"), |
---|
.. | .. |
---|
438 | 443 | BYT_RT5640_MCLK_EN), |
---|
439 | 444 | }, |
---|
440 | 445 | { |
---|
| 446 | + /* Advantech MICA-071 */ |
---|
| 447 | + .matches = { |
---|
| 448 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"), |
---|
| 449 | + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"), |
---|
| 450 | + }, |
---|
| 451 | + /* OVCD Th = 1500uA to reliable detect head-phones vs -set */ |
---|
| 452 | + .driver_data = (void *)(BYT_RT5640_IN3_MAP | |
---|
| 453 | + BYT_RT5640_JD_SRC_JD2_IN4N | |
---|
| 454 | + BYT_RT5640_OVCD_TH_1500UA | |
---|
| 455 | + BYT_RT5640_OVCD_SF_0P75 | |
---|
| 456 | + BYT_RT5640_MONO_SPEAKER | |
---|
| 457 | + BYT_RT5640_DIFF_MIC | |
---|
| 458 | + BYT_RT5640_MCLK_EN), |
---|
| 459 | + }, |
---|
| 460 | + { |
---|
441 | 461 | .matches = { |
---|
442 | 462 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"), |
---|
443 | 463 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 80 Cesium"), |
---|
.. | .. |
---|
451 | 471 | .matches = { |
---|
452 | 472 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"), |
---|
453 | 473 | DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 140 CESIUM"), |
---|
| 474 | + }, |
---|
| 475 | + .driver_data = (void *)(BYT_RT5640_IN1_MAP | |
---|
| 476 | + BYT_RT5640_JD_SRC_JD2_IN4N | |
---|
| 477 | + BYT_RT5640_OVCD_TH_2000UA | |
---|
| 478 | + BYT_RT5640_OVCD_SF_0P75 | |
---|
| 479 | + BYT_RT5640_SSP0_AIF1 | |
---|
| 480 | + BYT_RT5640_MCLK_EN), |
---|
| 481 | + }, |
---|
| 482 | + { |
---|
| 483 | + .matches = { |
---|
| 484 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
---|
| 485 | + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"), |
---|
454 | 486 | }, |
---|
455 | 487 | .driver_data = (void *)(BYT_RT5640_IN1_MAP | |
---|
456 | 488 | BYT_RT5640_JD_SRC_JD2_IN4N | |
---|
.. | .. |
---|
587 | 619 | .driver_data = (void *)(BYT_RT5640_IN1_MAP | |
---|
588 | 620 | BYT_RT5640_MCLK_EN), |
---|
589 | 621 | }, |
---|
590 | | - { /* HP Pavilion x2 10-n000nd */ |
---|
| 622 | + { /* HP Pavilion x2 10-k0XX, 10-n0XX */ |
---|
591 | 623 | .matches = { |
---|
592 | | - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
---|
593 | | - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), |
---|
| 624 | + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
---|
| 625 | + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"), |
---|
| 626 | + }, |
---|
| 627 | + .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | |
---|
| 628 | + BYT_RT5640_JD_SRC_JD2_IN4N | |
---|
| 629 | + BYT_RT5640_OVCD_TH_1500UA | |
---|
| 630 | + BYT_RT5640_OVCD_SF_0P75 | |
---|
| 631 | + BYT_RT5640_SSP0_AIF1 | |
---|
| 632 | + BYT_RT5640_MCLK_EN), |
---|
| 633 | + }, |
---|
| 634 | + { /* HP Pavilion x2 10-p0XX */ |
---|
| 635 | + .matches = { |
---|
| 636 | + DMI_MATCH(DMI_SYS_VENDOR, "HP"), |
---|
| 637 | + DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"), |
---|
| 638 | + }, |
---|
| 639 | + .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | |
---|
| 640 | + BYT_RT5640_JD_SRC_JD1_IN4P | |
---|
| 641 | + BYT_RT5640_OVCD_TH_2000UA | |
---|
| 642 | + BYT_RT5640_OVCD_SF_0P75 | |
---|
| 643 | + BYT_RT5640_MCLK_EN), |
---|
| 644 | + }, |
---|
| 645 | + { /* HP Pro Tablet 408 */ |
---|
| 646 | + .matches = { |
---|
| 647 | + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
---|
| 648 | + DMI_MATCH(DMI_PRODUCT_NAME, "HP Pro Tablet 408"), |
---|
594 | 649 | }, |
---|
595 | 650 | .driver_data = (void *)(BYT_RT5640_DMIC1_MAP | |
---|
596 | 651 | BYT_RT5640_JD_SRC_JD2_IN4N | |
---|
.. | .. |
---|
780 | 835 | BYT_RT5640_SSP0_AIF2 | |
---|
781 | 836 | BYT_RT5640_MCLK_EN), |
---|
782 | 837 | }, |
---|
| 838 | + { /* Point of View Mobii TAB-P1005W-232 (V2.0) */ |
---|
| 839 | + .matches = { |
---|
| 840 | + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "POV"), |
---|
| 841 | + DMI_EXACT_MATCH(DMI_BOARD_NAME, "I102A"), |
---|
| 842 | + }, |
---|
| 843 | + .driver_data = (void *)(BYT_RT5640_IN1_MAP | |
---|
| 844 | + BYT_RT5640_JD_SRC_JD2_IN4N | |
---|
| 845 | + BYT_RT5640_OVCD_TH_2000UA | |
---|
| 846 | + BYT_RT5640_OVCD_SF_0P75 | |
---|
| 847 | + BYT_RT5640_DIFF_MIC | |
---|
| 848 | + BYT_RT5640_SSP0_AIF1 | |
---|
| 849 | + BYT_RT5640_MCLK_EN), |
---|
| 850 | + }, |
---|
| 851 | + { |
---|
| 852 | + /* Prowise PT301 */ |
---|
| 853 | + .matches = { |
---|
| 854 | + DMI_MATCH(DMI_SYS_VENDOR, "Prowise"), |
---|
| 855 | + DMI_MATCH(DMI_PRODUCT_NAME, "PT301"), |
---|
| 856 | + }, |
---|
| 857 | + .driver_data = (void *)(BYT_RT5640_IN1_MAP | |
---|
| 858 | + BYT_RT5640_JD_SRC_JD2_IN4N | |
---|
| 859 | + BYT_RT5640_OVCD_TH_2000UA | |
---|
| 860 | + BYT_RT5640_OVCD_SF_0P75 | |
---|
| 861 | + BYT_RT5640_DIFF_MIC | |
---|
| 862 | + BYT_RT5640_SSP0_AIF1 | |
---|
| 863 | + BYT_RT5640_MCLK_EN), |
---|
| 864 | + }, |
---|
783 | 865 | { |
---|
784 | 866 | /* Teclast X89 */ |
---|
785 | 867 | .matches = { |
---|
.. | .. |
---|
917 | 999 | { |
---|
918 | 1000 | struct snd_soc_card *card = runtime->card; |
---|
919 | 1001 | struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card); |
---|
920 | | - struct snd_soc_component *component = runtime->codec_dai->component; |
---|
| 1002 | + struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component; |
---|
921 | 1003 | const struct snd_soc_dapm_route *custom_map; |
---|
922 | 1004 | int num_routes; |
---|
923 | 1005 | int ret; |
---|
.. | .. |
---|
991 | 1073 | ret = snd_soc_dapm_add_routes(&card->dapm, |
---|
992 | 1074 | byt_rt5640_mono_spk_map, |
---|
993 | 1075 | ARRAY_SIZE(byt_rt5640_mono_spk_map)); |
---|
994 | | - } else { |
---|
| 1076 | + } else if (!(byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)) { |
---|
995 | 1077 | ret = snd_soc_dapm_add_routes(&card->dapm, |
---|
996 | 1078 | byt_rt5640_stereo_spk_map, |
---|
997 | 1079 | ARRAY_SIZE(byt_rt5640_stereo_spk_map)); |
---|
998 | 1080 | } |
---|
999 | 1081 | if (ret) |
---|
1000 | 1082 | return ret; |
---|
1001 | | - |
---|
1002 | | - snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); |
---|
1003 | | - snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); |
---|
1004 | 1083 | |
---|
1005 | 1084 | if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) { |
---|
1006 | 1085 | /* |
---|
.. | .. |
---|
1045 | 1124 | return 0; |
---|
1046 | 1125 | } |
---|
1047 | 1126 | |
---|
1048 | | -static const struct snd_soc_pcm_stream byt_rt5640_dai_params = { |
---|
1049 | | - .formats = SNDRV_PCM_FMTBIT_S24_LE, |
---|
1050 | | - .rate_min = 48000, |
---|
1051 | | - .rate_max = 48000, |
---|
1052 | | - .channels_min = 2, |
---|
1053 | | - .channels_max = 2, |
---|
1054 | | -}; |
---|
1055 | | - |
---|
1056 | 1127 | static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd, |
---|
1057 | 1128 | struct snd_pcm_hw_params *params) |
---|
1058 | 1129 | { |
---|
.. | .. |
---|
1060 | 1131 | SNDRV_PCM_HW_PARAM_RATE); |
---|
1061 | 1132 | struct snd_interval *channels = hw_param_interval(params, |
---|
1062 | 1133 | SNDRV_PCM_HW_PARAM_CHANNELS); |
---|
1063 | | - int ret; |
---|
| 1134 | + int ret, bits; |
---|
1064 | 1135 | |
---|
1065 | 1136 | /* The DSP will covert the FE rate to 48k, stereo */ |
---|
1066 | 1137 | rate->min = rate->max = 48000; |
---|
1067 | 1138 | channels->min = channels->max = 2; |
---|
1068 | 1139 | |
---|
1069 | 1140 | if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) || |
---|
1070 | | - (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) { |
---|
1071 | | - |
---|
| 1141 | + (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) { |
---|
1072 | 1142 | /* set SSP0 to 16-bit */ |
---|
1073 | 1143 | params_set_format(params, SNDRV_PCM_FORMAT_S16_LE); |
---|
1074 | | - |
---|
1075 | | - /* |
---|
1076 | | - * Default mode for SSP configuration is TDM 4 slot, override config |
---|
1077 | | - * with explicit setting to I2S 2ch 16-bit. The word length is set with |
---|
1078 | | - * dai_set_tdm_slot() since there is no other API exposed |
---|
1079 | | - */ |
---|
1080 | | - ret = snd_soc_dai_set_fmt(rtd->cpu_dai, |
---|
1081 | | - SND_SOC_DAIFMT_I2S | |
---|
1082 | | - SND_SOC_DAIFMT_NB_NF | |
---|
1083 | | - SND_SOC_DAIFMT_CBS_CFS |
---|
1084 | | - ); |
---|
1085 | | - if (ret < 0) { |
---|
1086 | | - dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); |
---|
1087 | | - return ret; |
---|
1088 | | - } |
---|
1089 | | - |
---|
1090 | | - ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16); |
---|
1091 | | - if (ret < 0) { |
---|
1092 | | - dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); |
---|
1093 | | - return ret; |
---|
1094 | | - } |
---|
1095 | | - |
---|
| 1144 | + bits = 16; |
---|
1096 | 1145 | } else { |
---|
1097 | | - |
---|
1098 | 1146 | /* set SSP2 to 24-bit */ |
---|
1099 | 1147 | params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); |
---|
1100 | | - |
---|
1101 | | - /* |
---|
1102 | | - * Default mode for SSP configuration is TDM 4 slot, override config |
---|
1103 | | - * with explicit setting to I2S 2ch 24-bit. The word length is set with |
---|
1104 | | - * dai_set_tdm_slot() since there is no other API exposed |
---|
1105 | | - */ |
---|
1106 | | - ret = snd_soc_dai_set_fmt(rtd->cpu_dai, |
---|
1107 | | - SND_SOC_DAIFMT_I2S | |
---|
1108 | | - SND_SOC_DAIFMT_NB_NF | |
---|
1109 | | - SND_SOC_DAIFMT_CBS_CFS |
---|
1110 | | - ); |
---|
1111 | | - if (ret < 0) { |
---|
1112 | | - dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); |
---|
1113 | | - return ret; |
---|
1114 | | - } |
---|
1115 | | - |
---|
1116 | | - ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24); |
---|
1117 | | - if (ret < 0) { |
---|
1118 | | - dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); |
---|
1119 | | - return ret; |
---|
1120 | | - } |
---|
| 1148 | + bits = 24; |
---|
1121 | 1149 | } |
---|
| 1150 | + |
---|
| 1151 | + /* |
---|
| 1152 | + * Default mode for SSP configuration is TDM 4 slot, override config |
---|
| 1153 | + * with explicit setting to I2S 2ch. The word length is set with |
---|
| 1154 | + * dai_set_tdm_slot() since there is no other API exposed |
---|
| 1155 | + */ |
---|
| 1156 | + ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0), |
---|
| 1157 | + SND_SOC_DAIFMT_I2S | |
---|
| 1158 | + SND_SOC_DAIFMT_NB_NF | |
---|
| 1159 | + SND_SOC_DAIFMT_CBS_CFS); |
---|
| 1160 | + if (ret < 0) { |
---|
| 1161 | + dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret); |
---|
| 1162 | + return ret; |
---|
| 1163 | + } |
---|
| 1164 | + |
---|
| 1165 | + ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits); |
---|
| 1166 | + if (ret < 0) { |
---|
| 1167 | + dev_err(rtd->dev, "can't set I2S config, err %d\n", ret); |
---|
| 1168 | + return ret; |
---|
| 1169 | + } |
---|
| 1170 | + |
---|
1122 | 1171 | return 0; |
---|
1123 | 1172 | } |
---|
1124 | 1173 | |
---|
.. | .. |
---|
1136 | 1185 | .hw_params = byt_rt5640_aif1_hw_params, |
---|
1137 | 1186 | }; |
---|
1138 | 1187 | |
---|
| 1188 | +SND_SOC_DAILINK_DEF(dummy, |
---|
| 1189 | + DAILINK_COMP_ARRAY(COMP_DUMMY())); |
---|
| 1190 | + |
---|
| 1191 | +SND_SOC_DAILINK_DEF(media, |
---|
| 1192 | + DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai"))); |
---|
| 1193 | + |
---|
| 1194 | +SND_SOC_DAILINK_DEF(deepbuffer, |
---|
| 1195 | + DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai"))); |
---|
| 1196 | + |
---|
| 1197 | +SND_SOC_DAILINK_DEF(ssp2_port, |
---|
| 1198 | + /* overwritten for ssp0 routing */ |
---|
| 1199 | + DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port"))); |
---|
| 1200 | +SND_SOC_DAILINK_DEF(ssp2_codec, |
---|
| 1201 | + DAILINK_COMP_ARRAY(COMP_CODEC( |
---|
| 1202 | + /* overwritten with HID */ "i2c-10EC5640:00", |
---|
| 1203 | + /* changed w/ quirk */ "rt5640-aif1"))); |
---|
| 1204 | + |
---|
| 1205 | +SND_SOC_DAILINK_DEF(platform, |
---|
| 1206 | + DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform"))); |
---|
| 1207 | + |
---|
1139 | 1208 | static struct snd_soc_dai_link byt_rt5640_dais[] = { |
---|
1140 | 1209 | [MERR_DPCM_AUDIO] = { |
---|
1141 | 1210 | .name = "Baytrail Audio Port", |
---|
1142 | 1211 | .stream_name = "Baytrail Audio", |
---|
1143 | | - .cpu_dai_name = "media-cpu-dai", |
---|
1144 | | - .codec_dai_name = "snd-soc-dummy-dai", |
---|
1145 | | - .codec_name = "snd-soc-dummy", |
---|
1146 | | - .platform_name = "sst-mfld-platform", |
---|
1147 | 1212 | .nonatomic = true, |
---|
1148 | 1213 | .dynamic = 1, |
---|
1149 | 1214 | .dpcm_playback = 1, |
---|
1150 | 1215 | .dpcm_capture = 1, |
---|
1151 | 1216 | .ops = &byt_rt5640_aif1_ops, |
---|
| 1217 | + SND_SOC_DAILINK_REG(media, dummy, platform), |
---|
1152 | 1218 | }, |
---|
1153 | 1219 | [MERR_DPCM_DEEP_BUFFER] = { |
---|
1154 | 1220 | .name = "Deep-Buffer Audio Port", |
---|
1155 | 1221 | .stream_name = "Deep-Buffer Audio", |
---|
1156 | | - .cpu_dai_name = "deepbuffer-cpu-dai", |
---|
1157 | | - .codec_dai_name = "snd-soc-dummy-dai", |
---|
1158 | | - .codec_name = "snd-soc-dummy", |
---|
1159 | | - .platform_name = "sst-mfld-platform", |
---|
1160 | 1222 | .nonatomic = true, |
---|
1161 | 1223 | .dynamic = 1, |
---|
1162 | 1224 | .dpcm_playback = 1, |
---|
1163 | 1225 | .ops = &byt_rt5640_aif1_ops, |
---|
| 1226 | + SND_SOC_DAILINK_REG(deepbuffer, dummy, platform), |
---|
1164 | 1227 | }, |
---|
1165 | 1228 | /* back ends */ |
---|
1166 | 1229 | { |
---|
1167 | 1230 | .name = "SSP2-Codec", |
---|
1168 | 1231 | .id = 0, |
---|
1169 | | - .cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */ |
---|
1170 | | - .platform_name = "sst-mfld-platform", |
---|
1171 | 1232 | .no_pcm = 1, |
---|
1172 | | - .codec_dai_name = "rt5640-aif1", /* changed w/ quirk */ |
---|
1173 | | - .codec_name = "i2c-10EC5640:00", /* overwritten with HID */ |
---|
1174 | 1233 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
---|
1175 | 1234 | | SND_SOC_DAIFMT_CBS_CFS, |
---|
1176 | 1235 | .be_hw_params_fixup = byt_rt5640_codec_fixup, |
---|
1177 | | - .ignore_suspend = 1, |
---|
1178 | 1236 | .nonatomic = true, |
---|
1179 | 1237 | .dpcm_playback = 1, |
---|
1180 | 1238 | .dpcm_capture = 1, |
---|
1181 | 1239 | .init = byt_rt5640_init, |
---|
1182 | 1240 | .ops = &byt_rt5640_be_ssp2_ops, |
---|
| 1241 | + SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform), |
---|
1183 | 1242 | }, |
---|
1184 | 1243 | }; |
---|
1185 | 1244 | |
---|
1186 | 1245 | /* SoC card */ |
---|
1187 | 1246 | static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN]; |
---|
1188 | | -static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */ |
---|
1189 | | -static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */ |
---|
| 1247 | +#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES) |
---|
1190 | 1248 | static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */ |
---|
| 1249 | +#endif |
---|
| 1250 | +static char byt_rt5640_components[32]; /* = "cfg-spk:* cfg-mic:*" */ |
---|
1191 | 1251 | |
---|
1192 | 1252 | static int byt_rt5640_suspend(struct snd_soc_card *card) |
---|
1193 | 1253 | { |
---|
.. | .. |
---|
1196 | 1256 | if (!BYT_RT5640_JDSRC(byt_rt5640_quirk)) |
---|
1197 | 1257 | return 0; |
---|
1198 | 1258 | |
---|
1199 | | - list_for_each_entry(component, &card->component_dev_list, card_list) { |
---|
| 1259 | + for_each_card_components(card, component) { |
---|
1200 | 1260 | if (!strcmp(component->name, byt_rt5640_codec_name)) { |
---|
1201 | 1261 | dev_dbg(component->dev, "disabling jack detect before suspend\n"); |
---|
1202 | 1262 | snd_soc_component_set_jack(component, NULL, NULL); |
---|
.. | .. |
---|
1215 | 1275 | if (!BYT_RT5640_JDSRC(byt_rt5640_quirk)) |
---|
1216 | 1276 | return 0; |
---|
1217 | 1277 | |
---|
1218 | | - list_for_each_entry(component, &card->component_dev_list, card_list) { |
---|
| 1278 | + for_each_card_components(card, component) { |
---|
1219 | 1279 | if (!strcmp(component->name, byt_rt5640_codec_name)) { |
---|
1220 | 1280 | dev_dbg(component->dev, "re-enabling jack detect after resume\n"); |
---|
1221 | 1281 | snd_soc_component_set_jack(component, &priv->jack, NULL); |
---|
.. | .. |
---|
1226 | 1286 | return 0; |
---|
1227 | 1287 | } |
---|
1228 | 1288 | |
---|
| 1289 | +#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) |
---|
| 1290 | +/* use space before codec name to simplify card ID, and simplify driver name */ |
---|
| 1291 | +#define CARD_NAME "bytcht rt5640" /* card name will be 'sof-bytcht rt5640' */ |
---|
| 1292 | +#define DRIVER_NAME "SOF" |
---|
| 1293 | +#else |
---|
| 1294 | +#define CARD_NAME "bytcr-rt5640" |
---|
| 1295 | +#define DRIVER_NAME NULL /* card name will be used for driver name */ |
---|
| 1296 | +#endif |
---|
| 1297 | + |
---|
1229 | 1298 | static struct snd_soc_card byt_rt5640_card = { |
---|
1230 | | - .name = "bytcr-rt5640", |
---|
| 1299 | + .name = CARD_NAME, |
---|
| 1300 | + .driver_name = DRIVER_NAME, |
---|
1231 | 1301 | .owner = THIS_MODULE, |
---|
1232 | 1302 | .dai_link = byt_rt5640_dais, |
---|
1233 | 1303 | .num_links = ARRAY_SIZE(byt_rt5640_dais), |
---|
.. | .. |
---|
1240 | 1310 | .resume_post = byt_rt5640_resume, |
---|
1241 | 1311 | }; |
---|
1242 | 1312 | |
---|
1243 | | -static bool is_valleyview(void) |
---|
1244 | | -{ |
---|
1245 | | - static const struct x86_cpu_id cpu_ids[] = { |
---|
1246 | | - { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */ |
---|
1247 | | - {} |
---|
1248 | | - }; |
---|
1249 | | - |
---|
1250 | | - if (!x86_match_cpu(cpu_ids)) |
---|
1251 | | - return false; |
---|
1252 | | - return true; |
---|
1253 | | -} |
---|
1254 | | - |
---|
1255 | 1313 | struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */ |
---|
1256 | 1314 | u64 aif_value; /* 1: AIF1, 2: AIF2 */ |
---|
1257 | 1315 | u64 mclock_value; /* usually 25MHz (0x17d7940), ignored */ |
---|
.. | .. |
---|
1259 | 1317 | |
---|
1260 | 1318 | static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) |
---|
1261 | 1319 | { |
---|
1262 | | - const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" }; |
---|
| 1320 | + static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" }; |
---|
| 1321 | + __maybe_unused const char *spk_type; |
---|
1263 | 1322 | const struct dmi_system_id *dmi_id; |
---|
1264 | 1323 | struct byt_rt5640_private *priv; |
---|
1265 | 1324 | struct snd_soc_acpi_mach *mach; |
---|
1266 | | - const char *i2c_name = NULL; |
---|
| 1325 | + const char *platform_name; |
---|
| 1326 | + struct acpi_device *adev; |
---|
1267 | 1327 | int ret_val = 0; |
---|
1268 | 1328 | int dai_index = 0; |
---|
1269 | | - int i; |
---|
| 1329 | + int i, cfg_spk; |
---|
1270 | 1330 | |
---|
1271 | 1331 | is_bytcr = false; |
---|
1272 | 1332 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
---|
.. | .. |
---|
1280 | 1340 | |
---|
1281 | 1341 | /* fix index of codec dai */ |
---|
1282 | 1342 | for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) { |
---|
1283 | | - if (!strcmp(byt_rt5640_dais[i].codec_name, "i2c-10EC5640:00")) { |
---|
| 1343 | + if (!strcmp(byt_rt5640_dais[i].codecs->name, |
---|
| 1344 | + "i2c-10EC5640:00")) { |
---|
1284 | 1345 | dai_index = i; |
---|
1285 | 1346 | break; |
---|
1286 | 1347 | } |
---|
1287 | 1348 | } |
---|
1288 | 1349 | |
---|
1289 | 1350 | /* fixup codec name based on HID */ |
---|
1290 | | - i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); |
---|
1291 | | - if (i2c_name) { |
---|
| 1351 | + adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1); |
---|
| 1352 | + if (adev) { |
---|
1292 | 1353 | snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name), |
---|
1293 | | - "%s%s", "i2c-", i2c_name); |
---|
1294 | | - |
---|
1295 | | - byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name; |
---|
| 1354 | + "i2c-%s", acpi_dev_name(adev)); |
---|
| 1355 | + put_device(&adev->dev); |
---|
| 1356 | + byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name; |
---|
1296 | 1357 | } |
---|
1297 | 1358 | |
---|
1298 | 1359 | /* |
---|
1299 | 1360 | * swap SSP0 if bytcr is detected |
---|
1300 | 1361 | * (will be overridden if DMI quirk is detected) |
---|
1301 | 1362 | */ |
---|
1302 | | - if (is_valleyview()) { |
---|
1303 | | - struct sst_platform_info *p_info = mach->pdata; |
---|
1304 | | - const struct sst_res_info *res_info = p_info->res_info; |
---|
1305 | | - |
---|
1306 | | - if (res_info->acpi_ipc_irq_index == 0) |
---|
| 1363 | + if (soc_intel_is_byt()) { |
---|
| 1364 | + if (mach->mach_params.acpi_ipc_irq_index == 0) |
---|
1307 | 1365 | is_bytcr = true; |
---|
1308 | 1366 | } |
---|
1309 | 1367 | |
---|
.. | .. |
---|
1366 | 1424 | dmi_id = dmi_first_match(byt_rt5640_quirk_table); |
---|
1367 | 1425 | if (dmi_id) |
---|
1368 | 1426 | byt_rt5640_quirk = (unsigned long)dmi_id->driver_data; |
---|
1369 | | - if (quirk_override) { |
---|
1370 | | - dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n", |
---|
1371 | | - (unsigned int)byt_rt5640_quirk, quirk_override); |
---|
| 1427 | + if (quirk_override != -1) { |
---|
| 1428 | + dev_info(&pdev->dev, "Overriding quirk 0x%lx => 0x%x\n", |
---|
| 1429 | + byt_rt5640_quirk, quirk_override); |
---|
1372 | 1430 | byt_rt5640_quirk = quirk_override; |
---|
1373 | 1431 | } |
---|
1374 | 1432 | |
---|
.. | .. |
---|
1380 | 1438 | log_quirks(&pdev->dev); |
---|
1381 | 1439 | |
---|
1382 | 1440 | if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) || |
---|
1383 | | - (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) { |
---|
1384 | | - |
---|
1385 | | - /* fixup codec aif name */ |
---|
1386 | | - snprintf(byt_rt5640_codec_aif_name, |
---|
1387 | | - sizeof(byt_rt5640_codec_aif_name), |
---|
1388 | | - "%s", "rt5640-aif2"); |
---|
1389 | | - |
---|
1390 | | - byt_rt5640_dais[dai_index].codec_dai_name = |
---|
1391 | | - byt_rt5640_codec_aif_name; |
---|
1392 | | - } |
---|
| 1441 | + (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) |
---|
| 1442 | + byt_rt5640_dais[dai_index].codecs->dai_name = "rt5640-aif2"; |
---|
1393 | 1443 | |
---|
1394 | 1444 | if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) || |
---|
1395 | | - (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) { |
---|
1396 | | - |
---|
1397 | | - /* fixup cpu dai name name */ |
---|
1398 | | - snprintf(byt_rt5640_cpu_dai_name, |
---|
1399 | | - sizeof(byt_rt5640_cpu_dai_name), |
---|
1400 | | - "%s", "ssp0-port"); |
---|
1401 | | - |
---|
1402 | | - byt_rt5640_dais[dai_index].cpu_dai_name = |
---|
1403 | | - byt_rt5640_cpu_dai_name; |
---|
1404 | | - } |
---|
| 1445 | + (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) |
---|
| 1446 | + byt_rt5640_dais[dai_index].cpus->dai_name = "ssp0-port"; |
---|
1405 | 1447 | |
---|
1406 | 1448 | if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) { |
---|
1407 | 1449 | priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); |
---|
.. | .. |
---|
1423 | 1465 | } |
---|
1424 | 1466 | } |
---|
1425 | 1467 | |
---|
| 1468 | + if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) { |
---|
| 1469 | + cfg_spk = 0; |
---|
| 1470 | + spk_type = "none"; |
---|
| 1471 | + } else if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) { |
---|
| 1472 | + cfg_spk = 1; |
---|
| 1473 | + spk_type = "mono"; |
---|
| 1474 | + } else { |
---|
| 1475 | + cfg_spk = 2; |
---|
| 1476 | + spk_type = "stereo"; |
---|
| 1477 | + } |
---|
| 1478 | + |
---|
| 1479 | + snprintf(byt_rt5640_components, sizeof(byt_rt5640_components), |
---|
| 1480 | + "cfg-spk:%d cfg-mic:%s", cfg_spk, |
---|
| 1481 | + map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]); |
---|
| 1482 | + byt_rt5640_card.components = byt_rt5640_components; |
---|
| 1483 | +#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES) |
---|
1426 | 1484 | snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name), |
---|
1427 | | - "bytcr-rt5640-%s-spk-%s-mic", |
---|
1428 | | - (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ? |
---|
1429 | | - "mono" : "stereo", |
---|
| 1485 | + "bytcr-rt5640-%s-spk-%s-mic", spk_type, |
---|
1430 | 1486 | map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]); |
---|
1431 | 1487 | byt_rt5640_card.long_name = byt_rt5640_long_name; |
---|
| 1488 | +#endif |
---|
| 1489 | + |
---|
| 1490 | + /* override plaform name, if required */ |
---|
| 1491 | + platform_name = mach->mach_params.platform; |
---|
| 1492 | + |
---|
| 1493 | + ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5640_card, |
---|
| 1494 | + platform_name); |
---|
| 1495 | + if (ret_val) |
---|
| 1496 | + return ret_val; |
---|
1432 | 1497 | |
---|
1433 | 1498 | ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card); |
---|
1434 | 1499 | |
---|
.. | .. |
---|
1444 | 1509 | static struct platform_driver snd_byt_rt5640_mc_driver = { |
---|
1445 | 1510 | .driver = { |
---|
1446 | 1511 | .name = "bytcr_rt5640", |
---|
| 1512 | +#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) |
---|
| 1513 | + .pm = &snd_soc_pm_ops, |
---|
| 1514 | +#endif |
---|
1447 | 1515 | }, |
---|
1448 | 1516 | .probe = snd_byt_rt5640_mc_probe, |
---|
1449 | 1517 | }; |
---|