248 lines · c
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 Corporation5 * Copyright(c) 2024 Advanced Micro Devices, Inc.6 *7 */8 9#ifndef SOC_SDW_UTILS_H10#define SOC_SDW_UTILS_H11 12#include <sound/soc.h>13#include <sound/soc-acpi.h>14 15#define SOC_SDW_MAX_DAI_NUM 816#define SOC_SDW_MAX_NO_PROPS 217#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 output26 * - SOC_SDW_CODEC_SPKR - CODEC internal speaker27 * - SOC_SDW_SIDECAR_AMPS - 2x Sidecar amplifiers + CODEC internal speaker28 * - SOC_SDW_CODEC_SPKR | SOF_SIDECAR_AMPS - Not currently supported29 */30#define SOC_SDW_SIDECAR_AMPS BIT(16)31 32#define SOC_SDW_UNUSED_DAI_ID -133#define SOC_SDW_JACK_OUT_DAI_ID 034#define SOC_SDW_JACK_IN_DAI_ID 135#define SOC_SDW_AMP_OUT_DAI_ID 236#define SOC_SDW_AMP_IN_DAI_ID 337#define SOC_SDW_DMIC_DAI_ID 438 39#define SOC_SDW_DAI_TYPE_JACK 040#define SOC_SDW_DAI_TYPE_AMP 141#define SOC_SDW_DAI_TYPE_MIC 242 43struct asoc_sdw_codec_info;44 45struct 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 64struct 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 84struct 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 96struct 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 108struct 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 117extern struct asoc_sdw_codec_info codec_info_list[];118int asoc_sdw_get_codec_info_list_count(void);119 120int asoc_sdw_startup(struct snd_pcm_substream *substream);121int asoc_sdw_prepare(struct snd_pcm_substream *substream);122int asoc_sdw_prepare(struct snd_pcm_substream *substream);123int asoc_sdw_trigger(struct snd_pcm_substream *substream, int cmd);124int asoc_sdw_hw_params(struct snd_pcm_substream *substream,125 struct snd_pcm_hw_params *params);126int asoc_sdw_hw_free(struct snd_pcm_substream *substream);127void asoc_sdw_shutdown(struct snd_pcm_substream *substream);128 129const 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 134struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_part(const u64 adr);135 136struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_acpi(const u8 *acpi_id);137 138struct asoc_sdw_codec_info *asoc_sdw_find_codec_info_dai(const char *dai_name,139 int *dai_index);140 141struct snd_soc_dai_link *asoc_sdw_mc_find_codec_dai_used(struct snd_soc_card *card,142 const char *dai_name);143 144void asoc_sdw_mc_dailink_exit_loop(struct snd_soc_card *card);145 146int asoc_sdw_card_late_probe(struct snd_soc_card *card);147 148void 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 156int 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 164int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends);165 166struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks,167 const struct snd_soc_acpi_endpoint *new);168 169int 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 174int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd);175 176/* DMIC support */177int asoc_sdw_dmic_init(struct snd_soc_pcm_runtime *rtd);178 179/* RT711 support */180int 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);184int asoc_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);185 186/* RT711-SDCA support */187int 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);191int asoc_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);192 193/* RT1308 I2S support */194extern const struct snd_soc_ops soc_sdw_rt1308_i2s_ops;195 196/* generic amp support */197int 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);201int asoc_sdw_rt_amp_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link);202 203/* CS42L43 support */204int 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 */210int asoc_sdw_bridge_cs35l56_count_sidecar(struct snd_soc_card *card,211 int *num_dais, int *num_devs);212int 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);215int 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 220int 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 */226int 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 */232int asoc_sdw_rt_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);233int asoc_sdw_rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);234int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);235int asoc_sdw_rt700_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);236int asoc_sdw_rt711_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);237int asoc_sdw_rt712_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);238int asoc_sdw_rt722_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);239int asoc_sdw_rt5682_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);240int asoc_sdw_cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);241int asoc_sdw_cs42l43_hs_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);242int asoc_sdw_cs42l43_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);243int asoc_sdw_cs42l43_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);244int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);245int asoc_sdw_maxim_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai);246 247#endif248