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_NO_PROPS 2 17 #define SOC_SDW_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0)) 18 19 /* If a CODEC has an optional speaker output, this quirk will enable it */ 20 #define SOC_SDW_CODEC_SPKR BIT(15) 21 /* 22 * If the CODEC has additional devices attached directly to it. 23 * 24 * For the cs42l43: 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 29 */ 30 #define SOC_SDW_SIDECAR_AMPS BIT(16) 31 32 #define SOC_SDW_UNUSED_DAI_ID -1 33 #define SOC_SDW_JACK_OUT_DAI_ID 0 34 #define SOC_SDW_JACK_IN_DAI_ID 1 35 #define SOC_SDW_AMP_OUT_DAI_ID 2 36 #define SOC_SDW_AMP_IN_DAI_ID 3 37 #define SOC_SDW_DMIC_DAI_ID 4 38 39 #define SOC_SDW_DAI_TYPE_JACK 0 40 #define SOC_SDW_DAI_TYPE_AMP 1 41 #define SOC_SDW_DAI_TYPE_MIC 2 42 43 struct asoc_sdw_codec_info; 44 45 struct asoc_sdw_dai_info { 46 const bool direction[2]; /* playback & capture support */ 47 const char *dai_name; 48 const int dai_type; 49 const int dailink[2]; /* dailink id for each direction */ 50 const struct snd_kcontrol_new *controls; 51 const int num_controls; 52 const struct snd_soc_dapm_widget *widgets; 53 const int num_widgets; 54 int (*init)(struct snd_soc_card *card, 55 struct snd_soc_dai_link *dai_links, 56 struct asoc_sdw_codec_info *info, 57 bool playback); 58 int (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 59 int (*rtd_init)(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 60 bool rtd_init_done; /* Indicate that the rtd_init callback is done */ 61 unsigned long quirk; 62 }; 63 64 struct asoc_sdw_codec_info { 65 const int part_id; 66 const int version_id; 67 const char *codec_name; 68 int amp_num; 69 const u8 acpi_id[ACPI_ID_LEN]; 70 const bool ignore_internal_dmic; 71 const struct snd_soc_ops *ops; 72 struct asoc_sdw_dai_info dais[SOC_SDW_MAX_DAI_NUM]; 73 const int dai_num; 74 75 int (*codec_card_late_probe)(struct snd_soc_card *card); 76 77 int (*count_sidecar)(struct snd_soc_card *card, 78 int *num_dais, int *num_devs); 79 int (*add_sidecar)(struct snd_soc_card *card, 80 struct snd_soc_dai_link **dai_links, 81 struct snd_soc_codec_conf **codec_conf); 82 }; 83 84 struct asoc_sdw_mc_private { 85 struct snd_soc_card card; 86 struct snd_soc_jack sdw_headset; 87 struct device *headset_codec_dev; /* only one headset per card */ 88 struct device *amp_dev1, *amp_dev2; 89 bool append_dai_type; 90 bool ignore_internal_dmic; 91 void *private; 92 unsigned long mc_quirk; 93 int codec_info_list_count; 94 }; 95 96 struct asoc_sdw_endpoint { 97 struct list_head list; 98 99 u32 link_mask; 100 const char *codec_name; 101 const char *name_prefix; 102 bool include_sidecar; 103 104 struct asoc_sdw_codec_info *codec_info; 105 const struct asoc_sdw_dai_info *dai_info; 106 }; 107 108 struct asoc_sdw_dailink { 109 bool initialised; 110 111 u8 group_id; 112 u32 link_mask[SNDRV_PCM_STREAM_LAST + 1]; 113 int num_devs[SNDRV_PCM_STREAM_LAST + 1]; 114 struct list_head endpoints; 115 }; 116 117 extern struct asoc_sdw_codec_info codec_info_list[]; 118 int asoc_sdw_get_codec_info_list_count(void); 119 120 int asoc_sdw_startup(struct snd_pcm_substream *substream); 121 int asoc_sdw_prepare(struct snd_pcm_substream *substream); 122 int asoc_sdw_prepare(struct snd_pcm_substream *substream); 123 int asoc_sdw_trigger(struct snd_pcm_substream *substream, int cmd); 124 int asoc_sdw_hw_params(struct snd_pcm_substream *substream, 125 struct snd_pcm_hw_params *params); 126 int asoc_sdw_hw_free(struct snd_pcm_substream *substream); 127 void asoc_sdw_shutdown(struct snd_pcm_substream *substream); 128 129 const char *asoc_sdw_get_codec_name(struct device *dev, 130 const struct asoc_sdw_codec_info *codec_info, 131 const struct snd_soc_acpi_link_adr *adr_link, 132 int adr_index); 133 134 struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr); 135 136 struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id); 137 138 struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name, 139 int *dai_index); 140 141 struct snd_soc_dai_link *asoc_sdw_mc_find_codec_dai_used(struct snd_soc_card *card, 142 const char *dai_name); 143 144 void asoc_sdw_mc_dailink_exit_loop(struct snd_soc_card *card); 145 146 int asoc_sdw_card_late_probe(struct snd_soc_card *card); 147 148 void asoc_sdw_init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, 149 int *be_id, char *name, int playback, int capture, 150 struct snd_soc_dai_link_component *cpus, int cpus_num, 151 struct snd_soc_dai_link_component *platform_component, 152 int num_platforms, struct snd_soc_dai_link_component *codecs, 153 int codecs_num, int (*init)(struct snd_soc_pcm_runtime *rtd), 154 const struct snd_soc_ops *ops); 155 156 int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, 157 int *be_id, char *name, int playback, int capture, 158 const char *cpu_dai_name, const char *platform_comp_name, 159 int num_platforms, const char *codec_name, 160 const char *codec_dai_name, 161 int (*init)(struct snd_soc_pcm_runtime *rtd), 162 const struct snd_soc_ops *ops); 163 164 int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends); 165 166 struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks, 167 const struct snd_soc_acpi_endpoint *new); 168 169 int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card, 170 struct asoc_sdw_dailink *soc_dais, 171 struct asoc_sdw_endpoint *soc_ends, 172 int *num_devs); 173 174 int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd); 175 176 /* DMIC support */ 177 int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd); 178 179 /* RT711 support */ 180 int asoc_sdw_rt711_init(struct snd_soc_card *card, 181 struct snd_soc_dai_link *dai_links, 182 struct asoc_sdw_codec_info *info, 183 bool playback); 184 int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 185 186 /* RT711-SDCA support */ 187 int asoc_sdw_rt_sdca_jack_init(struct snd_soc_card *card, 188 struct snd_soc_dai_link *dai_links, 189 struct asoc_sdw_codec_info *info, 190 bool playback); 191 int asoc_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 192 193 /* RT1308 I2S support */ 194 extern const struct snd_soc_ops soc_sdw_rt1308_i2s_ops; 195 196 /* generic amp support */ 197 int asoc_sdw_rt_amp_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_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 202 203 /* CS42L43 support */ 204 int asoc_sdw_cs42l43_spk_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 209 /* CS AMP support */ 210 int asoc_sdw_bridge_cs35l56_count_sidecar(struct snd_soc_card *card, 211 int *num_dais, int *num_devs); 212 int asoc_sdw_bridge_cs35l56_add_sidecar(struct snd_soc_card *card, 213 struct snd_soc_dai_link **dai_links, 214 struct snd_soc_codec_conf **codec_conf); 215 int asoc_sdw_bridge_cs35l56_spk_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 220 int asoc_sdw_cs_amp_init(struct snd_soc_card *card, 221 struct snd_soc_dai_link *dai_links, 222 struct asoc_sdw_codec_info *info, 223 bool playback); 224 225 /* MAXIM codec support */ 226 int asoc_sdw_maxim_init(struct snd_soc_card *card, 227 struct snd_soc_dai_link *dai_links, 228 struct asoc_sdw_codec_info *info, 229 bool playback); 230 231 /* dai_link init callbacks */ 232 int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 233 int asoc_sdw_rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 234 int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 235 int asoc_sdw_rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 236 int asoc_sdw_rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 237 int asoc_sdw_rt712_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 238 int asoc_sdw_rt722_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 239 int asoc_sdw_rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 240 int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 241 int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 242 int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 243 int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 244 int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 245 int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 246 247 #endif 248