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 #define SOC_SDW_CODEC_MIC BIT(17) 32 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 39 40 #define SOC_SDW_DAI_TYPE_JACK 0 41 #define SOC_SDW_DAI_TYPE_AMP 1 42 #define SOC_SDW_DAI_TYPE_MIC 2 43 44 struct asoc_sdw_codec_info; 45 46 struct asoc_sdw_dai_info { 47 const bool direction[2]; /* playback & capture support */ 48 const char *dai_name; 49 const char *component_name; 50 const int dai_type; 51 const int dailink[2]; /* dailink id for each direction */ 52 const struct snd_kcontrol_new *controls; 53 const int num_controls; 54 const struct snd_soc_dapm_widget *widgets; 55 const int num_widgets; 56 int (*init)(struct snd_soc_card *card, 57 struct snd_soc_dai_link *dai_links, 58 struct asoc_sdw_codec_info *info, 59 bool playback); 60 int (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 61 int (*rtd_init)(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 62 bool rtd_init_done; /* Indicate that the rtd_init callback is done */ 63 unsigned long quirk; 64 bool quirk_exclude; 65 }; 66 67 struct asoc_sdw_codec_info { 68 const int part_id; 69 const int version_id; 70 const char *codec_name; 71 int amp_num; 72 const u8 acpi_id[ACPI_ID_LEN]; 73 const bool ignore_internal_dmic; 74 const struct snd_soc_ops *ops; 75 struct asoc_sdw_dai_info dais[SOC_SDW_MAX_DAI_NUM]; 76 const int dai_num; 77 78 int (*codec_card_late_probe)(struct snd_soc_card *card); 79 80 int (*count_sidecar)(struct snd_soc_card *card, 81 int *num_dais, int *num_devs); 82 int (*add_sidecar)(struct snd_soc_card *card, 83 struct snd_soc_dai_link **dai_links, 84 struct snd_soc_codec_conf **codec_conf); 85 }; 86 87 struct asoc_sdw_mc_private { 88 struct snd_soc_card card; 89 struct snd_soc_jack sdw_headset; 90 struct device *headset_codec_dev; /* only one headset per card */ 91 struct device *amp_dev1, *amp_dev2; 92 bool append_dai_type; 93 bool ignore_internal_dmic; 94 void *private; 95 unsigned long mc_quirk; 96 int codec_info_list_count; 97 }; 98 99 struct asoc_sdw_endpoint { 100 struct list_head list; 101 102 u32 link_mask; 103 const char *codec_name; 104 const char *name_prefix; 105 bool include_sidecar; 106 107 struct asoc_sdw_codec_info *codec_info; 108 const struct asoc_sdw_dai_info *dai_info; 109 }; 110 111 struct asoc_sdw_dailink { 112 bool initialised; 113 114 u8 group_id; 115 u32 link_mask[SNDRV_PCM_STREAM_LAST + 1]; 116 int num_devs[SNDRV_PCM_STREAM_LAST + 1]; 117 struct list_head endpoints; 118 }; 119 120 extern struct asoc_sdw_codec_info codec_info_list[]; 121 int asoc_sdw_get_codec_info_list_count(void); 122 123 int asoc_sdw_startup(struct snd_pcm_substream *substream); 124 int asoc_sdw_prepare(struct snd_pcm_substream *substream); 125 int asoc_sdw_prepare(struct snd_pcm_substream *substream); 126 int asoc_sdw_trigger(struct snd_pcm_substream *substream, int cmd); 127 int asoc_sdw_hw_params(struct snd_pcm_substream *substream, 128 struct snd_pcm_hw_params *params); 129 int asoc_sdw_hw_free(struct snd_pcm_substream *substream); 130 void asoc_sdw_shutdown(struct snd_pcm_substream *substream); 131 132 const char *asoc_sdw_get_codec_name(struct device *dev, 133 const struct asoc_sdw_codec_info *codec_info, 134 const struct snd_soc_acpi_link_adr *adr_link, 135 int adr_index); 136 137 struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr); 138 139 struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id); 140 141 struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name, 142 int *dai_index); 143 144 struct snd_soc_dai_link *asoc_sdw_mc_find_codec_dai_used(struct snd_soc_card *card, 145 const char *dai_name); 146 147 void asoc_sdw_mc_dailink_exit_loop(struct snd_soc_card *card); 148 149 int asoc_sdw_card_late_probe(struct snd_soc_card *card); 150 151 void asoc_sdw_init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, 152 int *be_id, char *name, int playback, int capture, 153 struct snd_soc_dai_link_component *cpus, int cpus_num, 154 struct snd_soc_dai_link_component *platform_component, 155 int num_platforms, struct snd_soc_dai_link_component *codecs, 156 int codecs_num, int no_pcm, 157 int (*init)(struct snd_soc_pcm_runtime *rtd), 158 const struct snd_soc_ops *ops); 159 160 int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *dai_links, 161 int *be_id, char *name, int playback, int capture, 162 const char *cpu_dai_name, const char *platform_comp_name, 163 const char *codec_name, const char *codec_dai_name, 164 int no_pcm, int (*init)(struct snd_soc_pcm_runtime *rtd), 165 const struct snd_soc_ops *ops); 166 167 int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends); 168 169 struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks, 170 const struct snd_soc_acpi_endpoint *new); 171 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, 175 int *num_devs); 176 177 int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd); 178 179 /* DMIC support */ 180 int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd); 181 182 /* RT711 support */ 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, 186 bool playback); 187 int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 188 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, 193 bool playback); 194 int asoc_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 195 196 /* RT1308 I2S support */ 197 extern const struct snd_soc_ops soc_sdw_rt1308_i2s_ops; 198 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, 203 bool playback); 204 int asoc_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); 205 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, 210 bool playback); 211 212 /* CS AMP support */ 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, 221 bool playback); 222 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, 226 bool playback); 227 int asoc_sdw_cs_spk_feedback_rtd_init(struct snd_soc_pcm_runtime *rtd, 228 struct snd_soc_dai *dai); 229 int asoc_sdw_cs35l56_volume_limit(struct snd_soc_card *card, const char *name_prefix); 230 231 /* MAXIM codec support */ 232 int asoc_sdw_maxim_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 /* dai_link init callbacks */ 238 int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 239 int asoc_sdw_rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 240 int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 241 int asoc_sdw_rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 242 int asoc_sdw_rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 243 int asoc_sdw_rt_mf_sdca_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 244 int asoc_sdw_rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 245 int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 246 int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 247 int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 248 int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 249 int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 250 int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); 251 252 #endif 253