utils.h 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright(c) 2023 Intel Corporation
  4. *
  5. * Authors: Cezary Rojewski <cezary.rojewski@intel.com>
  6. * Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
  7. */
  8. #ifndef __SOUND_SOC_INTEL_AVS_UTILS_H
  9. #define __SOUND_SOC_INTEL_AVS_UTILS_H
  10. #include <sound/soc-acpi.h>
  11. static inline bool avs_mach_singular_ssp(struct snd_soc_acpi_mach *mach)
  12. {
  13. return hweight_long(mach->mach_params.i2s_link_mask) == 1;
  14. }
  15. static inline u32 avs_mach_ssp_port(struct snd_soc_acpi_mach *mach)
  16. {
  17. return __ffs(mach->mach_params.i2s_link_mask);
  18. }
  19. static inline bool avs_mach_singular_tdm(struct snd_soc_acpi_mach *mach, u32 port)
  20. {
  21. unsigned long *tdms = mach->pdata;
  22. return !tdms || (hweight_long(tdms[port]) == 1);
  23. }
  24. static inline u32 avs_mach_ssp_tdm(struct snd_soc_acpi_mach *mach, u32 port)
  25. {
  26. unsigned long *tdms = mach->pdata;
  27. return tdms ? __ffs(tdms[port]) : 0;
  28. }
  29. static inline int avs_mach_get_ssp_tdm(struct device *dev, struct snd_soc_acpi_mach *mach,
  30. int *ssp_port, int *tdm_slot)
  31. {
  32. int port;
  33. if (!avs_mach_singular_ssp(mach)) {
  34. dev_err(dev, "Invalid SSP configuration\n");
  35. return -EINVAL;
  36. }
  37. port = avs_mach_ssp_port(mach);
  38. if (!avs_mach_singular_tdm(mach, port)) {
  39. dev_err(dev, "Invalid TDM configuration\n");
  40. return -EINVAL;
  41. }
  42. *ssp_port = port;
  43. *tdm_slot = avs_mach_ssp_tdm(mach, *ssp_port);
  44. return 0;
  45. }
  46. /*
  47. * Macro to easily generate format strings
  48. */
  49. #define AVS_STRING_FMT(prefix, suffix, ssp, tdm) \
  50. (tdm) ? prefix "%d:%d" suffix : prefix "%d" suffix, (ssp), (tdm)
  51. #endif