at v6.19 273 lines 10 kB view raw
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