1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * The MIPI SDCA specification is available for public downloads at 4 * https://www.mipi.org/mipi-sdca-v1-0-download 5 * 6 * Copyright (C) 2025 Cirrus Logic, Inc. and 7 * Cirrus Logic International Semiconductor Ltd. 8 */ 9 10 #ifndef __SDCA_ASOC_H__ 11 #define __SDCA_ASOC_H__ 12 13 struct device; 14 struct regmap; 15 struct sdca_function_data; 16 struct snd_ctl_elem_value; 17 struct snd_kcontrol; 18 struct snd_kcontrol_new; 19 struct snd_pcm_hw_params; 20 struct snd_pcm_substream; 21 struct snd_soc_component_driver; 22 struct snd_soc_dai; 23 struct snd_soc_dai_driver; 24 struct snd_soc_dai_ops; 25 struct snd_soc_dapm_route; 26 struct snd_soc_dapm_widget; 27 28 /* convenient macro to handle the mono volume in 7.8 fixed format representation */ 29 #define SDCA_SINGLE_Q78_TLV(xname, xreg, xmin, xmax, xstep, tlv_array) \ 30 { \ 31 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 32 .name = (xname), \ 33 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 34 .tlv.p = (tlv_array), \ 35 .info = snd_soc_info_volsw, \ 36 .get = sdca_asoc_q78_get_volsw, \ 37 .put = sdca_asoc_q78_put_volsw, \ 38 .private_value = (unsigned long)&(struct soc_mixer_control) { \ 39 .reg = (xreg), .rreg = (xreg), \ 40 .min = (xmin), .max = (xmax), \ 41 .shift = (xstep), .rshift = (xstep), \ 42 .sign_bit = 15 \ 43 } \ 44 } 45 46 /* convenient macro for stereo volume in 7.8 fixed format with separate registers for L/R */ 47 #define SDCA_DOUBLE_Q78_TLV(xname, xreg_l, xreg_r, xmin, xmax, xstep, tlv_array) \ 48 { \ 49 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 50 .name = (xname), \ 51 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE, \ 52 .tlv.p = (tlv_array), \ 53 .info = snd_soc_info_volsw, \ 54 .get = sdca_asoc_q78_get_volsw, \ 55 .put = sdca_asoc_q78_put_volsw, \ 56 .private_value = (unsigned long)&(struct soc_mixer_control) { \ 57 .reg = (xreg_l), .rreg = (xreg_r), \ 58 .min = (xmin), .max = (xmax), \ 59 .shift = (xstep), .rshift = (xstep), \ 60 .sign_bit = 15 \ 61 } \ 62 } 63 64 int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *function, 65 int *num_widgets, int *num_routes, int *num_controls, 66 int *num_dais); 67 68 int sdca_asoc_populate_dapm(struct device *dev, struct sdca_function_data *function, 69 struct snd_soc_dapm_widget *widgets, 70 struct snd_soc_dapm_route *routes); 71 int sdca_asoc_populate_controls(struct device *dev, 72 struct sdca_function_data *function, 73 struct snd_kcontrol_new *kctl); 74 int sdca_asoc_populate_dais(struct device *dev, struct sdca_function_data *function, 75 struct snd_soc_dai_driver *dais, 76 const struct snd_soc_dai_ops *ops); 77 78 int sdca_asoc_populate_component(struct device *dev, 79 struct sdca_function_data *function, 80 struct snd_soc_component_driver *component_drv, 81 struct snd_soc_dai_driver **dai_drv, int *num_dai_drv, 82 const struct snd_soc_dai_ops *ops); 83 84 int sdca_asoc_set_constraints(struct device *dev, struct regmap *regmap, 85 struct sdca_function_data *function, 86 struct snd_pcm_substream *substream, 87 struct snd_soc_dai *dai); 88 void sdca_asoc_free_constraints(struct snd_pcm_substream *substream, 89 struct snd_soc_dai *dai); 90 int sdca_asoc_get_port(struct device *dev, struct regmap *regmap, 91 struct sdca_function_data *function, 92 struct snd_soc_dai *dai); 93 int sdca_asoc_hw_params(struct device *dev, struct regmap *regmap, 94 struct sdca_function_data *function, 95 struct snd_pcm_substream *substream, 96 struct snd_pcm_hw_params *params, 97 struct snd_soc_dai *dai); 98 int sdca_asoc_q78_put_volsw(struct snd_kcontrol *kcontrol, 99 struct snd_ctl_elem_value *ucontrol); 100 int sdca_asoc_q78_get_volsw(struct snd_kcontrol *kcontrol, 101 struct snd_ctl_elem_value *ucontrol); 102 #endif // __SDCA_ASOC_H__ 103