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 goto out; 366 } 367 368 data->size = msg->data_size; 369 scontrol->size = sizeof(*cdata) + sizeof(*data) + data->size; 370 memcpy(data->data, msg->data_ptr, data->size); 371 } else { 372 dev_err(scomp->dev, "Failed to read control data for %s\n", 373 scontrol->name); 374 scontrol->comp_data_dirty = true; 375 } 376 377 out: 378 msg->data_ptr = NULL; 379 msg->data_size = 0; 380 381 kfree(msg_data); 382 383 return ret; 384 } 385 386 static bool sof_ipc4_switch_put(struct snd_sof_control *scontrol, 387 struct snd_ctl_elem_value *ucontrol) 388 { 389 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 390 struct snd_soc_component *scomp = scontrol->scomp; 391 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 392 struct snd_sof_widget *swidget; 393 bool widget_found = false; 394 bool change = false; 395 unsigned int i; 396 u32 value; 397 int ret; 398 399 /* update each channel */ 400 for (i = 0; i < scontrol->num_channels; i++) { 401 value = ucontrol->value.integer.value[i]; 402 change = change || (value != cdata->chanv[i].value); 403 cdata->chanv[i].channel = i; 404 cdata->chanv[i].value = value; 405 } 406 407 if (!pm_runtime_active(scomp->dev)) 408 return change; 409 410 /* find widget associated with the control */ 411 list_for_each_entry(swidget, &sdev->widget_list, list) { 412 if (swidget->comp_id == scontrol->comp_id) { 413 widget_found = true; 414 break; 415 } 416 } 417 418 if (!widget_found) { 419 dev_err(scomp->dev, "Failed to find widget for kcontrol %s\n", scontrol->name); 420 return false; 421 } 422 423 ret = sof_ipc4_set_generic_control_data(sdev, swidget, scontrol, true); 424 if (ret < 0) 425 return false; 426 427 return change; 428 } 429 430 static int sof_ipc4_switch_get(struct snd_sof_control *scontrol, 431 struct snd_ctl_elem_value *ucontrol) 432 { 433 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 434 unsigned int i; 435 436 sof_ipc4_refresh_generic_control(scontrol); 437 438 /* read back each channel */ 439 for (i = 0; i < scontrol->num_channels; i++) 440 ucontrol->value.integer.value[i] = cdata->chanv[i].value; 441 442 return 0; 443 } 444 445 static bool sof_ipc4_enum_put(struct snd_sof_control *scontrol, 446 struct snd_ctl_elem_value *ucontrol) 447 { 448 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 449 struct snd_soc_component *scomp = scontrol->scomp; 450 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 451 struct snd_sof_widget *swidget; 452 bool widget_found = false; 453 bool change = false; 454 unsigned int i; 455 u32 value; 456 int ret; 457 458 /* update each channel */ 459 for (i = 0; i < scontrol->num_channels; i++) { 460 value = ucontrol->value.enumerated.item[i]; 461 change = change || (value != cdata->chanv[i].value); 462 cdata->chanv[i].channel = i; 463 cdata->chanv[i].value = value; 464 } 465 466 if (!pm_runtime_active(scomp->dev)) 467 return change; 468 469 /* find widget associated with the control */ 470 list_for_each_entry(swidget, &sdev->widget_list, list) { 471 if (swidget->comp_id == scontrol->comp_id) { 472 widget_found = true; 473 break; 474 } 475 } 476 477 if (!widget_found) { 478 dev_err(scomp->dev, "Failed to find widget for kcontrol %s\n", scontrol->name); 479 return false; 480 } 481 482 ret = sof_ipc4_set_generic_control_data(sdev, swidget, scontrol, true); 483 if (ret < 0) 484 return false; 485 486 return change; 487 } 488 489 static int sof_ipc4_enum_get(struct snd_sof_control *scontrol, 490 struct snd_ctl_elem_value *ucontrol) 491 { 492 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 493 unsigned int i; 494 495 sof_ipc4_refresh_generic_control(scontrol); 496 497 /* read back each channel */ 498 for (i = 0; i < scontrol->num_channels; i++) 499 ucontrol->value.enumerated.item[i] = cdata->chanv[i].value; 500 501 return 0; 502 } 503 504 static int sof_ipc4_set_get_bytes_data(struct snd_sof_dev *sdev, 505 struct snd_sof_control *scontrol, 506 bool set, bool lock) 507 { 508 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 509 struct sof_abi_hdr *data = cdata->data; 510 struct sof_ipc4_msg *msg = &cdata->msg; 511 int ret = 0; 512 513 /* Send the new data to the firmware only if it is powered up */ 514 if (set) { 515 if (!pm_runtime_active(sdev->dev)) 516 return 0; 517 518 if (!data->size) { 519 dev_dbg(sdev->dev, "%s: No data to be sent.\n", 520 scontrol->name); 521 return 0; 522 } 523 } 524 525 if (data->type == SOF_IPC4_BYTES_CONTROL_PARAM_ID) { 526 if (set) 527 return sof_ipc4_set_bytes_control_data(scontrol, lock); 528 else 529 return sof_ipc4_refresh_bytes_control(scontrol, lock); 530 } 531 532 msg->extension = SOF_IPC4_MOD_EXT_MSG_PARAM_ID(data->type); 533 534 msg->data_ptr = data->data; 535 if (set) 536 msg->data_size = data->size; 537 else 538 msg->data_size = scontrol->max_size - sizeof(*data); 539 540 ret = sof_ipc4_set_get_kcontrol_data(scontrol, set, lock); 541 if (ret < 0) { 542 dev_err(sdev->dev, "Failed to %s for %s\n", 543 set ? "set bytes update" : "get bytes", 544 scontrol->name); 545 } else if (!set) { 546 /* Update the sizes according to the received payload data */ 547 data->size = msg->data_size; 548 scontrol->size = sizeof(*cdata) + sizeof(*data) + data->size; 549 } 550 551 msg->data_ptr = NULL; 552 msg->data_size = 0; 553 554 return ret; 555 } 556 557 static int sof_ipc4_bytes_put(struct snd_sof_control *scontrol, 558 struct snd_ctl_elem_value *ucontrol) 559 { 560 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 561 struct snd_soc_component *scomp = scontrol->scomp; 562 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 563 struct sof_abi_hdr *data = cdata->data; 564 size_t size; 565 int ret; 566 567 if (scontrol->max_size > sizeof(ucontrol->value.bytes.data)) { 568 dev_err_ratelimited(scomp->dev, 569 "data max %zu exceeds ucontrol data array size\n", 570 scontrol->max_size); 571 return -EINVAL; 572 } 573 574 /* scontrol->max_size has been verified to be >= sizeof(struct sof_abi_hdr) */ 575 if (data->size > scontrol->max_size - sizeof(*data)) { 576 dev_err_ratelimited(scomp->dev, 577 "data size too big %u bytes max is %zu\n", 578 data->size, scontrol->max_size - sizeof(*data)); 579 return -EINVAL; 580 } 581 582 size = data->size + sizeof(*data); 583 584 /* copy from kcontrol */ 585 memcpy(data, ucontrol->value.bytes.data, size); 586 587 ret = sof_ipc4_set_get_bytes_data(sdev, scontrol, true, true); 588 if (!ret) 589 /* Update the cdata size */ 590 scontrol->size = sizeof(*cdata) + size; 591 592 return ret; 593 } 594 595 static int sof_ipc4_bytes_get(struct snd_sof_control *scontrol, 596 struct snd_ctl_elem_value *ucontrol) 597 { 598 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 599 struct snd_soc_component *scomp = scontrol->scomp; 600 struct sof_abi_hdr *data = cdata->data; 601 size_t size; 602 603 if (scontrol->max_size > sizeof(ucontrol->value.bytes.data)) { 604 dev_err_ratelimited(scomp->dev, "data max %zu exceeds ucontrol data array size\n", 605 scontrol->max_size); 606 return -EINVAL; 607 } 608 609 if (data->size > scontrol->max_size - sizeof(*data)) { 610 dev_err_ratelimited(scomp->dev, 611 "%u bytes of control data is invalid, max is %zu\n", 612 data->size, scontrol->max_size - sizeof(*data)); 613 return -EINVAL; 614 } 615 616 sof_ipc4_refresh_bytes_control(scontrol, true); 617 618 size = data->size + sizeof(*data); 619 620 /* copy back to kcontrol */ 621 memcpy(ucontrol->value.bytes.data, data, size); 622 623 return 0; 624 } 625 626 static int sof_ipc4_bytes_ext_put(struct snd_sof_control *scontrol, 627 const unsigned int __user *binary_data, 628 unsigned int size) 629 { 630 struct snd_ctl_tlv __user *tlvd = (struct snd_ctl_tlv __user *)binary_data; 631 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 632 struct snd_soc_component *scomp = scontrol->scomp; 633 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 634 struct sof_abi_hdr *data = cdata->data; 635 struct sof_abi_hdr abi_hdr; 636 struct snd_ctl_tlv header; 637 638 /* 639 * The beginning of bytes data contains a header from where 640 * the length (as bytes) is needed to know the correct copy 641 * length of data from tlvd->tlv. 642 */ 643 if (copy_from_user(&header, tlvd, sizeof(struct snd_ctl_tlv))) 644 return -EFAULT; 645 646 /* make sure TLV info is consistent */ 647 if (header.length + sizeof(struct snd_ctl_tlv) > size) { 648 dev_err_ratelimited(scomp->dev, 649 "Inconsistent TLV, data %d + header %zu > %d\n", 650 header.length, sizeof(struct snd_ctl_tlv), size); 651 return -EINVAL; 652 } 653 654 /* be->max is coming from topology */ 655 if (header.length > scontrol->max_size) { 656 dev_err_ratelimited(scomp->dev, 657 "Bytes data size %d exceeds max %zu\n", 658 header.length, scontrol->max_size); 659 return -EINVAL; 660 } 661 662 /* Check header id */ 663 if (header.numid != SOF_CTRL_CMD_BINARY) { 664 dev_err_ratelimited(scomp->dev, 665 "Incorrect numid for bytes put %d\n", 666 header.numid); 667 return -EINVAL; 668 } 669 670 /* Verify the ABI header first */ 671 if (copy_from_user(&abi_hdr, tlvd->tlv, sizeof(abi_hdr))) 672 return -EFAULT; 673 674 if (abi_hdr.magic != SOF_IPC4_ABI_MAGIC) { 675 dev_err_ratelimited(scomp->dev, "Wrong ABI magic 0x%08x\n", 676 abi_hdr.magic); 677 return -EINVAL; 678 } 679 680 if (abi_hdr.size > scontrol->max_size - sizeof(abi_hdr)) { 681 dev_err_ratelimited(scomp->dev, 682 "%u bytes of control data is invalid, max is %zu\n", 683 abi_hdr.size, scontrol->max_size - sizeof(abi_hdr)); 684 return -EINVAL; 685 } 686 687 if (!scontrol->old_ipc_control_data) { 688 /* Create a backup of the current, valid bytes control */ 689 scontrol->old_ipc_control_data = kmemdup(scontrol->ipc_control_data, 690 scontrol->size, GFP_KERNEL); 691 if (!scontrol->old_ipc_control_data) 692 return -ENOMEM; 693 } 694 695 /* Copy the whole binary data which includes the ABI header and the payload */ 696 if (copy_from_user(data, tlvd->tlv, header.length)) { 697 memcpy(scontrol->ipc_control_data, scontrol->old_ipc_control_data, 698 scontrol->size); 699 kfree(scontrol->old_ipc_control_data); 700 scontrol->old_ipc_control_data = NULL; 701 return -EFAULT; 702 } 703 704 /* Update the cdata size */ 705 scontrol->size = sizeof(*cdata) + header.length; 706 707 return sof_ipc4_set_get_bytes_data(sdev, scontrol, true, true); 708 } 709 710 static int _sof_ipc4_bytes_ext_get(struct snd_sof_control *scontrol, 711 const unsigned int __user *binary_data, 712 unsigned int size, bool from_dsp) 713 { 714 struct snd_ctl_tlv __user *tlvd = (struct snd_ctl_tlv __user *)binary_data; 715 struct sof_ipc4_control_data *cdata = scontrol->ipc_control_data; 716 struct snd_soc_component *scomp = scontrol->scomp; 717 struct sof_abi_hdr *data = cdata->data; 718 struct snd_ctl_tlv header; 719 size_t data_size; 720 721 /* 722 * Decrement the limit by ext bytes header size to ensure the user space 723 * buffer is not exceeded. 724 */ 725 if (size < sizeof(struct snd_ctl_tlv)) 726 return -ENOSPC; 727 728 size -= sizeof(struct snd_ctl_tlv); 729 730 /* get all the component data from DSP */ 731 if (from_dsp) { 732 struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); 733 int ret = sof_ipc4_set_get_bytes_data(sdev, scontrol, false, true); 734 735 if (ret < 0) 736 return ret; 737 738 /* Set the ABI magic (if the control is not initialized) */ 739 data->magic = SOF_IPC4_ABI_MAGIC; 740 } 741 742 if (data->size > scontrol->max_size - sizeof(*data)) { 743 dev_err_ratelimited(scomp->dev, 744 "%u bytes of control data is invalid, max is %zu\n", 745 data->size, scontrol->max_size - sizeof(*data)); 746 return -EINVAL; 747 } 748 749 data_size = data->size + sizeof(struct sof_abi_hdr); 750 751 /* make sure we don't exceed size provided by user space for data */ 752 if (data_size > size) 753 return -ENOSPC; 754 755 /* Set header id and length */ 756 header.numid = SOF_CTRL_CMD_BINARY; 757 header.length = data_size; 758 759 if (copy_to_user(tlvd, &header, sizeof(struct snd_ctl_tlv))) 760 return -EFAULT; 761 762 if (copy_to_user(tlvd->tlv, data, data_size)) 763 return -EFAULT; 764 765 return 0; 766 } 767 768 static int sof_ipc4_bytes_ext_get(struct snd_sof_control *scontrol, 769 const unsigned int __user *binary_data, 770 unsigned int size) 771 { 772 sof_ipc4_refresh_bytes_control(scontrol, true); 773 774 return _sof_ipc4_bytes_ext_get(scontrol, binary_data, size, false); 775 } 776 777 static int sof_ipc4_bytes_ext_volatile_get(struct snd_sof_control *scontrol, 778 const unsigned int __user *binary_data, 779 unsigned int size) 780 { 781 return _sof_ipc4_bytes_ext_get(scontrol, binary_data, size, true); 782 } 783 784 static int 785 sof_ipc4_volsw_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget, 786 struct snd_sof_control *scontrol) 787 { 788 if (scontrol->max == 1) 789 return sof_ipc4_set_generic_control_data(sdev, swidget, scontrol, false); 790 791 return sof_ipc4_set_volume_data(sdev, swidget, scontrol, false); 792 } 793 794 #define PARAM_ID_FROM_EXTENSION(_ext) (((_ext) & SOF_IPC4_MOD_EXT_MSG_PARAM_ID_MASK) \ 795 >> SOF_IPC4_MOD_EXT_MSG_PARAM_ID_SHIFT) 796 797 static void sof_ipc4_control_update(struct snd_sof_dev *sdev, void *ipc_message) 798 { 799 struct sof_ipc4_msg *ipc4_msg = ipc_message; 800 struct sof_ipc4_notify_module_data *ndata = ipc4_msg->data_ptr; 801 struct sof_ipc4_control_msg_payload *msg_data; 802 struct sof_ipc4_control_data *cdata; 803 struct snd_soc_dapm_widget *widget; 804 struct snd_sof_control *scontrol; 805 struct snd_sof_widget *swidget; 806 struct snd_kcontrol *kc = NULL; 807 bool scontrol_found = false; 808 u32 event_param_id; 809 int i, type; 810 811 if (ndata->event_data_size < sizeof(*msg_data)) { 812 dev_err(sdev->dev, 813 "%s: Invalid event data size for module %u.%u: %u\n", 814 __func__, ndata->module_id, ndata->instance_id, 815 ndata->event_data_size); 816 return; 817 } 818 819 event_param_id = ndata->event_id & SOF_IPC4_NOTIFY_MODULE_EVENTID_ALSA_PARAMID_MASK; 820 switch (event_param_id) { 821 case SOF_IPC4_SWITCH_CONTROL_PARAM_ID: 822 type = SND_SOC_TPLG_TYPE_MIXER; 823 break; 824 case SOF_IPC4_ENUM_CONTROL_PARAM_ID: 825 type = SND_SOC_TPLG_TYPE_ENUM; 826 break; 827 case SOF_IPC4_BYTES_CONTROL_PARAM_ID: 828 type = SND_SOC_TPLG_TYPE_BYTES; 829 break; 830 default: 831 dev_err(sdev->dev, 832 "%s: Invalid control type for module %u.%u: %u\n", 833 __func__, ndata->module_id, ndata->instance_id, 834 event_param_id); 835 return; 836 } 837 838 /* Find the swidget based on ndata->module_id and ndata->instance_id */ 839 swidget = sof_ipc4_find_swidget_by_ids(sdev, ndata->module_id, 840 ndata->instance_id); 841 if (!swidget) { 842 dev_err(sdev->dev, "%s: Failed to find widget for module %u.%u\n", 843 __func__, ndata->module_id, ndata->instance_id); 844 return; 845 } 846 847 /* Find the scontrol which is the source of the notification */ 848 msg_data = (struct sof_ipc4_control_msg_payload *)ndata->event_data; 849 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { 850 if (scontrol->comp_id == swidget->comp_id) { 851 u32 local_param_id; 852 853 cdata = scontrol->ipc_control_data; 854 /* 855 * The scontrol's param_id is stored in the IPC message 856 * template's extension 857 */ 858 local_param_id = PARAM_ID_FROM_EXTENSION(cdata->msg.extension); 859 if (local_param_id == event_param_id && 860 msg_data->id == cdata->index) { 861 scontrol_found = true; 862 break; 863 } 864 } 865 } 866 867 if (!scontrol_found) { 868 dev_err(sdev->dev, 869 "%s: Failed to find control on widget %s: %u:%u\n", 870 __func__, swidget->widget->name, ndata->event_id & 0xffff, 871 msg_data->id); 872 return; 873 } 874 875 if (msg_data->num_elems) { 876 /* 877 * The message includes the updated value/data, update the 878 * control's local cache using the received notification 879 */ 880 if (type == SND_SOC_TPLG_TYPE_BYTES) { 881 struct sof_abi_hdr *data = cdata->data; 882 883 if (msg_data->num_elems > scontrol->max_size - sizeof(*data)) { 884 dev_warn(sdev->dev, 885 "%s: no space for data in %s (%u, %zu)\n", 886 __func__, scontrol->name, msg_data->num_elems, 887 scontrol->max_size - sizeof(*data)); 888 } else { 889 memcpy(data->data, msg_data->data, msg_data->num_elems); 890 data->size = msg_data->num_elems; 891 scontrol->size = sizeof(*cdata) + sizeof(*data) + data->size; 892 } 893 } else { 894 for (i = 0; i < msg_data->num_elems; i++) { 895 u32 channel = msg_data->chanv[i].channel; 896 897 if (channel >= scontrol->num_channels) { 898 dev_warn(sdev->dev, 899 "Invalid channel index for %s: %u\n", 900 scontrol->name, i); 901 902 /* 903 * Mark the scontrol as dirty to force a refresh 904 * on next read 905 */ 906 scontrol->comp_data_dirty = true; 907 break; 908 } 909 910 cdata->chanv[channel].value = msg_data->chanv[i].value; 911 } 912 } 913 } else { 914 /* 915 * Mark the scontrol as dirty because the value/data is changed 916 * in firmware, forcing a refresh on next read access 917 */ 918 scontrol->comp_data_dirty = true; 919 } 920 921 /* 922 * Look up the ALSA kcontrol of the scontrol to be able to send a 923 * notification to user space 924 */ 925 widget = swidget->widget; 926 for (i = 0; i < widget->num_kcontrols; i++) { 927 /* skip non matching types or non matching indexes within type */ 928 if (widget->dobj.widget.kcontrol_type[i] == type && 929 widget->kcontrol_news[i].index == cdata->index) { 930 kc = widget->kcontrols[i]; 931 break; 932 } 933 } 934 935 if (!kc) 936 return; 937 938 snd_ctl_notify_one(swidget->scomp->card->snd_card, 939 SNDRV_CTL_EVENT_MASK_VALUE, kc, 0); 940 } 941 942 /* set up all controls for the widget */ 943 static int sof_ipc4_widget_kcontrol_setup(struct snd_sof_dev *sdev, struct snd_sof_widget *swidget) 944 { 945 struct snd_sof_control *scontrol; 946 int ret = 0; 947 948 list_for_each_entry(scontrol, &sdev->kcontrol_list, list) { 949 if (scontrol->comp_id == swidget->comp_id) { 950 switch (scontrol->info_type) { 951 case SND_SOC_TPLG_CTL_VOLSW: 952 case SND_SOC_TPLG_CTL_VOLSW_SX: 953 case SND_SOC_TPLG_CTL_VOLSW_XR_SX: 954 ret = sof_ipc4_volsw_setup(sdev, swidget, scontrol); 955 break; 956 case SND_SOC_TPLG_CTL_BYTES: 957 ret = sof_ipc4_set_get_bytes_data(sdev, scontrol, 958 true, false); 959 break; 960 case SND_SOC_TPLG_CTL_ENUM: 961 case SND_SOC_TPLG_CTL_ENUM_VALUE: 962 ret = sof_ipc4_set_generic_control_data(sdev, swidget, 963 scontrol, false); 964 break; 965 default: 966 break; 967 } 968 969 if (ret < 0) { 970 dev_err(sdev->dev, 971 "kcontrol %d set up failed for widget %s\n", 972 scontrol->comp_id, swidget->widget->name); 973 return ret; 974 } 975 } 976 } 977 978 return 0; 979 } 980 981 static int 982 sof_ipc4_set_up_volume_table(struct snd_sof_control *scontrol, int tlv[SOF_TLV_ITEMS], int size) 983 { 984 int i; 985 986 /* init the volume table */ 987 scontrol->volume_table = kcalloc(size, sizeof(u32), GFP_KERNEL); 988 if (!scontrol->volume_table) 989 return -ENOMEM; 990 991 /* populate the volume table */ 992 for (i = 0; i < size ; i++) { 993 u32 val = vol_compute_gain(i, tlv); 994 u64 q31val = ((u64)val) << 15; /* Can be over Q1.31, need to saturate */ 995 996 scontrol->volume_table[i] = q31val > SOF_IPC4_VOL_ZERO_DB ? 997 SOF_IPC4_VOL_ZERO_DB : q31val; 998 } 999 1000 return 0; 1001 } 1002 1003 const struct sof_ipc_tplg_control_ops tplg_ipc4_control_ops = { 1004 .volume_put = sof_ipc4_volume_put, 1005 .volume_get = sof_ipc4_volume_get, 1006 .switch_put = sof_ipc4_switch_put, 1007 .switch_get = sof_ipc4_switch_get, 1008 .enum_put = sof_ipc4_enum_put, 1009 .enum_get = sof_ipc4_enum_get, 1010 .bytes_put = sof_ipc4_bytes_put, 1011 .bytes_get = sof_ipc4_bytes_get, 1012 .bytes_ext_put = sof_ipc4_bytes_ext_put, 1013 .bytes_ext_get = sof_ipc4_bytes_ext_get, 1014 .bytes_ext_volatile_get = sof_ipc4_bytes_ext_volatile_get, 1015 .update = sof_ipc4_control_update, 1016 .widget_kcontrol_setup = sof_ipc4_widget_kcontrol_setup, 1017 .set_up_volume_table = sof_ipc4_set_up_volume_table, 1018 }; 1019