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 static void snd_sof_refresh_control(struct snd_sof_control *scontrol) 69 { 70 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 71 struct snd_soc_component *scomp = scontrol->scomp; 72 int ret; 73 74 if (!scontrol->comp_data_dirty) 75 return; 76 77 if (!pm_runtime_active(scomp->dev)) 78 return; 79 80 /* set the ABI header values */ 81 cdata->data->magic = SOF_ABI_MAGIC; 82 cdata->data->abi = SOF_ABI_VERSION; 83 84 /* refresh the component data from DSP */ 85 scontrol->comp_data_dirty = false; 86 ret = snd_sof_ipc_set_get_comp_data(scontrol, false); 87 if (ret < 0) { 88 dev_err(scomp->dev, "error: failed to get control data: %d\n", ret); 89 /* Set the flag to re-try next time to get the data */ 90 scontrol->comp_data_dirty = true; 91 } 92 } 93 94 int snd_sof_volume_get(struct snd_kcontrol *kcontrol, 95 struct snd_ctl_elem_value *ucontrol) 96 { 97 struct soc_mixer_control *sm = 98 (struct soc_mixer_control *)kcontrol->private_value; 99 struct snd_sof_control *scontrol = sm->dobj.private; 100 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 101 unsigned int i, channels = scontrol->num_channels; 102 103 snd_sof_refresh_control(scontrol); 104 105 /* read back each channel */ 106 for (i = 0; i < channels; i++) 107 ucontrol->value.integer.value[i] = 108 ipc_to_mixer(cdata->chanv[i].value, 109 scontrol->volume_table, sm->max + 1); 110 111 return 0; 112 } 113 114 int snd_sof_volume_put(struct snd_kcontrol *kcontrol, 115 struct snd_ctl_elem_value *ucontrol) 116 { 117 struct soc_mixer_control *sm = 118 (struct soc_mixer_control *)kcontrol->private_value; 119 struct snd_sof_control *scontrol = sm->dobj.private; 120 struct snd_soc_component *scomp = scontrol->scomp; 121 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 122 unsigned int i, channels = scontrol->num_channels; 123 bool change = false; 124 u32 value; 125 126 /* update each channel */ 127 for (i = 0; i < channels; i++) { 128 value = mixer_to_ipc(ucontrol->value.integer.value[i], 129 scontrol->volume_table, sm->max + 1); 130 change = change || (value != cdata->chanv[i].value); 131 cdata->chanv[i].channel = i; 132 cdata->chanv[i].value = value; 133 } 134 135 /* notify DSP of mixer updates */ 136 if (pm_runtime_active(scomp->dev)) 137 snd_sof_ipc_set_get_comp_data(scontrol, true); 138 return change; 139 } 140 141 int snd_sof_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 142 { 143 struct soc_mixer_control *sm = (struct soc_mixer_control *)kcontrol->private_value; 144 struct snd_sof_control *scontrol = sm->dobj.private; 145 unsigned int channels = scontrol->num_channels; 146 int platform_max; 147 148 if (!sm->platform_max) 149 sm->platform_max = sm->max; 150 platform_max = sm->platform_max; 151 152 if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume")) 153 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; 154 else 155 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 156 157 uinfo->count = channels; 158 uinfo->value.integer.min = 0; 159 uinfo->value.integer.max = platform_max - sm->min; 160 return 0; 161 } 162 163 int snd_sof_switch_get(struct snd_kcontrol *kcontrol, 164 struct snd_ctl_elem_value *ucontrol) 165 { 166 struct soc_mixer_control *sm = 167 (struct soc_mixer_control *)kcontrol->private_value; 168 struct snd_sof_control *scontrol = sm->dobj.private; 169 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 170 unsigned int i, channels = scontrol->num_channels; 171 172 snd_sof_refresh_control(scontrol); 173 174 /* read back each channel */ 175 for (i = 0; i < channels; i++) 176 ucontrol->value.integer.value[i] = cdata->chanv[i].value; 177 178 return 0; 179 } 180 181 int snd_sof_switch_put(struct snd_kcontrol *kcontrol, 182 struct snd_ctl_elem_value *ucontrol) 183 { 184 struct soc_mixer_control *sm = 185 (struct soc_mixer_control *)kcontrol->private_value; 186 struct snd_sof_control *scontrol = sm->dobj.private; 187 struct snd_soc_component *scomp = scontrol->scomp; 188 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 189 unsigned int i, channels = scontrol->num_channels; 190 bool change = false; 191 u32 value; 192 193 /* update each channel */ 194 for (i = 0; i < channels; i++) { 195 value = ucontrol->value.integer.value[i]; 196 change = change || (value != cdata->chanv[i].value); 197 cdata->chanv[i].channel = i; 198 cdata->chanv[i].value = value; 199 } 200 201 if (scontrol->led_ctl.use_led) 202 update_mute_led(scontrol, kcontrol, ucontrol); 203 204 /* notify DSP of mixer updates */ 205 if (pm_runtime_active(scomp->dev)) 206 snd_sof_ipc_set_get_comp_data(scontrol, true); 207 208 return change; 209 } 210 211 int snd_sof_enum_get(struct snd_kcontrol *kcontrol, 212 struct snd_ctl_elem_value *ucontrol) 213 { 214 struct soc_enum *se = 215 (struct soc_enum *)kcontrol->private_value; 216 struct snd_sof_control *scontrol = se->dobj.private; 217 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 218 unsigned int i, channels = scontrol->num_channels; 219 220 snd_sof_refresh_control(scontrol); 221 222 /* read back each channel */ 223 for (i = 0; i < channels; i++) 224 ucontrol->value.enumerated.item[i] = cdata->chanv[i].value; 225 226 return 0; 227 } 228 229 int snd_sof_enum_put(struct snd_kcontrol *kcontrol, 230 struct snd_ctl_elem_value *ucontrol) 231 { 232 struct soc_enum *se = 233 (struct soc_enum *)kcontrol->private_value; 234 struct snd_sof_control *scontrol = se->dobj.private; 235 struct snd_soc_component *scomp = scontrol->scomp; 236 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 237 unsigned int i, channels = scontrol->num_channels; 238 bool change = false; 239 u32 value; 240 241 /* update each channel */ 242 for (i = 0; i < channels; i++) { 243 value = ucontrol->value.enumerated.item[i]; 244 change = change || (value != cdata->chanv[i].value); 245 cdata->chanv[i].channel = i; 246 cdata->chanv[i].value = value; 247 } 248 249 /* notify DSP of enum updates */ 250 if (pm_runtime_active(scomp->dev)) 251 snd_sof_ipc_set_get_comp_data(scontrol, true); 252 253 return change; 254 } 255 256 int snd_sof_bytes_get(struct snd_kcontrol *kcontrol, 257 struct snd_ctl_elem_value *ucontrol) 258 { 259 struct soc_bytes_ext *be = 260 (struct soc_bytes_ext *)kcontrol->private_value; 261 struct snd_sof_control *scontrol = be->dobj.private; 262 struct snd_soc_component *scomp = scontrol->scomp; 263 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 264 struct sof_abi_hdr *data = cdata->data; 265 size_t size; 266 267 snd_sof_refresh_control(scontrol); 268 269 if (be->max > sizeof(ucontrol->value.bytes.data)) { 270 dev_err_ratelimited(scomp->dev, 271 "error: data max %d exceeds ucontrol data array size\n", 272 be->max); 273 return -EINVAL; 274 } 275 276 /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */ 277 if (data->size > be->max - sizeof(*data)) { 278 dev_err_ratelimited(scomp->dev, 279 "error: %u bytes of control data is invalid, max is %zu\n", 280 data->size, be->max - sizeof(*data)); 281 return -EINVAL; 282 } 283 284 size = data->size + sizeof(*data); 285 286 /* copy back to kcontrol */ 287 memcpy(ucontrol->value.bytes.data, data, size); 288 289 return 0; 290 } 291 292 int snd_sof_bytes_put(struct snd_kcontrol *kcontrol, 293 struct snd_ctl_elem_value *ucontrol) 294 { 295 struct soc_bytes_ext *be = 296 (struct soc_bytes_ext *)kcontrol->private_value; 297 struct snd_sof_control *scontrol = be->dobj.private; 298 struct snd_soc_component *scomp = scontrol->scomp; 299 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 300 struct sof_abi_hdr *data = cdata->data; 301 size_t size; 302 303 if (be->max > sizeof(ucontrol->value.bytes.data)) { 304 dev_err_ratelimited(scomp->dev, 305 "error: data max %d exceeds ucontrol data array size\n", 306 be->max); 307 return -EINVAL; 308 } 309 310 /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */ 311 if (data->size > be->max - sizeof(*data)) { 312 dev_err_ratelimited(scomp->dev, 313 "error: data size too big %u bytes max is %zu\n", 314 data->size, be->max - sizeof(*data)); 315 return -EINVAL; 316 } 317 318 size = data->size + sizeof(*data); 319 320 /* copy from kcontrol */ 321 memcpy(data, ucontrol->value.bytes.data, size); 322 323 /* notify DSP of byte control updates */ 324 if (pm_runtime_active(scomp->dev)) 325 snd_sof_ipc_set_get_comp_data(scontrol, true); 326 327 return 0; 328 } 329 330 int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol, 331 const unsigned int __user *binary_data, 332 unsigned int size) 333 { 334 struct soc_bytes_ext *be = 335 (struct soc_bytes_ext *)kcontrol->private_value; 336 struct snd_sof_control *scontrol = be->dobj.private; 337 struct snd_soc_component *scomp = scontrol->scomp; 338 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 339 struct snd_ctl_tlv header; 340 const struct snd_ctl_tlv __user *tlvd = 341 (const struct snd_ctl_tlv __user *)binary_data; 342 343 /* make sure we have at least a header */ 344 if (size < sizeof(struct snd_ctl_tlv)) 345 return -EINVAL; 346 347 /* 348 * The beginning of bytes data contains a header from where 349 * the length (as bytes) is needed to know the correct copy 350 * length of data from tlvd->tlv. 351 */ 352 if (copy_from_user(&header, tlvd, sizeof(struct snd_ctl_tlv))) 353 return -EFAULT; 354 355 /* make sure TLV info is consistent */ 356 if (header.length + sizeof(struct snd_ctl_tlv) > size) { 357 dev_err_ratelimited(scomp->dev, "error: inconsistent TLV, data %d + header %zu > %d\n", 358 header.length, sizeof(struct snd_ctl_tlv), size); 359 return -EINVAL; 360 } 361 362 /* be->max is coming from topology */ 363 if (header.length > be->max) { 364 dev_err_ratelimited(scomp->dev, "error: Bytes data size %d exceeds max %d.\n", 365 header.length, be->max); 366 return -EINVAL; 367 } 368 369 /* Check that header id matches the command */ 370 if (header.numid != cdata->cmd) { 371 dev_err_ratelimited(scomp->dev, 372 "error: incorrect numid %d\n", 373 header.numid); 374 return -EINVAL; 375 } 376 377 if (copy_from_user(cdata->data, tlvd->tlv, header.length)) 378 return -EFAULT; 379 380 if (cdata->data->magic != SOF_ABI_MAGIC) { 381 dev_err_ratelimited(scomp->dev, 382 "error: Wrong ABI magic 0x%08x.\n", 383 cdata->data->magic); 384 return -EINVAL; 385 } 386 387 if (SOF_ABI_VERSION_INCOMPATIBLE(SOF_ABI_VERSION, cdata->data->abi)) { 388 dev_err_ratelimited(scomp->dev, "error: Incompatible ABI version 0x%08x.\n", 389 cdata->data->abi); 390 return -EINVAL; 391 } 392 393 /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */ 394 if (cdata->data->size > be->max - sizeof(struct sof_abi_hdr)) { 395 dev_err_ratelimited(scomp->dev, "error: Mismatch in ABI data size (truncated?).\n"); 396 return -EINVAL; 397 } 398 399 /* notify DSP of byte control updates */ 400 if (pm_runtime_active(scomp->dev)) 401 snd_sof_ipc_set_get_comp_data(scontrol, true); 402 403 return 0; 404 } 405 406 int snd_sof_bytes_ext_volatile_get(struct snd_kcontrol *kcontrol, unsigned int __user *binary_data, 407 unsigned int size) 408 { 409 struct soc_bytes_ext *be = (struct soc_bytes_ext *)kcontrol->private_value; 410 struct snd_sof_control *scontrol = be->dobj.private; 411 struct snd_soc_component *scomp = scontrol->scomp; 412 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 413 struct snd_ctl_tlv header; 414 struct snd_ctl_tlv __user *tlvd = (struct snd_ctl_tlv __user *)binary_data; 415 size_t data_size; 416 int ret; 417 int err; 418 419 /* 420 * Decrement the limit by ext bytes header size to 421 * ensure the user space buffer is not exceeded. 422 */ 423 if (size < sizeof(struct snd_ctl_tlv)) 424 return -ENOSPC; 425 size -= sizeof(struct snd_ctl_tlv); 426 427 ret = pm_runtime_get_sync(scomp->dev); 428 if (ret < 0 && ret != -EACCES) { 429 dev_err_ratelimited(scomp->dev, "error: bytes_ext get failed to resume %d\n", ret); 430 pm_runtime_put_noidle(scomp->dev); 431 return ret; 432 } 433 434 /* set the ABI header values */ 435 cdata->data->magic = SOF_ABI_MAGIC; 436 cdata->data->abi = SOF_ABI_VERSION; 437 /* get all the component data from DSP */ 438 ret = snd_sof_ipc_set_get_comp_data(scontrol, false); 439 if (ret < 0) 440 goto out; 441 442 /* check data size doesn't exceed max coming from topology */ 443 if (cdata->data->size > be->max - sizeof(struct sof_abi_hdr)) { 444 dev_err_ratelimited(scomp->dev, "error: user data size %d exceeds max size %zu.\n", 445 cdata->data->size, 446 be->max - sizeof(struct sof_abi_hdr)); 447 ret = -EINVAL; 448 goto out; 449 } 450 451 data_size = cdata->data->size + sizeof(struct sof_abi_hdr); 452 453 /* make sure we don't exceed size provided by user space for data */ 454 if (data_size > size) { 455 ret = -ENOSPC; 456 goto out; 457 } 458 459 header.numid = cdata->cmd; 460 header.length = data_size; 461 if (copy_to_user(tlvd, &header, sizeof(struct snd_ctl_tlv))) { 462 ret = -EFAULT; 463 goto out; 464 } 465 466 if (copy_to_user(tlvd->tlv, cdata->data, data_size)) 467 ret = -EFAULT; 468 out: 469 pm_runtime_mark_last_busy(scomp->dev); 470 err = pm_runtime_put_autosuspend(scomp->dev); 471 if (err < 0) 472 dev_err_ratelimited(scomp->dev, "error: bytes_ext get failed to idle %d\n", err); 473 474 return ret; 475 } 476 477 int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol, 478 unsigned int __user *binary_data, 479 unsigned int size) 480 { 481 struct soc_bytes_ext *be = 482 (struct soc_bytes_ext *)kcontrol->private_value; 483 struct snd_sof_control *scontrol = be->dobj.private; 484 struct snd_soc_component *scomp = scontrol->scomp; 485 struct sof_ipc_ctrl_data *cdata = scontrol->control_data; 486 struct snd_ctl_tlv header; 487 struct snd_ctl_tlv __user *tlvd = 488 (struct snd_ctl_tlv __user *)binary_data; 489 size_t data_size; 490 491 snd_sof_refresh_control(scontrol); 492 493 /* 494 * Decrement the limit by ext bytes header size to 495 * ensure the user space buffer is not exceeded. 496 */ 497 if (size < sizeof(struct snd_ctl_tlv)) 498 return -ENOSPC; 499 size -= sizeof(struct snd_ctl_tlv); 500 501 /* set the ABI header values */ 502 cdata->data->magic = SOF_ABI_MAGIC; 503 cdata->data->abi = SOF_ABI_VERSION; 504 505 /* check data size doesn't exceed max coming from topology */ 506 if (cdata->data->size > be->max - sizeof(struct sof_abi_hdr)) { 507 dev_err_ratelimited(scomp->dev, "error: user data size %d exceeds max size %zu.\n", 508 cdata->data->size, 509 be->max - sizeof(struct sof_abi_hdr)); 510 return -EINVAL; 511 } 512 513 data_size = cdata->data->size + sizeof(struct sof_abi_hdr); 514 515 /* make sure we don't exceed size provided by user space for data */ 516 if (data_size > size) 517 return -ENOSPC; 518 519 header.numid = cdata->cmd; 520 header.length = data_size; 521 if (copy_to_user(tlvd, &header, sizeof(struct snd_ctl_tlv))) 522 return -EFAULT; 523 524 if (copy_to_user(tlvd->tlv, cdata->data, data_size)) 525 return -EFAULT; 526 527 return 0; 528 } 529 530 static void snd_sof_update_control(struct snd_sof_control *scontrol, 531 struct sof_ipc_ctrl_data *cdata) 532 { 533 struct snd_soc_component *scomp = scontrol->scomp; 534 struct sof_ipc_ctrl_data *local_cdata; 535 int i; 536 537 local_cdata = scontrol->control_data; 538 539 if (cdata->cmd == SOF_CTRL_CMD_BINARY) { 540 if (cdata->num_elems != local_cdata->data->size) { 541 dev_err(scomp->dev, 542 "error: cdata binary size mismatch %u - %u\n", 543 cdata->num_elems, local_cdata->data->size); 544 return; 545 } 546 547 /* copy the new binary data */ 548 memcpy(local_cdata->data, cdata->data, cdata->num_elems); 549 } else if (cdata->num_elems != scontrol->num_channels) { 550 dev_err(scomp->dev, 551 "error: cdata channel count mismatch %u - %d\n", 552 cdata->num_elems, scontrol->num_channels); 553 } else { 554 /* copy the new values */ 555 for (i = 0; i < cdata->num_elems; i++) 556 local_cdata->chanv[i].value = cdata->chanv[i].value; 557 } 558 } 559 560 void snd_sof_control_notify(struct snd_sof_dev *sdev, 561 struct sof_ipc_ctrl_data *cdata) 562 { 563 struct snd_soc_dapm_widget *widget; 564 struct snd_sof_control *scontrol; 565 struct snd_sof_widget *swidget; 566 struct snd_kcontrol *kc = NULL; 567 struct soc_mixer_control *sm; 568 struct soc_bytes_ext *be; 569 size_t expected_size; 570 struct soc_enum *se; 571 bool found = false; 572 int i, type; 573 574 if (cdata->type == SOF_CTRL_TYPE_VALUE_COMP_GET || 575 cdata->type == SOF_CTRL_TYPE_VALUE_COMP_SET) { 576 dev_err(sdev->dev, 577 "Component data is not supported in control notification\n"); 578 return; 579 } 580 581 /* Find the swidget first */ 582 list_for_each_entry(swidget, &sdev->widget_list, list) { 583 if (swidget->comp_id == cdata->comp_id) { 584 found = true; 585 break; 586 } 587 } 588 589 if (!found) 590 return; 591 592 /* Translate SOF cmd to TPLG type */ 593 switch (cdata->cmd) { 594 case SOF_CTRL_CMD_VOLUME: 595 case SOF_CTRL_CMD_SWITCH: 596 type = SND_SOC_TPLG_TYPE_MIXER; 597 break; 598 case SOF_CTRL_CMD_BINARY: 599 type = SND_SOC_TPLG_TYPE_BYTES; 600 break; 601 case SOF_CTRL_CMD_ENUM: 602 type = SND_SOC_TPLG_TYPE_ENUM; 603 break; 604 default: 605 dev_err(sdev->dev, "error: unknown cmd %u\n", cdata->cmd); 606 return; 607 } 608 609 widget = swidget->widget; 610 for (i = 0; i < widget->num_kcontrols; i++) { 611 /* skip non matching types or non matching indexes within type */ 612 if (widget->dobj.widget.kcontrol_type[i] == type && 613 widget->kcontrol_news[i].index == cdata->index) { 614 kc = widget->kcontrols[i]; 615 break; 616 } 617 } 618 619 if (!kc) 620 return; 621 622 switch (cdata->cmd) { 623 case SOF_CTRL_CMD_VOLUME: 624 case SOF_CTRL_CMD_SWITCH: 625 sm = (struct soc_mixer_control *)kc->private_value; 626 scontrol = sm->dobj.private; 627 break; 628 case SOF_CTRL_CMD_BINARY: 629 be = (struct soc_bytes_ext *)kc->private_value; 630 scontrol = be->dobj.private; 631 break; 632 case SOF_CTRL_CMD_ENUM: 633 se = (struct soc_enum *)kc->private_value; 634 scontrol = se->dobj.private; 635 break; 636 default: 637 return; 638 } 639 640 expected_size = sizeof(struct sof_ipc_ctrl_data); 641 switch (cdata->type) { 642 case SOF_CTRL_TYPE_VALUE_CHAN_GET: 643 case SOF_CTRL_TYPE_VALUE_CHAN_SET: 644 expected_size += cdata->num_elems * 645 sizeof(struct sof_ipc_ctrl_value_chan); 646 break; 647 case SOF_CTRL_TYPE_DATA_GET: 648 case SOF_CTRL_TYPE_DATA_SET: 649 expected_size += cdata->num_elems + sizeof(struct sof_abi_hdr); 650 break; 651 default: 652 return; 653 } 654 655 if (cdata->rhdr.hdr.size != expected_size) { 656 dev_err(sdev->dev, "error: component notification size mismatch\n"); 657 return; 658 } 659 660 if (cdata->num_elems) 661 /* 662 * The message includes the updated value/data, update the 663 * control's local cache using the received notification 664 */ 665 snd_sof_update_control(scontrol, cdata); 666 else 667 /* Mark the scontrol that the value/data is changed in SOF */ 668 scontrol->comp_data_dirty = true; 669 670 snd_ctl_notify_one(swidget->scomp->card->snd_card, 671 SNDRV_CTL_EVENT_MASK_VALUE, kc, 0); 672 } 673