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