1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 // 3 // This file is provided under a dual BSD/GPLv2 license. When using or 4 // redistributing this file, you may do so under either license. 5 // 6 // Copyright(c) 2018 Intel Corporation. All rights reserved. 7 // 8 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> 9 // 10 11 /* Mixer Controls */ 12 13 #include <linux/pm_runtime.h> 14 #include <linux/leds.h> 15 #include "sof-priv.h" 16 #include "sof-audio.h" 17 18 static void update_mute_led(struct snd_sof_control *scontrol, 19 struct snd_kcontrol *kcontrol, 20 struct snd_ctl_elem_value *ucontrol) 21 { 22 unsigned int temp = 0; 23 unsigned int mask; 24 int i; 25 26 mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 27 28 for (i = 0; i < scontrol->num_channels; i++) { 29 if (ucontrol->value.integer.value[i]) { 30 temp |= mask; 31 break; 32 } 33 } 34 35 if (temp == scontrol->led_ctl.led_value) 36 return; 37 38 scontrol->led_ctl.led_value = temp; 39 40 #if IS_REACHABLE(CONFIG_LEDS_TRIGGER_AUDIO) 41 if (!scontrol->led_ctl.direction) 42 ledtrig_audio_set(LED_AUDIO_MUTE, temp ? LED_OFF : LED_ON); 43 else 44 ledtrig_audio_set(LED_AUDIO_MICMUTE, temp ? LED_OFF : LED_ON); 45 #endif 46 } 47 48 static inline u32 mixer_to_ipc(unsigned int value, u32 *volume_map, int size) 49 { 50 if (value >= size) 51 return volume_map[size - 1]; 52 53 return volume_map[value]; 54 } 55 56 static inline u32 ipc_to_mixer(u32 value, u32 *volume_map, int size) 57 { 58 int i; 59 60 for (i = 0; i < size; i++) { 61 if (volume_map[i] >= value) 62 return i; 63 } 64 65 return i - 1; 66 } 67 68 int snd_sof_volume_get(struct snd_kcontrol *kcontrol, 69 struct snd_ctl_elem_value *ucontrol) 70 { 71 struct soc_mixer_control *sm = 72 (struct soc_mixer_control *)kcontrol->private_value; 73 struct snd_sof_control *scontrol = sm->dobj.private; 74 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 75 unsigned int i, channels = scontrol->num_channels; 76 77 /* read back each channel */ 78 for (i = 0; i < channels; i++) 79 ucontrol->value.integer.value[i] = 80 ipc_to_mixer(cdata->chanv[i].value, 81 scontrol->volume_table, sm->max + 1); 82 83 return 0; 84 } 85 86 int snd_sof_volume_put(struct snd_kcontrol *kcontrol, 87 struct snd_ctl_elem_value *ucontrol) 88 { 89 struct soc_mixer_control *sm = 90 (struct soc_mixer_control *)kcontrol->private_value; 91 struct snd_sof_control *scontrol = sm->dobj.private; 92 struct snd_soc_component *scomp = scontrol->scomp; 93 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 94 unsigned int i, channels = scontrol->num_channels; 95 bool change = false; 96 u32 value; 97 98 /* update each channel */ 99 for (i = 0; i < channels; i++) { 100 value = mixer_to_ipc(ucontrol->value.integer.value[i], 101 scontrol->volume_table, sm->max + 1); 102 change = change || (value != cdata->chanv[i].value); 103 cdata->chanv[i].channel = i; 104 cdata->chanv[i].value = value; 105 } 106 107 /* notify DSP of mixer updates */ 108 if (pm_runtime_active(scomp->dev)) 109 snd_sof_ipc_set_get_comp_data(scontrol, 110 SOF_IPC_COMP_SET_VALUE, 111 SOF_CTRL_TYPE_VALUE_CHAN_GET, 112 SOF_CTRL_CMD_VOLUME, 113 true); 114 return change; 115 } 116 117 int snd_sof_switch_get(struct snd_kcontrol *kcontrol, 118 struct snd_ctl_elem_value *ucontrol) 119 { 120 struct soc_mixer_control *sm = 121 (struct soc_mixer_control *)kcontrol->private_value; 122 struct snd_sof_control *scontrol = sm->dobj.private; 123 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 124 unsigned int i, channels = scontrol->num_channels; 125 126 /* read back each channel */ 127 for (i = 0; i < channels; i++) 128 ucontrol->value.integer.value[i] = cdata->chanv[i].value; 129 130 return 0; 131 } 132 133 int snd_sof_switch_put(struct snd_kcontrol *kcontrol, 134 struct snd_ctl_elem_value *ucontrol) 135 { 136 struct soc_mixer_control *sm = 137 (struct soc_mixer_control *)kcontrol->private_value; 138 struct snd_sof_control *scontrol = sm->dobj.private; 139 struct snd_soc_component *scomp = scontrol->scomp; 140 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 141 unsigned int i, channels = scontrol->num_channels; 142 bool change = false; 143 u32 value; 144 145 /* update each channel */ 146 for (i = 0; i < channels; i++) { 147 value = ucontrol->value.integer.value[i]; 148 change = change || (value != cdata->chanv[i].value); 149 cdata->chanv[i].channel = i; 150 cdata->chanv[i].value = value; 151 } 152 153 if (scontrol->led_ctl.use_led) 154 update_mute_led(scontrol, kcontrol, ucontrol); 155 156 /* notify DSP of mixer updates */ 157 if (pm_runtime_active(scomp->dev)) 158 snd_sof_ipc_set_get_comp_data(scontrol, 159 SOF_IPC_COMP_SET_VALUE, 160 SOF_CTRL_TYPE_VALUE_CHAN_GET, 161 SOF_CTRL_CMD_SWITCH, 162 true); 163 164 return change; 165 } 166 167 int snd_sof_enum_get(struct snd_kcontrol *kcontrol, 168 struct snd_ctl_elem_value *ucontrol) 169 { 170 struct soc_enum *se = 171 (struct soc_enum *)kcontrol->private_value; 172 struct snd_sof_control *scontrol = se->dobj.private; 173 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 174 unsigned int i, channels = scontrol->num_channels; 175 176 /* read back each channel */ 177 for (i = 0; i < channels; i++) 178 ucontrol->value.enumerated.item[i] = cdata->chanv[i].value; 179 180 return 0; 181 } 182 183 int snd_sof_enum_put(struct snd_kcontrol *kcontrol, 184 struct snd_ctl_elem_value *ucontrol) 185 { 186 struct soc_enum *se = 187 (struct soc_enum *)kcontrol->private_value; 188 struct snd_sof_control *scontrol = se->dobj.private; 189 struct snd_soc_component *scomp = scontrol->scomp; 190 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 191 unsigned int i, channels = scontrol->num_channels; 192 bool change = false; 193 u32 value; 194 195 /* update each channel */ 196 for (i = 0; i < channels; i++) { 197 value = ucontrol->value.enumerated.item[i]; 198 change = change || (value != cdata->chanv[i].value); 199 cdata->chanv[i].channel = i; 200 cdata->chanv[i].value = value; 201 } 202 203 /* notify DSP of enum updates */ 204 if (pm_runtime_active(scomp->dev)) 205 snd_sof_ipc_set_get_comp_data(scontrol, 206 SOF_IPC_COMP_SET_VALUE, 207 SOF_CTRL_TYPE_VALUE_CHAN_GET, 208 SOF_CTRL_CMD_ENUM, 209 true); 210 211 return change; 212 } 213 214 int snd_sof_bytes_get(struct snd_kcontrol *kcontrol, 215 struct snd_ctl_elem_value *ucontrol) 216 { 217 struct soc_bytes_ext *be = 218 (struct soc_bytes_ext *)kcontrol->private_value; 219 struct snd_sof_control *scontrol = be->dobj.private; 220 struct snd_soc_component *scomp = scontrol->scomp; 221 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 222 struct sof_abi_hdr *data = cdata->data; 223 size_t size; 224 int ret = 0; 225 226 if (be->max > sizeof(ucontrol->value.bytes.data)) { 227 dev_err_ratelimited(scomp->dev, 228 "error: data max %d exceeds ucontrol data array size\n", 229 be->max); 230 return -EINVAL; 231 } 232 233 size = data->size + sizeof(*data); 234 if (size > be->max) { 235 dev_err_ratelimited(scomp->dev, 236 "error: DSP sent %zu bytes max is %d\n", 237 size, be->max); 238 ret = -EINVAL; 239 goto out; 240 } 241 242 /* copy back to kcontrol */ 243 memcpy(ucontrol->value.bytes.data, data, size); 244 245 out: 246 return ret; 247 } 248 249 int snd_sof_bytes_put(struct snd_kcontrol *kcontrol, 250 struct snd_ctl_elem_value *ucontrol) 251 { 252 struct soc_bytes_ext *be = 253 (struct soc_bytes_ext *)kcontrol->private_value; 254 struct snd_sof_control *scontrol = be->dobj.private; 255 struct snd_soc_component *scomp = scontrol->scomp; 256 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 257 struct sof_abi_hdr *data = cdata->data; 258 size_t size = data->size + sizeof(*data); 259 260 if (be->max > sizeof(ucontrol->value.bytes.data)) { 261 dev_err_ratelimited(scomp->dev, 262 "error: data max %d exceeds ucontrol data array size\n", 263 be->max); 264 return -EINVAL; 265 } 266 267 if (size > be->max) { 268 dev_err_ratelimited(scomp->dev, 269 "error: size too big %zu bytes max is %d\n", 270 size, be->max); 271 return -EINVAL; 272 } 273 274 /* copy from kcontrol */ 275 memcpy(data, ucontrol->value.bytes.data, size); 276 277 /* notify DSP of byte control updates */ 278 if (pm_runtime_active(scomp->dev)) 279 snd_sof_ipc_set_get_comp_data(scontrol, 280 SOF_IPC_COMP_SET_DATA, 281 SOF_CTRL_TYPE_DATA_SET, 282 scontrol->cmd, 283 true); 284 285 return 0; 286 } 287 288 int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol, 289 const unsigned int __user *binary_data, 290 unsigned int size) 291 { 292 struct soc_bytes_ext *be = 293 (struct soc_bytes_ext *)kcontrol->private_value; 294 struct snd_sof_control *scontrol = be->dobj.private; 295 struct snd_soc_component *scomp = scontrol->scomp; 296 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 297 struct snd_ctl_tlv header; 298 const struct snd_ctl_tlv __user *tlvd = 299 (const struct snd_ctl_tlv __user *)binary_data; 300 301 /* 302 * The beginning of bytes data contains a header from where 303 * the length (as bytes) is needed to know the correct copy 304 * length of data from tlvd->tlv. 305 */ 306 if (copy_from_user(&header, tlvd, sizeof(const struct snd_ctl_tlv))) 307 return -EFAULT; 308 309 /* be->max is coming from topology */ 310 if (header.length > be->max) { 311 dev_err_ratelimited(scomp->dev, "error: Bytes data size %d exceeds max %d.\n", 312 header.length, be->max); 313 return -EINVAL; 314 } 315 316 /* Check that header id matches the command */ 317 if (header.numid != scontrol->cmd) { 318 dev_err_ratelimited(scomp->dev, 319 "error: incorrect numid %d\n", 320 header.numid); 321 return -EINVAL; 322 } 323 324 if (copy_from_user(cdata->data, tlvd->tlv, header.length)) 325 return -EFAULT; 326 327 if (cdata->data->magic != SOF_ABI_MAGIC) { 328 dev_err_ratelimited(scomp->dev, 329 "error: Wrong ABI magic 0x%08x.\n", 330 cdata->data->magic); 331 return -EINVAL; 332 } 333 334 if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, cdata->data->abi)) { 335 dev_err_ratelimited(scomp->dev, "error: Incompatible ABI version 0x%08x.\n", 336 cdata->data->abi); 337 return -EINVAL; 338 } 339 340 if (cdata->data->size + sizeof(const struct sof_abi_hdr) > be->max) { 341 dev_err_ratelimited(scomp->dev, "error: Mismatch in ABI data size (truncated?).\n"); 342 return -EINVAL; 343 } 344 345 /* notify DSP of byte control updates */ 346 if (pm_runtime_active(scomp->dev)) 347 snd_sof_ipc_set_get_comp_data(scontrol, 348 SOF_IPC_COMP_SET_DATA, 349 SOF_CTRL_TYPE_DATA_SET, 350 scontrol->cmd, 351 true); 352 353 return 0; 354 } 355 356 int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol, 357 unsigned int __user *binary_data, 358 unsigned int size) 359 { 360 struct soc_bytes_ext *be = 361 (struct soc_bytes_ext *)kcontrol->private_value; 362 struct snd_sof_control *scontrol = be->dobj.private; 363 struct snd_soc_component *scomp = scontrol->scomp; 364 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 365 struct snd_ctl_tlv header; 366 struct snd_ctl_tlv __user *tlvd = 367 (struct snd_ctl_tlv __user *)binary_data; 368 int data_size; 369 int ret = 0; 370 371 /* 372 * Decrement the limit by ext bytes header size to 373 * ensure the user space buffer is not exceeded. 374 */ 375 size -= sizeof(const struct snd_ctl_tlv); 376 377 /* set the ABI header values */ 378 cdata->data->magic = SOF_ABI_MAGIC; 379 cdata->data->abi = SOF_ABI_VERSION; 380 381 /* Prevent read of other kernel data or possibly corrupt response */ 382 data_size = cdata->data->size + sizeof(const struct sof_abi_hdr); 383 384 /* check data size doesn't exceed max coming from topology */ 385 if (data_size > be->max) { 386 dev_err_ratelimited(scomp->dev, "error: user data size %d exceeds max size %d.\n", 387 data_size, be->max); 388 ret = -EINVAL; 389 goto out; 390 } 391 392 header.numid = scontrol->cmd; 393 header.length = data_size; 394 if (copy_to_user(tlvd, &header, sizeof(const struct snd_ctl_tlv))) { 395 ret = -EFAULT; 396 goto out; 397 } 398 399 if (copy_to_user(tlvd->tlv, cdata->data, data_size)) 400 ret = -EFAULT; 401 402 out: 403 return ret; 404 } 405