1 // SPDX-License-Identifier: (GPL-2.0-only 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 int temp = 0; 23 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 225 if (be->max > sizeof(ucontrol->value.bytes.data)) { 226 dev_err_ratelimited(scomp->dev, 227 "error: data max %d exceeds ucontrol data array size\n", 228 be->max); 229 return -EINVAL; 230 } 231 232 /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */ 233 if (data->size > be->max - sizeof(*data)) { 234 dev_err_ratelimited(scomp->dev, 235 "error: %u bytes of control data is invalid, max is %zu\n", 236 data->size, be->max - sizeof(*data)); 237 return -EINVAL; 238 } 239 240 size = data->size + sizeof(*data); 241 242 /* copy back to kcontrol */ 243 memcpy(ucontrol->value.bytes.data, data, size); 244 245 return 0; 246 } 247 248 int snd_sof_bytes_put(struct snd_kcontrol *kcontrol, 249 struct snd_ctl_elem_value *ucontrol) 250 { 251 struct soc_bytes_ext *be = 252 (struct soc_bytes_ext *)kcontrol->private_value; 253 struct snd_sof_control *scontrol = be->dobj.private; 254 struct snd_soc_component *scomp = scontrol->scomp; 255 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 256 struct sof_abi_hdr *data = cdata->data; 257 size_t size; 258 259 if (be->max > sizeof(ucontrol->value.bytes.data)) { 260 dev_err_ratelimited(scomp->dev, 261 "error: data max %d exceeds ucontrol data array size\n", 262 be->max); 263 return -EINVAL; 264 } 265 266 /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */ 267 if (data->size > be->max - sizeof(*data)) { 268 dev_err_ratelimited(scomp->dev, 269 "error: data size too big %u bytes max is %zu\n", 270 data->size, be->max - sizeof(*data)); 271 return -EINVAL; 272 } 273 274 size = data->size + sizeof(*data); 275 276 /* copy from kcontrol */ 277 memcpy(data, ucontrol->value.bytes.data, size); 278 279 /* notify DSP of byte control updates */ 280 if (pm_runtime_active(scomp->dev)) 281 snd_sof_ipc_set_get_comp_data(scontrol, 282 SOF_IPC_COMP_SET_DATA, 283 SOF_CTRL_TYPE_DATA_SET, 284 scontrol->cmd, 285 true); 286 287 return 0; 288 } 289 290 int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol, 291 const unsigned int __user *binary_data, 292 unsigned int size) 293 { 294 struct soc_bytes_ext *be = 295 (struct soc_bytes_ext *)kcontrol->private_value; 296 struct snd_sof_control *scontrol = be->dobj.private; 297 struct snd_soc_component *scomp = scontrol->scomp; 298 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 299 struct snd_ctl_tlv header; 300 const struct snd_ctl_tlv __user *tlvd = 301 (const struct snd_ctl_tlv __user *)binary_data; 302 303 /* make sure we have at least a header */ 304 if (size < sizeof(struct snd_ctl_tlv)) 305 return -EINVAL; 306 307 /* 308 * The beginning of bytes data contains a header from where 309 * the length (as bytes) is needed to know the correct copy 310 * length of data from tlvd->tlv. 311 */ 312 if (copy_from_user(&header, tlvd, sizeof(const struct snd_ctl_tlv))) 313 return -EFAULT; 314 315 /* make sure TLV info is consistent */ 316 if (header.length + sizeof(struct snd_ctl_tlv) > size) { 317 dev_err_ratelimited(scomp->dev, "error: inconsistent TLV, data %d + header %zu > %d\n", 318 header.length, sizeof(struct snd_ctl_tlv), size); 319 return -EINVAL; 320 } 321 322 /* be->max is coming from topology */ 323 if (header.length > be->max) { 324 dev_err_ratelimited(scomp->dev, "error: Bytes data size %d exceeds max %d.\n", 325 header.length, be->max); 326 return -EINVAL; 327 } 328 329 /* Check that header id matches the command */ 330 if (header.numid != scontrol->cmd) { 331 dev_err_ratelimited(scomp->dev, 332 "error: incorrect numid %d\n", 333 header.numid); 334 return -EINVAL; 335 } 336 337 if (copy_from_user(cdata->data, tlvd->tlv, header.length)) 338 return -EFAULT; 339 340 if (cdata->data->magic != SOF_ABI_MAGIC) { 341 dev_err_ratelimited(scomp->dev, 342 "error: Wrong ABI magic 0x%08x.\n", 343 cdata->data->magic); 344 return -EINVAL; 345 } 346 347 if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, cdata->data->abi)) { 348 dev_err_ratelimited(scomp->dev, "error: Incompatible ABI version 0x%08x.\n", 349 cdata->data->abi); 350 return -EINVAL; 351 } 352 353 /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */ 354 if (cdata->data->size > be->max - sizeof(const struct sof_abi_hdr)) { 355 dev_err_ratelimited(scomp->dev, "error: Mismatch in ABI data size (truncated?).\n"); 356 return -EINVAL; 357 } 358 359 /* notify DSP of byte control updates */ 360 if (pm_runtime_active(scomp->dev)) 361 snd_sof_ipc_set_get_comp_data(scontrol, 362 SOF_IPC_COMP_SET_DATA, 363 SOF_CTRL_TYPE_DATA_SET, 364 scontrol->cmd, 365 true); 366 367 return 0; 368 } 369 370 int snd_sof_bytes_ext_volatile_get(struct snd_kcontrol *kcontrol, unsigned int __user *binary_data, 371 unsigned int size) 372 { 373 struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value; 374 struct snd_sof_control *scontrol = be->dobj.private; 375 struct snd_soc_component *scomp = scontrol->scomp; 376 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 377 struct snd_ctl_tlv header; 378 struct snd_ctl_tlv __user *tlvd = (struct snd_ctl_tlv __user *)binary_data; 379 size_t data_size; 380 int ret; 381 int err; 382 383 /* 384 * Decrement the limit by ext bytes header size to 385 * ensure the user space buffer is not exceeded. 386 */ 387 if (size < sizeof(struct snd_ctl_tlv)) 388 return -ENOSPC; 389 size -= sizeof(struct snd_ctl_tlv); 390 391 ret = pm_runtime_get_sync(scomp->dev); 392 if (ret < 0 && ret != -EACCES) { 393 dev_err_ratelimited(scomp->dev, "error: bytes_ext get failed to resume %d\n", ret); 394 pm_runtime_put_noidle(scomp->dev); 395 return ret; 396 } 397 398 /* set the ABI header values */ 399 cdata->data->magic = SOF_ABI_MAGIC; 400 cdata->data->abi = SOF_ABI_VERSION; 401 /* get all the component data from DSP */ 402 ret = snd_sof_ipc_set_get_comp_data(scontrol, SOF_IPC_COMP_GET_DATA, SOF_CTRL_TYPE_DATA_GET, 403 scontrol->cmd, false); 404 if (ret < 0) 405 goto out; 406 407 /* check data size doesn't exceed max coming from topology */ 408 if (cdata->data->size > be->max - sizeof(const struct sof_abi_hdr)) { 409 dev_err_ratelimited(scomp->dev, "error: user data size %d exceeds max size %zu.\n", 410 cdata->data->size, 411 be->max - sizeof(const struct sof_abi_hdr)); 412 ret = -EINVAL; 413 goto out; 414 } 415 416 data_size = cdata->data->size + sizeof(const struct sof_abi_hdr); 417 418 /* make sure we don't exceed size provided by user space for data */ 419 if (data_size > size) { 420 ret = -ENOSPC; 421 goto out; 422 } 423 424 header.numid = scontrol->cmd; 425 header.length = data_size; 426 if (copy_to_user(tlvd, &header, sizeof(const struct snd_ctl_tlv))) { 427 ret = -EFAULT; 428 goto out; 429 } 430 431 if (copy_to_user(tlvd->tlv, cdata->data, data_size)) 432 ret = -EFAULT; 433 out: 434 pm_runtime_mark_last_busy(scomp->dev); 435 err = pm_runtime_put_autosuspend(scomp->dev); 436 if (err < 0) 437 dev_err_ratelimited(scomp->dev, "error: bytes_ext get failed to idle %d\n", err); 438 439 return ret; 440 } 441 442 int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol, 443 unsigned int __user *binary_data, 444 unsigned int size) 445 { 446 struct soc_bytes_ext *be = 447 (struct soc_bytes_ext *)kcontrol->private_value; 448 struct snd_sof_control *scontrol = be->dobj.private; 449 struct snd_soc_component *scomp = scontrol->scomp; 450 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 451 struct snd_ctl_tlv header; 452 struct snd_ctl_tlv __user *tlvd = 453 (struct snd_ctl_tlv __user *)binary_data; 454 size_t data_size; 455 456 /* 457 * Decrement the limit by ext bytes header size to 458 * ensure the user space buffer is not exceeded. 459 */ 460 if (size < sizeof(struct snd_ctl_tlv)) 461 return -ENOSPC; 462 size -= sizeof(struct snd_ctl_tlv); 463 464 /* set the ABI header values */ 465 cdata->data->magic = SOF_ABI_MAGIC; 466 cdata->data->abi = SOF_ABI_VERSION; 467 468 /* check data size doesn't exceed max coming from topology */ 469 if (cdata->data->size > be->max - sizeof(const struct sof_abi_hdr)) { 470 dev_err_ratelimited(scomp->dev, "error: user data size %d exceeds max size %zu.\n", 471 cdata->data->size, 472 be->max - sizeof(const struct sof_abi_hdr)); 473 return -EINVAL; 474 } 475 476 data_size = cdata->data->size + sizeof(const struct sof_abi_hdr); 477 478 /* make sure we don't exceed size provided by user space for data */ 479 if (data_size > size) 480 return -ENOSPC; 481 482 header.numid = scontrol->cmd; 483 header.length = data_size; 484 if (copy_to_user(tlvd, &header, sizeof(const struct snd_ctl_tlv))) 485 return -EFAULT; 486 487 if (copy_to_user(tlvd->tlv, cdata->data, data_size)) 488 return -EFAULT; 489 490 return 0; 491 } 492