Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Add DAPM/ASoC helpers to create SDCA drivers

Merge series from Charles Keepax <ckeepax@opensource.cirrus.com>:

Add helper functions to add DAPM widgets, routes, ALSA controls,
and DAI drivers, these will be used to create SDCA function device
drivers.

This series should provide most of the core functionality needed to
get a device registered and have a working DAPM graph within the
device. There are some features that still need additional work, these
are marked with FIXMEs in the code. The two main things are SDCA
Clock Muxes (not used in our devices and needs some ASoC core work),
and better support for more complex SDCA volume control definitions
(our parts have fairly simple volumes, and SDCA has a large amount of
flexibility in how the volume control is specified).

The next steps in the process are to add helpers for the DAI ops
themselves, some IRQ handling, and firmware download. And finally we
should be able to actually add the SDCA class driver itself.

Mark Brown 0d2992d3 828497fb

+1504 -27
+42
include/sound/sdca_asoc.h
··· 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 sdca_function_data; 15 + struct snd_kcontrol_new; 16 + struct snd_soc_component_driver; 17 + struct snd_soc_dai_driver; 18 + struct snd_soc_dai_ops; 19 + struct snd_soc_dapm_route; 20 + struct snd_soc_dapm_widget; 21 + 22 + int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *function, 23 + int *num_widgets, int *num_routes, int *num_controls, 24 + int *num_dais); 25 + 26 + int sdca_asoc_populate_dapm(struct device *dev, struct sdca_function_data *function, 27 + struct snd_soc_dapm_widget *widgets, 28 + struct snd_soc_dapm_route *routes); 29 + int sdca_asoc_populate_controls(struct device *dev, 30 + struct sdca_function_data *function, 31 + struct snd_kcontrol_new *kctl); 32 + int sdca_asoc_populate_dais(struct device *dev, struct sdca_function_data *function, 33 + struct snd_soc_dai_driver *dais, 34 + const struct snd_soc_dai_ops *ops); 35 + 36 + int sdca_asoc_populate_component(struct device *dev, 37 + struct sdca_function_data *function, 38 + struct snd_soc_component_driver *component_drv, 39 + struct snd_soc_dai_driver **dai_drv, int *num_dai_drv, 40 + const struct snd_soc_dai_ops *ops); 41 + 42 + #endif // __SDCA_ASOC_H__
+70 -1
include/sound/sdca_function.h
··· 125 125 * macros. 126 126 * 127 127 * Short hand to specific a Control type statically for example: 128 - * SDAC_CTL_TYPE_S(IT, MIC_BIAS). 128 + * SDCA_CTL_TYPE_S(IT, MIC_BIAS). 129 129 */ 130 130 #define SDCA_CTL_TYPE_S(ent, sel) SDCA_CTL_TYPE(SDCA_ENTITY_TYPE_##ent, \ 131 131 SDCA_CTL_##ent##_##sel) ··· 169 169 }; 170 170 171 171 /** 172 + * enum sdca_usage_range - Column definitions for Usage 173 + */ 174 + enum sdca_usage_range { 175 + SDCA_USAGE_NUMBER = 0, 176 + SDCA_USAGE_CBN = 1, 177 + SDCA_USAGE_SAMPLE_RATE = 2, 178 + SDCA_USAGE_SAMPLE_WIDTH = 3, 179 + SDCA_USAGE_FULL_SCALE = 4, 180 + SDCA_USAGE_NOISE_FLOOR = 5, 181 + SDCA_USAGE_TAG = 6, 182 + SDCA_USAGE_NCOLS = 7, 183 + }; 184 + 185 + /** 172 186 * enum sdca_mu_controls - SDCA Controls for Mixer Unit 173 187 * 174 188 * Control Selectors for Mixer Unit from SDCA specification v1.0 ··· 221 207 }; 222 208 223 209 /** 210 + * enum sdca_volume_range - Column definitions for Q7.8dB volumes/gains 211 + */ 212 + enum sdca_volume_range { 213 + SDCA_VOLUME_LINEAR_MIN = 0, 214 + SDCA_VOLUME_LINEAR_MAX = 1, 215 + SDCA_VOLUME_LINEAR_STEP = 2, 216 + SDCA_VOLUME_LINEAR_NCOLS = 3, 217 + }; 218 + 219 + /** 224 220 * enum sdca_xu_controls - SDCA Controls for Extension Unit 225 221 * 226 222 * Control Selectors for Extension Unit from SDCA specification v1.0 ··· 261 237 }; 262 238 263 239 /** 240 + * enum sdca_samplerateindex_range - Column definitions for SampleRateIndex 241 + */ 242 + enum sdca_samplerateindex_range { 243 + SDCA_SAMPLERATEINDEX_INDEX = 0, 244 + SDCA_SAMPLERATEINDEX_RATE = 1, 245 + SDCA_SAMPLERATEINDEX_NCOLS = 2, 246 + }; 247 + 248 + /** 264 249 * enum sdca_cx_controls - SDCA Controls for Clock Selector 265 250 * 266 251 * Control Selectors for Clock Selector from SDCA specification v1.0 ··· 291 258 }; 292 259 293 260 /** 261 + * enum sdca_requested_ps_range - Column definitions for Requested PS 262 + */ 263 + enum sdca_requested_ps_range { 264 + SDCA_REQUESTED_PS_STATE = 0, 265 + SDCA_REQUESTED_PS_NCOLS = 1, 266 + }; 267 + 268 + /** 294 269 * enum sdca_ge_controls - SDCA Controls for Group Unit 295 270 * 296 271 * Control Selectors for Group Unit from SDCA specification v1.0 ··· 307 266 enum sdca_ge_controls { 308 267 SDCA_CTL_GE_SELECTED_MODE = 0x01, 309 268 SDCA_CTL_GE_DETECTED_MODE = 0x02, 269 + }; 270 + 271 + /** 272 + * enum sdca_selected_mode_range - Column definitions for Selected Mode 273 + */ 274 + enum sdca_selected_mode_range { 275 + SDCA_SELECTED_MODE_INDEX = 0, 276 + SDCA_SELECTED_MODE_TERM_TYPE = 1, 277 + SDCA_SELECTED_MODE_NCOLS = 2, 310 278 }; 311 279 312 280 /** ··· 822 772 SDCA_TERM_TYPE_PRIVACY_SIGNALING = 0x741, 823 773 SDCA_TERM_TYPE_PRIVACY_INDICATORS = 0x747, 824 774 }; 775 + 776 + #define SDCA_TERM_TYPE_LINEIN_STEREO_NAME "LineIn Stereo" 777 + #define SDCA_TERM_TYPE_LINEIN_FRONT_LR_NAME "LineIn Front-LR" 778 + #define SDCA_TERM_TYPE_LINEIN_CENTER_LFE_NAME "LineIn Center-LFE" 779 + #define SDCA_TERM_TYPE_LINEIN_SURROUND_LR_NAME "LineIn Surround-LR" 780 + #define SDCA_TERM_TYPE_LINEIN_REAR_LR_NAME "LineIn Rear-LR" 781 + #define SDCA_TERM_TYPE_LINEOUT_STEREO_NAME "LineOut Stereo" 782 + #define SDCA_TERM_TYPE_LINEOUT_FRONT_LR_NAME "LineOut Front-LR" 783 + #define SDCA_TERM_TYPE_LINEOUT_CENTER_LFE_NAME "LineOut Center-LFE" 784 + #define SDCA_TERM_TYPE_LINEOUT_SURROUND_LR_NAME "LineOut Surround-LR" 785 + #define SDCA_TERM_TYPE_LINEOUT_REAR_LR_NAME "LineOut Rear-LR" 786 + #define SDCA_TERM_TYPE_MIC_JACK_NAME "Microphone" 787 + #define SDCA_TERM_TYPE_STEREO_JACK_NAME "Speaker Stereo" 788 + #define SDCA_TERM_TYPE_FRONT_LR_JACK_NAME "Speaker Front-LR" 789 + #define SDCA_TERM_TYPE_CENTER_LFE_JACK_NAME "Speaker Center-LFE" 790 + #define SDCA_TERM_TYPE_SURROUND_LR_JACK_NAME "Speaker Surround-LR" 791 + #define SDCA_TERM_TYPE_REAR_LR_JACK_NAME "Speaker Rear-LR" 792 + #define SDCA_TERM_TYPE_HEADPHONE_JACK_NAME "Headphone" 793 + #define SDCA_TERM_TYPE_HEADSET_JACK_NAME "Headset" 825 794 826 795 /** 827 796 * enum sdca_connector_type - SDCA Connector Types
+4
include/sound/soc-dapm.h
··· 445 445 struct snd_ctl_elem_value *uncontrol); 446 446 int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, 447 447 struct snd_ctl_elem_value *uncontrol); 448 + int snd_soc_dapm_get_component_pin_switch(struct snd_kcontrol *kcontrol, 449 + struct snd_ctl_elem_value *uncontrol); 450 + int snd_soc_dapm_put_component_pin_switch(struct snd_kcontrol *kcontrol, 451 + struct snd_ctl_elem_value *uncontrol); 448 452 int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, 449 453 const struct snd_soc_dapm_widget *widget, unsigned int num); 450 454 struct snd_soc_dapm_widget *snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
+1 -1
sound/soc/sdca/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 3 - snd-soc-sdca-y := sdca_functions.o sdca_device.o sdca_regmap.o 3 + snd-soc-sdca-y := sdca_functions.o sdca_device.o sdca_regmap.o sdca_asoc.o 4 4 5 5 obj-$(CONFIG_SND_SOC_SDCA) += snd-soc-sdca.o
+1311
sound/soc/sdca/sdca_asoc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (C) 2025 Cirrus Logic, Inc. and 3 + // Cirrus Logic International Semiconductor Ltd. 4 + 5 + /* 6 + * The MIPI SDCA specification is available for public downloads at 7 + * https://www.mipi.org/mipi-sdca-v1-0-download 8 + */ 9 + 10 + #include <linux/bitmap.h> 11 + #include <linux/delay.h> 12 + #include <linux/dev_printk.h> 13 + #include <linux/device.h> 14 + #include <linux/minmax.h> 15 + #include <linux/module.h> 16 + #include <linux/overflow.h> 17 + #include <linux/soundwire/sdw_registers.h> 18 + #include <linux/string_helpers.h> 19 + #include <sound/control.h> 20 + #include <sound/sdca.h> 21 + #include <sound/sdca_asoc.h> 22 + #include <sound/sdca_function.h> 23 + #include <sound/soc.h> 24 + #include <sound/soc-component.h> 25 + #include <sound/soc-dai.h> 26 + #include <sound/soc-dapm.h> 27 + #include <sound/tlv.h> 28 + 29 + static struct sdca_control *selector_find_control(struct device *dev, 30 + struct sdca_entity *entity, 31 + const int sel) 32 + { 33 + int i; 34 + 35 + for (i = 0; i < entity->num_controls; i++) { 36 + struct sdca_control *control = &entity->controls[i]; 37 + 38 + if (control->sel == sel) 39 + return control; 40 + } 41 + 42 + dev_err(dev, "%s: control %#x: missing\n", entity->label, sel); 43 + return NULL; 44 + } 45 + 46 + static struct sdca_control_range *control_find_range(struct device *dev, 47 + struct sdca_entity *entity, 48 + struct sdca_control *control, 49 + int cols, int rows) 50 + { 51 + struct sdca_control_range *range = &control->range; 52 + 53 + if ((cols && range->cols != cols) || (rows && range->rows != rows) || 54 + !range->data) { 55 + dev_err(dev, "%s: control %#x: ranges invalid (%d,%d)\n", 56 + entity->label, control->sel, range->cols, range->rows); 57 + return NULL; 58 + } 59 + 60 + return range; 61 + } 62 + 63 + static struct sdca_control_range *selector_find_range(struct device *dev, 64 + struct sdca_entity *entity, 65 + int sel, int cols, int rows) 66 + { 67 + struct sdca_control *control; 68 + 69 + control = selector_find_control(dev, entity, sel); 70 + if (!control) 71 + return NULL; 72 + 73 + return control_find_range(dev, entity, control, cols, rows); 74 + } 75 + 76 + static bool exported_control(struct sdca_entity *entity, struct sdca_control *control) 77 + { 78 + switch (SDCA_CTL_TYPE(entity->type, control->sel)) { 79 + case SDCA_CTL_TYPE_S(GE, DETECTED_MODE): 80 + return true; 81 + default: 82 + break; 83 + } 84 + 85 + return control->layers & (SDCA_ACCESS_LAYER_USER | 86 + SDCA_ACCESS_LAYER_APPLICATION); 87 + } 88 + 89 + static bool readonly_control(struct sdca_control *control) 90 + { 91 + return control->has_fixed || control->mode == SDCA_ACCESS_MODE_RO; 92 + } 93 + 94 + /** 95 + * sdca_asoc_count_component - count the various component parts 96 + * @function: Pointer to the Function information. 97 + * @num_widgets: Output integer pointer, will be filled with the 98 + * required number of DAPM widgets for the Function. 99 + * @num_routes: Output integer pointer, will be filled with the 100 + * required number of DAPM routes for the Function. 101 + * @num_controls: Output integer pointer, will be filled with the 102 + * required number of ALSA controls for the Function. 103 + * @num_dais: Output integer pointer, will be filled with the 104 + * required number of ASoC DAIs for the Function. 105 + * 106 + * This function counts various things within the SDCA Function such 107 + * that the calling driver can allocate appropriate space before 108 + * calling the appropriate population functions. 109 + * 110 + * Return: Returns zero on success, and a negative error code on failure. 111 + */ 112 + int sdca_asoc_count_component(struct device *dev, struct sdca_function_data *function, 113 + int *num_widgets, int *num_routes, int *num_controls, 114 + int *num_dais) 115 + { 116 + int i, j; 117 + 118 + *num_widgets = function->num_entities - 1; 119 + *num_routes = 0; 120 + *num_controls = 0; 121 + *num_dais = 0; 122 + 123 + for (i = 0; i < function->num_entities - 1; i++) { 124 + struct sdca_entity *entity = &function->entities[i]; 125 + 126 + /* Add supply/DAI widget connections */ 127 + switch (entity->type) { 128 + case SDCA_ENTITY_TYPE_IT: 129 + case SDCA_ENTITY_TYPE_OT: 130 + *num_routes += !!entity->iot.clock; 131 + *num_routes += !!entity->iot.is_dataport; 132 + *num_controls += !entity->iot.is_dataport; 133 + *num_dais += !!entity->iot.is_dataport; 134 + break; 135 + case SDCA_ENTITY_TYPE_PDE: 136 + *num_routes += entity->pde.num_managed; 137 + break; 138 + default: 139 + break; 140 + } 141 + 142 + if (entity->group) 143 + (*num_routes)++; 144 + 145 + /* Add primary entity connections from DisCo */ 146 + *num_routes += entity->num_sources; 147 + 148 + for (j = 0; j < entity->num_controls; j++) { 149 + if (exported_control(entity, &entity->controls[j])) 150 + (*num_controls)++; 151 + } 152 + } 153 + 154 + return 0; 155 + } 156 + EXPORT_SYMBOL_NS(sdca_asoc_count_component, "SND_SOC_SDCA"); 157 + 158 + static const char *get_terminal_name(enum sdca_terminal_type type) 159 + { 160 + switch (type) { 161 + case SDCA_TERM_TYPE_LINEIN_STEREO: 162 + return SDCA_TERM_TYPE_LINEIN_STEREO_NAME; 163 + case SDCA_TERM_TYPE_LINEIN_FRONT_LR: 164 + return SDCA_TERM_TYPE_LINEIN_FRONT_LR_NAME; 165 + case SDCA_TERM_TYPE_LINEIN_CENTER_LFE: 166 + return SDCA_TERM_TYPE_LINEIN_CENTER_LFE_NAME; 167 + case SDCA_TERM_TYPE_LINEIN_SURROUND_LR: 168 + return SDCA_TERM_TYPE_LINEIN_SURROUND_LR_NAME; 169 + case SDCA_TERM_TYPE_LINEIN_REAR_LR: 170 + return SDCA_TERM_TYPE_LINEIN_REAR_LR_NAME; 171 + case SDCA_TERM_TYPE_LINEOUT_STEREO: 172 + return SDCA_TERM_TYPE_LINEOUT_STEREO_NAME; 173 + case SDCA_TERM_TYPE_LINEOUT_FRONT_LR: 174 + return SDCA_TERM_TYPE_LINEOUT_FRONT_LR_NAME; 175 + case SDCA_TERM_TYPE_LINEOUT_CENTER_LFE: 176 + return SDCA_TERM_TYPE_LINEOUT_CENTER_LFE_NAME; 177 + case SDCA_TERM_TYPE_LINEOUT_SURROUND_LR: 178 + return SDCA_TERM_TYPE_LINEOUT_SURROUND_LR_NAME; 179 + case SDCA_TERM_TYPE_LINEOUT_REAR_LR: 180 + return SDCA_TERM_TYPE_LINEOUT_REAR_LR_NAME; 181 + case SDCA_TERM_TYPE_MIC_JACK: 182 + return SDCA_TERM_TYPE_MIC_JACK_NAME; 183 + case SDCA_TERM_TYPE_STEREO_JACK: 184 + return SDCA_TERM_TYPE_STEREO_JACK_NAME; 185 + case SDCA_TERM_TYPE_FRONT_LR_JACK: 186 + return SDCA_TERM_TYPE_FRONT_LR_JACK_NAME; 187 + case SDCA_TERM_TYPE_CENTER_LFE_JACK: 188 + return SDCA_TERM_TYPE_CENTER_LFE_JACK_NAME; 189 + case SDCA_TERM_TYPE_SURROUND_LR_JACK: 190 + return SDCA_TERM_TYPE_SURROUND_LR_JACK_NAME; 191 + case SDCA_TERM_TYPE_REAR_LR_JACK: 192 + return SDCA_TERM_TYPE_REAR_LR_JACK_NAME; 193 + case SDCA_TERM_TYPE_HEADPHONE_JACK: 194 + return SDCA_TERM_TYPE_HEADPHONE_JACK_NAME; 195 + case SDCA_TERM_TYPE_HEADSET_JACK: 196 + return SDCA_TERM_TYPE_HEADSET_JACK_NAME; 197 + default: 198 + return NULL; 199 + } 200 + } 201 + 202 + static int entity_early_parse_ge(struct device *dev, 203 + struct sdca_function_data *function, 204 + struct sdca_entity *entity) 205 + { 206 + struct sdca_control_range *range; 207 + struct sdca_control *control; 208 + struct snd_kcontrol_new *kctl; 209 + struct soc_enum *soc_enum; 210 + const char *control_name; 211 + unsigned int *values; 212 + const char **texts; 213 + int i; 214 + 215 + control = selector_find_control(dev, entity, SDCA_CTL_GE_SELECTED_MODE); 216 + if (!control) 217 + return -EINVAL; 218 + 219 + if (control->layers != SDCA_ACCESS_LAYER_CLASS) 220 + dev_warn(dev, "%s: unexpected access layer: %x\n", 221 + entity->label, control->layers); 222 + 223 + range = control_find_range(dev, entity, control, SDCA_SELECTED_MODE_NCOLS, 0); 224 + if (!range) 225 + return -EINVAL; 226 + 227 + control_name = devm_kasprintf(dev, GFP_KERNEL, "%s %s", 228 + entity->label, control->label); 229 + if (!control_name) 230 + return -ENOMEM; 231 + 232 + kctl = devm_kmalloc(dev, sizeof(*kctl), GFP_KERNEL); 233 + if (!kctl) 234 + return -ENOMEM; 235 + 236 + soc_enum = devm_kmalloc(dev, sizeof(*soc_enum), GFP_KERNEL); 237 + if (!soc_enum) 238 + return -ENOMEM; 239 + 240 + texts = devm_kcalloc(dev, range->rows + 3, sizeof(*texts), GFP_KERNEL); 241 + if (!texts) 242 + return -ENOMEM; 243 + 244 + values = devm_kcalloc(dev, range->rows + 3, sizeof(*values), GFP_KERNEL); 245 + if (!values) 246 + return -ENOMEM; 247 + 248 + texts[0] = "No Jack"; 249 + texts[1] = "Jack Unknown"; 250 + texts[2] = "Detection in Progress"; 251 + values[0] = 0; 252 + values[1] = 1; 253 + values[2] = 2; 254 + for (i = 0; i < range->rows; i++) { 255 + enum sdca_terminal_type type; 256 + 257 + type = sdca_range(range, SDCA_SELECTED_MODE_TERM_TYPE, i); 258 + 259 + values[i + 3] = sdca_range(range, SDCA_SELECTED_MODE_INDEX, i); 260 + texts[i + 3] = get_terminal_name(type); 261 + if (!texts[i + 3]) { 262 + dev_err(dev, "%s: unrecognised terminal type: %#x\n", 263 + entity->label, type); 264 + return -EINVAL; 265 + } 266 + } 267 + 268 + soc_enum->reg = SDW_SDCA_CTL(function->desc->adr, entity->id, control->sel, 0); 269 + soc_enum->items = range->rows + 3; 270 + soc_enum->mask = roundup_pow_of_two(soc_enum->items) - 1; 271 + soc_enum->texts = texts; 272 + soc_enum->values = values; 273 + 274 + kctl->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 275 + kctl->name = control_name; 276 + kctl->info = snd_soc_info_enum_double; 277 + kctl->get = snd_soc_dapm_get_enum_double; 278 + kctl->put = snd_soc_dapm_put_enum_double; 279 + kctl->private_value = (unsigned long)soc_enum; 280 + 281 + entity->ge.kctl = kctl; 282 + 283 + return 0; 284 + } 285 + 286 + static void add_route(struct snd_soc_dapm_route **route, const char *sink, 287 + const char *control, const char *source) 288 + { 289 + (*route)->sink = sink; 290 + (*route)->control = control; 291 + (*route)->source = source; 292 + (*route)++; 293 + } 294 + 295 + static int entity_parse_simple(struct device *dev, 296 + struct sdca_function_data *function, 297 + struct sdca_entity *entity, 298 + struct snd_soc_dapm_widget **widget, 299 + struct snd_soc_dapm_route **route, 300 + enum snd_soc_dapm_type id) 301 + { 302 + int i; 303 + 304 + (*widget)->id = id; 305 + (*widget)++; 306 + 307 + for (i = 0; i < entity->num_sources; i++) 308 + add_route(route, entity->label, NULL, entity->sources[i]->label); 309 + 310 + return 0; 311 + } 312 + 313 + static int entity_parse_it(struct device *dev, 314 + struct sdca_function_data *function, 315 + struct sdca_entity *entity, 316 + struct snd_soc_dapm_widget **widget, 317 + struct snd_soc_dapm_route **route) 318 + { 319 + int i; 320 + 321 + if (entity->iot.is_dataport) { 322 + const char *aif_name = devm_kasprintf(dev, GFP_KERNEL, "%s %s", 323 + entity->label, "Playback"); 324 + if (!aif_name) 325 + return -ENOMEM; 326 + 327 + (*widget)->id = snd_soc_dapm_aif_in; 328 + 329 + add_route(route, entity->label, NULL, aif_name); 330 + } else { 331 + (*widget)->id = snd_soc_dapm_mic; 332 + } 333 + 334 + if (entity->iot.clock) 335 + add_route(route, entity->label, NULL, entity->iot.clock->label); 336 + 337 + for (i = 0; i < entity->num_sources; i++) 338 + add_route(route, entity->label, NULL, entity->sources[i]->label); 339 + 340 + (*widget)++; 341 + 342 + return 0; 343 + } 344 + 345 + static int entity_parse_ot(struct device *dev, 346 + struct sdca_function_data *function, 347 + struct sdca_entity *entity, 348 + struct snd_soc_dapm_widget **widget, 349 + struct snd_soc_dapm_route **route) 350 + { 351 + int i; 352 + 353 + if (entity->iot.is_dataport) { 354 + const char *aif_name = devm_kasprintf(dev, GFP_KERNEL, "%s %s", 355 + entity->label, "Capture"); 356 + if (!aif_name) 357 + return -ENOMEM; 358 + 359 + (*widget)->id = snd_soc_dapm_aif_out; 360 + 361 + add_route(route, aif_name, NULL, entity->label); 362 + } else { 363 + (*widget)->id = snd_soc_dapm_spk; 364 + } 365 + 366 + if (entity->iot.clock) 367 + add_route(route, entity->label, NULL, entity->iot.clock->label); 368 + 369 + for (i = 0; i < entity->num_sources; i++) 370 + add_route(route, entity->label, NULL, entity->sources[i]->label); 371 + 372 + (*widget)++; 373 + 374 + return 0; 375 + } 376 + 377 + static int entity_pde_event(struct snd_soc_dapm_widget *widget, 378 + struct snd_kcontrol *kctl, int event) 379 + { 380 + struct snd_soc_component *component = widget->dapm->component; 381 + struct sdca_entity *entity = widget->priv; 382 + static const int polls = 100; 383 + unsigned int reg, val; 384 + int from, to, i; 385 + int poll_us; 386 + int ret; 387 + 388 + if (!component) 389 + return -EIO; 390 + 391 + switch (event) { 392 + case SND_SOC_DAPM_POST_PMD: 393 + from = widget->on_val; 394 + to = widget->off_val; 395 + break; 396 + case SND_SOC_DAPM_POST_PMU: 397 + from = widget->off_val; 398 + to = widget->on_val; 399 + break; 400 + } 401 + 402 + for (i = 0; i < entity->pde.num_max_delay; i++) { 403 + struct sdca_pde_delay *delay = &entity->pde.max_delay[i]; 404 + 405 + if (delay->from_ps == from && delay->to_ps == to) { 406 + poll_us = delay->us / polls; 407 + break; 408 + } 409 + } 410 + 411 + reg = SDW_SDCA_CTL(SDW_SDCA_CTL_FUNC(widget->reg), 412 + SDW_SDCA_CTL_ENT(widget->reg), 413 + SDCA_CTL_PDE_ACTUAL_PS, 0); 414 + 415 + for (i = 0; i < polls; i++) { 416 + if (i) 417 + fsleep(poll_us); 418 + 419 + ret = regmap_read(component->regmap, reg, &val); 420 + if (ret) 421 + return ret; 422 + else if (val == to) 423 + return 0; 424 + } 425 + 426 + dev_err(component->dev, "%s: power transition failed: %x\n", 427 + entity->label, val); 428 + return -ETIMEDOUT; 429 + } 430 + 431 + static int entity_parse_pde(struct device *dev, 432 + struct sdca_function_data *function, 433 + struct sdca_entity *entity, 434 + struct snd_soc_dapm_widget **widget, 435 + struct snd_soc_dapm_route **route) 436 + { 437 + unsigned int target = (1 << SDCA_PDE_PS0) | (1 << SDCA_PDE_PS3); 438 + struct sdca_control_range *range; 439 + struct sdca_control *control; 440 + unsigned int mask = 0; 441 + int i; 442 + 443 + control = selector_find_control(dev, entity, SDCA_CTL_PDE_REQUESTED_PS); 444 + if (!control) 445 + return -EINVAL; 446 + 447 + /* Power should only be controlled by the driver */ 448 + if (control->layers != SDCA_ACCESS_LAYER_CLASS) 449 + dev_warn(dev, "%s: unexpected access layer: %x\n", 450 + entity->label, control->layers); 451 + 452 + range = control_find_range(dev, entity, control, SDCA_REQUESTED_PS_NCOLS, 0); 453 + if (!range) 454 + return -EINVAL; 455 + 456 + for (i = 0; i < range->rows; i++) 457 + mask |= 1 << sdca_range(range, SDCA_REQUESTED_PS_STATE, i); 458 + 459 + if ((mask & target) != target) { 460 + dev_err(dev, "%s: power control missing states\n", entity->label); 461 + return -EINVAL; 462 + } 463 + 464 + (*widget)->id = snd_soc_dapm_supply; 465 + (*widget)->reg = SDW_SDCA_CTL(function->desc->adr, entity->id, control->sel, 0); 466 + (*widget)->mask = GENMASK(control->nbits - 1, 0); 467 + (*widget)->on_val = SDCA_PDE_PS0; 468 + (*widget)->off_val = SDCA_PDE_PS3; 469 + (*widget)->event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD; 470 + (*widget)->event = entity_pde_event; 471 + (*widget)->priv = entity; 472 + (*widget)++; 473 + 474 + for (i = 0; i < entity->pde.num_managed; i++) 475 + add_route(route, entity->pde.managed[i]->label, NULL, entity->label); 476 + 477 + for (i = 0; i < entity->num_sources; i++) 478 + add_route(route, entity->label, NULL, entity->sources[i]->label); 479 + 480 + return 0; 481 + } 482 + 483 + /* Device selector units are controlled through a group entity */ 484 + static int entity_parse_su_device(struct device *dev, 485 + struct sdca_function_data *function, 486 + struct sdca_entity *entity, 487 + struct snd_soc_dapm_widget **widget, 488 + struct snd_soc_dapm_route **route) 489 + { 490 + struct sdca_control_range *range; 491 + int num_routes = 0; 492 + int i, j; 493 + 494 + if (!entity->group) { 495 + dev_err(dev, "%s: device selector unit missing group\n", entity->label); 496 + return -EINVAL; 497 + } 498 + 499 + range = selector_find_range(dev, entity->group, SDCA_CTL_GE_SELECTED_MODE, 500 + SDCA_SELECTED_MODE_NCOLS, 0); 501 + if (!range) 502 + return -EINVAL; 503 + 504 + (*widget)->id = snd_soc_dapm_mux; 505 + (*widget)->kcontrol_news = entity->group->ge.kctl; 506 + (*widget)->num_kcontrols = 1; 507 + (*widget)++; 508 + 509 + for (i = 0; i < entity->group->ge.num_modes; i++) { 510 + struct sdca_ge_mode *mode = &entity->group->ge.modes[i]; 511 + 512 + for (j = 0; j < mode->num_controls; j++) { 513 + struct sdca_ge_control *affected = &mode->controls[j]; 514 + int term; 515 + 516 + if (affected->id != entity->id || 517 + affected->sel != SDCA_CTL_SU_SELECTOR || 518 + !affected->val) 519 + continue; 520 + 521 + if (affected->val - 1 >= entity->num_sources) { 522 + dev_err(dev, "%s: bad control value: %#x\n", 523 + entity->label, affected->val); 524 + return -EINVAL; 525 + } 526 + 527 + if (++num_routes > entity->num_sources) { 528 + dev_err(dev, "%s: too many input routes\n", entity->label); 529 + return -EINVAL; 530 + } 531 + 532 + term = sdca_range_search(range, SDCA_SELECTED_MODE_INDEX, 533 + mode->val, SDCA_SELECTED_MODE_TERM_TYPE); 534 + if (!term) { 535 + dev_err(dev, "%s: mode not found: %#x\n", 536 + entity->label, mode->val); 537 + return -EINVAL; 538 + } 539 + 540 + add_route(route, entity->label, get_terminal_name(term), 541 + entity->sources[affected->val - 1]->label); 542 + } 543 + } 544 + 545 + return 0; 546 + } 547 + 548 + /* Class selector units will be exported as an ALSA control */ 549 + static int entity_parse_su_class(struct device *dev, 550 + struct sdca_function_data *function, 551 + struct sdca_entity *entity, 552 + struct sdca_control *control, 553 + struct snd_soc_dapm_widget **widget, 554 + struct snd_soc_dapm_route **route) 555 + { 556 + struct snd_kcontrol_new *kctl; 557 + struct soc_enum *soc_enum; 558 + const char **texts; 559 + int i; 560 + 561 + kctl = devm_kmalloc(dev, sizeof(*kctl), GFP_KERNEL); 562 + if (!kctl) 563 + return -ENOMEM; 564 + 565 + soc_enum = devm_kmalloc(dev, sizeof(*soc_enum), GFP_KERNEL); 566 + if (!soc_enum) 567 + return -ENOMEM; 568 + 569 + texts = devm_kcalloc(dev, entity->num_sources + 1, sizeof(*texts), GFP_KERNEL); 570 + if (!texts) 571 + return -ENOMEM; 572 + 573 + texts[0] = "No Signal"; 574 + for (i = 0; i < entity->num_sources; i++) 575 + texts[i + 1] = entity->sources[i]->label; 576 + 577 + soc_enum->reg = SDW_SDCA_CTL(function->desc->adr, entity->id, control->sel, 0); 578 + soc_enum->items = entity->num_sources + 1; 579 + soc_enum->mask = roundup_pow_of_two(soc_enum->items) - 1; 580 + soc_enum->texts = texts; 581 + 582 + kctl->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 583 + kctl->name = "Route"; 584 + kctl->info = snd_soc_info_enum_double; 585 + kctl->get = snd_soc_dapm_get_enum_double; 586 + kctl->put = snd_soc_dapm_put_enum_double; 587 + kctl->private_value = (unsigned long)soc_enum; 588 + 589 + (*widget)->id = snd_soc_dapm_mux; 590 + (*widget)->kcontrol_news = kctl; 591 + (*widget)->num_kcontrols = 1; 592 + (*widget)++; 593 + 594 + for (i = 0; i < entity->num_sources; i++) 595 + add_route(route, entity->label, texts[i + 1], entity->sources[i]->label); 596 + 597 + return 0; 598 + } 599 + 600 + static int entity_parse_su(struct device *dev, 601 + struct sdca_function_data *function, 602 + struct sdca_entity *entity, 603 + struct snd_soc_dapm_widget **widget, 604 + struct snd_soc_dapm_route **route) 605 + { 606 + struct sdca_control *control; 607 + 608 + if (!entity->num_sources) { 609 + dev_err(dev, "%s: selector with no inputs\n", entity->label); 610 + return -EINVAL; 611 + } 612 + 613 + control = selector_find_control(dev, entity, SDCA_CTL_SU_SELECTOR); 614 + if (!control) 615 + return -EINVAL; 616 + 617 + if (control->layers == SDCA_ACCESS_LAYER_DEVICE) 618 + return entity_parse_su_device(dev, function, entity, widget, route); 619 + 620 + if (control->layers != SDCA_ACCESS_LAYER_CLASS) 621 + dev_warn(dev, "%s: unexpected access layer: %x\n", 622 + entity->label, control->layers); 623 + 624 + return entity_parse_su_class(dev, function, entity, control, widget, route); 625 + } 626 + 627 + static int entity_parse_mu(struct device *dev, 628 + struct sdca_function_data *function, 629 + struct sdca_entity *entity, 630 + struct snd_soc_dapm_widget **widget, 631 + struct snd_soc_dapm_route **route) 632 + { 633 + struct sdca_control *control; 634 + struct snd_kcontrol_new *kctl; 635 + int cn; 636 + int i; 637 + 638 + if (!entity->num_sources) { 639 + dev_err(dev, "%s: selector 1 or more inputs\n", entity->label); 640 + return -EINVAL; 641 + } 642 + 643 + control = selector_find_control(dev, entity, SDCA_CTL_MU_MIXER); 644 + if (!control) 645 + return -EINVAL; 646 + 647 + /* MU control should be through DAPM */ 648 + if (control->layers != SDCA_ACCESS_LAYER_CLASS) 649 + dev_warn(dev, "%s: unexpected access layer: %x\n", 650 + entity->label, control->layers); 651 + 652 + if (entity->num_sources != hweight64(control->cn_list)) { 653 + dev_err(dev, "%s: mismatched control and sources\n", entity->label); 654 + return -EINVAL; 655 + } 656 + 657 + kctl = devm_kcalloc(dev, entity->num_sources, sizeof(*kctl), GFP_KERNEL); 658 + if (!kctl) 659 + return -ENOMEM; 660 + 661 + i = 0; 662 + for_each_set_bit(cn, (unsigned long *)&control->cn_list, 663 + BITS_PER_TYPE(control->cn_list)) { 664 + const char *control_name; 665 + struct soc_mixer_control *mc; 666 + 667 + control_name = devm_kasprintf(dev, GFP_KERNEL, "%s %d", 668 + control->label, i + 1); 669 + if (!control_name) 670 + return -ENOMEM; 671 + 672 + mc = devm_kmalloc(dev, sizeof(*mc), GFP_KERNEL); 673 + if (!mc) 674 + return -ENOMEM; 675 + 676 + mc->reg = SND_SOC_NOPM; 677 + mc->rreg = SND_SOC_NOPM; 678 + mc->invert = 1; // Ensure default is connected 679 + mc->min = 0; 680 + mc->max = 1; 681 + 682 + kctl[i].name = control_name; 683 + kctl[i].private_value = (unsigned long)mc; 684 + kctl[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; 685 + kctl[i].info = snd_soc_info_volsw; 686 + kctl[i].get = snd_soc_dapm_get_volsw; 687 + kctl[i].put = snd_soc_dapm_put_volsw; 688 + i++; 689 + } 690 + 691 + (*widget)->id = snd_soc_dapm_mixer; 692 + (*widget)->kcontrol_news = kctl; 693 + (*widget)->num_kcontrols = entity->num_sources; 694 + (*widget)++; 695 + 696 + for (i = 0; i < entity->num_sources; i++) 697 + add_route(route, entity->label, kctl[i].name, entity->sources[i]->label); 698 + 699 + return 0; 700 + } 701 + 702 + static int entity_cs_event(struct snd_soc_dapm_widget *widget, 703 + struct snd_kcontrol *kctl, int event) 704 + { 705 + struct snd_soc_component *component = widget->dapm->component; 706 + struct sdca_entity *entity = widget->priv; 707 + 708 + if (!component) 709 + return -EIO; 710 + 711 + if (entity->cs.max_delay) 712 + fsleep(entity->cs.max_delay); 713 + 714 + return 0; 715 + } 716 + 717 + static int entity_parse_cs(struct device *dev, 718 + struct sdca_function_data *function, 719 + struct sdca_entity *entity, 720 + struct snd_soc_dapm_widget **widget, 721 + struct snd_soc_dapm_route **route) 722 + { 723 + int i; 724 + 725 + (*widget)->id = snd_soc_dapm_supply; 726 + (*widget)->subseq = 1; /* Ensure these run after PDEs */ 727 + (*widget)->event_flags = SND_SOC_DAPM_POST_PMU; 728 + (*widget)->event = entity_cs_event; 729 + (*widget)->priv = entity; 730 + (*widget)++; 731 + 732 + for (i = 0; i < entity->num_sources; i++) 733 + add_route(route, entity->label, NULL, entity->sources[i]->label); 734 + 735 + return 0; 736 + } 737 + 738 + /** 739 + * sdca_asoc_populate_dapm - fill in arrays of DAPM widgets and routes 740 + * @dev: Pointer to the device against which allocations will be done. 741 + * @function: Pointer to the Function information. 742 + * @widget: Array of DAPM widgets to be populated. 743 + * @route: Array of DAPM routes to be populated. 744 + * 745 + * This function populates arrays of DAPM widgets and routes from the 746 + * DisCo information for a particular SDCA Function. Typically, 747 + * snd_soc_asoc_count_component will be used to allocate appropriately 748 + * sized arrays before calling this function. 749 + * 750 + * Return: Returns zero on success, and a negative error code on failure. 751 + */ 752 + int sdca_asoc_populate_dapm(struct device *dev, struct sdca_function_data *function, 753 + struct snd_soc_dapm_widget *widget, 754 + struct snd_soc_dapm_route *route) 755 + { 756 + int ret; 757 + int i; 758 + 759 + for (i = 0; i < function->num_entities - 1; i++) { 760 + struct sdca_entity *entity = &function->entities[i]; 761 + 762 + /* 763 + * Some entities need to add controls "early" as they are 764 + * referenced by other entities. 765 + */ 766 + switch (entity->type) { 767 + case SDCA_ENTITY_TYPE_GE: 768 + ret = entity_early_parse_ge(dev, function, entity); 769 + if (ret) 770 + return ret; 771 + break; 772 + default: 773 + break; 774 + } 775 + } 776 + 777 + for (i = 0; i < function->num_entities - 1; i++) { 778 + struct sdca_entity *entity = &function->entities[i]; 779 + 780 + widget->name = entity->label; 781 + widget->reg = SND_SOC_NOPM; 782 + 783 + switch (entity->type) { 784 + case SDCA_ENTITY_TYPE_IT: 785 + ret = entity_parse_it(dev, function, entity, &widget, &route); 786 + break; 787 + case SDCA_ENTITY_TYPE_OT: 788 + ret = entity_parse_ot(dev, function, entity, &widget, &route); 789 + break; 790 + case SDCA_ENTITY_TYPE_PDE: 791 + ret = entity_parse_pde(dev, function, entity, &widget, &route); 792 + break; 793 + case SDCA_ENTITY_TYPE_SU: 794 + ret = entity_parse_su(dev, function, entity, &widget, &route); 795 + break; 796 + case SDCA_ENTITY_TYPE_MU: 797 + ret = entity_parse_mu(dev, function, entity, &widget, &route); 798 + break; 799 + case SDCA_ENTITY_TYPE_CS: 800 + ret = entity_parse_cs(dev, function, entity, &widget, &route); 801 + break; 802 + case SDCA_ENTITY_TYPE_CX: 803 + /* 804 + * FIXME: For now we will just treat these as a supply, 805 + * meaning all options are enabled. 806 + */ 807 + dev_warn(dev, "%s: clock selectors not fully supported yet\n", 808 + entity->label); 809 + ret = entity_parse_simple(dev, function, entity, &widget, 810 + &route, snd_soc_dapm_supply); 811 + break; 812 + case SDCA_ENTITY_TYPE_TG: 813 + ret = entity_parse_simple(dev, function, entity, &widget, 814 + &route, snd_soc_dapm_siggen); 815 + break; 816 + case SDCA_ENTITY_TYPE_GE: 817 + ret = entity_parse_simple(dev, function, entity, &widget, 818 + &route, snd_soc_dapm_supply); 819 + break; 820 + default: 821 + ret = entity_parse_simple(dev, function, entity, &widget, 822 + &route, snd_soc_dapm_pga); 823 + break; 824 + } 825 + if (ret) 826 + return ret; 827 + 828 + if (entity->group) 829 + add_route(&route, entity->label, NULL, entity->group->label); 830 + } 831 + 832 + return 0; 833 + } 834 + EXPORT_SYMBOL_NS(sdca_asoc_populate_dapm, "SND_SOC_SDCA"); 835 + 836 + static int control_limit_kctl(struct device *dev, 837 + struct sdca_entity *entity, 838 + struct sdca_control *control, 839 + struct snd_kcontrol_new *kctl) 840 + { 841 + struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; 842 + struct sdca_control_range *range; 843 + int min, max, step; 844 + unsigned int *tlv; 845 + int shift; 846 + 847 + if (control->type != SDCA_CTL_DATATYPE_Q7P8DB) 848 + return 0; 849 + 850 + /* 851 + * FIXME: For now only handle the simple case of a single linear range 852 + */ 853 + range = control_find_range(dev, entity, control, SDCA_VOLUME_LINEAR_NCOLS, 1); 854 + if (!range) 855 + return -EINVAL; 856 + 857 + min = sdca_range(range, SDCA_VOLUME_LINEAR_MIN, 0); 858 + max = sdca_range(range, SDCA_VOLUME_LINEAR_MAX, 0); 859 + step = sdca_range(range, SDCA_VOLUME_LINEAR_STEP, 0); 860 + 861 + min = sign_extend32(min, control->nbits - 1); 862 + max = sign_extend32(max, control->nbits - 1); 863 + 864 + /* 865 + * FIXME: Only support power of 2 step sizes as this can be supported 866 + * by a simple shift. 867 + */ 868 + if (hweight32(step) != 1) { 869 + dev_err(dev, "%s: %s: currently unsupported step size\n", 870 + entity->label, control->label); 871 + return -EINVAL; 872 + } 873 + 874 + /* 875 + * The SDCA volumes are in steps of 1/256th of a dB, a step down of 876 + * 64 (shift of 6) gives 1/4dB. 1/4dB is the smallest unit that is also 877 + * representable in the ALSA TLVs which are in 1/100ths of a dB. 878 + */ 879 + shift = max(ffs(step) - 1, 6); 880 + 881 + tlv = devm_kcalloc(dev, 4, sizeof(*tlv), GFP_KERNEL); 882 + if (!tlv) 883 + return -ENOMEM; 884 + 885 + tlv[0] = SNDRV_CTL_TLVT_DB_SCALE; 886 + tlv[1] = 2 * sizeof(*tlv); 887 + tlv[2] = (min * 100) >> 8; 888 + tlv[3] = ((1 << shift) * 100) >> 8; 889 + 890 + mc->min = min >> shift; 891 + mc->max = max >> shift; 892 + mc->shift = shift; 893 + mc->rshift = shift; 894 + mc->sign_bit = 15 - shift; 895 + 896 + kctl->tlv.p = tlv; 897 + kctl->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; 898 + 899 + return 0; 900 + } 901 + 902 + static int populate_control(struct device *dev, 903 + struct sdca_function_data *function, 904 + struct sdca_entity *entity, 905 + struct sdca_control *control, 906 + struct snd_kcontrol_new **kctl) 907 + { 908 + const char *control_suffix = ""; 909 + const char *control_name; 910 + struct soc_mixer_control *mc; 911 + int index = 0; 912 + int ret; 913 + int cn; 914 + 915 + if (!exported_control(entity, control)) 916 + return 0; 917 + 918 + if (control->type == SDCA_CTL_DATATYPE_ONEBIT) 919 + control_suffix = " Switch"; 920 + 921 + control_name = devm_kasprintf(dev, GFP_KERNEL, "%s %s%s", entity->label, 922 + control->label, control_suffix); 923 + if (!control_name) 924 + return -ENOMEM; 925 + 926 + mc = devm_kmalloc(dev, sizeof(*mc), GFP_KERNEL); 927 + if (!mc) 928 + return -ENOMEM; 929 + 930 + for_each_set_bit(cn, (unsigned long *)&control->cn_list, 931 + BITS_PER_TYPE(control->cn_list)) { 932 + switch (index++) { 933 + case 0: 934 + mc->reg = SDW_SDCA_CTL(function->desc->adr, entity->id, 935 + control->sel, cn); 936 + mc->rreg = mc->reg; 937 + break; 938 + case 1: 939 + mc->rreg = SDW_SDCA_CTL(function->desc->adr, entity->id, 940 + control->sel, cn); 941 + break; 942 + default: 943 + dev_err(dev, "%s: %s: only mono/stereo controls supported\n", 944 + entity->label, control->label); 945 + return -EINVAL; 946 + } 947 + } 948 + 949 + mc->min = 0; 950 + mc->max = clamp((0x1ull << control->nbits) - 1, 0, type_max(mc->max)); 951 + 952 + (*kctl)->name = control_name; 953 + (*kctl)->private_value = (unsigned long)mc; 954 + (*kctl)->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 955 + (*kctl)->info = snd_soc_info_volsw; 956 + (*kctl)->get = snd_soc_get_volsw; 957 + (*kctl)->put = snd_soc_put_volsw; 958 + 959 + if (readonly_control(control)) 960 + (*kctl)->access = SNDRV_CTL_ELEM_ACCESS_READ; 961 + else 962 + (*kctl)->access = SNDRV_CTL_ELEM_ACCESS_READWRITE; 963 + 964 + ret = control_limit_kctl(dev, entity, control, *kctl); 965 + if (ret) 966 + return ret; 967 + 968 + (*kctl)++; 969 + 970 + return 0; 971 + } 972 + 973 + static int populate_pin_switch(struct device *dev, 974 + struct sdca_entity *entity, 975 + struct snd_kcontrol_new **kctl) 976 + { 977 + const char *control_name; 978 + 979 + control_name = devm_kasprintf(dev, GFP_KERNEL, "%s Switch", entity->label); 980 + if (!control_name) 981 + return -ENOMEM; 982 + 983 + (*kctl)->name = control_name; 984 + (*kctl)->private_value = (unsigned long)entity->label; 985 + (*kctl)->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 986 + (*kctl)->info = snd_soc_dapm_info_pin_switch; 987 + (*kctl)->get = snd_soc_dapm_get_component_pin_switch; 988 + (*kctl)->put = snd_soc_dapm_put_component_pin_switch; 989 + (*kctl)++; 990 + 991 + return 0; 992 + } 993 + 994 + /** 995 + * sdca_asoc_populate_controls - fill in an array of ALSA controls for a Function 996 + * @dev: Pointer to the device against which allocations will be done. 997 + * @function: Pointer to the Function information. 998 + * @route: Array of ALSA controls to be populated. 999 + * 1000 + * This function populates an array of ALSA controls from the DisCo 1001 + * information for a particular SDCA Function. Typically, 1002 + * snd_soc_asoc_count_component will be used to allocate an 1003 + * appropriately sized array before calling this function. 1004 + * 1005 + * Return: Returns zero on success, and a negative error code on failure. 1006 + */ 1007 + int sdca_asoc_populate_controls(struct device *dev, 1008 + struct sdca_function_data *function, 1009 + struct snd_kcontrol_new *kctl) 1010 + { 1011 + int i, j; 1012 + int ret; 1013 + 1014 + for (i = 0; i < function->num_entities; i++) { 1015 + struct sdca_entity *entity = &function->entities[i]; 1016 + 1017 + switch (entity->type) { 1018 + case SDCA_ENTITY_TYPE_IT: 1019 + case SDCA_ENTITY_TYPE_OT: 1020 + if (!entity->iot.is_dataport) { 1021 + ret = populate_pin_switch(dev, entity, &kctl); 1022 + if (ret) 1023 + return ret; 1024 + } 1025 + break; 1026 + default: 1027 + break; 1028 + } 1029 + 1030 + for (j = 0; j < entity->num_controls; j++) { 1031 + ret = populate_control(dev, function, entity, 1032 + &entity->controls[j], &kctl); 1033 + if (ret) 1034 + return ret; 1035 + } 1036 + } 1037 + 1038 + return 0; 1039 + } 1040 + EXPORT_SYMBOL_NS(sdca_asoc_populate_controls, "SND_SOC_SDCA"); 1041 + 1042 + static unsigned int rate_find_mask(unsigned int rate) 1043 + { 1044 + switch (rate) { 1045 + case 0: 1046 + return SNDRV_PCM_RATE_8000_768000; 1047 + case 5512: 1048 + return SNDRV_PCM_RATE_5512; 1049 + case 8000: 1050 + return SNDRV_PCM_RATE_8000; 1051 + case 11025: 1052 + return SNDRV_PCM_RATE_11025; 1053 + case 16000: 1054 + return SNDRV_PCM_RATE_16000; 1055 + case 22050: 1056 + return SNDRV_PCM_RATE_22050; 1057 + case 32000: 1058 + return SNDRV_PCM_RATE_32000; 1059 + case 44100: 1060 + return SNDRV_PCM_RATE_44100; 1061 + case 48000: 1062 + return SNDRV_PCM_RATE_48000; 1063 + case 64000: 1064 + return SNDRV_PCM_RATE_64000; 1065 + case 88200: 1066 + return SNDRV_PCM_RATE_88200; 1067 + case 96000: 1068 + return SNDRV_PCM_RATE_96000; 1069 + case 176400: 1070 + return SNDRV_PCM_RATE_176400; 1071 + case 192000: 1072 + return SNDRV_PCM_RATE_192000; 1073 + case 352800: 1074 + return SNDRV_PCM_RATE_352800; 1075 + case 384000: 1076 + return SNDRV_PCM_RATE_384000; 1077 + case 705600: 1078 + return SNDRV_PCM_RATE_705600; 1079 + case 768000: 1080 + return SNDRV_PCM_RATE_768000; 1081 + case 12000: 1082 + return SNDRV_PCM_RATE_12000; 1083 + case 24000: 1084 + return SNDRV_PCM_RATE_24000; 1085 + case 128000: 1086 + return SNDRV_PCM_RATE_128000; 1087 + default: 1088 + return 0; 1089 + } 1090 + } 1091 + 1092 + static u64 width_find_mask(unsigned int bits) 1093 + { 1094 + switch (bits) { 1095 + case 0: 1096 + return SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | 1097 + SNDRV_PCM_FMTBIT_S20_LE | SNDRV_PCM_FMTBIT_S24_LE | 1098 + SNDRV_PCM_FMTBIT_S32_LE; 1099 + case 8: 1100 + return SNDRV_PCM_FMTBIT_S8; 1101 + case 16: 1102 + return SNDRV_PCM_FMTBIT_S16_LE; 1103 + case 20: 1104 + return SNDRV_PCM_FMTBIT_S20_LE; 1105 + case 24: 1106 + return SNDRV_PCM_FMTBIT_S24_LE; 1107 + case 32: 1108 + return SNDRV_PCM_FMTBIT_S32_LE; 1109 + default: 1110 + return 0; 1111 + } 1112 + } 1113 + 1114 + static int populate_rate_format(struct device *dev, 1115 + struct sdca_function_data *function, 1116 + struct sdca_entity *entity, 1117 + struct snd_soc_pcm_stream *stream) 1118 + { 1119 + struct sdca_control_range *range; 1120 + unsigned int sample_rate, sample_width; 1121 + unsigned int clock_rates = 0; 1122 + unsigned int rates = 0; 1123 + u64 formats = 0; 1124 + int sel, i; 1125 + 1126 + switch (entity->type) { 1127 + case SDCA_ENTITY_TYPE_IT: 1128 + sel = SDCA_CTL_IT_USAGE; 1129 + break; 1130 + case SDCA_ENTITY_TYPE_OT: 1131 + sel = SDCA_CTL_OT_USAGE; 1132 + break; 1133 + default: 1134 + dev_err(dev, "%s: entity type has no usage control\n", 1135 + entity->label); 1136 + return -EINVAL; 1137 + } 1138 + 1139 + if (entity->iot.clock) { 1140 + range = selector_find_range(dev, entity->iot.clock, 1141 + SDCA_CTL_CS_SAMPLERATEINDEX, 1142 + SDCA_SAMPLERATEINDEX_NCOLS, 0); 1143 + if (!range) 1144 + return -EINVAL; 1145 + 1146 + for (i = 0; i < range->rows; i++) { 1147 + sample_rate = sdca_range(range, SDCA_SAMPLERATEINDEX_RATE, i); 1148 + clock_rates |= rate_find_mask(sample_rate); 1149 + } 1150 + } else { 1151 + clock_rates = UINT_MAX; 1152 + } 1153 + 1154 + range = selector_find_range(dev, entity, sel, SDCA_USAGE_NCOLS, 0); 1155 + if (!range) 1156 + return -EINVAL; 1157 + 1158 + for (i = 0; i < range->rows; i++) { 1159 + sample_rate = sdca_range(range, SDCA_USAGE_SAMPLE_RATE, i); 1160 + sample_rate = rate_find_mask(sample_rate); 1161 + 1162 + if (sample_rate & clock_rates) { 1163 + rates |= sample_rate; 1164 + 1165 + sample_width = sdca_range(range, SDCA_USAGE_SAMPLE_WIDTH, i); 1166 + formats |= width_find_mask(sample_width); 1167 + } 1168 + } 1169 + 1170 + stream->formats = formats; 1171 + stream->rates = rates; 1172 + 1173 + return 0; 1174 + } 1175 + 1176 + /** 1177 + * sdca_asoc_populate_dais - fill in an array of DAI drivers for a Function 1178 + * @dev: Pointer to the device against which allocations will be done. 1179 + * @function: Pointer to the Function information. 1180 + * @dais: Array of DAI drivers to be populated. 1181 + * @ops: DAI ops to be attached to each of the created DAI drivers. 1182 + * 1183 + * This function populates an array of ASoC DAI drivers from the DisCo 1184 + * information for a particular SDCA Function. Typically, 1185 + * snd_soc_asoc_count_component will be used to allocate an 1186 + * appropriately sized array before calling this function. 1187 + * 1188 + * Return: Returns zero on success, and a negative error code on failure. 1189 + */ 1190 + int sdca_asoc_populate_dais(struct device *dev, struct sdca_function_data *function, 1191 + struct snd_soc_dai_driver *dais, 1192 + const struct snd_soc_dai_ops *ops) 1193 + { 1194 + int i, j; 1195 + int ret; 1196 + 1197 + for (i = 0, j = 0; i < function->num_entities - 1; i++) { 1198 + struct sdca_entity *entity = &function->entities[i]; 1199 + struct snd_soc_pcm_stream *stream; 1200 + const char *stream_suffix; 1201 + 1202 + switch (entity->type) { 1203 + case SDCA_ENTITY_TYPE_IT: 1204 + stream = &dais[j].playback; 1205 + stream_suffix = "Playback"; 1206 + break; 1207 + case SDCA_ENTITY_TYPE_OT: 1208 + stream = &dais[j].capture; 1209 + stream_suffix = "Capture"; 1210 + break; 1211 + default: 1212 + continue; 1213 + } 1214 + 1215 + /* Can't check earlier as only terminals have an iot member. */ 1216 + if (!entity->iot.is_dataport) 1217 + continue; 1218 + 1219 + stream->stream_name = devm_kasprintf(dev, GFP_KERNEL, "%s %s", 1220 + entity->label, stream_suffix); 1221 + if (!stream->stream_name) 1222 + return -ENOMEM; 1223 + /* Channels will be further limited by constraints */ 1224 + stream->channels_min = 1; 1225 + stream->channels_max = SDCA_MAX_CHANNEL_COUNT; 1226 + 1227 + ret = populate_rate_format(dev, function, entity, stream); 1228 + if (ret) 1229 + return ret; 1230 + 1231 + dais[j].id = i; 1232 + dais[j].name = entity->label; 1233 + dais[j].ops = ops; 1234 + j++; 1235 + } 1236 + 1237 + return 0; 1238 + } 1239 + EXPORT_SYMBOL_NS(sdca_asoc_populate_dais, "SND_SOC_SDCA"); 1240 + 1241 + /** 1242 + * sdca_asoc_populate_component - fill in a component driver for a Function 1243 + * @dev: Pointer to the device against which allocations will be done. 1244 + * @function: Pointer to the Function information. 1245 + * @copmonent_drv: Pointer to the component driver to be populated. 1246 + * 1247 + * This function populates a snd_soc_component_driver structure based 1248 + * on the DisCo information for a particular SDCA Function. It does 1249 + * all allocation internally. 1250 + * 1251 + * Return: Returns zero on success, and a negative error code on failure. 1252 + */ 1253 + int sdca_asoc_populate_component(struct device *dev, 1254 + struct sdca_function_data *function, 1255 + struct snd_soc_component_driver *component_drv, 1256 + struct snd_soc_dai_driver **dai_drv, int *num_dai_drv, 1257 + const struct snd_soc_dai_ops *ops) 1258 + { 1259 + struct snd_soc_dapm_widget *widgets; 1260 + struct snd_soc_dapm_route *routes; 1261 + struct snd_kcontrol_new *controls; 1262 + struct snd_soc_dai_driver *dais; 1263 + int num_widgets, num_routes, num_controls, num_dais; 1264 + int ret; 1265 + 1266 + ret = sdca_asoc_count_component(dev, function, &num_widgets, &num_routes, 1267 + &num_controls, &num_dais); 1268 + if (ret) 1269 + return ret; 1270 + 1271 + widgets = devm_kcalloc(dev, num_widgets, sizeof(*widgets), GFP_KERNEL); 1272 + if (!widgets) 1273 + return -ENOMEM; 1274 + 1275 + routes = devm_kcalloc(dev, num_routes, sizeof(*routes), GFP_KERNEL); 1276 + if (!routes) 1277 + return -ENOMEM; 1278 + 1279 + controls = devm_kcalloc(dev, num_controls, sizeof(*controls), GFP_KERNEL); 1280 + if (!controls) 1281 + return -ENOMEM; 1282 + 1283 + dais = devm_kcalloc(dev, num_dais, sizeof(*dais), GFP_KERNEL); 1284 + if (!dais) 1285 + return -ENOMEM; 1286 + 1287 + ret = sdca_asoc_populate_dapm(dev, function, widgets, routes); 1288 + if (ret) 1289 + return ret; 1290 + 1291 + ret = sdca_asoc_populate_controls(dev, function, controls); 1292 + if (ret) 1293 + return ret; 1294 + 1295 + ret = sdca_asoc_populate_dais(dev, function, dais, ops); 1296 + if (ret) 1297 + return ret; 1298 + 1299 + component_drv->dapm_widgets = widgets; 1300 + component_drv->num_dapm_widgets = num_widgets; 1301 + component_drv->dapm_routes = routes; 1302 + component_drv->num_dapm_routes = num_routes; 1303 + component_drv->controls = controls; 1304 + component_drv->num_controls = num_controls; 1305 + 1306 + *dai_drv = dais; 1307 + *num_dai_drv = num_dais; 1308 + 1309 + return 0; 1310 + } 1311 + EXPORT_SYMBOL_NS(sdca_asoc_populate_component, "SND_SOC_SDCA");
+4 -6
sound/soc/sdca/sdca_functions.c
··· 1105 1105 return -EINVAL; 1106 1106 } 1107 1107 1108 - /* There are 3 values per delay */ 1109 - delays = devm_kcalloc(dev, num_delays / mult_delay, 1110 - sizeof(*delays), GFP_KERNEL); 1111 - if (!delays) 1112 - return -ENOMEM; 1113 - 1114 1108 delay_list = kcalloc(num_delays, sizeof(*delay_list), GFP_KERNEL); 1115 1109 if (!delay_list) 1116 1110 return -ENOMEM; ··· 1114 1120 delay_list, num_delays); 1115 1121 1116 1122 num_delays /= mult_delay; 1123 + 1124 + delays = devm_kcalloc(dev, num_delays, sizeof(*delays), GFP_KERNEL); 1125 + if (!delays) 1126 + return -ENOMEM; 1117 1127 1118 1128 for (i = 0, j = 0; i < num_delays; i++) { 1119 1129 delays[i].from_ps = delay_list[j++];
-3
sound/soc/sdca/sdca_regmap.c
··· 316 316 return 0; 317 317 } 318 318 EXPORT_SYMBOL_NS(sdca_regmap_write_defaults, "SND_SOC_SDCA"); 319 - 320 - MODULE_LICENSE("GPL"); 321 - MODULE_DESCRIPTION("SDCA library");
+72 -16
sound/soc/soc-dapm.c
··· 3626 3626 } 3627 3627 EXPORT_SYMBOL_GPL(snd_soc_dapm_info_pin_switch); 3628 3628 3629 + static int __snd_soc_dapm_get_pin_switch(struct snd_soc_dapm_context *dapm, 3630 + const char *pin, 3631 + struct snd_ctl_elem_value *ucontrol) 3632 + { 3633 + snd_soc_dapm_mutex_lock(dapm); 3634 + ucontrol->value.integer.value[0] = snd_soc_dapm_get_pin_status(dapm, pin); 3635 + snd_soc_dapm_mutex_unlock(dapm); 3636 + 3637 + return 0; 3638 + } 3639 + 3629 3640 /** 3630 3641 * snd_soc_dapm_get_pin_switch - Get information for a pin switch 3631 3642 * 3632 3643 * @kcontrol: mixer control 3633 3644 * @ucontrol: Value 3645 + * 3646 + * Callback to provide information for a pin switch added at the card 3647 + * level. 3634 3648 */ 3635 3649 int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, 3636 3650 struct snd_ctl_elem_value *ucontrol) ··· 3652 3638 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 3653 3639 const char *pin = (const char *)kcontrol->private_value; 3654 3640 3655 - snd_soc_dapm_mutex_lock(card); 3656 - 3657 - ucontrol->value.integer.value[0] = 3658 - snd_soc_dapm_get_pin_status(&card->dapm, pin); 3659 - 3660 - snd_soc_dapm_mutex_unlock(card); 3661 - 3662 - return 0; 3641 + return __snd_soc_dapm_get_pin_switch(&card->dapm, pin, ucontrol); 3663 3642 } 3664 3643 EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_switch); 3644 + 3645 + /** 3646 + * snd_soc_dapm_get_component_pin_switch - Get information for a pin switch 3647 + * 3648 + * @kcontrol: mixer control 3649 + * @ucontrol: Value 3650 + * 3651 + * Callback to provide information for a pin switch added at the component 3652 + * level. 3653 + */ 3654 + int snd_soc_dapm_get_component_pin_switch(struct snd_kcontrol *kcontrol, 3655 + struct snd_ctl_elem_value *ucontrol) 3656 + { 3657 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 3658 + const char *pin = (const char *)kcontrol->private_value; 3659 + 3660 + return __snd_soc_dapm_get_pin_switch(&component->dapm, pin, ucontrol); 3661 + } 3662 + EXPORT_SYMBOL_GPL(snd_soc_dapm_get_component_pin_switch); 3663 + 3664 + static int __snd_soc_dapm_put_pin_switch(struct snd_soc_dapm_context *dapm, 3665 + const char *pin, 3666 + struct snd_ctl_elem_value *ucontrol) 3667 + { 3668 + int ret; 3669 + 3670 + snd_soc_dapm_mutex_lock(dapm); 3671 + ret = __snd_soc_dapm_set_pin(dapm, pin, !!ucontrol->value.integer.value[0]); 3672 + snd_soc_dapm_mutex_unlock(dapm); 3673 + 3674 + snd_soc_dapm_sync(dapm); 3675 + 3676 + return ret; 3677 + } 3665 3678 3666 3679 /** 3667 3680 * snd_soc_dapm_put_pin_switch - Set information for a pin switch 3668 3681 * 3669 3682 * @kcontrol: mixer control 3670 3683 * @ucontrol: Value 3684 + * 3685 + * Callback to provide information for a pin switch added at the card 3686 + * level. 3671 3687 */ 3672 3688 int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, 3673 3689 struct snd_ctl_elem_value *ucontrol) 3674 3690 { 3675 3691 struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); 3676 3692 const char *pin = (const char *)kcontrol->private_value; 3677 - int ret; 3678 3693 3679 - snd_soc_dapm_mutex_lock(card); 3680 - ret = __snd_soc_dapm_set_pin(&card->dapm, pin, 3681 - !!ucontrol->value.integer.value[0]); 3682 - snd_soc_dapm_mutex_unlock(card); 3683 - 3684 - snd_soc_dapm_sync(&card->dapm); 3685 - return ret; 3694 + return __snd_soc_dapm_put_pin_switch(&card->dapm, pin, ucontrol); 3686 3695 } 3687 3696 EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); 3697 + 3698 + /** 3699 + * snd_soc_dapm_put_component_pin_switch - Set information for a pin switch 3700 + * 3701 + * @kcontrol: mixer control 3702 + * @ucontrol: Value 3703 + * 3704 + * Callback to provide information for a pin switch added at the component 3705 + * level. 3706 + */ 3707 + int snd_soc_dapm_put_component_pin_switch(struct snd_kcontrol *kcontrol, 3708 + struct snd_ctl_elem_value *ucontrol) 3709 + { 3710 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 3711 + const char *pin = (const char *)kcontrol->private_value; 3712 + 3713 + return __snd_soc_dapm_put_pin_switch(&component->dapm, pin, ucontrol); 3714 + } 3715 + EXPORT_SYMBOL_GPL(snd_soc_dapm_put_component_pin_switch); 3688 3716 3689 3717 struct snd_soc_dapm_widget * 3690 3718 snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm,