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

ASoC: core: Add component pin control functions

It's often the case that a codec driver will need to control its
own pins. However, if a name_prefix has been applied to this codec it
must be included in the name passed to any of the snd_soc_dapm_x_pin()
functions.

The behaviour of the existing pin control functions is reasonable, since
you may want to search for a fully-specified name within the scope of an
entire card. This means that we can't apply the prefix in these functions
because it will break card-scope searches.

Constructing a prefixed string "manually" in codec drivers leads to a lot
of repetition of the same code.

To make this tidier in codec drivers this patch adds a new set of
equivalent functions that take a struct snd_soc_component instead of a
dapm context and automatically add the component's name_prefix to the
given name. This makes it a simple change in codec drivers to be
prefix-safe.

The new functions are not quite trivial enough to be inlines and the
compiler won't be able to compile-away any part of them.

Although it looks somewhat inefficient to have to allocate a temporary
buffer and combine strings, the current design of the widget list
doesn't lend itself to a more optimized implementation - it's a single
list of all widgets on a card and is searched linearly for a matching
string. As pin state changes are generally low-frequency events it's
unlikely to be a significant issue - at least not enough to rewrite the
widget list handling just for this.

Signed-off-by: Richard Fitzgerald <rf@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Richard Fitzgerald and committed by
Mark Brown
1b4d9c22 1001354c

