Warning: This file is not a C or C++ file. It does not have highlighting.
| 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 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 | |
| 95 | struct 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 | |
| 107 | struct 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 | |
| 119 | struct 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 | |
| 128 | extern struct asoc_sdw_codec_info codec_info_list[]; |
| 129 | int asoc_sdw_get_codec_info_list_count(void); |
| 130 | |
| 131 | int asoc_sdw_startup(struct snd_pcm_substream *substream); |
| 132 | int asoc_sdw_prepare(struct snd_pcm_substream *substream); |
| 133 | int asoc_sdw_prepare(struct snd_pcm_substream *substream); |
| 134 | int asoc_sdw_trigger(struct snd_pcm_substream *substream, int cmd); |
| 135 | int asoc_sdw_hw_params(struct snd_pcm_substream *substream, |
| 136 | struct snd_pcm_hw_params *params); |
| 137 | int asoc_sdw_hw_free(struct snd_pcm_substream *substream); |
| 138 | void asoc_sdw_shutdown(struct snd_pcm_substream *substream); |
| 139 | |
| 140 | const 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 | |
| 145 | struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr); |
| 146 | |
| 147 | struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id); |
| 148 | |
| 149 | struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name, |
| 150 | int *dai_index); |
| 151 | |
| 152 | struct snd_soc_dai_link *asoc_sdw_mc_find_codec_dai_used(struct snd_soc_card *card, |
| 153 | const char *dai_name); |
| 154 | |
| 155 | void asoc_sdw_mc_dailink_exit_loop(struct snd_soc_card *card); |
| 156 | |
| 157 | int asoc_sdw_card_late_probe(struct snd_soc_card *card); |
| 158 | |
| 159 | void 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 | |
| 168 | int 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 | |
| 175 | int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, |
| 176 | int *num_devs, int *num_ends, int *num_aux); |
| 177 | |
| 178 | struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks, |
| 179 | const struct snd_soc_acpi_endpoint *new); |
| 180 | int asoc_sdw_get_dai_type(u32 type); |
| 181 | |
| 182 | int 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 | |
| 188 | int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd); |
| 189 | |
| 190 | /* DMIC support */ |
| 191 | int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd); |
| 192 | |
| 193 | /* RT711 support */ |
| 194 | int 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); |
| 198 | int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); |
| 199 | |
| 200 | /* RT711-SDCA support */ |
| 201 | int 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); |
| 205 | int asoc_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); |
| 206 | |
| 207 | /* RT1308 I2S support */ |
| 208 | extern const struct snd_soc_ops soc_sdw_rt1308_i2s_ops; |
| 209 | |
| 210 | /* generic amp support */ |
| 211 | int 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); |
| 215 | int asoc_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); |
| 216 | |
| 217 | /* CS42L43 support */ |
| 218 | int 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 */ |
| 224 | int asoc_sdw_bridge_cs35l56_count_sidecar(struct snd_soc_card *card, |
| 225 | int *num_dais, int *num_devs); |
| 226 | int 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); |
| 229 | int 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 | |
| 234 | int 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); |
| 238 | int asoc_sdw_cs_spk_feedback_rtd_init(struct snd_soc_pcm_runtime *rtd, |
| 239 | struct snd_soc_dai *dai); |
| 240 | int asoc_sdw_cs35l56_volume_limit(struct snd_soc_card *card, const char *name_prefix); |
| 241 | |
| 242 | /* MAXIM codec support */ |
| 243 | int 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 */ |
| 249 | int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 250 | int asoc_sdw_rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 251 | int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 252 | int asoc_sdw_rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 253 | int asoc_sdw_rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 254 | int asoc_sdw_rt_mf_sdca_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 255 | int asoc_sdw_rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 256 | int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 257 | int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 258 | int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 259 | int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 260 | int asoc_sdw_cs42l45_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 261 | int asoc_sdw_cs42l45_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 262 | int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 263 | int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 264 | /* TI */ |
| 265 | int 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); |
| 269 | int asoc_sdw_ti_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); |
| 270 | int asoc_sdw_ti_amp_initial_settings(struct snd_soc_card *card, |
| 271 | const char *name_prefix); |
| 272 | |
| 273 | #endif |
| 274 |
Warning: This file is not a C or C++ file. It does not have highlighting.
