1 /* SPDX-License-Identifier: GPL-2.0-only */
3 * This file incorporates work covered by the following copyright notice:
4 * Copyright (c) 2020 Intel Corporation
5 * Copyright(c) 2024 Advanced Micro Devices, Inc.
9 #ifndef SOC_SDW_UTILS_H
10 #define SOC_SDW_UTILS_H
12 #include <sound/soc.h>
13 #include <sound/soc-acpi.h>
15 #define SOC_SDW_MAX_DAI_NUM 8
16 #define SOC_SDW_MAX_NO_PROPS 2
17 #define SOC_SDW_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0))
19 /* If a CODEC has an optional speaker output, this quirk will enable it */
20 #define SOC_SDW_CODEC_SPKR BIT(15)
22 * If the CODEC has additional devices attached directly to it.
25 * - 0 - No speaker output
26 * - SOC_SDW_CODEC_SPKR - CODEC internal speaker
27 * - SOC_SDW_SIDECAR_AMPS - 2x Sidecar amplifiers + CODEC internal speaker
28 * - SOC_SDW_CODEC_SPKR | SOF_SIDECAR_AMPS - Not currently supported
30 #define SOC_SDW_SIDECAR_AMPS BIT(16)
31 #define SOC_SDW_CODEC_MIC BIT(17)
33 #define SOC_SDW_UNUSED_DAI_ID -1
34 #define SOC_SDW_JACK_OUT_DAI_ID 0
35 #define SOC_SDW_JACK_IN_DAI_ID 1
36 #define SOC_SDW_AMP_OUT_DAI_ID 2
37 #define SOC_SDW_AMP_IN_DAI_ID 3
38 #define SOC_SDW_DMIC_DAI_ID 4
40 #define SOC_SDW_DAI_TYPE_JACK 0
41 #define SOC_SDW_DAI_TYPE_AMP 1
42 #define SOC_SDW_DAI_TYPE_MIC 2
44 struct asoc_sdw_codec_info
;
46 struct asoc_sdw_dai_info
{
47 const bool direction
[2]; /* playback & capture support */
50 const int dailink
[2]; /* dailink id for each direction */
51 const struct snd_kcontrol_new
*controls
;
52 const int num_controls
;
53 const struct snd_soc_dapm_widget
*widgets
;
54 const int num_widgets
;
55 int (*init
)(struct snd_soc_card
*card
,
56 struct snd_soc_dai_link
*dai_links
,
57 struct asoc_sdw_codec_info
*info
,
59 int (*exit
)(struct snd_soc_card
*card
, struct snd_soc_dai_link
*dai_link
);
60 int (*rtd_init
)(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);
61 bool rtd_init_done
; /* Indicate that the rtd_init callback is done */
66 struct asoc_sdw_codec_info
{
69 const char *codec_name
;
71 const u8 acpi_id
[ACPI_ID_LEN
];
72 const bool ignore_internal_dmic
;
73 const struct snd_soc_ops
*ops
;
74 struct asoc_sdw_dai_info dais
[SOC_SDW_MAX_DAI_NUM
];
77 int (*codec_card_late_probe
)(struct snd_soc_card
*card
);
79 int (*count_sidecar
)(struct snd_soc_card
*card
,
80 int *num_dais
, int *num_devs
);
81 int (*add_sidecar
)(struct snd_soc_card
*card
,
82 struct snd_soc_dai_link
**dai_links
,
83 struct snd_soc_codec_conf
**codec_conf
);
86 struct asoc_sdw_mc_private
{
87 struct snd_soc_card card
;
88 struct snd_soc_jack sdw_headset
;
89 struct device
*headset_codec_dev
; /* only one headset per card */
90 struct device
*amp_dev1
, *amp_dev2
;
92 bool ignore_internal_dmic
;
94 unsigned long mc_quirk
;
95 int codec_info_list_count
;
98 struct asoc_sdw_endpoint
{
99 struct list_head list
;
102 const char *codec_name
;
103 const char *name_prefix
;
104 bool include_sidecar
;
106 struct asoc_sdw_codec_info
*codec_info
;
107 const struct asoc_sdw_dai_info
*dai_info
;
110 struct asoc_sdw_dailink
{
114 u32 link_mask
[SNDRV_PCM_STREAM_LAST
+ 1];
115 int num_devs
[SNDRV_PCM_STREAM_LAST
+ 1];
116 struct list_head endpoints
;
119 extern struct asoc_sdw_codec_info codec_info_list
[];
120 int asoc_sdw_get_codec_info_list_count(void);
122 int asoc_sdw_startup(struct snd_pcm_substream
*substream
);
123 int asoc_sdw_prepare(struct snd_pcm_substream
*substream
);
124 int asoc_sdw_prepare(struct snd_pcm_substream
*substream
);
125 int asoc_sdw_trigger(struct snd_pcm_substream
*substream
, int cmd
);
126 int asoc_sdw_hw_params(struct snd_pcm_substream
*substream
,
127 struct snd_pcm_hw_params
*params
);
128 int asoc_sdw_hw_free(struct snd_pcm_substream
*substream
);
129 void asoc_sdw_shutdown(struct snd_pcm_substream
*substream
);
131 const char *asoc_sdw_get_codec_name(struct device
*dev
,
132 const struct asoc_sdw_codec_info
*codec_info
,
133 const struct snd_soc_acpi_link_adr
*adr_link
,
136 struct asoc_sdw_codec_info
*asoc_sdw_find_codec_info_part(const u64 adr
);
138 struct asoc_sdw_codec_info
*asoc_sdw_find_codec_info_acpi(const u8
*acpi_id
);
140 struct asoc_sdw_codec_info
*asoc_sdw_find_codec_info_dai(const char *dai_name
,
143 struct snd_soc_dai_link
*asoc_sdw_mc_find_codec_dai_used(struct snd_soc_card
*card
,
144 const char *dai_name
);
146 void asoc_sdw_mc_dailink_exit_loop(struct snd_soc_card
*card
);
148 int asoc_sdw_card_late_probe(struct snd_soc_card
*card
);
150 void asoc_sdw_init_dai_link(struct device
*dev
, struct snd_soc_dai_link
*dai_links
,
151 int *be_id
, char *name
, int playback
, int capture
,
152 struct snd_soc_dai_link_component
*cpus
, int cpus_num
,
153 struct snd_soc_dai_link_component
*platform_component
,
154 int num_platforms
, struct snd_soc_dai_link_component
*codecs
,
155 int codecs_num
, int no_pcm
,
156 int (*init
)(struct snd_soc_pcm_runtime
*rtd
),
157 const struct snd_soc_ops
*ops
);
159 int asoc_sdw_init_simple_dai_link(struct device
*dev
, struct snd_soc_dai_link
*dai_links
,
160 int *be_id
, char *name
, int playback
, int capture
,
161 const char *cpu_dai_name
, const char *platform_comp_name
,
162 int num_platforms
, const char *codec_name
,
163 const char *codec_dai_name
, int no_pcm
,
164 int (*init
)(struct snd_soc_pcm_runtime
*rtd
),
165 const struct snd_soc_ops
*ops
);
167 int asoc_sdw_count_sdw_endpoints(struct snd_soc_card
*card
, int *num_devs
, int *num_ends
);
169 struct asoc_sdw_dailink
*asoc_sdw_find_dailink(struct asoc_sdw_dailink
*dailinks
,
170 const struct snd_soc_acpi_endpoint
*new);
172 int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card
*card
,
173 struct asoc_sdw_dailink
*soc_dais
,
174 struct asoc_sdw_endpoint
*soc_ends
,
177 int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime
*rtd
);
180 int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime
*rtd
);
183 int asoc_sdw_rt711_init(struct snd_soc_card
*card
,
184 struct snd_soc_dai_link
*dai_links
,
185 struct asoc_sdw_codec_info
*info
,
187 int asoc_sdw_rt711_exit(struct snd_soc_card
*card
, struct snd_soc_dai_link
*dai_link
);
189 /* RT711-SDCA support */
190 int asoc_sdw_rt_sdca_jack_init(struct snd_soc_card
*card
,
191 struct snd_soc_dai_link
*dai_links
,
192 struct asoc_sdw_codec_info
*info
,
194 int asoc_sdw_rt_sdca_jack_exit(struct snd_soc_card
*card
, struct snd_soc_dai_link
*dai_link
);
196 /* RT1308 I2S support */
197 extern const struct snd_soc_ops soc_sdw_rt1308_i2s_ops
;
199 /* generic amp support */
200 int asoc_sdw_rt_amp_init(struct snd_soc_card
*card
,
201 struct snd_soc_dai_link
*dai_links
,
202 struct asoc_sdw_codec_info
*info
,
204 int asoc_sdw_rt_amp_exit(struct snd_soc_card
*card
, struct snd_soc_dai_link
*dai_link
);
206 /* CS42L43 support */
207 int asoc_sdw_cs42l43_spk_init(struct snd_soc_card
*card
,
208 struct snd_soc_dai_link
*dai_links
,
209 struct asoc_sdw_codec_info
*info
,
213 int asoc_sdw_bridge_cs35l56_count_sidecar(struct snd_soc_card
*card
,
214 int *num_dais
, int *num_devs
);
215 int asoc_sdw_bridge_cs35l56_add_sidecar(struct snd_soc_card
*card
,
216 struct snd_soc_dai_link
**dai_links
,
217 struct snd_soc_codec_conf
**codec_conf
);
218 int asoc_sdw_bridge_cs35l56_spk_init(struct snd_soc_card
*card
,
219 struct snd_soc_dai_link
*dai_links
,
220 struct asoc_sdw_codec_info
*info
,
223 int asoc_sdw_cs_amp_init(struct snd_soc_card
*card
,
224 struct snd_soc_dai_link
*dai_links
,
225 struct asoc_sdw_codec_info
*info
,
227 int asoc_sdw_cs_spk_feedback_rtd_init(struct snd_soc_pcm_runtime
*rtd
,
228 struct snd_soc_dai
*dai
);
230 /* MAXIM codec support */
231 int asoc_sdw_maxim_init(struct snd_soc_card
*card
,
232 struct snd_soc_dai_link
*dai_links
,
233 struct asoc_sdw_codec_info
*info
,
236 /* dai_link init callbacks */
237 int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);
238 int asoc_sdw_rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);
239 int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);
240 int asoc_sdw_rt700_rtd_init(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);
241 int asoc_sdw_rt711_rtd_init(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);
242 int asoc_sdw_rt_mf_sdca_spk_rtd_init(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);
243 int asoc_sdw_rt5682_rtd_init(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);
244 int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);
245 int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);
246 int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);
247 int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);
248 int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);
249 int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime
*rtd
, struct snd_soc_dai
*dai
);