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 | |
14 | static inline bool avs_mach_singular_ssp(struct snd_soc_acpi_mach *mach) |
15 | { |
16 | return hweight_long(w: mach->mach_params.i2s_link_mask) == 1; |
17 | } |
18 | |
19 | static inline u32 avs_mach_ssp_port(struct snd_soc_acpi_mach *mach) |
20 | { |
21 | return __ffs(mach->mach_params.i2s_link_mask); |
22 | } |
23 | |
24 | static 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(w: tdms[port]) == 1); |
29 | } |
30 | |
31 | static 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 | |
38 | static 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, port: *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 | |