soc_sdw_utils.h 9.8 KB

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