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_mc_private { 48 struct snd_soc_card card; 49 struct snd_soc_jack sdw_headset; 50 struct device *headset_codec_dev; /* only one headset per card */ 51 struct device *amp_dev1, *amp_dev2; 52 bool append_dai_type; 53 bool ignore_internal_dmic; 54 void *private; 55 unsigned long mc_quirk; 56 int codec_info_list_count; 57 }; 58 59 struct asoc_sdw_dai_info { 60 const bool direction[2]; /* playback & capture support */ 61 const char *codec_name; 62 const char *dai_name; 63 const char *component_name; 64 const int dai_type; 65 const int dailink[2]; /* dailink id for each direction */ 66 const struct snd_kcontrol_new *controls; 67 const int num_controls; 68 const struct snd_soc_dapm_widget *widgets; 69 const int num_widgets; 70 int (*init)(struct snd_soc_card *card, 71 struct snd_soc_dai_link *dai_links, 72 struct asoc_sdw_codec_info *info, 73 bool playback); 74 int (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 75 int (*rtd_init)(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 76 bool rtd_init_done; /* Indicate that the rtd_init callback is done */ 77 unsigned long quirk; 78 bool quirk_exclude; 79 }; 80 81 struct asoc_sdw_aux_info { 82 const char *codec_name; 83 }; 84 85 struct asoc_sdw_codec_info { 86 const int vendor_id; 87 const int part_id; 88 const int version_id; 89 const char *name_prefix; 90 int amp_num; 91 const u8 acpi_id[ACPI_ID_LEN]; 92 const bool ignore_internal_dmic; 93 const struct snd_soc_ops *ops; 94 struct asoc_sdw_dai_info dais[SOC_SDW_MAX_DAI_NUM]; 95 const int dai_num; 96 struct asoc_sdw_aux_info auxs[SOC_SDW_MAX_AUX_NUM]; 97 const int aux_num; 98 /* Force AMP-style name_prefix handling (append AMP index) even if MIC/Jack DAIs exist */ 99 const bool is_amp; 100 101 int (*codec_card_late_probe)(struct snd_soc_card *card); 102 103 int (*count_sidecar)(struct asoc_sdw_mc_private *ctx, 104 int *num_dais, int *num_devs); 105 int (*add_sidecar)(struct snd_soc_card *card, 106 struct snd_soc_dai_link **dai_links, 107 struct snd_soc_codec_conf **codec_conf); 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 device *dev, 186 struct asoc_sdw_mc_private *ctx, 187 struct snd_soc_aux_dev *soc_aux, 188 struct asoc_sdw_dailink *soc_dais, 189 struct asoc_sdw_endpoint *soc_ends, 190 int *num_devs); 191 192 int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd); 193 194 /* DMIC support */ 195 int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd); 196 197 /* RT711 support */ 198 int asoc_sdw_rt711_init(struct snd_soc_card *card, 199 struct snd_soc_dai_link *dai_links, 200 struct asoc_sdw_codec_info *info, 201 bool playback); 202 int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 203 204 /* RT711-SDCA support */ 205 int asoc_sdw_rt_sdca_jack_init(struct snd_soc_card *card, 206 struct snd_soc_dai_link *dai_links, 207 struct asoc_sdw_codec_info *info, 208 bool playback); 209 int asoc_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 210 211 /* RT1308 I2S support */ 212 extern const struct snd_soc_ops soc_sdw_rt1308_i2s_ops; 213 214 /* generic amp support */ 215 int asoc_sdw_rt_amp_init(struct snd_soc_card *card, 216 struct snd_soc_dai_link *dai_links, 217 struct asoc_sdw_codec_info *info, 218 bool playback); 219 int asoc_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 220 221 /* CS42L43 support */ 222 int asoc_sdw_cs42l43_spk_init(struct snd_soc_card *card, 223 struct snd_soc_dai_link *dai_links, 224 struct asoc_sdw_codec_info *info, 225 bool playback); 226 227 /* es9356 codec support */ 228 int asoc_sdw_es9356_init(struct snd_soc_card *card, 229 struct snd_soc_dai_link *dai_links, 230 struct asoc_sdw_codec_info *info, 231 bool playback); 232 int asoc_sdw_es9356_amp_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 int asoc_sdw_es9356_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 237 238 /* CS AMP support */ 239 int asoc_sdw_bridge_cs35l56_count_sidecar(struct asoc_sdw_mc_private *ctx, 240 int *num_dais, int *num_devs); 241 int asoc_sdw_bridge_cs35l56_add_sidecar(struct snd_soc_card *card, 242 struct snd_soc_dai_link **dai_links, 243 struct snd_soc_codec_conf **codec_conf); 244 int asoc_sdw_bridge_cs35l56_spk_init(struct snd_soc_card *card, 245 struct snd_soc_dai_link *dai_links, 246 struct asoc_sdw_codec_info *info, 247 bool playback); 248 249 int asoc_sdw_cs_amp_init(struct snd_soc_card *card, 250 struct snd_soc_dai_link *dai_links, 251 struct asoc_sdw_codec_info *info, 252 bool playback); 253 int asoc_sdw_cs_spk_feedback_rtd_init(struct snd_soc_pcm_runtime *rtd, 254 struct snd_soc_dai *dai); 255 int asoc_sdw_cs35l56_volume_limit(struct snd_soc_card *card, const char *name_prefix); 256 257 /* MAXIM codec support */ 258 int asoc_sdw_maxim_init(struct snd_soc_card *card, 259 struct snd_soc_dai_link *dai_links, 260 struct asoc_sdw_codec_info *info, 261 bool playback); 262 263 /* dai_link init callbacks */ 264 int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 265 int asoc_sdw_rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 266 int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 267 int asoc_sdw_rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 268 int asoc_sdw_rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 269 int asoc_sdw_rt_mf_sdca_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 270 int asoc_sdw_rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 271 int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 272 int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 273 int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 274 int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 275 int asoc_sdw_cs42l45_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 276 int asoc_sdw_cs42l45_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 277 int asoc_sdw_cs47l47_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 278 int asoc_sdw_cs47l47_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 279 int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 280 int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 281 /* TI */ 282 int asoc_sdw_ti_amp_init(struct snd_soc_card *card, 283 struct snd_soc_dai_link *dai_links, 284 struct asoc_sdw_codec_info *info, 285 bool playback); 286 int asoc_sdw_ti_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 287 int asoc_sdw_ti_tac5xx2_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, 288 struct snd_soc_dai *dai); 289 int asoc_sdw_ti_amp_initial_settings(struct snd_soc_card *card, 290 const char *name_prefix); 291 int asoc_sdw_ti_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 292 int asoc_sdw_ti_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 293 int asoc_sdw_es9356_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 294 int asoc_sdw_es9356_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 295 int asoc_sdw_es9356_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 296 297 #endif 298