+219
+20
include/sound/soc.h
··· 1697 1697 mutex_unlock(&dapm->card->dapm_mutex); 1698 1698 } 1699 1699 1700 + int snd_soc_component_enable_pin(struct snd_soc_component *component, 1701 + const char *pin); 1702 + int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component, 1703 + const char *pin); 1704 + int snd_soc_component_disable_pin(struct snd_soc_component *component, 1705 + const char *pin); 1706 + int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component, 1707 + const char *pin); 1708 + int snd_soc_component_nc_pin(struct snd_soc_component *component, 1709 + const char *pin); 1710 + int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component, 1711 + const char *pin); 1712 + int snd_soc_component_get_pin_status(struct snd_soc_component *component, 1713 + const char *pin); 1714 + int snd_soc_component_force_enable_pin(struct snd_soc_component *component, 1715 + const char *pin); 1716 + int snd_soc_component_force_enable_pin_unlocked( 1717 + struct snd_soc_component *component, 1718 + const char *pin); 1719 + 1700 1720 #endif
+199
sound/soc/soc-utils.c
··· 58 58 } 59 59 EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); 60 60 61 + int snd_soc_component_enable_pin(struct snd_soc_component *component, 62 + const char *pin) 63 + { 64 + struct snd_soc_dapm_context *dapm = 65 + snd_soc_component_get_dapm(component); 66 + char *full_name; 67 + int ret; 68 + 69 + if (!component->name_prefix) 70 + return snd_soc_dapm_enable_pin(dapm, pin); 71 + 72 + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 73 + if (!full_name) 74 + return -ENOMEM; 75 + 76 + ret = snd_soc_dapm_enable_pin(dapm, full_name); 77 + kfree(full_name); 78 + 79 + return ret; 80 + } 81 + EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin); 82 + 83 + int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component, 84 + const char *pin) 85 + { 86 + struct snd_soc_dapm_context *dapm = 87 + snd_soc_component_get_dapm(component); 88 + char *full_name; 89 + int ret; 90 + 91 + if (!component->name_prefix) 92 + return snd_soc_dapm_enable_pin_unlocked(dapm, pin); 93 + 94 + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 95 + if (!full_name) 96 + return -ENOMEM; 97 + 98 + ret = snd_soc_dapm_enable_pin_unlocked(dapm, full_name); 99 + kfree(full_name); 100 + 101 + return ret; 102 + } 103 + EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked); 104 + 105 + int snd_soc_component_disable_pin(struct snd_soc_component *component, 106 + const char *pin) 107 + { 108 + struct snd_soc_dapm_context *dapm = 109 + snd_soc_component_get_dapm(component); 110 + char *full_name; 111 + int ret; 112 + 113 + if (!component->name_prefix) 114 + return snd_soc_dapm_disable_pin(dapm, pin); 115 + 116 + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 117 + if (!full_name) 118 + return -ENOMEM; 119 + 120 + ret = snd_soc_dapm_disable_pin(dapm, full_name); 121 + kfree(full_name); 122 + 123 + return ret; 124 + } 125 + EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin); 126 + 127 + int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component, 128 + const char *pin) 129 + { 130 + struct snd_soc_dapm_context *dapm = 131 + snd_soc_component_get_dapm(component); 132 + char *full_name; 133 + int ret; 134 + 135 + if (!component->name_prefix) 136 + return snd_soc_dapm_disable_pin_unlocked(dapm, pin); 137 + 138 + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 139 + if (!full_name) 140 + return -ENOMEM; 141 + 142 + ret = snd_soc_dapm_disable_pin_unlocked(dapm, full_name); 143 + kfree(full_name); 144 + 145 + return ret; 146 + } 147 + EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked); 148 + 149 + int snd_soc_component_nc_pin(struct snd_soc_component *component, 150 + const char *pin) 151 + { 152 + struct snd_soc_dapm_context *dapm = 153 + snd_soc_component_get_dapm(component); 154 + char *full_name; 155 + int ret; 156 + 157 + if (!component->name_prefix) 158 + return snd_soc_dapm_nc_pin(dapm, pin); 159 + 160 + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 161 + if (!full_name) 162 + return -ENOMEM; 163 + 164 + ret = snd_soc_dapm_nc_pin(dapm, full_name); 165 + kfree(full_name); 166 + 167 + return ret; 168 + } 169 + EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin); 170 + 171 + int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component, 172 + const char *pin) 173 + { 174 + struct snd_soc_dapm_context *dapm = 175 + snd_soc_component_get_dapm(component); 176 + char *full_name; 177 + int ret; 178 + 179 + if (!component->name_prefix) 180 + return snd_soc_dapm_nc_pin_unlocked(dapm, pin); 181 + 182 + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 183 + if (!full_name) 184 + return -ENOMEM; 185 + 186 + ret = snd_soc_dapm_nc_pin_unlocked(dapm, full_name); 187 + kfree(full_name); 188 + 189 + return ret; 190 + } 191 + EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked); 192 + 193 + int snd_soc_component_get_pin_status(struct snd_soc_component *component, 194 + const char *pin) 195 + { 196 + struct snd_soc_dapm_context *dapm = 197 + snd_soc_component_get_dapm(component); 198 + char *full_name; 199 + int ret; 200 + 201 + if (!component->name_prefix) 202 + return snd_soc_dapm_get_pin_status(dapm, pin); 203 + 204 + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 205 + if (!full_name) 206 + return -ENOMEM; 207 + 208 + ret = snd_soc_dapm_get_pin_status(dapm, full_name); 209 + kfree(full_name); 210 + 211 + return ret; 212 + } 213 + EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status); 214 + 215 + int snd_soc_component_force_enable_pin(struct snd_soc_component *component, 216 + const char *pin) 217 + { 218 + struct snd_soc_dapm_context *dapm = 219 + snd_soc_component_get_dapm(component); 220 + char *full_name; 221 + int ret; 222 + 223 + if (!component->name_prefix) 224 + return snd_soc_dapm_force_enable_pin(dapm, pin); 225 + 226 + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 227 + if (!full_name) 228 + return -ENOMEM; 229 + 230 + ret = snd_soc_dapm_force_enable_pin(dapm, full_name); 231 + kfree(full_name); 232 + 233 + return ret; 234 + } 235 + EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin); 236 + 237 + int snd_soc_component_force_enable_pin_unlocked( 238 + struct snd_soc_component *component, 239 + const char *pin) 240 + { 241 + struct snd_soc_dapm_context *dapm = 242 + snd_soc_component_get_dapm(component); 243 + char *full_name; 244 + int ret; 245 + 246 + if (!component->name_prefix) 247 + return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin); 248 + 249 + full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 250 + if (!full_name) 251 + return -ENOMEM; 252 + 253 + ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, full_name); 254 + kfree(full_name); 255 + 256 + return ret; 257 + } 258 + EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked); 259 + 61 260 static const struct snd_pcm_hardware dummy_dma_hardware = { 62 261 /* Random values to keep userspace happy when checking constraints */ 63 262 .info = SNDRV_PCM_INFO_INTERLEAVED |