xref: /linux/include/sound/soc_sdw_utils.h (revision a8e7ef3cec99ba2487110e01d77a8a278593b3e9)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
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.
6  *
7  */
8 
9 #ifndef SOC_SDW_UTILS_H
10 #define SOC_SDW_UTILS_H
11 
12 #include <sound/soc.h>
13 #include <sound/soc-acpi.h>
14 
15 #define SOC_SDW_MAX_DAI_NUM             8
16 #define SOC_SDW_MAX_AUX_NUM		2
17 #define SOC_SDW_MAX_NO_PROPS		2
18 #define SOC_SDW_JACK_JDSRC(quirk)	((quirk) & GENMASK(3, 0))
19 
20 /* If a CODEC has an optional speaker output, this quirk will enable it */
21 #define SOC_SDW_CODEC_SPKR			BIT(15)
22 /*
23  * If the CODEC has additional devices attached directly to it.
24  *
25  * For the cs42l43:
26  *   - 0 - No speaker output
27  *   - SOC_SDW_CODEC_SPKR - CODEC internal speaker
28  *   - SOC_SDW_SIDECAR_AMPS - 2x Sidecar amplifiers + CODEC internal speaker
29  *   - SOC_SDW_CODEC_SPKR | SOF_SIDECAR_AMPS - Not currently supported
30  */
31 #define SOC_SDW_SIDECAR_AMPS		BIT(16)
32 #define SOC_SDW_CODEC_MIC		BIT(17)
33 
34 #define SOC_SDW_UNUSED_DAI_ID		-1
35 #define SOC_SDW_JACK_OUT_DAI_ID		0
36 #define SOC_SDW_JACK_IN_DAI_ID		1
37 #define SOC_SDW_AMP_OUT_DAI_ID		2
38 #define SOC_SDW_AMP_IN_DAI_ID		3
39 #define SOC_SDW_DMIC_DAI_ID		4
40 
41 #define SOC_SDW_DAI_TYPE_JACK		0
42 #define SOC_SDW_DAI_TYPE_AMP		1
43 #define SOC_SDW_DAI_TYPE_MIC		2
44 
45 struct asoc_sdw_codec_info;
46 
47 struct asoc_sdw_dai_info {
48 	const bool direction[2]; /* playback & capture support */
49 	const char *codec_name;
50 	const char *dai_name;
51 	const char *component_name;
52 	const int dai_type;
53 	const int dailink[2]; /* dailink id for each direction */
54 	const struct snd_kcontrol_new *controls;
55 	const int num_controls;
56 	const struct snd_soc_dapm_widget *widgets;
57 	const int num_widgets;
58 	int  (*init)(struct snd_soc_card *card,
59 		     struct snd_soc_dai_link *dai_links,
60 		     struct asoc_sdw_codec_info *info,
61 		     bool playback);
62 	int (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
63 	int (*rtd_init)(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
64 	bool rtd_init_done; /* Indicate that the rtd_init callback is done */
65 	unsigned long quirk;
66 	bool quirk_exclude;
67 };
68 
69 struct asoc_sdw_aux_info {
70 	const char *codec_name;
71 };
72 
73 struct asoc_sdw_codec_info {
74 	const int vendor_id;
75 	const int part_id;
76 	const int version_id;
77 	const char *name_prefix;
78 	int amp_num;
79 	const u8 acpi_id[ACPI_ID_LEN];
80 	const bool ignore_internal_dmic;
81 	const struct snd_soc_ops *ops;
82 	struct asoc_sdw_dai_info dais[SOC_SDW_MAX_DAI_NUM];
83 	const int dai_num;
84 	struct asoc_sdw_aux_info auxs[SOC_SDW_MAX_AUX_NUM];
85 	const int aux_num;
86 	/* Force AMP-style name_prefix handling (append AMP index) even if MIC/Jack DAIs exist */
87 	const bool is_amp;
88 
89 	int (*codec_card_late_probe)(struct snd_soc_card *card);
90 
91 	int  (*count_sidecar)(struct snd_soc_card *card,
92 			      int *num_dais, int *num_devs);
93 	int  (*add_sidecar)(struct snd_soc_card *card,
94 			    struct snd_soc_dai_link **dai_links,
95 			    struct snd_soc_codec_conf **codec_conf);
96 };
97 
98 struct asoc_sdw_mc_private {
99 	struct snd_soc_card card;
100 	struct snd_soc_jack sdw_headset;
101 	struct device *headset_codec_dev; /* only one headset per card */
102 	struct device *amp_dev1, *amp_dev2;
103 	bool append_dai_type;
104 	bool ignore_internal_dmic;
105 	void *private;
106 	unsigned long mc_quirk;
107 	int codec_info_list_count;
108 };
109 
110 struct asoc_sdw_endpoint {
111 	struct list_head list;
112 
113 	u32 link_mask;
114 	const char *codec_name;
115 	const char *name_prefix;
116 	bool include_sidecar;
117 
118 	struct asoc_sdw_codec_info *codec_info;
119 	const struct asoc_sdw_dai_info *dai_info;
120 };
121 
122 struct asoc_sdw_dailink {
123 	bool initialised;
124 
125 	u8 group_id;
126 	u32 link_mask[SNDRV_PCM_STREAM_LAST + 1];
127 	int num_devs[SNDRV_PCM_STREAM_LAST + 1];
128 	struct list_head endpoints;
129 };
130 
131 extern struct asoc_sdw_codec_info codec_info_list[];
132 int asoc_sdw_get_codec_info_list_count(void);
133 
134 int asoc_sdw_startup(struct snd_pcm_substream *substream);
135 int asoc_sdw_prepare(struct snd_pcm_substream *substream);
136 int asoc_sdw_prepare(struct snd_pcm_substream *substream);
137 int asoc_sdw_trigger(struct snd_pcm_substream *substream, int cmd);
138 int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
139 		       struct snd_pcm_hw_params *params);
140 int asoc_sdw_hw_free(struct snd_pcm_substream *substream);
141 void asoc_sdw_shutdown(struct snd_pcm_substream *substream);
142 
143 const char *asoc_sdw_get_codec_name(struct device *dev,
144 				    const struct asoc_sdw_dai_info *dai_info,
145 				    const struct snd_soc_acpi_link_adr *adr_link,
146 				    int adr_index);
147 
148 struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr);
149 
150 struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id);
151 
152 struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name,
153 							 int *dai_index);
154 
155 struct snd_soc_dai_link *asoc_sdw_mc_find_codec_dai_used(struct snd_soc_card *card,
156 							 const char *dai_name);
157 
158 void asoc_sdw_mc_dailink_exit_loop(struct snd_soc_card *card);
159 
160 int asoc_sdw_card_late_probe(struct snd_soc_card *card);
161 
162 void asoc_sdw_init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
163 			    int *be_id, char *name, int playback, int capture,
164 			    struct snd_soc_dai_link_component *cpus, int cpus_num,
165 			    struct snd_soc_dai_link_component *platform_component,
166 			    int num_platforms, struct snd_soc_dai_link_component *codecs,
167 			    int codecs_num, int no_pcm,
168 			    int (*init)(struct snd_soc_pcm_runtime *rtd),
169 			    const struct snd_soc_ops *ops);
170 
171 int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
172 				  int *be_id, char *name, int playback, int capture,
173 				  const char *cpu_dai_name, const char *platform_comp_name,
174 				  const char *codec_name, const char *codec_dai_name,
175 				  int no_pcm, int (*init)(struct snd_soc_pcm_runtime *rtd),
176 				  const struct snd_soc_ops *ops);
177 
178 int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card,
179 				 int *num_devs, int *num_ends, int *num_aux);
180 
181 struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks,
182 					       const struct snd_soc_acpi_endpoint *new);
183 int asoc_sdw_get_dai_type(u32 type);
184 
185 int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
186 				 struct snd_soc_aux_dev *soc_aux,
187 				 struct asoc_sdw_dailink *soc_dais,
188 				 struct asoc_sdw_endpoint *soc_ends,
189 				 int *num_devs);
190 
191 int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd);
192 
193 /* DMIC support */
194 int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd);
195 
196 /* RT711 support */
197 int asoc_sdw_rt711_init(struct snd_soc_card *card,
198 			struct snd_soc_dai_link *dai_links,
199 			struct asoc_sdw_codec_info *info,
200 			bool playback);
201 int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
202 
203 /* RT711-SDCA support */
204 int asoc_sdw_rt_sdca_jack_init(struct snd_soc_card *card,
205 			       struct snd_soc_dai_link *dai_links,
206 			       struct asoc_sdw_codec_info *info,
207 			       bool playback);
208 int asoc_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
209 
210 /* RT1308 I2S support */
211 extern const struct snd_soc_ops soc_sdw_rt1308_i2s_ops;
212 
213 /* generic amp support */
214 int asoc_sdw_rt_amp_init(struct snd_soc_card *card,
215 			 struct snd_soc_dai_link *dai_links,
216 			 struct asoc_sdw_codec_info *info,
217 			 bool playback);
218 int asoc_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
219 
220 /* CS42L43 support */
221 int asoc_sdw_cs42l43_spk_init(struct snd_soc_card *card,
222 			      struct snd_soc_dai_link *dai_links,
223 			      struct asoc_sdw_codec_info *info,
224 			      bool playback);
225 
226 /* CS AMP support */
227 int asoc_sdw_bridge_cs35l56_count_sidecar(struct snd_soc_card *card,
228 					  int *num_dais, int *num_devs);
229 int asoc_sdw_bridge_cs35l56_add_sidecar(struct snd_soc_card *card,
230 					struct snd_soc_dai_link **dai_links,
231 					struct snd_soc_codec_conf **codec_conf);
232 int asoc_sdw_bridge_cs35l56_spk_init(struct snd_soc_card *card,
233 				     struct snd_soc_dai_link *dai_links,
234 				     struct asoc_sdw_codec_info *info,
235 				     bool playback);
236 
237 int asoc_sdw_cs_amp_init(struct snd_soc_card *card,
238 			 struct snd_soc_dai_link *dai_links,
239 			 struct asoc_sdw_codec_info *info,
240 			 bool playback);
241 int asoc_sdw_cs_spk_feedback_rtd_init(struct snd_soc_pcm_runtime *rtd,
242 				      struct snd_soc_dai *dai);
243 int asoc_sdw_cs35l56_volume_limit(struct snd_soc_card *card, const char *name_prefix);
244 
245 /* MAXIM codec support */
246 int asoc_sdw_maxim_init(struct snd_soc_card *card,
247 			struct snd_soc_dai_link *dai_links,
248 			struct asoc_sdw_codec_info *info,
249 			bool playback);
250 
251 /* dai_link init callbacks */
252 int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
253 int asoc_sdw_rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
254 int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
255 int asoc_sdw_rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
256 int asoc_sdw_rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
257 int asoc_sdw_rt_mf_sdca_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
258 int asoc_sdw_rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
259 int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
260 int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
261 int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
262 int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
263 int asoc_sdw_cs42l45_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
264 int asoc_sdw_cs42l45_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
265 int asoc_sdw_cs47l47_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
266 int asoc_sdw_cs47l47_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
267 int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
268 int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
269 /* TI */
270 int asoc_sdw_ti_amp_init(struct snd_soc_card *card,
271 			 struct snd_soc_dai_link *dai_links,
272 			 struct asoc_sdw_codec_info *info,
273 			 bool playback);
274 int asoc_sdw_ti_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
275 int asoc_sdw_ti_amp_initial_settings(struct snd_soc_card *card,
276 				     const char *name_prefix);
277 
278 #endif
279