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) 2022 Intel Corporation 7 // 8 // 9 10 #include "sof-priv.h" 11 #include "sof-audio.h" 12 #include "ipc4-priv.h" 13 #include "ipc4-topology.h" 14 15 static int sof_ipc4_set_get_kcontrol_data(struct snd_sof_control *scontrol, 16 bool set, bool lock) 17 { 18 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 19 struct snd_soc_component *scomp = scontrol->scomp; 20 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 21 const struct sof_ipc_ops *iops = sdev->ipc->ops; 22 struct sof_ipc4_msg *msg = &cdata->msg; 23 struct snd_sof_widget *swidget; 24 bool widget_found = false; 25 int ret = 0; 26 27 /* find widget associated with the control */ 28 list_for_each_entry(swidget, &sdev->widget_list, list) { 29 if (swidget->comp_id == scontrol->comp_id) { 30 widget_found = true; 31 break; 32 } 33 } 34 35 if (!widget_found) { 36 dev_err(scomp->dev, "Failed to find widget for kcontrol %s\n", scontrol->name); 37 return -ENOENT; 38 } 39 40 if (lock) 41 mutex_lock(&swidget->setup_mutex); 42 else 43 lockdep_assert_held(&swidget->setup_mutex); 44 45 /* 46 * Volatile controls should always be part of static pipelines and the 47 * widget use_count would always be > 0 in this case. For the others, 48 * just return the cached value if the widget is not set up. 49 */ 50 if (!swidget->use_count) 51 goto unlock; 52 53 msg->primary &= ~SOF_IPC4_MOD_INSTANCE_MASK; 54 msg->primary |= SOF_IPC4_MOD_INSTANCE(swidget->instance_id); 55 56 ret = iops->set_get_data(sdev, msg, msg->data_size, set); 57 if (!set) 58 goto unlock; 59 60 /* It is a set-data operation, and we have a valid backup that we can restore */ 61 if (ret < 0) { 62 if (!scontrol->old_ipc_control_data) 63 goto unlock; 64 /* 65 * Current ipc_control_data is not valid, we use the last known good 66 * configuration 67 */ 68 memcpy(scontrol->ipc_control_data, scontrol->old_ipc_control_data, 69 scontrol->size); 70 kfree(scontrol->old_ipc_control_data); 71 scontrol->old_ipc_control_data = NULL; 72 /* Send the last known good configuration to firmware */ 73 ret = iops->set_get_data(sdev, msg, msg->data_size, set); 74 if (ret < 0) 75 goto unlock; 76 } 77 78 unlock: 79 if (lock) 80 mutex_unlock(&swidget->setup_mutex); 81 82 return ret; 83 } 84 85 static int 86 sof_ipc4_set_volume_data(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, 87 struct snd_sof_control *scontrol, bool lock) 88 { 89 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 90 struct sof_ipc4_gain *gain = swidget->private; 91 struct sof_ipc4_msg *msg = &cdata->msg; 92 struct sof_ipc4_gain_params params; 93 bool all_channels_equal = true; 94 u32 value; 95 int ret, i; 96 97 /* check if all channel values are equal */ 98 value = cdata->chanv[0].value; 99 for (i = 1; i < scontrol->num_channels; i++) { 100 if (cdata->chanv[i].value != value) { 101 all_channels_equal = false; 102 break; 103 } 104 } 105 106 /* 107 * notify DSP with a single IPC message if all channel values are equal. Otherwise send 108 * a separate IPC for each channel. 109 */ 110 for (i = 0; i < scontrol->num_channels; i++) { 111 if (all_channels_equal) { 112 params.channels = SOF_IPC4_GAIN_ALL_CHANNELS_MASK; 113 params.init_val = cdata->chanv[0].value; 114 } else { 115 params.channels = cdata->chanv[i].channel; 116 params.init_val = cdata->chanv[i].value; 117 } 118 119 /* set curve type and duration from topology */ 120 params.curve_duration_l = gain->data.params.curve_duration_l; 121 params.curve_duration_h = gain->data.params.curve_duration_h; 122 params.curve_type = gain->data.params.curve_type; 123 124 msg->data_ptr = ¶ms; 125 msg->data_size = sizeof(params); 126 127 ret = sof_ipc4_set_get_kcontrol_data(scontrol, true, lock); 128 msg->data_ptr = NULL; 129 msg->data_size = 0; 130 if (ret < 0) { 131 dev_err(sdev->dev, "Failed to set volume update for %s\n", 132 scontrol->name); 133 return ret; 134 } 135 136 if (all_channels_equal) 137 break; 138 } 139 140 return 0; 141 } 142 143 static bool sof_ipc4_volume_put(struct snd_sof_control *scontrol, 144 struct snd_ctl_elem_value *ucontrol) 145 { 146 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 147 struct snd_soc_component *scomp = scontrol->scomp; 148 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 149 unsigned int channels = scontrol->num_channels; 150 struct snd_sof_widget *swidget; 151 bool widget_found = false; 152 bool change = false; 153 unsigned int i; 154 int ret; 155 156 /* update each channel */ 157 for (i = 0; i < channels; i++) { 158 u32 value = mixer_to_ipc(ucontrol->value.integer.value[i], 159 scontrol->volume_table, scontrol->max + 1); 160 161 change = change || (value != cdata->chanv[i].value); 162 cdata->chanv[i].channel = i; 163 cdata->chanv[i].value = value; 164 } 165 166 if (!pm_runtime_active(scomp->dev)) 167 return change; 168 169 /* find widget associated with the control */ 170 list_for_each_entry(swidget, &sdev->widget_list, list) { 171 if (swidget->comp_id == scontrol->comp_id) { 172 widget_found = true; 173 break; 174 } 175 } 176 177 if (!widget_found) { 178 dev_err(scomp->dev, "Failed to find widget for kcontrol %s\n", scontrol->name); 179 return false; 180 } 181 182 ret = sof_ipc4_set_volume_data(sdev, swidget, scontrol, true); 183 if (ret < 0) 184 return false; 185 186 return change; 187 } 188 189 static int sof_ipc4_volume_get(struct snd_sof_control *scontrol, 190 struct snd_ctl_elem_value *ucontrol) 191 { 192 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 193 unsigned int channels = scontrol->num_channels; 194 unsigned int i; 195 196 for (i = 0; i < channels; i++) 197 ucontrol->value.integer.value[i] = ipc_to_mixer(cdata->chanv[i].value, 198 scontrol->volume_table, 199 scontrol->max + 1); 200 201 return 0; 202 } 203 204 static int 205 sof_ipc4_set_generic_control_data(struct snd_sof_dev *sdev, 206 struct snd_sof_widget *swidget, 207 struct snd_sof_control *scontrol, bool lock) 208 { 209 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 210 struct sof_ipc4_control_msg_payload *data; 211 struct sof_ipc4_msg *msg = &cdata->msg; 212 size_t data_size; 213 unsigned int i; 214 int ret; 215 216 data_size = struct_size(data, chanv, scontrol->num_channels); 217 data = kzalloc(data_size, GFP_KERNEL); 218 if (!data) 219 return -ENOMEM; 220 221 data->id = cdata->index; 222 data->num_elems = scontrol->num_channels; 223 for (i = 0; i < scontrol->num_channels; i++) { 224 data->chanv[i].channel = cdata->chanv[i].channel; 225 data->chanv[i].value = cdata->chanv[i].value; 226 } 227 228 msg->data_ptr = data; 229 msg->data_size = data_size; 230 231 ret = sof_ipc4_set_get_kcontrol_data(scontrol, true, lock); 232 msg->data_ptr = NULL; 233 msg->data_size = 0; 234 if (ret < 0) 235 dev_err(sdev->dev, "Failed to set control update for %s\n", 236 scontrol->name); 237 238 kfree(data); 239 240 return ret; 241 } 242 243 static void sof_ipc4_refresh_generic_control(struct snd_sof_control *scontrol) 244 { 245 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 246 struct snd_soc_component *scomp = scontrol->scomp; 247 struct sof_ipc4_control_msg_payload *data; 248 struct sof_ipc4_msg *msg = &cdata->msg; 249 size_t data_size; 250 unsigned int i; 251 int ret; 252 253 if (!scontrol->comp_data_dirty) 254 return; 255 256 if (!pm_runtime_active(scomp->dev)) 257 return; 258 259 data_size = struct_size(data, chanv, scontrol->num_channels); 260 data = kmalloc(data_size, GFP_KERNEL); 261 if (!data) 262 return; 263 264 data->id = cdata->index; 265 data->num_elems = scontrol->num_channels; 266 msg->data_ptr = data; 267 msg->data_size = data_size; 268 269 scontrol->comp_data_dirty = false; 270 ret = sof_ipc4_set_get_kcontrol_data(scontrol, false, true); 271 msg->data_ptr = NULL; 272 msg->data_size = 0; 273 if (!ret) { 274 for (i = 0; i < scontrol->num_channels; i++) { 275 cdata->chanv[i].channel = data->chanv[i].channel; 276 cdata->chanv[i].value = data->chanv[i].value; 277 } 278 } else { 279 dev_err(scomp->dev, "Failed to read control data for %s\n", 280 scontrol->name); 281 scontrol->comp_data_dirty = true; 282 } 283 284 kfree(data); 285 } 286 287 static int 288 sof_ipc4_set_bytes_control_data(struct snd_sof_control *scontrol, bool lock) 289 { 290 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 291 struct snd_soc_component *scomp = scontrol->scomp; 292 struct sof_ipc4_control_msg_payload *msg_data; 293 struct sof_abi_hdr *data = cdata->data; 294 struct sof_ipc4_msg *msg = &cdata->msg; 295 size_t data_size; 296 int ret; 297 298 data_size = struct_size(msg_data, data, data->size); 299 msg_data = kzalloc(data_size, GFP_KERNEL); 300 if (!msg_data) 301 return -ENOMEM; 302 303 msg_data->id = cdata->index; 304 msg_data->num_elems = data->size; 305 memcpy(msg_data->data, data->data, data->size); 306 307 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(data->type); 308 309 msg->data_ptr = msg_data; 310 msg->data_size = data_size; 311 312 ret = sof_ipc4_set_get_kcontrol_data(scontrol, true, lock); 313 msg->data_ptr = NULL; 314 msg->data_size = 0; 315 if (ret < 0) 316 dev_err(scomp->dev, "%s: Failed to set control update for %s\n", 317 __func__, scontrol->name); 318 319 kfree(msg_data); 320 321 return ret; 322 } 323 324 static int 325 sof_ipc4_refresh_bytes_control(struct snd_sof_control *scontrol, bool lock) 326 { 327 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 328 struct snd_soc_component *scomp = scontrol->scomp; 329 struct sof_ipc4_control_msg_payload *msg_data; 330 struct sof_abi_hdr *data = cdata->data; 331 struct sof_ipc4_msg *msg = &cdata->msg; 332 size_t data_size; 333 int ret = 0; 334 335 if (!scontrol->comp_data_dirty) 336 return 0; 337 338 if (!pm_runtime_active(scomp->dev)) 339 return 0; 340 341 data_size = scontrol->max_size - sizeof(*data); 342 if (data_size < sizeof(*msg_data)) 343 data_size = sizeof(*msg_data); 344 345 msg_data = kzalloc(data_size, GFP_KERNEL); 346 if (!msg_data) 347 return -ENOMEM; 348 349 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(data->type); 350 351 msg_data->id = cdata->index; 352 msg_data->num_elems = 0; /* ignored for bytes */ 353 354 msg->data_ptr = msg_data; 355 msg->data_size = data_size; 356 357 scontrol->comp_data_dirty = false; 358 ret = sof_ipc4_set_get_kcontrol_data(scontrol, false, lock); 359 if (!ret) { 360 if (msg->data_size > scontrol->max_size - sizeof(*data)) { 361 dev_err(scomp->dev, 362 "%s: no space for data in %s (%zu, %zu)\n", 363 __func__, scontrol->name, msg->data_size, 364 scontrol->max_size - sizeof(*data)); 365 ret = -EINVAL; 366 goto out; 367 } 368 369 data->size = msg->data_size; 370 scontrol->size = sizeof(*cdata) + sizeof(*data) + data->size; 371 memcpy(data->data, msg->data_ptr, data->size); 372 } else { 373 dev_err(scomp->dev, "Failed to read control data for %s\n", 374 scontrol->name); 375 scontrol->comp_data_dirty = true; 376 } 377 378 out: 379 msg->data_ptr = NULL; 380 msg->data_size = 0; 381 382 kfree(msg_data); 383 384 return ret; 385 } 386 387 static bool sof_ipc4_switch_put(struct snd_sof_control *scontrol, 388 struct snd_ctl_elem_value *ucontrol) 389 { 390 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 391 struct snd_soc_component *scomp = scontrol->scomp; 392 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 393 struct snd_sof_widget *swidget; 394 bool widget_found = false; 395 bool change = false; 396 unsigned int i; 397 u32 value; 398 int ret; 399 400 /* update each channel */ 401 for (i = 0; i < scontrol->num_channels; i++) { 402 value = ucontrol->value.integer.value[i]; 403 change = change || (value != cdata->chanv[i].value); 404 cdata->chanv[i].channel = i; 405 cdata->chanv[i].value = value; 406 } 407 408 if (!pm_runtime_active(scomp->dev)) 409 return change; 410 411 /* find widget associated with the control */ 412 list_for_each_entry(swidget, &sdev->widget_list, list) { 413 if (swidget->comp_id == scontrol->comp_id) { 414 widget_found = true; 415 break; 416 } 417 } 418 419 if (!widget_found) { 420 dev_err(scomp->dev, "Failed to find widget for kcontrol %s\n", scontrol->name); 421 return false; 422 } 423 424 ret = sof_ipc4_set_generic_control_data(sdev, swidget, scontrol, true); 425 if (ret < 0) 426 return false; 427 428 return change; 429 } 430 431 static int sof_ipc4_switch_get(struct snd_sof_control *scontrol, 432 struct snd_ctl_elem_value *ucontrol) 433 { 434 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 435 unsigned int i; 436 437 sof_ipc4_refresh_generic_control(scontrol); 438 439 /* read back each channel */ 440 for (i = 0; i < scontrol->num_channels; i++) 441 ucontrol->value.integer.value[i] = cdata->chanv[i].value; 442 443 return 0; 444 } 445 446 static bool sof_ipc4_enum_put(struct snd_sof_control *scontrol, 447 struct snd_ctl_elem_value *ucontrol) 448 { 449 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 450 struct snd_soc_component *scomp = scontrol->scomp; 451 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 452 struct snd_sof_widget *swidget; 453 bool widget_found = false; 454 bool change = false; 455 unsigned int i; 456 u32 value; 457 int ret; 458 459 /* update each channel */ 460 for (i = 0; i < scontrol->num_channels; i++) { 461 value = ucontrol->value.enumerated.item[i]; 462 change = change || (value != cdata->chanv[i].value); 463 cdata->chanv[i].channel = i; 464 cdata->chanv[i].value = value; 465 } 466 467 if (!pm_runtime_active(scomp->dev)) 468 return change; 469 470 /* find widget associated with the control */ 471 list_for_each_entry(swidget, &sdev->widget_list, list) { 472 if (swidget->comp_id == scontrol->comp_id) { 473 widget_found = true; 474 break; 475 } 476 } 477 478 if (!widget_found) { 479 dev_err(scomp->dev, "Failed to find widget for kcontrol %s\n", scontrol->name); 480 return false; 481 } 482 483 ret = sof_ipc4_set_generic_control_data(sdev, swidget, scontrol, true); 484 if (ret < 0) 485 return false; 486 487 return change; 488 } 489 490 static int sof_ipc4_enum_get(struct snd_sof_control *scontrol, 491 struct snd_ctl_elem_value *ucontrol) 492 { 493 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 494 unsigned int i; 495 496 sof_ipc4_refresh_generic_control(scontrol); 497 498 /* read back each channel */ 499 for (i = 0; i < scontrol->num_channels; i++) 500 ucontrol->value.enumerated.item[i] = cdata->chanv[i].value; 501 502 return 0; 503 } 504 505 static int sof_ipc4_set_get_bytes_data(struct snd_sof_dev *sdev, 506 struct snd_sof_control *scontrol, 507 bool set, bool lock) 508 { 509 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 510 struct sof_abi_hdr *data = cdata->data; 511 struct sof_ipc4_msg *msg = &cdata->msg; 512 int ret = 0; 513 514 /* Send the new data to the firmware only if it is powered up */ 515 if (set) { 516 if (!pm_runtime_active(sdev->dev)) 517 return 0; 518 519 if (!data->size) { 520 dev_dbg(sdev->dev, "%s: No data to be sent.\n", 521 scontrol->name); 522 return 0; 523 } 524 } 525 526 if (data->type == SOF_IPC4_BYTES_CONTROL_PARAM_ID) { 527 if (set) 528 return sof_ipc4_set_bytes_control_data(scontrol, lock); 529 else 530 return sof_ipc4_refresh_bytes_control(scontrol, lock); 531 } 532 533 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(data->type); 534 535 msg->data_ptr = data->data; 536 if (set) 537 msg->data_size = data->size; 538 else 539 msg->data_size = scontrol->max_size - sizeof(*data); 540 541 ret = sof_ipc4_set_get_kcontrol_data(scontrol, set, lock); 542 if (ret < 0) { 543 dev_err(sdev->dev, "Failed to %s for %s\n", 544 set ? "set bytes update" : "get bytes", 545 scontrol->name); 546 } else if (!set) { 547 /* Update the sizes according to the received payload data */ 548 data->size = msg->data_size; 549 scontrol->size = sizeof(*cdata) + sizeof(*data) + data->size; 550 } 551 552 msg->data_ptr = NULL; 553 msg->data_size = 0; 554 555 return ret; 556 } 557 558 static int sof_ipc4_bytes_put(struct snd_sof_control *scontrol, 559 struct snd_ctl_elem_value *ucontrol) 560 { 561 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 562 struct snd_soc_component *scomp = scontrol->scomp; 563 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 564 struct sof_abi_hdr *data = cdata->data; 565 size_t size; 566 int ret; 567 568 if (scontrol->max_size > sizeof(ucontrol->value.bytes.data)) { 569 dev_err_ratelimited(scomp->dev, 570 "data max %zu exceeds ucontrol data array size\n", 571 scontrol->max_size); 572 return -EINVAL; 573 } 574 575 /* scontrol->max_size has been verified to be >= sizeof(struct sof_abi_hdr) */ 576 if (data->size > scontrol->max_size - sizeof(*data)) { 577 dev_err_ratelimited(scomp->dev, 578 "data size too big %u bytes max is %zu\n", 579 data->size, scontrol->max_size - sizeof(*data)); 580 return -EINVAL; 581 } 582 583 size = data->size + sizeof(*data); 584 585 /* copy from kcontrol */ 586 memcpy(data, ucontrol->value.bytes.data, size); 587 588 ret = sof_ipc4_set_get_bytes_data(sdev, scontrol, true, true); 589 if (!ret) 590 /* Update the cdata size */ 591 scontrol->size = sizeof(*cdata) + size; 592 593 return ret; 594 } 595 596 static int sof_ipc4_bytes_get(struct snd_sof_control *scontrol, 597 struct snd_ctl_elem_value *ucontrol) 598 { 599 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 600 struct snd_soc_component *scomp = scontrol->scomp; 601 struct sof_abi_hdr *data = cdata->data; 602 size_t size; 603 604 if (scontrol->max_size > sizeof(ucontrol->value.bytes.data)) { 605 dev_err_ratelimited(scomp->dev, "data max %zu exceeds ucontrol data array size\n", 606 scontrol->max_size); 607 return -EINVAL; 608 } 609 610 if (data->size > scontrol->max_size - sizeof(*data)) { 611 dev_err_ratelimited(scomp->dev, 612 "%u bytes of control data is invalid, max is %zu\n", 613 data->size, scontrol->max_size - sizeof(*data)); 614 return -EINVAL; 615 } 616 617 sof_ipc4_refresh_bytes_control(scontrol, true); 618 619 size = data->size + sizeof(*data); 620 621 /* copy back to kcontrol */ 622 memcpy(ucontrol->value.bytes.data, data, size); 623 624 return 0; 625 } 626 627 static int sof_ipc4_bytes_ext_put(struct snd_sof_control *scontrol, 628 const unsigned int __user *binary_data, 629 unsigned int size) 630 { 631 struct snd_ctl_tlv __user *tlvd = (struct snd_ctl_tlv __user *)binary_data; 632 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 633 struct snd_soc_component *scomp = scontrol->scomp; 634 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 635 struct sof_abi_hdr *data = cdata->data; 636 struct sof_abi_hdr abi_hdr; 637 struct snd_ctl_tlv header; 638 639 /* 640 * The beginning of bytes data contains a header from where 641 * the length (as bytes) is needed to know the correct copy 642 * length of data from tlvd->tlv. 643 */ 644 if (copy_from_user(&header, tlvd, sizeof(struct snd_ctl_tlv))) 645 return -EFAULT; 646 647 /* make sure TLV info is consistent */ 648 if (header.length + sizeof(struct snd_ctl_tlv) > size) { 649 dev_err_ratelimited(scomp->dev, 650 "Inconsistent TLV, data %d + header %zu > %d\n", 651 header.length, sizeof(struct snd_ctl_tlv), size); 652 return -EINVAL; 653 } 654 655 /* be->max is coming from topology */ 656 if (header.length > scontrol->max_size) { 657 dev_err_ratelimited(scomp->dev, 658 "Bytes data size %d exceeds max %zu\n", 659 header.length, scontrol->max_size); 660 return -EINVAL; 661 } 662 663 /* Check header id */ 664 if (header.numid != SOF_CTRL_CMD_BINARY) { 665 dev_err_ratelimited(scomp->dev, 666 "Incorrect numid for bytes put %d\n", 667 header.numid); 668 return -EINVAL; 669 } 670 671 /* Verify the ABI header first */ 672 if (copy_from_user(&abi_hdr, tlvd->tlv, sizeof(abi_hdr))) 673 return -EFAULT; 674 675 if (abi_hdr.magic != SOF_IPC4_ABI_MAGIC) { 676 dev_err_ratelimited(scomp->dev, "Wrong ABI magic 0x%08x\n", 677 abi_hdr.magic); 678 return -EINVAL; 679 } 680 681 if (abi_hdr.size > scontrol->max_size - sizeof(abi_hdr)) { 682 dev_err_ratelimited(scomp->dev, 683 "%u bytes of control data is invalid, max is %zu\n", 684 abi_hdr.size, scontrol->max_size - sizeof(abi_hdr)); 685 return -EINVAL; 686 } 687 688 if (!scontrol->old_ipc_control_data) { 689 /* Create a backup of the current, valid bytes control */ 690 scontrol->old_ipc_control_data = kmemdup(scontrol->ipc_control_data, 691 scontrol->size, GFP_KERNEL); 692 if (!scontrol->old_ipc_control_data) 693 return -ENOMEM; 694 } 695 696 /* Copy the whole binary data which includes the ABI header and the payload */ 697 if (copy_from_user(data, tlvd->tlv, header.length)) { 698 memcpy(scontrol->ipc_control_data, scontrol->old_ipc_control_data, 699 scontrol->size); 700 kfree(scontrol->old_ipc_control_data); 701 scontrol->old_ipc_control_data = NULL; 702 return -EFAULT; 703 } 704 705 /* Update the cdata size */ 706 scontrol->size = sizeof(*cdata) + header.length; 707 708 return sof_ipc4_set_get_bytes_data(sdev, scontrol, true, true); 709 } 710 711 static int _sof_ipc4_bytes_ext_get(struct snd_sof_control *scontrol, 712 const unsigned int __user *binary_data, 713 unsigned int size, bool from_dsp) 714 { 715 struct snd_ctl_tlv __user *tlvd = (struct snd_ctl_tlv __user *)binary_data; 716 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 717 struct snd_soc_component *scomp = scontrol->scomp; 718 struct sof_abi_hdr *data = cdata->data; 719 struct snd_ctl_tlv header; 720 size_t data_size; 721 722 /* 723 * Decrement the limit by ext bytes header size to ensure the user space 724 * buffer is not exceeded. 725 */ 726 if (size < sizeof(struct snd_ctl_tlv)) 727 return -ENOSPC; 728 729 size -= sizeof(struct snd_ctl_tlv); 730 731 /* get all the component data from DSP */ 732 if (from_dsp) { 733 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 734 int ret = sof_ipc4_set_get_bytes_data(sdev, scontrol, false, true); 735 736 if (ret < 0) 737 return ret; 738 739 /* Set the ABI magic (if the control is not initialized) */ 740 data->magic = SOF_IPC4_ABI_MAGIC; 741 } 742 743 if (data->size > scontrol->max_size - sizeof(*data)) { 744 dev_err_ratelimited(scomp->dev, 745 "%u bytes of control data is invalid, max is %zu\n", 746 data->size, scontrol->max_size - sizeof(*data)); 747 return -EINVAL; 748 } 749 750 data_size = data->size + sizeof(struct sof_abi_hdr); 751 752 /* make sure we don't exceed size provided by user space for data */ 753 if (data_size > size) 754 return -ENOSPC; 755 756 /* Set header id and length */ 757 header.numid = SOF_CTRL_CMD_BINARY; 758 header.length = data_size; 759 760 if (copy_to_user(tlvd, &header, sizeof(struct snd_ctl_tlv))) 761 return -EFAULT; 762 763 if (copy_to_user(tlvd->tlv, data, data_size)) 764 return -EFAULT; 765 766 return 0; 767 } 768 769 static int sof_ipc4_bytes_ext_get(struct snd_sof_control *scontrol, 770 const unsigned int __user *binary_data, 771 unsigned int size) 772 { 773 sof_ipc4_refresh_bytes_control(scontrol, true); 774 775 return _sof_ipc4_bytes_ext_get(scontrol, binary_data, size, false); 776 } 777 778 static int sof_ipc4_bytes_ext_volatile_get(struct snd_sof_control *scontrol, 779 const unsigned int __user *binary_data, 780 unsigned int size) 781 { 782 return _sof_ipc4_bytes_ext_get(scontrol, binary_data, size, true); 783 } 784 785 static int 786 sof_ipc4_volsw_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, 787 struct snd_sof_control *scontrol) 788 { 789 if (scontrol->max == 1) 790 return sof_ipc4_set_generic_control_data(sdev, swidget, scontrol, false); 791 792 return sof_ipc4_set_volume_data(sdev, swidget, scontrol, false); 793 } 794 795 #define PARAM_ID_FROM_EXTENSION(_ext) (((_ext) & SOF_IPC4_MOD_EXT_MSG_PARAM_ID_MASK) \ 796 >> SOF_IPC4_MOD_EXT_MSG_PARAM_ID_SHIFT) 797 798 static void sof_ipc4_control_update(struct snd_sof_dev *sdev, void *ipc_message) 799 { 800 struct sof_ipc4_msg *ipc4_msg = ipc_message; 801 struct sof_ipc4_notify_module_data *ndata = ipc4_msg->data_ptr; 802 struct sof_ipc4_control_msg_payload *msg_data; 803 struct sof_ipc4_control_data *cdata; 804 struct snd_soc_dapm_widget *widget; 805 struct snd_sof_control *scontrol; 806 struct snd_sof_widget *swidget; 807 struct snd_kcontrol *kc = NULL; 808 bool scontrol_found = false; 809 u32 event_param_id; 810 int i, type; 811 812 if (ndata->event_data_size < sizeof(*msg_data)) { 813 dev_err(sdev->dev, 814 "%s: Invalid event data size for module %u.%u: %u\n", 815 __func__, ndata->module_id, ndata->instance_id, 816 ndata->event_data_size); 817 return; 818 } 819 820 event_param_id = ndata->event_id & SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_PARAMID_MASK; 821 switch (event_param_id) { 822 case SOF_IPC4_SWITCH_CONTROL_PARAM_ID: 823 type = SND_SOC_TPLG_TYPE_MIXER; 824 break; 825 case SOF_IPC4_ENUM_CONTROL_PARAM_ID: 826 type = SND_SOC_TPLG_TYPE_ENUM; 827 break; 828 case SOF_IPC4_BYTES_CONTROL_PARAM_ID: 829 type = SND_SOC_TPLG_TYPE_BYTES; 830 break; 831 default: 832 dev_err(sdev->dev, 833 "%s: Invalid control type for module %u.%u: %u\n", 834 __func__, ndata->module_id, ndata->instance_id, 835 event_param_id); 836 return; 837 } 838 839 /* Find the swidget based on ndata->module_id and ndata->instance_id */ 840 swidget = sof_ipc4_find_swidget_by_ids(sdev, ndata->module_id, 841 ndata->instance_id); 842 if (!swidget) { 843 dev_err(sdev->dev, "%s: Failed to find widget for module %u.%u\n", 844 __func__, ndata->module_id, ndata->instance_id); 845 return; 846 } 847 848 /* Find the scontrol which is the source of the notification */ 849 msg_data = (struct sof_ipc4_control_msg_payload *)ndata->event_data; 850 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { 851 if (scontrol->comp_id == swidget->comp_id) { 852 u32 local_param_id; 853 854 cdata = scontrol->ipc_control_data; 855 /* 856 * The scontrol's param_id is stored in the IPC message 857 * template's extension 858 */ 859 local_param_id = PARAM_ID_FROM_EXTENSION(cdata->msg.extension); 860 if (local_param_id == event_param_id && 861 msg_data->id == cdata->index) { 862 scontrol_found = true; 863 break; 864 } 865 } 866 } 867 868 if (!scontrol_found) { 869 dev_err(sdev->dev, 870 "%s: Failed to find control on widget %s: %u:%u\n", 871 __func__, swidget->widget->name, ndata->event_id & 0xffff, 872 msg_data->id); 873 return; 874 } 875 876 if (msg_data->num_elems) { 877 /* 878 * The message includes the updated value/data, update the 879 * control's local cache using the received notification 880 */ 881 if (type == SND_SOC_TPLG_TYPE_BYTES) { 882 struct sof_abi_hdr *data = cdata->data; 883 884 if (msg_data->num_elems > scontrol->max_size - sizeof(*data)) { 885 dev_warn(sdev->dev, 886 "%s: no space for data in %s (%u, %zu)\n", 887 __func__, scontrol->name, msg_data->num_elems, 888 scontrol->max_size - sizeof(*data)); 889 } else { 890 memcpy(data->data, msg_data->data, msg_data->num_elems); 891 data->size = msg_data->num_elems; 892 scontrol->size = sizeof(*cdata) + sizeof(*data) + data->size; 893 } 894 } else { 895 for (i = 0; i < msg_data->num_elems; i++) { 896 u32 channel = msg_data->chanv[i].channel; 897 898 if (channel >= scontrol->num_channels) { 899 dev_warn(sdev->dev, 900 "Invalid channel index for %s: %u\n", 901 scontrol->name, i); 902 903 /* 904 * Mark the scontrol as dirty to force a refresh 905 * on next read 906 */ 907 scontrol->comp_data_dirty = true; 908 break; 909 } 910 911 cdata->chanv[channel].value = msg_data->chanv[i].value; 912 } 913 } 914 } else { 915 /* 916 * Mark the scontrol as dirty because the value/data is changed 917 * in firmware, forcing a refresh on next read access 918 */ 919 scontrol->comp_data_dirty = true; 920 } 921 922 /* 923 * Look up the ALSA kcontrol of the scontrol to be able to send a 924 * notification to user space 925 */ 926 widget = swidget->widget; 927 for (i = 0; i < widget->num_kcontrols; i++) { 928 /* skip non matching types or non matching indexes within type */ 929 if (widget->dobj.widget.kcontrol_type[i] == type && 930 widget->kcontrol_news[i].index == cdata->index) { 931 kc = widget->kcontrols[i]; 932 break; 933 } 934 } 935 936 if (!kc) 937 return; 938 939 snd_ctl_notify_one(swidget->scomp->card->snd_card, 940 SNDRV_CTL_EVENT_MASK_VALUE, kc, 0); 941 } 942 943 /* set up all controls for the widget */ 944 static int sof_ipc4_widget_kcontrol_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) 945 { 946 struct snd_sof_control *scontrol; 947 int ret = 0; 948 949 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { 950 if (scontrol->comp_id == swidget->comp_id) { 951 switch (scontrol->info_type) { 952 case SND_SOC_TPLG_CTL_VOLSW: 953 case SND_SOC_TPLG_CTL_VOLSW_SX: 954 case SND_SOC_TPLG_CTL_VOLSW_XR_SX: 955 ret = sof_ipc4_volsw_setup(sdev, swidget, scontrol); 956 break; 957 case SND_SOC_TPLG_CTL_BYTES: 958 ret = sof_ipc4_set_get_bytes_data(sdev, scontrol, 959 true, false); 960 break; 961 case SND_SOC_TPLG_CTL_ENUM: 962 case SND_SOC_TPLG_CTL_ENUM_VALUE: 963 ret = sof_ipc4_set_generic_control_data(sdev, swidget, 964 scontrol, false); 965 break; 966 default: 967 break; 968 } 969 970 if (ret < 0) { 971 dev_err(sdev->dev, 972 "kcontrol %d set up failed for widget %s\n", 973 scontrol->comp_id, swidget->widget->name); 974 return ret; 975 } 976 } 977 } 978 979 return 0; 980 } 981 982 static int 983 sof_ipc4_set_up_volume_table(struct snd_sof_control *scontrol, int tlv[SOF_TLV_ITEMS], int size) 984 { 985 int i; 986 987 /* init the volume table */ 988 scontrol->volume_table = kcalloc(size, sizeof(u32), GFP_KERNEL); 989 if (!scontrol->volume_table) 990 return -ENOMEM; 991 992 /* populate the volume table */ 993 for (i = 0; i < size ; i++) { 994 u32 val = vol_compute_gain(i, tlv); 995 u64 q31val = ((u64)val) << 15; /* Can be over Q1.31, need to saturate */ 996 997 scontrol->volume_table[i] = q31val > SOF_IPC4_VOL_ZERO_DB ? 998 SOF_IPC4_VOL_ZERO_DB : q31val; 999 } 1000 1001 return 0; 1002 } 1003 1004 const struct sof_ipc_tplg_control_ops tplg_ipc4_control_ops = { 1005 .volume_put = sof_ipc4_volume_put, 1006 .volume_get = sof_ipc4_volume_get, 1007 .switch_put = sof_ipc4_switch_put, 1008 .switch_get = sof_ipc4_switch_get, 1009 .enum_put = sof_ipc4_enum_put, 1010 .enum_get = sof_ipc4_enum_get, 1011 .bytes_put = sof_ipc4_bytes_put, 1012 .bytes_get = sof_ipc4_bytes_get, 1013 .bytes_ext_put = sof_ipc4_bytes_ext_put, 1014 .bytes_ext_get = sof_ipc4_bytes_ext_get, 1015 .bytes_ext_volatile_get = sof_ipc4_bytes_ext_volatile_get, 1016 .update = sof_ipc4_control_update, 1017 .widget_kcontrol_setup = sof_ipc4_widget_kcontrol_setup, 1018 .set_up_volume_table = sof_ipc4_set_up_volume_table, 1019 }; 1020