Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: Intel: maxim-common: get codec number from ACPI table

We implement a helper function to get number of codecs from ACPI
subsystem instead of using quirk flag in machine driver. Also refactor
module interface by adding max_98390_dai_link() function.

On the sof_rt5682 machine driver side, we remove the quirk flag
SOF_MAX98390_TWEETER_SPEAKER_PRESENT and use the new interface of
max98390 to setup dai link.

Signed-off-by: Brent Lu <brent.lu@intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://lore.kernel.org/r/20230731103419.2536036-2-brent.lu@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Brent Lu and committed by
Mark Brown
36eb9868 138b5c27

+110 -116
+100 -70
sound/soc/intel/boards/sof_maxim_common.c
··· 4 4 #include <linux/module.h> 5 5 #include <linux/string.h> 6 6 #include <sound/pcm.h> 7 + #include <sound/pcm_params.h> 7 8 #include <sound/soc.h> 8 9 #include <sound/soc-acpi.h> 9 10 #include <sound/soc-dai.h> 10 11 #include <sound/soc-dapm.h> 11 12 #include <uapi/sound/asound.h> 12 13 #include "sof_maxim_common.h" 14 + 15 + /* helper function to get the number of specific codec */ 16 + static unsigned int get_num_codecs(const char *hid) 17 + { 18 + struct acpi_device *adev; 19 + unsigned int dev_num = 0; 20 + 21 + for_each_acpi_dev_match(adev, hid, NULL, -1) 22 + dev_num++; 23 + 24 + return dev_num; 25 + } 13 26 14 27 #define MAX_98373_PIN_NAME 16 15 28 ··· 181 168 .dlc = COMP_CODEC_CONF(MAX_98390_DEV1_NAME), 182 169 .name_prefix = "Left", 183 170 }, 184 - }; 185 - 186 - static struct snd_soc_codec_conf max_98390_4spk_codec_conf[] = { 187 - { 188 - .dlc = COMP_CODEC_CONF(MAX_98390_DEV0_NAME), 189 - .name_prefix = "Right", 190 - }, 191 - { 192 - .dlc = COMP_CODEC_CONF(MAX_98390_DEV1_NAME), 193 - .name_prefix = "Left", 194 - }, 195 171 { 196 172 .dlc = COMP_CODEC_CONF(MAX_98390_DEV2_NAME), 197 173 .name_prefix = "Tweeter Right", ··· 191 189 }, 192 190 }; 193 191 194 - struct snd_soc_dai_link_component max_98390_components[] = { 195 - { 196 - .name = MAX_98390_DEV0_NAME, 197 - .dai_name = MAX_98390_CODEC_DAI, 198 - }, 199 - { 200 - .name = MAX_98390_DEV1_NAME, 201 - .dai_name = MAX_98390_CODEC_DAI, 202 - }, 203 - }; 204 - EXPORT_SYMBOL_NS(max_98390_components, SND_SOC_INTEL_SOF_MAXIM_COMMON); 205 - 206 - struct snd_soc_dai_link_component max_98390_4spk_components[] = { 192 + static struct snd_soc_dai_link_component max_98390_components[] = { 207 193 { 208 194 .name = MAX_98390_DEV0_NAME, 209 195 .dai_name = MAX_98390_CODEC_DAI, ··· 209 219 .dai_name = MAX_98390_CODEC_DAI, 210 220 }, 211 221 }; 212 - EXPORT_SYMBOL_NS(max_98390_4spk_components, SND_SOC_INTEL_SOF_MAXIM_COMMON); 222 + 223 + static const struct { 224 + unsigned int tx; 225 + unsigned int rx; 226 + } max_98390_tdm_mask[] = { 227 + {.tx = 0x01, .rx = 0x3}, 228 + {.tx = 0x02, .rx = 0x3}, 229 + {.tx = 0x04, .rx = 0x3}, 230 + {.tx = 0x08, .rx = 0x3}, 231 + }; 213 232 214 233 static int max_98390_hw_params(struct snd_pcm_substream *substream, 215 234 struct snd_pcm_hw_params *params) 216 235 { 217 236 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); 218 237 struct snd_soc_dai *codec_dai; 219 - int i; 238 + int i, ret; 220 239 221 240 for_each_rtd_codec_dais(rtd, i, codec_dai) { 222 - if (i >= ARRAY_SIZE(max_98390_4spk_components)) { 241 + if (i >= ARRAY_SIZE(max_98390_tdm_mask)) { 223 242 dev_err(codec_dai->dev, "invalid codec index %d\n", i); 224 243 return -ENODEV; 225 244 } 226 245 227 - if (!strcmp(codec_dai->component->name, MAX_98390_DEV0_NAME)) { 228 - /* DEV0 tdm slot configuration Right */ 229 - snd_soc_dai_set_tdm_slot(codec_dai, 0x01, 3, 4, 32); 230 - } 231 - if (!strcmp(codec_dai->component->name, MAX_98390_DEV1_NAME)) { 232 - /* DEV1 tdm slot configuration Left */ 233 - snd_soc_dai_set_tdm_slot(codec_dai, 0x02, 3, 4, 32); 234 - } 235 - 236 - if (!strcmp(codec_dai->component->name, MAX_98390_DEV2_NAME)) { 237 - /* DEVi2 tdm slot configuration Tweeter Right */ 238 - snd_soc_dai_set_tdm_slot(codec_dai, 0x04, 3, 4, 32); 239 - } 240 - if (!strcmp(codec_dai->component->name, MAX_98390_DEV3_NAME)) { 241 - /* DEV3 tdm slot configuration Tweeter Left */ 242 - snd_soc_dai_set_tdm_slot(codec_dai, 0x08, 3, 4, 32); 246 + ret = snd_soc_dai_set_tdm_slot(codec_dai, max_98390_tdm_mask[i].tx, 247 + max_98390_tdm_mask[i].rx, 4, 248 + params_width(params)); 249 + if (ret < 0) { 250 + dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n", 251 + ret); 252 + return ret; 243 253 } 244 254 } 245 255 return 0; 246 256 } 247 257 248 - int max_98390_spk_codec_init(struct snd_soc_pcm_runtime *rtd) 258 + static int max_98390_init(struct snd_soc_pcm_runtime *rtd) 249 259 { 250 260 struct snd_soc_card *card = rtd->card; 261 + unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID); 251 262 int ret; 252 263 253 - /* add regular speakers dapm route */ 254 - ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_dapm_routes, 255 - ARRAY_SIZE(max_98390_dapm_routes)); 256 - if (ret) { 257 - dev_err(rtd->dev, "unable to add Left/Right Speaker dapm, ret %d\n", ret); 258 - return ret; 259 - } 260 - 261 - /* add widgets/controls/dapm for tweeter speakers */ 262 - if (acpi_dev_present("MX98390", "3", -1)) { 264 + switch (num_codecs) { 265 + case 4: 266 + /* add widgets/controls/dapm for tweeter speakers */ 263 267 ret = snd_soc_dapm_new_controls(&card->dapm, max_98390_tt_dapm_widgets, 264 268 ARRAY_SIZE(max_98390_tt_dapm_widgets)); 265 - 266 269 if (ret) { 267 - dev_err(rtd->dev, "unable to add tweeter dapm controls, ret %d\n", ret); 270 + dev_err(rtd->dev, "unable to add tweeter dapm widgets, ret %d\n", 271 + ret); 268 272 /* Don't need to add routes if widget addition failed */ 269 273 return ret; 270 274 } ··· 266 282 ret = snd_soc_add_card_controls(card, max_98390_tt_kcontrols, 267 283 ARRAY_SIZE(max_98390_tt_kcontrols)); 268 284 if (ret) { 269 - dev_err(rtd->dev, "unable to add tweeter card controls, ret %d\n", ret); 285 + dev_err(rtd->dev, "unable to add tweeter controls, ret %d\n", 286 + ret); 270 287 return ret; 271 288 } 272 289 273 290 ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_tt_dapm_routes, 274 291 ARRAY_SIZE(max_98390_tt_dapm_routes)); 275 - if (ret) 276 - dev_err(rtd->dev, 277 - "unable to add Tweeter Left/Right Speaker dapm, ret %d\n", ret); 292 + if (ret) { 293 + dev_err(rtd->dev, "unable to add tweeter dapm routes, ret %d\n", 294 + ret); 295 + return ret; 296 + } 297 + 298 + fallthrough; 299 + case 2: 300 + /* add regular speakers dapm route */ 301 + ret = snd_soc_dapm_add_routes(&card->dapm, max_98390_dapm_routes, 302 + ARRAY_SIZE(max_98390_dapm_routes)); 303 + if (ret) { 304 + dev_err(rtd->dev, "unable to add dapm routes, ret %d\n", 305 + ret); 306 + return ret; 307 + } 308 + break; 309 + default: 310 + dev_err(rtd->dev, "invalid codec number %d\n", num_codecs); 311 + return -EINVAL; 278 312 } 313 + 279 314 return ret; 280 315 } 281 - EXPORT_SYMBOL_NS(max_98390_spk_codec_init, SND_SOC_INTEL_SOF_MAXIM_COMMON); 282 316 283 - const struct snd_soc_ops max_98390_ops = { 317 + static const struct snd_soc_ops max_98390_ops = { 284 318 .hw_params = max_98390_hw_params, 285 319 }; 286 - EXPORT_SYMBOL_NS(max_98390_ops, SND_SOC_INTEL_SOF_MAXIM_COMMON); 287 320 288 - void max_98390_set_codec_conf(struct snd_soc_card *card, int ch) 321 + void max_98390_dai_link(struct device *dev, struct snd_soc_dai_link *link) 289 322 { 290 - if (ch == ARRAY_SIZE(max_98390_4spk_codec_conf)) { 291 - card->codec_conf = max_98390_4spk_codec_conf; 292 - card->num_configs = ARRAY_SIZE(max_98390_4spk_codec_conf); 293 - } else { 294 - card->codec_conf = max_98390_codec_conf; 295 - card->num_configs = ARRAY_SIZE(max_98390_codec_conf); 323 + unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID); 324 + 325 + link->codecs = max_98390_components; 326 + 327 + switch (num_codecs) { 328 + case 2: 329 + case 4: 330 + link->num_codecs = num_codecs; 331 + break; 332 + default: 333 + dev_err(dev, "invalid codec number %d for %s\n", num_codecs, 334 + MAX_98390_ACPI_HID); 335 + break; 336 + } 337 + 338 + link->init = max_98390_init; 339 + link->ops = &max_98390_ops; 340 + } 341 + EXPORT_SYMBOL_NS(max_98390_dai_link, SND_SOC_INTEL_SOF_MAXIM_COMMON); 342 + 343 + void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card) 344 + { 345 + unsigned int num_codecs = get_num_codecs(MAX_98390_ACPI_HID); 346 + 347 + card->codec_conf = max_98390_codec_conf; 348 + 349 + switch (num_codecs) { 350 + case 2: 351 + case 4: 352 + card->num_configs = num_codecs; 353 + break; 354 + default: 355 + dev_err(dev, "invalid codec number %d for %s\n", num_codecs, 356 + MAX_98390_ACPI_HID); 357 + break; 296 358 } 297 359 } 298 360 EXPORT_SYMBOL_NS(max_98390_set_codec_conf, SND_SOC_INTEL_SOF_MAXIM_COMMON);
+8 -11
sound/soc/intel/boards/sof_maxim_common.h
··· 27 27 /* 28 28 * Maxim MAX98390 29 29 */ 30 - #define MAX_98390_CODEC_DAI "max98390-aif1" 31 - #define MAX_98390_DEV0_NAME "i2c-MX98390:00" 32 - #define MAX_98390_DEV1_NAME "i2c-MX98390:01" 33 - #define MAX_98390_DEV2_NAME "i2c-MX98390:02" 34 - #define MAX_98390_DEV3_NAME "i2c-MX98390:03" 30 + #define MAX_98390_ACPI_HID "MX98390" 31 + #define MAX_98390_CODEC_DAI "max98390-aif1" 32 + #define MAX_98390_DEV0_NAME "i2c-" MAX_98390_ACPI_HID ":00" 33 + #define MAX_98390_DEV1_NAME "i2c-" MAX_98390_ACPI_HID ":01" 34 + #define MAX_98390_DEV2_NAME "i2c-" MAX_98390_ACPI_HID ":02" 35 + #define MAX_98390_DEV3_NAME "i2c-" MAX_98390_ACPI_HID ":03" 35 36 36 - extern struct snd_soc_dai_link_component max_98390_components[2]; 37 - extern struct snd_soc_dai_link_component max_98390_4spk_components[4]; 38 - extern const struct snd_soc_ops max_98390_ops; 39 - 40 - void max_98390_set_codec_conf(struct snd_soc_card *card, int ch); 41 - int max_98390_spk_codec_init(struct snd_soc_pcm_runtime *rtd); 37 + void max_98390_dai_link(struct device *dev, struct snd_soc_dai_link *link); 38 + void max_98390_set_codec_conf(struct device *dev, struct snd_soc_card *card); 42 39 43 40 /* 44 41 * Maxim MAX98357A/MAX98360A
+2 -35
sound/soc/intel/boards/sof_rt5682.c
··· 59 59 #define SOF_SSP_BT_OFFLOAD_PRESENT BIT(22) 60 60 #define SOF_RT5682S_HEADPHONE_CODEC_PRESENT BIT(23) 61 61 #define SOF_MAX98390_SPEAKER_AMP_PRESENT BIT(24) 62 - #define SOF_MAX98390_TWEETER_SPEAKER_PRESENT BIT(25) 63 62 #define SOF_RT1019_SPEAKER_AMP_PRESENT BIT(26) 64 63 #define SOF_RT5650_HEADPHONE_CODEC_PRESENT BIT(27) 65 64 ··· 193 194 SOF_MAX98390_SPEAKER_AMP_PRESENT | 194 195 SOF_RT5682_SSP_AMP(2) | 195 196 SOF_RT5682_NUM_HDMIDEV(4)), 196 - }, 197 - { 198 - .callback = sof_rt5682_quirk_cb, 199 - .matches = { 200 - DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Brya"), 201 - DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98390_ALC5682I_I2S_4SPK"), 202 - }, 203 - .driver_data = (void *)(SOF_RT5682_MCLK_EN | 204 - SOF_RT5682_SSP_CODEC(0) | 205 - SOF_SPEAKER_AMP_PRESENT | 206 - SOF_MAX98390_SPEAKER_AMP_PRESENT | 207 - SOF_MAX98390_TWEETER_SPEAKER_PRESENT | 208 - SOF_RT5682_SSP_AMP(1) | 209 - SOF_RT5682_NUM_HDMIDEV(4) | 210 - SOF_BT_OFFLOAD_SSP(2) | 211 - SOF_SSP_BT_OFFLOAD_PRESENT), 212 - 213 197 }, 214 198 { 215 199 .callback = sof_rt5682_quirk_cb, ··· 832 850 sof_rt1011_dai_link(&links[id]); 833 851 } else if (sof_rt5682_quirk & 834 852 SOF_MAX98390_SPEAKER_AMP_PRESENT) { 835 - if (sof_rt5682_quirk & 836 - SOF_MAX98390_TWEETER_SPEAKER_PRESENT) { 837 - links[id].codecs = max_98390_4spk_components; 838 - links[id].num_codecs = ARRAY_SIZE(max_98390_4spk_components); 839 - } else { 840 - links[id].codecs = max_98390_components; 841 - links[id].num_codecs = ARRAY_SIZE(max_98390_components); 842 - } 843 - links[id].init = max_98390_spk_codec_init; 844 - links[id].ops = &max_98390_ops; 845 - 853 + max_98390_dai_link(dev, &links[id]); 846 854 } else if (sof_rt5682_quirk & SOF_RT5650_HEADPHONE_CODEC_PRESENT) { 847 855 links[id].codecs = &rt5650_components[1]; 848 856 links[id].num_codecs = 1; ··· 991 1019 else if (sof_rt5682_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) 992 1020 sof_rt1015p_codec_conf(&sof_audio_card_rt5682); 993 1021 else if (sof_rt5682_quirk & SOF_MAX98390_SPEAKER_AMP_PRESENT) { 994 - if (sof_rt5682_quirk & SOF_MAX98390_TWEETER_SPEAKER_PRESENT) 995 - max_98390_set_codec_conf(&sof_audio_card_rt5682, 996 - ARRAY_SIZE(max_98390_4spk_components)); 997 - else 998 - max_98390_set_codec_conf(&sof_audio_card_rt5682, 999 - ARRAY_SIZE(max_98390_components)); 1022 + max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682); 1000 1023 } 1001 1024 1002 1025 if (sof_rt5682_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)