Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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
45struct asoc_sdw_codec_info;
46
47struct 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
69struct asoc_sdw_aux_info {
70 const char *codec_name;
71};
72
73struct asoc_sdw_codec_info {
74 const int part_id;
75 const int version_id;
76 const char *name_prefix;
77 int amp_num;
78 const u8 acpi_id[ACPI_ID_LEN];
79 const bool ignore_internal_dmic;
80 const struct snd_soc_ops *ops;
81 struct asoc_sdw_dai_info dais[SOC_SDW_MAX_DAI_NUM];
82 const int dai_num;
83 struct asoc_sdw_aux_info auxs[SOC_SDW_MAX_AUX_NUM];
84 const int aux_num;
85
86 int (*codec_card_late_probe)(struct snd_soc_card *card);
87
88 int (*count_sidecar)(struct snd_soc_card *card,
89 int *num_dais, int *num_devs);
90 int (*add_sidecar)(struct snd_soc_card *card,
91 struct snd_soc_dai_link **dai_links,
92 struct snd_soc_codec_conf **codec_conf);
93};
94
95struct asoc_sdw_mc_private {
96 struct snd_soc_card card;
97 struct snd_soc_jack sdw_headset;
98 struct device *headset_codec_dev; /* only one headset per card */
99 struct device *amp_dev1, *amp_dev2;
100 bool append_dai_type;
101 bool ignore_internal_dmic;
102 void *private;
103 unsigned long mc_quirk;
104 int codec_info_list_count;
105};
106
107struct asoc_sdw_endpoint {
108 struct list_head list;
109
110 u32 link_mask;
111 const char *codec_name;
112 const char *name_prefix;
113 bool include_sidecar;
114
115 struct asoc_sdw_codec_info *codec_info;
116 const struct asoc_sdw_dai_info *dai_info;
117};
118
119struct asoc_sdw_dailink {
120 bool initialised;
121
122 u8 group_id;
123 u32 link_mask[SNDRV_PCM_STREAM_LAST + 1];
124 int num_devs[SNDRV_PCM_STREAM_LAST + 1];
125 struct list_head endpoints;
126};
127
128extern struct asoc_sdw_codec_info codec_info_list[];
129int asoc_sdw_get_codec_info_list_count(void);
130
131int asoc_sdw_startup(struct snd_pcm_substream *substream);
132int asoc_sdw_prepare(struct snd_pcm_substream *substream);
133int asoc_sdw_prepare(struct snd_pcm_substream *substream);
134int asoc_sdw_trigger(struct snd_pcm_substream *substream, int cmd);
135int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
136 struct snd_pcm_hw_params *params);
137int asoc_sdw_hw_free(struct snd_pcm_substream *substream);
138void asoc_sdw_shutdown(struct snd_pcm_substream *substream);
139
140const char *asoc_sdw_get_codec_name(struct device *dev,
141 const struct asoc_sdw_dai_info *dai_info,
142 const struct snd_soc_acpi_link_adr *adr_link,
143 int adr_index);
144
145struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr);
146
147struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id);
148
149struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name,
150 int *dai_index);
151
152struct snd_soc_dai_link *asoc_sdw_mc_find_codec_dai_used(struct snd_soc_card *card,
153 const char *dai_name);
154
155void asoc_sdw_mc_dailink_exit_loop(struct snd_soc_card *card);
156
157int asoc_sdw_card_late_probe(struct snd_soc_card *card);
158
159void asoc_sdw_init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
160 int *be_id, char *name, int playback, int capture,
161 struct snd_soc_dai_link_component *cpus, int cpus_num,
162 struct snd_soc_dai_link_component *platform_component,
163 int num_platforms, struct snd_soc_dai_link_component *codecs,
164 int codecs_num, int no_pcm,
165 int (*init)(struct snd_soc_pcm_runtime *rtd),
166 const struct snd_soc_ops *ops);
167
168int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links,
169 int *be_id, char *name, int playback, int capture,
170 const char *cpu_dai_name, const char *platform_comp_name,
171 const char *codec_name, const char *codec_dai_name,
172 int no_pcm, int (*init)(struct snd_soc_pcm_runtime *rtd),
173 const struct snd_soc_ops *ops);
174
175int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card,
176 int *num_devs, int *num_ends, int *num_aux);
177
178struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks,
179 const struct snd_soc_acpi_endpoint *new);
180int asoc_sdw_get_dai_type(u32 type);
181
182int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
183 struct snd_soc_aux_dev *soc_aux,
184 struct asoc_sdw_dailink *soc_dais,
185 struct asoc_sdw_endpoint *soc_ends,
186 int *num_devs);
187
188int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd);
189
190/* DMIC support */
191int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd);
192
193/* RT711 support */
194int asoc_sdw_rt711_init(struct snd_soc_card *card,
195 struct snd_soc_dai_link *dai_links,
196 struct asoc_sdw_codec_info *info,
197 bool playback);
198int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
199
200/* RT711-SDCA support */
201int asoc_sdw_rt_sdca_jack_init(struct snd_soc_card *card,
202 struct snd_soc_dai_link *dai_links,
203 struct asoc_sdw_codec_info *info,
204 bool playback);
205int asoc_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
206
207/* RT1308 I2S support */
208extern const struct snd_soc_ops soc_sdw_rt1308_i2s_ops;
209
210/* generic amp support */
211int asoc_sdw_rt_amp_init(struct snd_soc_card *card,
212 struct snd_soc_dai_link *dai_links,
213 struct asoc_sdw_codec_info *info,
214 bool playback);
215int asoc_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);
216
217/* CS42L43 support */
218int asoc_sdw_cs42l43_spk_init(struct snd_soc_card *card,
219 struct snd_soc_dai_link *dai_links,
220 struct asoc_sdw_codec_info *info,
221 bool playback);
222
223/* CS AMP support */
224int asoc_sdw_bridge_cs35l56_count_sidecar(struct snd_soc_card *card,
225 int *num_dais, int *num_devs);
226int asoc_sdw_bridge_cs35l56_add_sidecar(struct snd_soc_card *card,
227 struct snd_soc_dai_link **dai_links,
228 struct snd_soc_codec_conf **codec_conf);
229int asoc_sdw_bridge_cs35l56_spk_init(struct snd_soc_card *card,
230 struct snd_soc_dai_link *dai_links,
231 struct asoc_sdw_codec_info *info,
232 bool playback);
233
234int asoc_sdw_cs_amp_init(struct snd_soc_card *card,
235 struct snd_soc_dai_link *dai_links,
236 struct asoc_sdw_codec_info *info,
237 bool playback);
238int asoc_sdw_cs_spk_feedback_rtd_init(struct snd_soc_pcm_runtime *rtd,
239 struct snd_soc_dai *dai);
240int asoc_sdw_cs35l56_volume_limit(struct snd_soc_card *card, const char *name_prefix);
241
242/* MAXIM codec support */
243int asoc_sdw_maxim_init(struct snd_soc_card *card,
244 struct snd_soc_dai_link *dai_links,
245 struct asoc_sdw_codec_info *info,
246 bool playback);
247
248/* dai_link init callbacks */
249int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
250int asoc_sdw_rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
251int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
252int asoc_sdw_rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
253int asoc_sdw_rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
254int asoc_sdw_rt_mf_sdca_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
255int asoc_sdw_rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
256int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
257int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
258int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
259int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
260int asoc_sdw_cs42l45_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
261int asoc_sdw_cs42l45_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
262int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
263int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
264/* TI */
265int asoc_sdw_ti_amp_init(struct snd_soc_card *card,
266 struct snd_soc_dai_link *dai_links,
267 struct asoc_sdw_codec_info *info,
268 bool playback);
269int asoc_sdw_ti_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);
270int asoc_sdw_ti_amp_initial_settings(struct snd_soc_card *card,
271 const char *name_prefix);
272
273#endif