1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * uvc_configfs.c 4 * 5 * Configfs support for the uvc function. 6 * 7 * Copyright (c) 2014 Samsung Electronics Co., Ltd. 8 * http://www.samsung.com 9 * 10 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> 11 */ 12 #include "u_uvc.h" 13 #include "uvc_configfs.h" 14 15 /* ----------------------------------------------------------------------------- 16 * Global Utility Structures and Macros 17 */ 18 19 #define UVCG_STREAMING_CONTROL_SIZE 1 20 21 #define UVC_ATTR(prefix, cname, aname) \ 22 static struct configfs_attribute prefix##attr_##cname = { \ 23 .ca_name = __stringify(aname), \ 24 .ca_mode = S_IRUGO | S_IWUGO, \ 25 .ca_owner = THIS_MODULE, \ 26 .show = prefix##cname##_show, \ 27 .store = prefix##cname##_store, \ 28 } 29 30 #define UVC_ATTR_RO(prefix, cname, aname) \ 31 static struct configfs_attribute prefix##attr_##cname = { \ 32 .ca_name = __stringify(aname), \ 33 .ca_mode = S_IRUGO, \ 34 .ca_owner = THIS_MODULE, \ 35 .show = prefix##cname##_show, \ 36 } 37 38 static inline struct f_uvc_opts *to_f_uvc_opts(struct config_item *item) 39 { 40 return container_of(to_config_group(item), struct f_uvc_opts, 41 func_inst.group); 42 } 43 44 struct uvcg_config_group_type { 45 struct config_item_type type; 46 const char *name; 47 const struct uvcg_config_group_type **children; 48 int (*create_children)(struct config_group *group); 49 }; 50 51 static void uvcg_config_item_release(struct config_item *item) 52 { 53 struct config_group *group = to_config_group(item); 54 55 kfree(group); 56 } 57 58 static struct configfs_item_operations uvcg_config_item_ops = { 59 .release = uvcg_config_item_release, 60 }; 61 62 static int uvcg_config_create_group(struct config_group *parent, 63 const struct uvcg_config_group_type *type); 64 65 static int uvcg_config_create_children(struct config_group *group, 66 const struct uvcg_config_group_type *type) 67 { 68 const struct uvcg_config_group_type **child; 69 int ret; 70 71 if (type->create_children) 72 return type->create_children(group); 73 74 for (child = type->children; child && *child; ++child) { 75 ret = uvcg_config_create_group(group, *child); 76 if (ret < 0) 77 return ret; 78 } 79 80 return 0; 81 } 82 83 static int uvcg_config_create_group(struct config_group *parent, 84 const struct uvcg_config_group_type *type) 85 { 86 struct config_group *group; 87 88 group = kzalloc(sizeof(*group), GFP_KERNEL); 89 if (!group) 90 return -ENOMEM; 91 92 config_group_init_type_name(group, type->name, &type->type); 93 configfs_add_default_group(group, parent); 94 95 return uvcg_config_create_children(group, type); 96 } 97 98 static void uvcg_config_remove_children(struct config_group *group) 99 { 100 struct config_group *child, *n; 101 102 list_for_each_entry_safe(child, n, &group->default_groups, group_entry) { 103 list_del(&child->group_entry); 104 uvcg_config_remove_children(child); 105 config_item_put(&child->cg_item); 106 } 107 } 108 109 /* ----------------------------------------------------------------------------- 110 * control/header/<NAME> 111 * control/header 112 */ 113 114 DECLARE_UVC_HEADER_DESCRIPTOR(1); 115 116 struct uvcg_control_header { 117 struct config_item item; 118 struct UVC_HEADER_DESCRIPTOR(1) desc; 119 unsigned linked; 120 }; 121 122 static struct uvcg_control_header *to_uvcg_control_header(struct config_item *item) 123 { 124 return container_of(item, struct uvcg_control_header, item); 125 } 126 127 #define UVCG_CTRL_HDR_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit) \ 128 static ssize_t uvcg_control_header_##cname##_show( \ 129 struct config_item *item, char *page) \ 130 { \ 131 struct uvcg_control_header *ch = to_uvcg_control_header(item); \ 132 struct f_uvc_opts *opts; \ 133 struct config_item *opts_item; \ 134 struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\ 135 int result; \ 136 \ 137 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 138 \ 139 opts_item = ch->item.ci_parent->ci_parent->ci_parent; \ 140 opts = to_f_uvc_opts(opts_item); \ 141 \ 142 mutex_lock(&opts->lock); \ 143 result = sprintf(page, "%d\n", conv(ch->desc.aname)); \ 144 mutex_unlock(&opts->lock); \ 145 \ 146 mutex_unlock(su_mutex); \ 147 return result; \ 148 } \ 149 \ 150 static ssize_t \ 151 uvcg_control_header_##cname##_store(struct config_item *item, \ 152 const char *page, size_t len) \ 153 { \ 154 struct uvcg_control_header *ch = to_uvcg_control_header(item); \ 155 struct f_uvc_opts *opts; \ 156 struct config_item *opts_item; \ 157 struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;\ 158 int ret; \ 159 uxx num; \ 160 \ 161 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 162 \ 163 opts_item = ch->item.ci_parent->ci_parent->ci_parent; \ 164 opts = to_f_uvc_opts(opts_item); \ 165 \ 166 mutex_lock(&opts->lock); \ 167 if (ch->linked || opts->refcnt) { \ 168 ret = -EBUSY; \ 169 goto end; \ 170 } \ 171 \ 172 ret = str2u(page, 0, &num); \ 173 if (ret) \ 174 goto end; \ 175 \ 176 if (num > limit) { \ 177 ret = -EINVAL; \ 178 goto end; \ 179 } \ 180 ch->desc.aname = vnoc(num); \ 181 ret = len; \ 182 end: \ 183 mutex_unlock(&opts->lock); \ 184 mutex_unlock(su_mutex); \ 185 return ret; \ 186 } \ 187 \ 188 UVC_ATTR(uvcg_control_header_, cname, aname) 189 190 UVCG_CTRL_HDR_ATTR(bcd_uvc, bcdUVC, le16_to_cpu, kstrtou16, u16, cpu_to_le16, 191 0xffff); 192 193 UVCG_CTRL_HDR_ATTR(dw_clock_frequency, dwClockFrequency, le32_to_cpu, kstrtou32, 194 u32, cpu_to_le32, 0x7fffffff); 195 196 #undef UVCG_CTRL_HDR_ATTR 197 198 static struct configfs_attribute *uvcg_control_header_attrs[] = { 199 &uvcg_control_header_attr_bcd_uvc, 200 &uvcg_control_header_attr_dw_clock_frequency, 201 NULL, 202 }; 203 204 static const struct config_item_type uvcg_control_header_type = { 205 .ct_item_ops = &uvcg_config_item_ops, 206 .ct_attrs = uvcg_control_header_attrs, 207 .ct_owner = THIS_MODULE, 208 }; 209 210 static struct config_item *uvcg_control_header_make(struct config_group *group, 211 const char *name) 212 { 213 struct uvcg_control_header *h; 214 215 h = kzalloc(sizeof(*h), GFP_KERNEL); 216 if (!h) 217 return ERR_PTR(-ENOMEM); 218 219 h->desc.bLength = UVC_DT_HEADER_SIZE(1); 220 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 221 h->desc.bDescriptorSubType = UVC_VC_HEADER; 222 h->desc.bcdUVC = cpu_to_le16(0x0100); 223 h->desc.dwClockFrequency = cpu_to_le32(48000000); 224 225 config_item_init_type_name(&h->item, name, &uvcg_control_header_type); 226 227 return &h->item; 228 } 229 230 static struct configfs_group_operations uvcg_control_header_grp_ops = { 231 .make_item = uvcg_control_header_make, 232 }; 233 234 static const struct uvcg_config_group_type uvcg_control_header_grp_type = { 235 .type = { 236 .ct_item_ops = &uvcg_config_item_ops, 237 .ct_group_ops = &uvcg_control_header_grp_ops, 238 .ct_owner = THIS_MODULE, 239 }, 240 .name = "header", 241 }; 242 243 /* ----------------------------------------------------------------------------- 244 * control/processing/default 245 */ 246 247 #define UVCG_DEFAULT_PROCESSING_ATTR(cname, aname, conv) \ 248 static ssize_t uvcg_default_processing_##cname##_show( \ 249 struct config_item *item, char *page) \ 250 { \ 251 struct config_group *group = to_config_group(item); \ 252 struct f_uvc_opts *opts; \ 253 struct config_item *opts_item; \ 254 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \ 255 struct uvc_processing_unit_descriptor *pd; \ 256 int result; \ 257 \ 258 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 259 \ 260 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; \ 261 opts = to_f_uvc_opts(opts_item); \ 262 pd = &opts->uvc_processing; \ 263 \ 264 mutex_lock(&opts->lock); \ 265 result = sprintf(page, "%d\n", conv(pd->aname)); \ 266 mutex_unlock(&opts->lock); \ 267 \ 268 mutex_unlock(su_mutex); \ 269 return result; \ 270 } \ 271 \ 272 UVC_ATTR_RO(uvcg_default_processing_, cname, aname) 273 274 #define identity_conv(x) (x) 275 276 UVCG_DEFAULT_PROCESSING_ATTR(b_unit_id, bUnitID, identity_conv); 277 UVCG_DEFAULT_PROCESSING_ATTR(b_source_id, bSourceID, identity_conv); 278 UVCG_DEFAULT_PROCESSING_ATTR(w_max_multiplier, wMaxMultiplier, le16_to_cpu); 279 UVCG_DEFAULT_PROCESSING_ATTR(i_processing, iProcessing, identity_conv); 280 281 #undef identity_conv 282 283 #undef UVCG_DEFAULT_PROCESSING_ATTR 284 285 static ssize_t uvcg_default_processing_bm_controls_show( 286 struct config_item *item, char *page) 287 { 288 struct config_group *group = to_config_group(item); 289 struct f_uvc_opts *opts; 290 struct config_item *opts_item; 291 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 292 struct uvc_processing_unit_descriptor *pd; 293 int result, i; 294 char *pg = page; 295 296 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 297 298 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 299 opts = to_f_uvc_opts(opts_item); 300 pd = &opts->uvc_processing; 301 302 mutex_lock(&opts->lock); 303 for (result = 0, i = 0; i < pd->bControlSize; ++i) { 304 result += sprintf(pg, "%d\n", pd->bmControls[i]); 305 pg = page + result; 306 } 307 mutex_unlock(&opts->lock); 308 309 mutex_unlock(su_mutex); 310 311 return result; 312 } 313 314 UVC_ATTR_RO(uvcg_default_processing_, bm_controls, bmControls); 315 316 static struct configfs_attribute *uvcg_default_processing_attrs[] = { 317 &uvcg_default_processing_attr_b_unit_id, 318 &uvcg_default_processing_attr_b_source_id, 319 &uvcg_default_processing_attr_w_max_multiplier, 320 &uvcg_default_processing_attr_bm_controls, 321 &uvcg_default_processing_attr_i_processing, 322 NULL, 323 }; 324 325 static const struct uvcg_config_group_type uvcg_default_processing_type = { 326 .type = { 327 .ct_item_ops = &uvcg_config_item_ops, 328 .ct_attrs = uvcg_default_processing_attrs, 329 .ct_owner = THIS_MODULE, 330 }, 331 .name = "default", 332 }; 333 334 /* ----------------------------------------------------------------------------- 335 * control/processing 336 */ 337 338 static const struct uvcg_config_group_type uvcg_processing_grp_type = { 339 .type = { 340 .ct_item_ops = &uvcg_config_item_ops, 341 .ct_owner = THIS_MODULE, 342 }, 343 .name = "processing", 344 .children = (const struct uvcg_config_group_type*[]) { 345 &uvcg_default_processing_type, 346 NULL, 347 }, 348 }; 349 350 /* ----------------------------------------------------------------------------- 351 * control/terminal/camera/default 352 */ 353 354 #define UVCG_DEFAULT_CAMERA_ATTR(cname, aname, conv) \ 355 static ssize_t uvcg_default_camera_##cname##_show( \ 356 struct config_item *item, char *page) \ 357 { \ 358 struct config_group *group = to_config_group(item); \ 359 struct f_uvc_opts *opts; \ 360 struct config_item *opts_item; \ 361 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \ 362 struct uvc_camera_terminal_descriptor *cd; \ 363 int result; \ 364 \ 365 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 366 \ 367 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent-> \ 368 ci_parent; \ 369 opts = to_f_uvc_opts(opts_item); \ 370 cd = &opts->uvc_camera_terminal; \ 371 \ 372 mutex_lock(&opts->lock); \ 373 result = sprintf(page, "%d\n", conv(cd->aname)); \ 374 mutex_unlock(&opts->lock); \ 375 \ 376 mutex_unlock(su_mutex); \ 377 \ 378 return result; \ 379 } \ 380 \ 381 UVC_ATTR_RO(uvcg_default_camera_, cname, aname) 382 383 #define identity_conv(x) (x) 384 385 UVCG_DEFAULT_CAMERA_ATTR(b_terminal_id, bTerminalID, identity_conv); 386 UVCG_DEFAULT_CAMERA_ATTR(w_terminal_type, wTerminalType, le16_to_cpu); 387 UVCG_DEFAULT_CAMERA_ATTR(b_assoc_terminal, bAssocTerminal, identity_conv); 388 UVCG_DEFAULT_CAMERA_ATTR(i_terminal, iTerminal, identity_conv); 389 UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_min, wObjectiveFocalLengthMin, 390 le16_to_cpu); 391 UVCG_DEFAULT_CAMERA_ATTR(w_objective_focal_length_max, wObjectiveFocalLengthMax, 392 le16_to_cpu); 393 UVCG_DEFAULT_CAMERA_ATTR(w_ocular_focal_length, wOcularFocalLength, 394 le16_to_cpu); 395 396 #undef identity_conv 397 398 #undef UVCG_DEFAULT_CAMERA_ATTR 399 400 static ssize_t uvcg_default_camera_bm_controls_show( 401 struct config_item *item, char *page) 402 { 403 struct config_group *group = to_config_group(item); 404 struct f_uvc_opts *opts; 405 struct config_item *opts_item; 406 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 407 struct uvc_camera_terminal_descriptor *cd; 408 int result, i; 409 char *pg = page; 410 411 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 412 413 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent-> 414 ci_parent; 415 opts = to_f_uvc_opts(opts_item); 416 cd = &opts->uvc_camera_terminal; 417 418 mutex_lock(&opts->lock); 419 for (result = 0, i = 0; i < cd->bControlSize; ++i) { 420 result += sprintf(pg, "%d\n", cd->bmControls[i]); 421 pg = page + result; 422 } 423 mutex_unlock(&opts->lock); 424 425 mutex_unlock(su_mutex); 426 return result; 427 } 428 429 UVC_ATTR_RO(uvcg_default_camera_, bm_controls, bmControls); 430 431 static struct configfs_attribute *uvcg_default_camera_attrs[] = { 432 &uvcg_default_camera_attr_b_terminal_id, 433 &uvcg_default_camera_attr_w_terminal_type, 434 &uvcg_default_camera_attr_b_assoc_terminal, 435 &uvcg_default_camera_attr_i_terminal, 436 &uvcg_default_camera_attr_w_objective_focal_length_min, 437 &uvcg_default_camera_attr_w_objective_focal_length_max, 438 &uvcg_default_camera_attr_w_ocular_focal_length, 439 &uvcg_default_camera_attr_bm_controls, 440 NULL, 441 }; 442 443 static const struct uvcg_config_group_type uvcg_default_camera_type = { 444 .type = { 445 .ct_item_ops = &uvcg_config_item_ops, 446 .ct_attrs = uvcg_default_camera_attrs, 447 .ct_owner = THIS_MODULE, 448 }, 449 .name = "default", 450 }; 451 452 /* ----------------------------------------------------------------------------- 453 * control/terminal/camera 454 */ 455 456 static const struct uvcg_config_group_type uvcg_camera_grp_type = { 457 .type = { 458 .ct_item_ops = &uvcg_config_item_ops, 459 .ct_owner = THIS_MODULE, 460 }, 461 .name = "camera", 462 .children = (const struct uvcg_config_group_type*[]) { 463 &uvcg_default_camera_type, 464 NULL, 465 }, 466 }; 467 468 /* ----------------------------------------------------------------------------- 469 * control/terminal/output/default 470 */ 471 472 #define UVCG_DEFAULT_OUTPUT_ATTR(cname, aname, conv) \ 473 static ssize_t uvcg_default_output_##cname##_show( \ 474 struct config_item *item, char *page) \ 475 { \ 476 struct config_group *group = to_config_group(item); \ 477 struct f_uvc_opts *opts; \ 478 struct config_item *opts_item; \ 479 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \ 480 struct uvc_output_terminal_descriptor *cd; \ 481 int result; \ 482 \ 483 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 484 \ 485 opts_item = group->cg_item.ci_parent->ci_parent-> \ 486 ci_parent->ci_parent; \ 487 opts = to_f_uvc_opts(opts_item); \ 488 cd = &opts->uvc_output_terminal; \ 489 \ 490 mutex_lock(&opts->lock); \ 491 result = sprintf(page, "%d\n", conv(cd->aname)); \ 492 mutex_unlock(&opts->lock); \ 493 \ 494 mutex_unlock(su_mutex); \ 495 \ 496 return result; \ 497 } \ 498 \ 499 UVC_ATTR_RO(uvcg_default_output_, cname, aname) 500 501 #define identity_conv(x) (x) 502 503 UVCG_DEFAULT_OUTPUT_ATTR(b_terminal_id, bTerminalID, identity_conv); 504 UVCG_DEFAULT_OUTPUT_ATTR(w_terminal_type, wTerminalType, le16_to_cpu); 505 UVCG_DEFAULT_OUTPUT_ATTR(b_assoc_terminal, bAssocTerminal, identity_conv); 506 UVCG_DEFAULT_OUTPUT_ATTR(b_source_id, bSourceID, identity_conv); 507 UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, identity_conv); 508 509 #undef identity_conv 510 511 #undef UVCG_DEFAULT_OUTPUT_ATTR 512 513 static struct configfs_attribute *uvcg_default_output_attrs[] = { 514 &uvcg_default_output_attr_b_terminal_id, 515 &uvcg_default_output_attr_w_terminal_type, 516 &uvcg_default_output_attr_b_assoc_terminal, 517 &uvcg_default_output_attr_b_source_id, 518 &uvcg_default_output_attr_i_terminal, 519 NULL, 520 }; 521 522 static const struct uvcg_config_group_type uvcg_default_output_type = { 523 .type = { 524 .ct_item_ops = &uvcg_config_item_ops, 525 .ct_attrs = uvcg_default_output_attrs, 526 .ct_owner = THIS_MODULE, 527 }, 528 .name = "default", 529 }; 530 531 /* ----------------------------------------------------------------------------- 532 * control/terminal/output 533 */ 534 535 static const struct uvcg_config_group_type uvcg_output_grp_type = { 536 .type = { 537 .ct_item_ops = &uvcg_config_item_ops, 538 .ct_owner = THIS_MODULE, 539 }, 540 .name = "output", 541 .children = (const struct uvcg_config_group_type*[]) { 542 &uvcg_default_output_type, 543 NULL, 544 }, 545 }; 546 547 /* ----------------------------------------------------------------------------- 548 * control/terminal 549 */ 550 551 static const struct uvcg_config_group_type uvcg_terminal_grp_type = { 552 .type = { 553 .ct_item_ops = &uvcg_config_item_ops, 554 .ct_owner = THIS_MODULE, 555 }, 556 .name = "terminal", 557 .children = (const struct uvcg_config_group_type*[]) { 558 &uvcg_camera_grp_type, 559 &uvcg_output_grp_type, 560 NULL, 561 }, 562 }; 563 564 /* ----------------------------------------------------------------------------- 565 * control/class/{fs|ss} 566 */ 567 568 struct uvcg_control_class_group { 569 struct config_group group; 570 const char *name; 571 }; 572 573 static inline struct uvc_descriptor_header 574 **uvcg_get_ctl_class_arr(struct config_item *i, struct f_uvc_opts *o) 575 { 576 struct uvcg_control_class_group *group = 577 container_of(i, struct uvcg_control_class_group, 578 group.cg_item); 579 580 if (!strcmp(group->name, "fs")) 581 return o->uvc_fs_control_cls; 582 583 if (!strcmp(group->name, "ss")) 584 return o->uvc_ss_control_cls; 585 586 return NULL; 587 } 588 589 static int uvcg_control_class_allow_link(struct config_item *src, 590 struct config_item *target) 591 { 592 struct config_item *control, *header; 593 struct f_uvc_opts *opts; 594 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 595 struct uvc_descriptor_header **class_array; 596 struct uvcg_control_header *target_hdr; 597 int ret = -EINVAL; 598 599 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 600 601 control = src->ci_parent->ci_parent; 602 header = config_group_find_item(to_config_group(control), "header"); 603 if (!header || target->ci_parent != header) 604 goto out; 605 606 opts = to_f_uvc_opts(control->ci_parent); 607 608 mutex_lock(&opts->lock); 609 610 class_array = uvcg_get_ctl_class_arr(src, opts); 611 if (!class_array) 612 goto unlock; 613 if (opts->refcnt || class_array[0]) { 614 ret = -EBUSY; 615 goto unlock; 616 } 617 618 target_hdr = to_uvcg_control_header(target); 619 ++target_hdr->linked; 620 class_array[0] = (struct uvc_descriptor_header *)&target_hdr->desc; 621 ret = 0; 622 623 unlock: 624 mutex_unlock(&opts->lock); 625 out: 626 config_item_put(header); 627 mutex_unlock(su_mutex); 628 return ret; 629 } 630 631 static void uvcg_control_class_drop_link(struct config_item *src, 632 struct config_item *target) 633 { 634 struct config_item *control, *header; 635 struct f_uvc_opts *opts; 636 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 637 struct uvc_descriptor_header **class_array; 638 struct uvcg_control_header *target_hdr; 639 640 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 641 642 control = src->ci_parent->ci_parent; 643 header = config_group_find_item(to_config_group(control), "header"); 644 if (!header || target->ci_parent != header) 645 goto out; 646 647 opts = to_f_uvc_opts(control->ci_parent); 648 649 mutex_lock(&opts->lock); 650 651 class_array = uvcg_get_ctl_class_arr(src, opts); 652 if (!class_array || opts->refcnt) 653 goto unlock; 654 655 target_hdr = to_uvcg_control_header(target); 656 --target_hdr->linked; 657 class_array[0] = NULL; 658 659 unlock: 660 mutex_unlock(&opts->lock); 661 out: 662 config_item_put(header); 663 mutex_unlock(su_mutex); 664 } 665 666 static struct configfs_item_operations uvcg_control_class_item_ops = { 667 .release = uvcg_config_item_release, 668 .allow_link = uvcg_control_class_allow_link, 669 .drop_link = uvcg_control_class_drop_link, 670 }; 671 672 static const struct config_item_type uvcg_control_class_type = { 673 .ct_item_ops = &uvcg_control_class_item_ops, 674 .ct_owner = THIS_MODULE, 675 }; 676 677 /* ----------------------------------------------------------------------------- 678 * control/class 679 */ 680 681 static int uvcg_control_class_create_children(struct config_group *parent) 682 { 683 static const char * const names[] = { "fs", "ss" }; 684 unsigned int i; 685 686 for (i = 0; i < ARRAY_SIZE(names); ++i) { 687 struct uvcg_control_class_group *group; 688 689 group = kzalloc(sizeof(*group), GFP_KERNEL); 690 if (!group) 691 return -ENOMEM; 692 693 group->name = names[i]; 694 695 config_group_init_type_name(&group->group, group->name, 696 &uvcg_control_class_type); 697 configfs_add_default_group(&group->group, parent); 698 } 699 700 return 0; 701 } 702 703 static const struct uvcg_config_group_type uvcg_control_class_grp_type = { 704 .type = { 705 .ct_item_ops = &uvcg_config_item_ops, 706 .ct_owner = THIS_MODULE, 707 }, 708 .name = "class", 709 .create_children = uvcg_control_class_create_children, 710 }; 711 712 /* ----------------------------------------------------------------------------- 713 * control 714 */ 715 716 static ssize_t uvcg_default_control_b_interface_number_show( 717 struct config_item *item, char *page) 718 { 719 struct config_group *group = to_config_group(item); 720 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 721 struct config_item *opts_item; 722 struct f_uvc_opts *opts; 723 int result = 0; 724 725 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 726 727 opts_item = item->ci_parent; 728 opts = to_f_uvc_opts(opts_item); 729 730 mutex_lock(&opts->lock); 731 result += sprintf(page, "%u\n", opts->control_interface); 732 mutex_unlock(&opts->lock); 733 734 mutex_unlock(su_mutex); 735 736 return result; 737 } 738 739 UVC_ATTR_RO(uvcg_default_control_, b_interface_number, bInterfaceNumber); 740 741 static struct configfs_attribute *uvcg_default_control_attrs[] = { 742 &uvcg_default_control_attr_b_interface_number, 743 NULL, 744 }; 745 746 static const struct uvcg_config_group_type uvcg_control_grp_type = { 747 .type = { 748 .ct_item_ops = &uvcg_config_item_ops, 749 .ct_attrs = uvcg_default_control_attrs, 750 .ct_owner = THIS_MODULE, 751 }, 752 .name = "control", 753 .children = (const struct uvcg_config_group_type*[]) { 754 &uvcg_control_header_grp_type, 755 &uvcg_processing_grp_type, 756 &uvcg_terminal_grp_type, 757 &uvcg_control_class_grp_type, 758 NULL, 759 }, 760 }; 761 762 /* ----------------------------------------------------------------------------- 763 * streaming/uncompressed 764 * streaming/mjpeg 765 */ 766 767 static const char * const uvcg_format_names[] = { 768 "uncompressed", 769 "mjpeg", 770 }; 771 772 enum uvcg_format_type { 773 UVCG_UNCOMPRESSED = 0, 774 UVCG_MJPEG, 775 }; 776 777 struct uvcg_format { 778 struct config_group group; 779 enum uvcg_format_type type; 780 unsigned linked; 781 unsigned num_frames; 782 __u8 bmaControls[UVCG_STREAMING_CONTROL_SIZE]; 783 }; 784 785 static struct uvcg_format *to_uvcg_format(struct config_item *item) 786 { 787 return container_of(to_config_group(item), struct uvcg_format, group); 788 } 789 790 static ssize_t uvcg_format_bma_controls_show(struct uvcg_format *f, char *page) 791 { 792 struct f_uvc_opts *opts; 793 struct config_item *opts_item; 794 struct mutex *su_mutex = &f->group.cg_subsys->su_mutex; 795 int result, i; 796 char *pg = page; 797 798 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 799 800 opts_item = f->group.cg_item.ci_parent->ci_parent->ci_parent; 801 opts = to_f_uvc_opts(opts_item); 802 803 mutex_lock(&opts->lock); 804 result = sprintf(pg, "0x"); 805 pg += result; 806 for (i = 0; i < UVCG_STREAMING_CONTROL_SIZE; ++i) { 807 result += sprintf(pg, "%x\n", f->bmaControls[i]); 808 pg = page + result; 809 } 810 mutex_unlock(&opts->lock); 811 812 mutex_unlock(su_mutex); 813 return result; 814 } 815 816 static ssize_t uvcg_format_bma_controls_store(struct uvcg_format *ch, 817 const char *page, size_t len) 818 { 819 struct f_uvc_opts *opts; 820 struct config_item *opts_item; 821 struct mutex *su_mutex = &ch->group.cg_subsys->su_mutex; 822 int ret = -EINVAL; 823 824 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 825 826 opts_item = ch->group.cg_item.ci_parent->ci_parent->ci_parent; 827 opts = to_f_uvc_opts(opts_item); 828 829 mutex_lock(&opts->lock); 830 if (ch->linked || opts->refcnt) { 831 ret = -EBUSY; 832 goto end; 833 } 834 835 if (len < 4 || *page != '0' || 836 (*(page + 1) != 'x' && *(page + 1) != 'X')) 837 goto end; 838 ret = hex2bin(ch->bmaControls, page + 2, 1); 839 if (ret < 0) 840 goto end; 841 ret = len; 842 end: 843 mutex_unlock(&opts->lock); 844 mutex_unlock(su_mutex); 845 return ret; 846 } 847 848 struct uvcg_format_ptr { 849 struct uvcg_format *fmt; 850 struct list_head entry; 851 }; 852 853 /* ----------------------------------------------------------------------------- 854 * streaming/header/<NAME> 855 * streaming/header 856 */ 857 858 struct uvcg_streaming_header { 859 struct config_item item; 860 struct uvc_input_header_descriptor desc; 861 unsigned linked; 862 struct list_head formats; 863 unsigned num_fmt; 864 }; 865 866 static struct uvcg_streaming_header *to_uvcg_streaming_header(struct config_item *item) 867 { 868 return container_of(item, struct uvcg_streaming_header, item); 869 } 870 871 static void uvcg_format_set_indices(struct config_group *fmt); 872 873 static int uvcg_streaming_header_allow_link(struct config_item *src, 874 struct config_item *target) 875 { 876 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 877 struct config_item *opts_item; 878 struct f_uvc_opts *opts; 879 struct uvcg_streaming_header *src_hdr; 880 struct uvcg_format *target_fmt = NULL; 881 struct uvcg_format_ptr *format_ptr; 882 int i, ret = -EINVAL; 883 884 src_hdr = to_uvcg_streaming_header(src); 885 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 886 887 opts_item = src->ci_parent->ci_parent->ci_parent; 888 opts = to_f_uvc_opts(opts_item); 889 890 mutex_lock(&opts->lock); 891 892 if (src_hdr->linked) { 893 ret = -EBUSY; 894 goto out; 895 } 896 897 /* 898 * Linking is only allowed to direct children of the format nodes 899 * (streaming/uncompressed or streaming/mjpeg nodes). First check that 900 * the grand-parent of the target matches the grand-parent of the source 901 * (the streaming node), and then verify that the target parent is a 902 * format node. 903 */ 904 if (src->ci_parent->ci_parent != target->ci_parent->ci_parent) 905 goto out; 906 907 for (i = 0; i < ARRAY_SIZE(uvcg_format_names); ++i) { 908 if (!strcmp(target->ci_parent->ci_name, uvcg_format_names[i])) 909 break; 910 } 911 912 if (i == ARRAY_SIZE(uvcg_format_names)) 913 goto out; 914 915 target_fmt = container_of(to_config_group(target), struct uvcg_format, 916 group); 917 if (!target_fmt) 918 goto out; 919 920 uvcg_format_set_indices(to_config_group(target)); 921 922 format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL); 923 if (!format_ptr) { 924 ret = -ENOMEM; 925 goto out; 926 } 927 ret = 0; 928 format_ptr->fmt = target_fmt; 929 list_add_tail(&format_ptr->entry, &src_hdr->formats); 930 ++src_hdr->num_fmt; 931 932 out: 933 mutex_unlock(&opts->lock); 934 mutex_unlock(su_mutex); 935 return ret; 936 } 937 938 static void uvcg_streaming_header_drop_link(struct config_item *src, 939 struct config_item *target) 940 { 941 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 942 struct config_item *opts_item; 943 struct f_uvc_opts *opts; 944 struct uvcg_streaming_header *src_hdr; 945 struct uvcg_format *target_fmt = NULL; 946 struct uvcg_format_ptr *format_ptr, *tmp; 947 948 src_hdr = to_uvcg_streaming_header(src); 949 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 950 951 opts_item = src->ci_parent->ci_parent->ci_parent; 952 opts = to_f_uvc_opts(opts_item); 953 954 mutex_lock(&opts->lock); 955 target_fmt = container_of(to_config_group(target), struct uvcg_format, 956 group); 957 if (!target_fmt) 958 goto out; 959 960 list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry) 961 if (format_ptr->fmt == target_fmt) { 962 list_del(&format_ptr->entry); 963 kfree(format_ptr); 964 --src_hdr->num_fmt; 965 break; 966 } 967 968 out: 969 mutex_unlock(&opts->lock); 970 mutex_unlock(su_mutex); 971 } 972 973 static struct configfs_item_operations uvcg_streaming_header_item_ops = { 974 .release = uvcg_config_item_release, 975 .allow_link = uvcg_streaming_header_allow_link, 976 .drop_link = uvcg_streaming_header_drop_link, 977 }; 978 979 #define UVCG_STREAMING_HEADER_ATTR(cname, aname, conv) \ 980 static ssize_t uvcg_streaming_header_##cname##_show( \ 981 struct config_item *item, char *page) \ 982 { \ 983 struct uvcg_streaming_header *sh = to_uvcg_streaming_header(item); \ 984 struct f_uvc_opts *opts; \ 985 struct config_item *opts_item; \ 986 struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\ 987 int result; \ 988 \ 989 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 990 \ 991 opts_item = sh->item.ci_parent->ci_parent->ci_parent; \ 992 opts = to_f_uvc_opts(opts_item); \ 993 \ 994 mutex_lock(&opts->lock); \ 995 result = sprintf(page, "%d\n", conv(sh->desc.aname)); \ 996 mutex_unlock(&opts->lock); \ 997 \ 998 mutex_unlock(su_mutex); \ 999 return result; \ 1000 } \ 1001 \ 1002 UVC_ATTR_RO(uvcg_streaming_header_, cname, aname) 1003 1004 #define identity_conv(x) (x) 1005 1006 UVCG_STREAMING_HEADER_ATTR(bm_info, bmInfo, identity_conv); 1007 UVCG_STREAMING_HEADER_ATTR(b_terminal_link, bTerminalLink, identity_conv); 1008 UVCG_STREAMING_HEADER_ATTR(b_still_capture_method, bStillCaptureMethod, 1009 identity_conv); 1010 UVCG_STREAMING_HEADER_ATTR(b_trigger_support, bTriggerSupport, identity_conv); 1011 UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, identity_conv); 1012 1013 #undef identity_conv 1014 1015 #undef UVCG_STREAMING_HEADER_ATTR 1016 1017 static struct configfs_attribute *uvcg_streaming_header_attrs[] = { 1018 &uvcg_streaming_header_attr_bm_info, 1019 &uvcg_streaming_header_attr_b_terminal_link, 1020 &uvcg_streaming_header_attr_b_still_capture_method, 1021 &uvcg_streaming_header_attr_b_trigger_support, 1022 &uvcg_streaming_header_attr_b_trigger_usage, 1023 NULL, 1024 }; 1025 1026 static const struct config_item_type uvcg_streaming_header_type = { 1027 .ct_item_ops = &uvcg_streaming_header_item_ops, 1028 .ct_attrs = uvcg_streaming_header_attrs, 1029 .ct_owner = THIS_MODULE, 1030 }; 1031 1032 static struct config_item 1033 *uvcg_streaming_header_make(struct config_group *group, const char *name) 1034 { 1035 struct uvcg_streaming_header *h; 1036 1037 h = kzalloc(sizeof(*h), GFP_KERNEL); 1038 if (!h) 1039 return ERR_PTR(-ENOMEM); 1040 1041 INIT_LIST_HEAD(&h->formats); 1042 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 1043 h->desc.bDescriptorSubType = UVC_VS_INPUT_HEADER; 1044 h->desc.bTerminalLink = 3; 1045 h->desc.bControlSize = UVCG_STREAMING_CONTROL_SIZE; 1046 1047 config_item_init_type_name(&h->item, name, &uvcg_streaming_header_type); 1048 1049 return &h->item; 1050 } 1051 1052 static struct configfs_group_operations uvcg_streaming_header_grp_ops = { 1053 .make_item = uvcg_streaming_header_make, 1054 }; 1055 1056 static const struct uvcg_config_group_type uvcg_streaming_header_grp_type = { 1057 .type = { 1058 .ct_item_ops = &uvcg_config_item_ops, 1059 .ct_group_ops = &uvcg_streaming_header_grp_ops, 1060 .ct_owner = THIS_MODULE, 1061 }, 1062 .name = "header", 1063 }; 1064 1065 /* ----------------------------------------------------------------------------- 1066 * streaming/<mode>/<format>/<NAME> 1067 */ 1068 1069 struct uvcg_frame { 1070 struct config_item item; 1071 enum uvcg_format_type fmt_type; 1072 struct { 1073 u8 b_length; 1074 u8 b_descriptor_type; 1075 u8 b_descriptor_subtype; 1076 u8 b_frame_index; 1077 u8 bm_capabilities; 1078 u16 w_width; 1079 u16 w_height; 1080 u32 dw_min_bit_rate; 1081 u32 dw_max_bit_rate; 1082 u32 dw_max_video_frame_buffer_size; 1083 u32 dw_default_frame_interval; 1084 u8 b_frame_interval_type; 1085 } __attribute__((packed)) frame; 1086 u32 *dw_frame_interval; 1087 }; 1088 1089 static struct uvcg_frame *to_uvcg_frame(struct config_item *item) 1090 { 1091 return container_of(item, struct uvcg_frame, item); 1092 } 1093 1094 #define UVCG_FRAME_ATTR(cname, aname, to_cpu_endian, to_little_endian, bits) \ 1095 static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\ 1096 { \ 1097 struct uvcg_frame *f = to_uvcg_frame(item); \ 1098 struct f_uvc_opts *opts; \ 1099 struct config_item *opts_item; \ 1100 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ 1101 int result; \ 1102 \ 1103 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1104 \ 1105 opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ 1106 opts = to_f_uvc_opts(opts_item); \ 1107 \ 1108 mutex_lock(&opts->lock); \ 1109 result = sprintf(page, "%d\n", to_cpu_endian(f->frame.cname)); \ 1110 mutex_unlock(&opts->lock); \ 1111 \ 1112 mutex_unlock(su_mutex); \ 1113 return result; \ 1114 } \ 1115 \ 1116 static ssize_t uvcg_frame_##cname##_store(struct config_item *item, \ 1117 const char *page, size_t len)\ 1118 { \ 1119 struct uvcg_frame *f = to_uvcg_frame(item); \ 1120 struct f_uvc_opts *opts; \ 1121 struct config_item *opts_item; \ 1122 struct uvcg_format *fmt; \ 1123 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ 1124 int ret; \ 1125 u##bits num; \ 1126 \ 1127 ret = kstrtou##bits(page, 0, &num); \ 1128 if (ret) \ 1129 return ret; \ 1130 \ 1131 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1132 \ 1133 opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ 1134 opts = to_f_uvc_opts(opts_item); \ 1135 fmt = to_uvcg_format(f->item.ci_parent); \ 1136 \ 1137 mutex_lock(&opts->lock); \ 1138 if (fmt->linked || opts->refcnt) { \ 1139 ret = -EBUSY; \ 1140 goto end; \ 1141 } \ 1142 \ 1143 f->frame.cname = to_little_endian(num); \ 1144 ret = len; \ 1145 end: \ 1146 mutex_unlock(&opts->lock); \ 1147 mutex_unlock(su_mutex); \ 1148 return ret; \ 1149 } \ 1150 \ 1151 UVC_ATTR(uvcg_frame_, cname, aname); 1152 1153 static ssize_t uvcg_frame_b_frame_index_show(struct config_item *item, 1154 char *page) 1155 { 1156 struct uvcg_frame *f = to_uvcg_frame(item); 1157 struct uvcg_format *fmt; 1158 struct f_uvc_opts *opts; 1159 struct config_item *opts_item; 1160 struct config_item *fmt_item; 1161 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex; 1162 int result; 1163 1164 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1165 1166 fmt_item = f->item.ci_parent; 1167 fmt = to_uvcg_format(fmt_item); 1168 1169 if (!fmt->linked) { 1170 result = -EBUSY; 1171 goto out; 1172 } 1173 1174 opts_item = fmt_item->ci_parent->ci_parent->ci_parent; 1175 opts = to_f_uvc_opts(opts_item); 1176 1177 mutex_lock(&opts->lock); 1178 result = sprintf(page, "%d\n", f->frame.b_frame_index); 1179 mutex_unlock(&opts->lock); 1180 1181 out: 1182 mutex_unlock(su_mutex); 1183 return result; 1184 } 1185 1186 UVC_ATTR_RO(uvcg_frame_, b_frame_index, bFrameIndex); 1187 1188 #define noop_conversion(x) (x) 1189 1190 UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion, 1191 noop_conversion, 8); 1192 UVCG_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16); 1193 UVCG_FRAME_ATTR(w_height, wHeight, le16_to_cpu, cpu_to_le16, 16); 1194 UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, le32_to_cpu, cpu_to_le32, 32); 1195 UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, le32_to_cpu, cpu_to_le32, 32); 1196 UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize, 1197 le32_to_cpu, cpu_to_le32, 32); 1198 UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, 1199 le32_to_cpu, cpu_to_le32, 32); 1200 1201 #undef noop_conversion 1202 1203 #undef UVCG_FRAME_ATTR 1204 1205 static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item, 1206 char *page) 1207 { 1208 struct uvcg_frame *frm = to_uvcg_frame(item); 1209 struct f_uvc_opts *opts; 1210 struct config_item *opts_item; 1211 struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex; 1212 int result, i; 1213 char *pg = page; 1214 1215 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1216 1217 opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent; 1218 opts = to_f_uvc_opts(opts_item); 1219 1220 mutex_lock(&opts->lock); 1221 for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) { 1222 result += sprintf(pg, "%d\n", 1223 le32_to_cpu(frm->dw_frame_interval[i])); 1224 pg = page + result; 1225 } 1226 mutex_unlock(&opts->lock); 1227 1228 mutex_unlock(su_mutex); 1229 return result; 1230 } 1231 1232 static inline int __uvcg_count_frm_intrv(char *buf, void *priv) 1233 { 1234 ++*((int *)priv); 1235 return 0; 1236 } 1237 1238 static inline int __uvcg_fill_frm_intrv(char *buf, void *priv) 1239 { 1240 u32 num, **interv; 1241 int ret; 1242 1243 ret = kstrtou32(buf, 0, &num); 1244 if (ret) 1245 return ret; 1246 1247 interv = priv; 1248 **interv = cpu_to_le32(num); 1249 ++*interv; 1250 1251 return 0; 1252 } 1253 1254 static int __uvcg_iter_frm_intrv(const char *page, size_t len, 1255 int (*fun)(char *, void *), void *priv) 1256 { 1257 /* sign, base 2 representation, newline, terminator */ 1258 char buf[1 + sizeof(u32) * 8 + 1 + 1]; 1259 const char *pg = page; 1260 int i, ret; 1261 1262 if (!fun) 1263 return -EINVAL; 1264 1265 while (pg - page < len) { 1266 i = 0; 1267 while (i < sizeof(buf) && (pg - page < len) && 1268 *pg != '\0' && *pg != '\n') 1269 buf[i++] = *pg++; 1270 if (i == sizeof(buf)) 1271 return -EINVAL; 1272 while ((pg - page < len) && (*pg == '\0' || *pg == '\n')) 1273 ++pg; 1274 buf[i] = '\0'; 1275 ret = fun(buf, priv); 1276 if (ret) 1277 return ret; 1278 } 1279 1280 return 0; 1281 } 1282 1283 static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item, 1284 const char *page, size_t len) 1285 { 1286 struct uvcg_frame *ch = to_uvcg_frame(item); 1287 struct f_uvc_opts *opts; 1288 struct config_item *opts_item; 1289 struct uvcg_format *fmt; 1290 struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex; 1291 int ret = 0, n = 0; 1292 u32 *frm_intrv, *tmp; 1293 1294 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1295 1296 opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent; 1297 opts = to_f_uvc_opts(opts_item); 1298 fmt = to_uvcg_format(ch->item.ci_parent); 1299 1300 mutex_lock(&opts->lock); 1301 if (fmt->linked || opts->refcnt) { 1302 ret = -EBUSY; 1303 goto end; 1304 } 1305 1306 ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n); 1307 if (ret) 1308 goto end; 1309 1310 tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL); 1311 if (!frm_intrv) { 1312 ret = -ENOMEM; 1313 goto end; 1314 } 1315 1316 ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp); 1317 if (ret) { 1318 kfree(frm_intrv); 1319 goto end; 1320 } 1321 1322 kfree(ch->dw_frame_interval); 1323 ch->dw_frame_interval = frm_intrv; 1324 ch->frame.b_frame_interval_type = n; 1325 ret = len; 1326 1327 end: 1328 mutex_unlock(&opts->lock); 1329 mutex_unlock(su_mutex); 1330 return ret; 1331 } 1332 1333 UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval); 1334 1335 static struct configfs_attribute *uvcg_frame_attrs[] = { 1336 &uvcg_frame_attr_b_frame_index, 1337 &uvcg_frame_attr_bm_capabilities, 1338 &uvcg_frame_attr_w_width, 1339 &uvcg_frame_attr_w_height, 1340 &uvcg_frame_attr_dw_min_bit_rate, 1341 &uvcg_frame_attr_dw_max_bit_rate, 1342 &uvcg_frame_attr_dw_max_video_frame_buffer_size, 1343 &uvcg_frame_attr_dw_default_frame_interval, 1344 &uvcg_frame_attr_dw_frame_interval, 1345 NULL, 1346 }; 1347 1348 static const struct config_item_type uvcg_frame_type = { 1349 .ct_item_ops = &uvcg_config_item_ops, 1350 .ct_attrs = uvcg_frame_attrs, 1351 .ct_owner = THIS_MODULE, 1352 }; 1353 1354 static struct config_item *uvcg_frame_make(struct config_group *group, 1355 const char *name) 1356 { 1357 struct uvcg_frame *h; 1358 struct uvcg_format *fmt; 1359 struct f_uvc_opts *opts; 1360 struct config_item *opts_item; 1361 1362 h = kzalloc(sizeof(*h), GFP_KERNEL); 1363 if (!h) 1364 return ERR_PTR(-ENOMEM); 1365 1366 h->frame.b_descriptor_type = USB_DT_CS_INTERFACE; 1367 h->frame.b_frame_index = 1; 1368 h->frame.w_width = cpu_to_le16(640); 1369 h->frame.w_height = cpu_to_le16(360); 1370 h->frame.dw_min_bit_rate = cpu_to_le32(18432000); 1371 h->frame.dw_max_bit_rate = cpu_to_le32(55296000); 1372 h->frame.dw_max_video_frame_buffer_size = cpu_to_le32(460800); 1373 h->frame.dw_default_frame_interval = cpu_to_le32(666666); 1374 1375 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 1376 opts = to_f_uvc_opts(opts_item); 1377 1378 mutex_lock(&opts->lock); 1379 fmt = to_uvcg_format(&group->cg_item); 1380 if (fmt->type == UVCG_UNCOMPRESSED) { 1381 h->frame.b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED; 1382 h->fmt_type = UVCG_UNCOMPRESSED; 1383 } else if (fmt->type == UVCG_MJPEG) { 1384 h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG; 1385 h->fmt_type = UVCG_MJPEG; 1386 } else { 1387 mutex_unlock(&opts->lock); 1388 kfree(h); 1389 return ERR_PTR(-EINVAL); 1390 } 1391 ++fmt->num_frames; 1392 mutex_unlock(&opts->lock); 1393 1394 config_item_init_type_name(&h->item, name, &uvcg_frame_type); 1395 1396 return &h->item; 1397 } 1398 1399 static void uvcg_frame_drop(struct config_group *group, struct config_item *item) 1400 { 1401 struct uvcg_format *fmt; 1402 struct f_uvc_opts *opts; 1403 struct config_item *opts_item; 1404 1405 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 1406 opts = to_f_uvc_opts(opts_item); 1407 1408 mutex_lock(&opts->lock); 1409 fmt = to_uvcg_format(&group->cg_item); 1410 --fmt->num_frames; 1411 mutex_unlock(&opts->lock); 1412 1413 config_item_put(item); 1414 } 1415 1416 static void uvcg_format_set_indices(struct config_group *fmt) 1417 { 1418 struct config_item *ci; 1419 unsigned int i = 1; 1420 1421 list_for_each_entry(ci, &fmt->cg_children, ci_entry) { 1422 struct uvcg_frame *frm; 1423 1424 if (ci->ci_type != &uvcg_frame_type) 1425 continue; 1426 1427 frm = to_uvcg_frame(ci); 1428 frm->frame.b_frame_index = i++; 1429 } 1430 } 1431 1432 /* ----------------------------------------------------------------------------- 1433 * streaming/uncompressed/<NAME> 1434 */ 1435 1436 struct uvcg_uncompressed { 1437 struct uvcg_format fmt; 1438 struct uvc_format_uncompressed desc; 1439 }; 1440 1441 static struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item) 1442 { 1443 return container_of( 1444 container_of(to_config_group(item), struct uvcg_format, group), 1445 struct uvcg_uncompressed, fmt); 1446 } 1447 1448 static struct configfs_group_operations uvcg_uncompressed_group_ops = { 1449 .make_item = uvcg_frame_make, 1450 .drop_item = uvcg_frame_drop, 1451 }; 1452 1453 static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item, 1454 char *page) 1455 { 1456 struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); 1457 struct f_uvc_opts *opts; 1458 struct config_item *opts_item; 1459 struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; 1460 1461 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1462 1463 opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; 1464 opts = to_f_uvc_opts(opts_item); 1465 1466 mutex_lock(&opts->lock); 1467 memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat)); 1468 mutex_unlock(&opts->lock); 1469 1470 mutex_unlock(su_mutex); 1471 1472 return sizeof(ch->desc.guidFormat); 1473 } 1474 1475 static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item, 1476 const char *page, size_t len) 1477 { 1478 struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); 1479 struct f_uvc_opts *opts; 1480 struct config_item *opts_item; 1481 struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; 1482 int ret; 1483 1484 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1485 1486 opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; 1487 opts = to_f_uvc_opts(opts_item); 1488 1489 mutex_lock(&opts->lock); 1490 if (ch->fmt.linked || opts->refcnt) { 1491 ret = -EBUSY; 1492 goto end; 1493 } 1494 1495 memcpy(ch->desc.guidFormat, page, 1496 min(sizeof(ch->desc.guidFormat), len)); 1497 ret = sizeof(ch->desc.guidFormat); 1498 1499 end: 1500 mutex_unlock(&opts->lock); 1501 mutex_unlock(su_mutex); 1502 return ret; 1503 } 1504 1505 UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat); 1506 1507 #define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, conv) \ 1508 static ssize_t uvcg_uncompressed_##cname##_show( \ 1509 struct config_item *item, char *page) \ 1510 { \ 1511 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ 1512 struct f_uvc_opts *opts; \ 1513 struct config_item *opts_item; \ 1514 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1515 int result; \ 1516 \ 1517 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1518 \ 1519 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1520 opts = to_f_uvc_opts(opts_item); \ 1521 \ 1522 mutex_lock(&opts->lock); \ 1523 result = sprintf(page, "%d\n", conv(u->desc.aname)); \ 1524 mutex_unlock(&opts->lock); \ 1525 \ 1526 mutex_unlock(su_mutex); \ 1527 return result; \ 1528 } \ 1529 \ 1530 UVC_ATTR_RO(uvcg_uncompressed_, cname, aname); 1531 1532 #define UVCG_UNCOMPRESSED_ATTR(cname, aname, conv) \ 1533 static ssize_t uvcg_uncompressed_##cname##_show( \ 1534 struct config_item *item, char *page) \ 1535 { \ 1536 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ 1537 struct f_uvc_opts *opts; \ 1538 struct config_item *opts_item; \ 1539 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1540 int result; \ 1541 \ 1542 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1543 \ 1544 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1545 opts = to_f_uvc_opts(opts_item); \ 1546 \ 1547 mutex_lock(&opts->lock); \ 1548 result = sprintf(page, "%d\n", conv(u->desc.aname)); \ 1549 mutex_unlock(&opts->lock); \ 1550 \ 1551 mutex_unlock(su_mutex); \ 1552 return result; \ 1553 } \ 1554 \ 1555 static ssize_t \ 1556 uvcg_uncompressed_##cname##_store(struct config_item *item, \ 1557 const char *page, size_t len) \ 1558 { \ 1559 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ 1560 struct f_uvc_opts *opts; \ 1561 struct config_item *opts_item; \ 1562 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1563 int ret; \ 1564 u8 num; \ 1565 \ 1566 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1567 \ 1568 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1569 opts = to_f_uvc_opts(opts_item); \ 1570 \ 1571 mutex_lock(&opts->lock); \ 1572 if (u->fmt.linked || opts->refcnt) { \ 1573 ret = -EBUSY; \ 1574 goto end; \ 1575 } \ 1576 \ 1577 ret = kstrtou8(page, 0, &num); \ 1578 if (ret) \ 1579 goto end; \ 1580 \ 1581 if (num > 255) { \ 1582 ret = -EINVAL; \ 1583 goto end; \ 1584 } \ 1585 u->desc.aname = num; \ 1586 ret = len; \ 1587 end: \ 1588 mutex_unlock(&opts->lock); \ 1589 mutex_unlock(su_mutex); \ 1590 return ret; \ 1591 } \ 1592 \ 1593 UVC_ATTR(uvcg_uncompressed_, cname, aname); 1594 1595 #define identity_conv(x) (x) 1596 1597 UVCG_UNCOMPRESSED_ATTR_RO(b_format_index, bFormatIndex, identity_conv); 1598 UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, identity_conv); 1599 UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex, 1600 identity_conv); 1601 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv); 1602 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv); 1603 UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv); 1604 1605 #undef identity_conv 1606 1607 #undef UVCG_UNCOMPRESSED_ATTR 1608 #undef UVCG_UNCOMPRESSED_ATTR_RO 1609 1610 static inline ssize_t 1611 uvcg_uncompressed_bma_controls_show(struct config_item *item, char *page) 1612 { 1613 struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item); 1614 return uvcg_format_bma_controls_show(&unc->fmt, page); 1615 } 1616 1617 static inline ssize_t 1618 uvcg_uncompressed_bma_controls_store(struct config_item *item, 1619 const char *page, size_t len) 1620 { 1621 struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item); 1622 return uvcg_format_bma_controls_store(&unc->fmt, page, len); 1623 } 1624 1625 UVC_ATTR(uvcg_uncompressed_, bma_controls, bmaControls); 1626 1627 static struct configfs_attribute *uvcg_uncompressed_attrs[] = { 1628 &uvcg_uncompressed_attr_b_format_index, 1629 &uvcg_uncompressed_attr_guid_format, 1630 &uvcg_uncompressed_attr_b_bits_per_pixel, 1631 &uvcg_uncompressed_attr_b_default_frame_index, 1632 &uvcg_uncompressed_attr_b_aspect_ratio_x, 1633 &uvcg_uncompressed_attr_b_aspect_ratio_y, 1634 &uvcg_uncompressed_attr_bm_interface_flags, 1635 &uvcg_uncompressed_attr_bma_controls, 1636 NULL, 1637 }; 1638 1639 static const struct config_item_type uvcg_uncompressed_type = { 1640 .ct_item_ops = &uvcg_config_item_ops, 1641 .ct_group_ops = &uvcg_uncompressed_group_ops, 1642 .ct_attrs = uvcg_uncompressed_attrs, 1643 .ct_owner = THIS_MODULE, 1644 }; 1645 1646 static struct config_group *uvcg_uncompressed_make(struct config_group *group, 1647 const char *name) 1648 { 1649 static char guid[] = { 1650 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, 1651 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 1652 }; 1653 struct uvcg_uncompressed *h; 1654 1655 h = kzalloc(sizeof(*h), GFP_KERNEL); 1656 if (!h) 1657 return ERR_PTR(-ENOMEM); 1658 1659 h->desc.bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE; 1660 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 1661 h->desc.bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED; 1662 memcpy(h->desc.guidFormat, guid, sizeof(guid)); 1663 h->desc.bBitsPerPixel = 16; 1664 h->desc.bDefaultFrameIndex = 1; 1665 h->desc.bAspectRatioX = 0; 1666 h->desc.bAspectRatioY = 0; 1667 h->desc.bmInterfaceFlags = 0; 1668 h->desc.bCopyProtect = 0; 1669 1670 h->fmt.type = UVCG_UNCOMPRESSED; 1671 config_group_init_type_name(&h->fmt.group, name, 1672 &uvcg_uncompressed_type); 1673 1674 return &h->fmt.group; 1675 } 1676 1677 static struct configfs_group_operations uvcg_uncompressed_grp_ops = { 1678 .make_group = uvcg_uncompressed_make, 1679 }; 1680 1681 static const struct uvcg_config_group_type uvcg_uncompressed_grp_type = { 1682 .type = { 1683 .ct_item_ops = &uvcg_config_item_ops, 1684 .ct_group_ops = &uvcg_uncompressed_grp_ops, 1685 .ct_owner = THIS_MODULE, 1686 }, 1687 .name = "uncompressed", 1688 }; 1689 1690 /* ----------------------------------------------------------------------------- 1691 * streaming/mjpeg/<NAME> 1692 */ 1693 1694 struct uvcg_mjpeg { 1695 struct uvcg_format fmt; 1696 struct uvc_format_mjpeg desc; 1697 }; 1698 1699 static struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item) 1700 { 1701 return container_of( 1702 container_of(to_config_group(item), struct uvcg_format, group), 1703 struct uvcg_mjpeg, fmt); 1704 } 1705 1706 static struct configfs_group_operations uvcg_mjpeg_group_ops = { 1707 .make_item = uvcg_frame_make, 1708 .drop_item = uvcg_frame_drop, 1709 }; 1710 1711 #define UVCG_MJPEG_ATTR_RO(cname, aname, conv) \ 1712 static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\ 1713 { \ 1714 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 1715 struct f_uvc_opts *opts; \ 1716 struct config_item *opts_item; \ 1717 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1718 int result; \ 1719 \ 1720 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1721 \ 1722 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1723 opts = to_f_uvc_opts(opts_item); \ 1724 \ 1725 mutex_lock(&opts->lock); \ 1726 result = sprintf(page, "%d\n", conv(u->desc.aname)); \ 1727 mutex_unlock(&opts->lock); \ 1728 \ 1729 mutex_unlock(su_mutex); \ 1730 return result; \ 1731 } \ 1732 \ 1733 UVC_ATTR_RO(uvcg_mjpeg_, cname, aname) 1734 1735 #define UVCG_MJPEG_ATTR(cname, aname, conv) \ 1736 static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\ 1737 { \ 1738 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 1739 struct f_uvc_opts *opts; \ 1740 struct config_item *opts_item; \ 1741 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1742 int result; \ 1743 \ 1744 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1745 \ 1746 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1747 opts = to_f_uvc_opts(opts_item); \ 1748 \ 1749 mutex_lock(&opts->lock); \ 1750 result = sprintf(page, "%d\n", conv(u->desc.aname)); \ 1751 mutex_unlock(&opts->lock); \ 1752 \ 1753 mutex_unlock(su_mutex); \ 1754 return result; \ 1755 } \ 1756 \ 1757 static ssize_t \ 1758 uvcg_mjpeg_##cname##_store(struct config_item *item, \ 1759 const char *page, size_t len) \ 1760 { \ 1761 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 1762 struct f_uvc_opts *opts; \ 1763 struct config_item *opts_item; \ 1764 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1765 int ret; \ 1766 u8 num; \ 1767 \ 1768 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1769 \ 1770 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1771 opts = to_f_uvc_opts(opts_item); \ 1772 \ 1773 mutex_lock(&opts->lock); \ 1774 if (u->fmt.linked || opts->refcnt) { \ 1775 ret = -EBUSY; \ 1776 goto end; \ 1777 } \ 1778 \ 1779 ret = kstrtou8(page, 0, &num); \ 1780 if (ret) \ 1781 goto end; \ 1782 \ 1783 if (num > 255) { \ 1784 ret = -EINVAL; \ 1785 goto end; \ 1786 } \ 1787 u->desc.aname = num; \ 1788 ret = len; \ 1789 end: \ 1790 mutex_unlock(&opts->lock); \ 1791 mutex_unlock(su_mutex); \ 1792 return ret; \ 1793 } \ 1794 \ 1795 UVC_ATTR(uvcg_mjpeg_, cname, aname) 1796 1797 #define identity_conv(x) (x) 1798 1799 UVCG_MJPEG_ATTR_RO(b_format_index, bFormatIndex, identity_conv); 1800 UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex, 1801 identity_conv); 1802 UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, identity_conv); 1803 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv); 1804 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv); 1805 UVCG_MJPEG_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv); 1806 1807 #undef identity_conv 1808 1809 #undef UVCG_MJPEG_ATTR 1810 #undef UVCG_MJPEG_ATTR_RO 1811 1812 static inline ssize_t 1813 uvcg_mjpeg_bma_controls_show(struct config_item *item, char *page) 1814 { 1815 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); 1816 return uvcg_format_bma_controls_show(&u->fmt, page); 1817 } 1818 1819 static inline ssize_t 1820 uvcg_mjpeg_bma_controls_store(struct config_item *item, 1821 const char *page, size_t len) 1822 { 1823 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); 1824 return uvcg_format_bma_controls_store(&u->fmt, page, len); 1825 } 1826 1827 UVC_ATTR(uvcg_mjpeg_, bma_controls, bmaControls); 1828 1829 static struct configfs_attribute *uvcg_mjpeg_attrs[] = { 1830 &uvcg_mjpeg_attr_b_format_index, 1831 &uvcg_mjpeg_attr_b_default_frame_index, 1832 &uvcg_mjpeg_attr_bm_flags, 1833 &uvcg_mjpeg_attr_b_aspect_ratio_x, 1834 &uvcg_mjpeg_attr_b_aspect_ratio_y, 1835 &uvcg_mjpeg_attr_bm_interface_flags, 1836 &uvcg_mjpeg_attr_bma_controls, 1837 NULL, 1838 }; 1839 1840 static const struct config_item_type uvcg_mjpeg_type = { 1841 .ct_item_ops = &uvcg_config_item_ops, 1842 .ct_group_ops = &uvcg_mjpeg_group_ops, 1843 .ct_attrs = uvcg_mjpeg_attrs, 1844 .ct_owner = THIS_MODULE, 1845 }; 1846 1847 static struct config_group *uvcg_mjpeg_make(struct config_group *group, 1848 const char *name) 1849 { 1850 struct uvcg_mjpeg *h; 1851 1852 h = kzalloc(sizeof(*h), GFP_KERNEL); 1853 if (!h) 1854 return ERR_PTR(-ENOMEM); 1855 1856 h->desc.bLength = UVC_DT_FORMAT_MJPEG_SIZE; 1857 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 1858 h->desc.bDescriptorSubType = UVC_VS_FORMAT_MJPEG; 1859 h->desc.bDefaultFrameIndex = 1; 1860 h->desc.bAspectRatioX = 0; 1861 h->desc.bAspectRatioY = 0; 1862 h->desc.bmInterfaceFlags = 0; 1863 h->desc.bCopyProtect = 0; 1864 1865 h->fmt.type = UVCG_MJPEG; 1866 config_group_init_type_name(&h->fmt.group, name, 1867 &uvcg_mjpeg_type); 1868 1869 return &h->fmt.group; 1870 } 1871 1872 static struct configfs_group_operations uvcg_mjpeg_grp_ops = { 1873 .make_group = uvcg_mjpeg_make, 1874 }; 1875 1876 static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = { 1877 .type = { 1878 .ct_item_ops = &uvcg_config_item_ops, 1879 .ct_group_ops = &uvcg_mjpeg_grp_ops, 1880 .ct_owner = THIS_MODULE, 1881 }, 1882 .name = "mjpeg", 1883 }; 1884 1885 /* ----------------------------------------------------------------------------- 1886 * streaming/color_matching/default 1887 */ 1888 1889 #define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, conv) \ 1890 static ssize_t uvcg_default_color_matching_##cname##_show( \ 1891 struct config_item *item, char *page) \ 1892 { \ 1893 struct config_group *group = to_config_group(item); \ 1894 struct f_uvc_opts *opts; \ 1895 struct config_item *opts_item; \ 1896 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \ 1897 struct uvc_color_matching_descriptor *cd; \ 1898 int result; \ 1899 \ 1900 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1901 \ 1902 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; \ 1903 opts = to_f_uvc_opts(opts_item); \ 1904 cd = &opts->uvc_color_matching; \ 1905 \ 1906 mutex_lock(&opts->lock); \ 1907 result = sprintf(page, "%d\n", conv(cd->aname)); \ 1908 mutex_unlock(&opts->lock); \ 1909 \ 1910 mutex_unlock(su_mutex); \ 1911 return result; \ 1912 } \ 1913 \ 1914 UVC_ATTR_RO(uvcg_default_color_matching_, cname, aname) 1915 1916 #define identity_conv(x) (x) 1917 1918 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries, 1919 identity_conv); 1920 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_transfer_characteristics, 1921 bTransferCharacteristics, identity_conv); 1922 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients, 1923 identity_conv); 1924 1925 #undef identity_conv 1926 1927 #undef UVCG_DEFAULT_COLOR_MATCHING_ATTR 1928 1929 static struct configfs_attribute *uvcg_default_color_matching_attrs[] = { 1930 &uvcg_default_color_matching_attr_b_color_primaries, 1931 &uvcg_default_color_matching_attr_b_transfer_characteristics, 1932 &uvcg_default_color_matching_attr_b_matrix_coefficients, 1933 NULL, 1934 }; 1935 1936 static const struct uvcg_config_group_type uvcg_default_color_matching_type = { 1937 .type = { 1938 .ct_item_ops = &uvcg_config_item_ops, 1939 .ct_attrs = uvcg_default_color_matching_attrs, 1940 .ct_owner = THIS_MODULE, 1941 }, 1942 .name = "default", 1943 }; 1944 1945 /* ----------------------------------------------------------------------------- 1946 * streaming/color_matching 1947 */ 1948 1949 static const struct uvcg_config_group_type uvcg_color_matching_grp_type = { 1950 .type = { 1951 .ct_item_ops = &uvcg_config_item_ops, 1952 .ct_owner = THIS_MODULE, 1953 }, 1954 .name = "color_matching", 1955 .children = (const struct uvcg_config_group_type*[]) { 1956 &uvcg_default_color_matching_type, 1957 NULL, 1958 }, 1959 }; 1960 1961 /* ----------------------------------------------------------------------------- 1962 * streaming/class/{fs|hs|ss} 1963 */ 1964 1965 struct uvcg_streaming_class_group { 1966 struct config_group group; 1967 const char *name; 1968 }; 1969 1970 static inline struct uvc_descriptor_header 1971 ***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o) 1972 { 1973 struct uvcg_streaming_class_group *group = 1974 container_of(i, struct uvcg_streaming_class_group, 1975 group.cg_item); 1976 1977 if (!strcmp(group->name, "fs")) 1978 return &o->uvc_fs_streaming_cls; 1979 1980 if (!strcmp(group->name, "hs")) 1981 return &o->uvc_hs_streaming_cls; 1982 1983 if (!strcmp(group->name, "ss")) 1984 return &o->uvc_ss_streaming_cls; 1985 1986 return NULL; 1987 } 1988 1989 enum uvcg_strm_type { 1990 UVCG_HEADER = 0, 1991 UVCG_FORMAT, 1992 UVCG_FRAME 1993 }; 1994 1995 /* 1996 * Iterate over a hierarchy of streaming descriptors' config items. 1997 * The items are created by the user with configfs. 1998 * 1999 * It "processes" the header pointed to by @priv1, then for each format 2000 * that follows the header "processes" the format itself and then for 2001 * each frame inside a format "processes" the frame. 2002 * 2003 * As a "processing" function the @fun is used. 2004 * 2005 * __uvcg_iter_strm_cls() is used in two context: first, to calculate 2006 * the amount of memory needed for an array of streaming descriptors 2007 * and second, to actually fill the array. 2008 * 2009 * @h: streaming header pointer 2010 * @priv2: an "inout" parameter (the caller might want to see the changes to it) 2011 * @priv3: an "inout" parameter (the caller might want to see the changes to it) 2012 * @fun: callback function for processing each level of the hierarchy 2013 */ 2014 static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h, 2015 void *priv2, void *priv3, 2016 int (*fun)(void *, void *, void *, int, enum uvcg_strm_type type)) 2017 { 2018 struct uvcg_format_ptr *f; 2019 struct config_group *grp; 2020 struct config_item *item; 2021 struct uvcg_frame *frm; 2022 int ret, i, j; 2023 2024 if (!fun) 2025 return -EINVAL; 2026 2027 i = j = 0; 2028 ret = fun(h, priv2, priv3, 0, UVCG_HEADER); 2029 if (ret) 2030 return ret; 2031 list_for_each_entry(f, &h->formats, entry) { 2032 ret = fun(f->fmt, priv2, priv3, i++, UVCG_FORMAT); 2033 if (ret) 2034 return ret; 2035 grp = &f->fmt->group; 2036 list_for_each_entry(item, &grp->cg_children, ci_entry) { 2037 frm = to_uvcg_frame(item); 2038 ret = fun(frm, priv2, priv3, j++, UVCG_FRAME); 2039 if (ret) 2040 return ret; 2041 } 2042 } 2043 2044 return ret; 2045 } 2046 2047 /* 2048 * Count how many bytes are needed for an array of streaming descriptors. 2049 * 2050 * @priv1: pointer to a header, format or frame 2051 * @priv2: inout parameter, accumulated size of the array 2052 * @priv3: inout parameter, accumulated number of the array elements 2053 * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls 2054 */ 2055 static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n, 2056 enum uvcg_strm_type type) 2057 { 2058 size_t *size = priv2; 2059 size_t *count = priv3; 2060 2061 switch (type) { 2062 case UVCG_HEADER: { 2063 struct uvcg_streaming_header *h = priv1; 2064 2065 *size += sizeof(h->desc); 2066 /* bmaControls */ 2067 *size += h->num_fmt * UVCG_STREAMING_CONTROL_SIZE; 2068 } 2069 break; 2070 case UVCG_FORMAT: { 2071 struct uvcg_format *fmt = priv1; 2072 2073 if (fmt->type == UVCG_UNCOMPRESSED) { 2074 struct uvcg_uncompressed *u = 2075 container_of(fmt, struct uvcg_uncompressed, 2076 fmt); 2077 2078 *size += sizeof(u->desc); 2079 } else if (fmt->type == UVCG_MJPEG) { 2080 struct uvcg_mjpeg *m = 2081 container_of(fmt, struct uvcg_mjpeg, fmt); 2082 2083 *size += sizeof(m->desc); 2084 } else { 2085 return -EINVAL; 2086 } 2087 } 2088 break; 2089 case UVCG_FRAME: { 2090 struct uvcg_frame *frm = priv1; 2091 int sz = sizeof(frm->dw_frame_interval); 2092 2093 *size += sizeof(frm->frame); 2094 *size += frm->frame.b_frame_interval_type * sz; 2095 } 2096 break; 2097 } 2098 2099 ++*count; 2100 2101 return 0; 2102 } 2103 2104 /* 2105 * Fill an array of streaming descriptors. 2106 * 2107 * @priv1: pointer to a header, format or frame 2108 * @priv2: inout parameter, pointer into a block of memory 2109 * @priv3: inout parameter, pointer to a 2-dimensional array 2110 */ 2111 static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n, 2112 enum uvcg_strm_type type) 2113 { 2114 void **dest = priv2; 2115 struct uvc_descriptor_header ***array = priv3; 2116 size_t sz; 2117 2118 **array = *dest; 2119 ++*array; 2120 2121 switch (type) { 2122 case UVCG_HEADER: { 2123 struct uvc_input_header_descriptor *ihdr = *dest; 2124 struct uvcg_streaming_header *h = priv1; 2125 struct uvcg_format_ptr *f; 2126 2127 memcpy(*dest, &h->desc, sizeof(h->desc)); 2128 *dest += sizeof(h->desc); 2129 sz = UVCG_STREAMING_CONTROL_SIZE; 2130 list_for_each_entry(f, &h->formats, entry) { 2131 memcpy(*dest, f->fmt->bmaControls, sz); 2132 *dest += sz; 2133 } 2134 ihdr->bLength = sizeof(h->desc) + h->num_fmt * sz; 2135 ihdr->bNumFormats = h->num_fmt; 2136 } 2137 break; 2138 case UVCG_FORMAT: { 2139 struct uvcg_format *fmt = priv1; 2140 2141 if (fmt->type == UVCG_UNCOMPRESSED) { 2142 struct uvcg_uncompressed *u = 2143 container_of(fmt, struct uvcg_uncompressed, 2144 fmt); 2145 2146 u->desc.bFormatIndex = n + 1; 2147 u->desc.bNumFrameDescriptors = fmt->num_frames; 2148 memcpy(*dest, &u->desc, sizeof(u->desc)); 2149 *dest += sizeof(u->desc); 2150 } else if (fmt->type == UVCG_MJPEG) { 2151 struct uvcg_mjpeg *m = 2152 container_of(fmt, struct uvcg_mjpeg, fmt); 2153 2154 m->desc.bFormatIndex = n + 1; 2155 m->desc.bNumFrameDescriptors = fmt->num_frames; 2156 memcpy(*dest, &m->desc, sizeof(m->desc)); 2157 *dest += sizeof(m->desc); 2158 } else { 2159 return -EINVAL; 2160 } 2161 } 2162 break; 2163 case UVCG_FRAME: { 2164 struct uvcg_frame *frm = priv1; 2165 struct uvc_descriptor_header *h = *dest; 2166 2167 sz = sizeof(frm->frame); 2168 memcpy(*dest, &frm->frame, sz); 2169 *dest += sz; 2170 sz = frm->frame.b_frame_interval_type * 2171 sizeof(*frm->dw_frame_interval); 2172 memcpy(*dest, frm->dw_frame_interval, sz); 2173 *dest += sz; 2174 if (frm->fmt_type == UVCG_UNCOMPRESSED) 2175 h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE( 2176 frm->frame.b_frame_interval_type); 2177 else if (frm->fmt_type == UVCG_MJPEG) 2178 h->bLength = UVC_DT_FRAME_MJPEG_SIZE( 2179 frm->frame.b_frame_interval_type); 2180 } 2181 break; 2182 } 2183 2184 return 0; 2185 } 2186 2187 static int uvcg_streaming_class_allow_link(struct config_item *src, 2188 struct config_item *target) 2189 { 2190 struct config_item *streaming, *header; 2191 struct f_uvc_opts *opts; 2192 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 2193 struct uvc_descriptor_header ***class_array, **cl_arr; 2194 struct uvcg_streaming_header *target_hdr; 2195 void *data, *data_save; 2196 size_t size = 0, count = 0; 2197 int ret = -EINVAL; 2198 2199 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2200 2201 streaming = src->ci_parent->ci_parent; 2202 header = config_group_find_item(to_config_group(streaming), "header"); 2203 if (!header || target->ci_parent != header) 2204 goto out; 2205 2206 opts = to_f_uvc_opts(streaming->ci_parent); 2207 2208 mutex_lock(&opts->lock); 2209 2210 class_array = __uvcg_get_stream_class_arr(src, opts); 2211 if (!class_array || *class_array || opts->refcnt) { 2212 ret = -EBUSY; 2213 goto unlock; 2214 } 2215 2216 target_hdr = to_uvcg_streaming_header(target); 2217 ret = __uvcg_iter_strm_cls(target_hdr, &size, &count, __uvcg_cnt_strm); 2218 if (ret) 2219 goto unlock; 2220 2221 count += 2; /* color_matching, NULL */ 2222 *class_array = kcalloc(count, sizeof(void *), GFP_KERNEL); 2223 if (!*class_array) { 2224 ret = -ENOMEM; 2225 goto unlock; 2226 } 2227 2228 data = data_save = kzalloc(size, GFP_KERNEL); 2229 if (!data) { 2230 kfree(*class_array); 2231 *class_array = NULL; 2232 ret = -ENOMEM; 2233 goto unlock; 2234 } 2235 cl_arr = *class_array; 2236 ret = __uvcg_iter_strm_cls(target_hdr, &data, &cl_arr, 2237 __uvcg_fill_strm); 2238 if (ret) { 2239 kfree(*class_array); 2240 *class_array = NULL; 2241 /* 2242 * __uvcg_fill_strm() called from __uvcg_iter_stream_cls() 2243 * might have advanced the "data", so use a backup copy 2244 */ 2245 kfree(data_save); 2246 goto unlock; 2247 } 2248 *cl_arr = (struct uvc_descriptor_header *)&opts->uvc_color_matching; 2249 2250 ++target_hdr->linked; 2251 ret = 0; 2252 2253 unlock: 2254 mutex_unlock(&opts->lock); 2255 out: 2256 config_item_put(header); 2257 mutex_unlock(su_mutex); 2258 return ret; 2259 } 2260 2261 static void uvcg_streaming_class_drop_link(struct config_item *src, 2262 struct config_item *target) 2263 { 2264 struct config_item *streaming, *header; 2265 struct f_uvc_opts *opts; 2266 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 2267 struct uvc_descriptor_header ***class_array; 2268 struct uvcg_streaming_header *target_hdr; 2269 2270 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2271 2272 streaming = src->ci_parent->ci_parent; 2273 header = config_group_find_item(to_config_group(streaming), "header"); 2274 if (!header || target->ci_parent != header) 2275 goto out; 2276 2277 opts = to_f_uvc_opts(streaming->ci_parent); 2278 2279 mutex_lock(&opts->lock); 2280 2281 class_array = __uvcg_get_stream_class_arr(src, opts); 2282 if (!class_array || !*class_array) 2283 goto unlock; 2284 2285 if (opts->refcnt) 2286 goto unlock; 2287 2288 target_hdr = to_uvcg_streaming_header(target); 2289 --target_hdr->linked; 2290 kfree(**class_array); 2291 kfree(*class_array); 2292 *class_array = NULL; 2293 2294 unlock: 2295 mutex_unlock(&opts->lock); 2296 out: 2297 config_item_put(header); 2298 mutex_unlock(su_mutex); 2299 } 2300 2301 static struct configfs_item_operations uvcg_streaming_class_item_ops = { 2302 .release = uvcg_config_item_release, 2303 .allow_link = uvcg_streaming_class_allow_link, 2304 .drop_link = uvcg_streaming_class_drop_link, 2305 }; 2306 2307 static const struct config_item_type uvcg_streaming_class_type = { 2308 .ct_item_ops = &uvcg_streaming_class_item_ops, 2309 .ct_owner = THIS_MODULE, 2310 }; 2311 2312 /* ----------------------------------------------------------------------------- 2313 * streaming/class 2314 */ 2315 2316 static int uvcg_streaming_class_create_children(struct config_group *parent) 2317 { 2318 static const char * const names[] = { "fs", "hs", "ss" }; 2319 unsigned int i; 2320 2321 for (i = 0; i < ARRAY_SIZE(names); ++i) { 2322 struct uvcg_streaming_class_group *group; 2323 2324 group = kzalloc(sizeof(*group), GFP_KERNEL); 2325 if (!group) 2326 return -ENOMEM; 2327 2328 group->name = names[i]; 2329 2330 config_group_init_type_name(&group->group, group->name, 2331 &uvcg_streaming_class_type); 2332 configfs_add_default_group(&group->group, parent); 2333 } 2334 2335 return 0; 2336 } 2337 2338 static const struct uvcg_config_group_type uvcg_streaming_class_grp_type = { 2339 .type = { 2340 .ct_item_ops = &uvcg_config_item_ops, 2341 .ct_owner = THIS_MODULE, 2342 }, 2343 .name = "class", 2344 .create_children = uvcg_streaming_class_create_children, 2345 }; 2346 2347 /* ----------------------------------------------------------------------------- 2348 * streaming 2349 */ 2350 2351 static ssize_t uvcg_default_streaming_b_interface_number_show( 2352 struct config_item *item, char *page) 2353 { 2354 struct config_group *group = to_config_group(item); 2355 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 2356 struct config_item *opts_item; 2357 struct f_uvc_opts *opts; 2358 int result = 0; 2359 2360 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2361 2362 opts_item = item->ci_parent; 2363 opts = to_f_uvc_opts(opts_item); 2364 2365 mutex_lock(&opts->lock); 2366 result += sprintf(page, "%u\n", opts->streaming_interface); 2367 mutex_unlock(&opts->lock); 2368 2369 mutex_unlock(su_mutex); 2370 2371 return result; 2372 } 2373 2374 UVC_ATTR_RO(uvcg_default_streaming_, b_interface_number, bInterfaceNumber); 2375 2376 static struct configfs_attribute *uvcg_default_streaming_attrs[] = { 2377 &uvcg_default_streaming_attr_b_interface_number, 2378 NULL, 2379 }; 2380 2381 static const struct uvcg_config_group_type uvcg_streaming_grp_type = { 2382 .type = { 2383 .ct_item_ops = &uvcg_config_item_ops, 2384 .ct_attrs = uvcg_default_streaming_attrs, 2385 .ct_owner = THIS_MODULE, 2386 }, 2387 .name = "streaming", 2388 .children = (const struct uvcg_config_group_type*[]) { 2389 &uvcg_streaming_header_grp_type, 2390 &uvcg_uncompressed_grp_type, 2391 &uvcg_mjpeg_grp_type, 2392 &uvcg_color_matching_grp_type, 2393 &uvcg_streaming_class_grp_type, 2394 NULL, 2395 }, 2396 }; 2397 2398 /* ----------------------------------------------------------------------------- 2399 * UVC function 2400 */ 2401 2402 static void uvc_func_item_release(struct config_item *item) 2403 { 2404 struct f_uvc_opts *opts = to_f_uvc_opts(item); 2405 2406 uvcg_config_remove_children(to_config_group(item)); 2407 usb_put_function_instance(&opts->func_inst); 2408 } 2409 2410 static struct configfs_item_operations uvc_func_item_ops = { 2411 .release = uvc_func_item_release, 2412 }; 2413 2414 #define UVCG_OPTS_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit) \ 2415 static ssize_t f_uvc_opts_##cname##_show( \ 2416 struct config_item *item, char *page) \ 2417 { \ 2418 struct f_uvc_opts *opts = to_f_uvc_opts(item); \ 2419 int result; \ 2420 \ 2421 mutex_lock(&opts->lock); \ 2422 result = sprintf(page, "%d\n", conv(opts->cname)); \ 2423 mutex_unlock(&opts->lock); \ 2424 \ 2425 return result; \ 2426 } \ 2427 \ 2428 static ssize_t \ 2429 f_uvc_opts_##cname##_store(struct config_item *item, \ 2430 const char *page, size_t len) \ 2431 { \ 2432 struct f_uvc_opts *opts = to_f_uvc_opts(item); \ 2433 int ret; \ 2434 uxx num; \ 2435 \ 2436 mutex_lock(&opts->lock); \ 2437 if (opts->refcnt) { \ 2438 ret = -EBUSY; \ 2439 goto end; \ 2440 } \ 2441 \ 2442 ret = str2u(page, 0, &num); \ 2443 if (ret) \ 2444 goto end; \ 2445 \ 2446 if (num > limit) { \ 2447 ret = -EINVAL; \ 2448 goto end; \ 2449 } \ 2450 opts->cname = vnoc(num); \ 2451 ret = len; \ 2452 end: \ 2453 mutex_unlock(&opts->lock); \ 2454 return ret; \ 2455 } \ 2456 \ 2457 UVC_ATTR(f_uvc_opts_, cname, cname) 2458 2459 #define identity_conv(x) (x) 2460 2461 UVCG_OPTS_ATTR(streaming_interval, streaming_interval, identity_conv, 2462 kstrtou8, u8, identity_conv, 16); 2463 UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, le16_to_cpu, 2464 kstrtou16, u16, le16_to_cpu, 3072); 2465 UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, identity_conv, 2466 kstrtou8, u8, identity_conv, 15); 2467 2468 #undef identity_conv 2469 2470 #undef UVCG_OPTS_ATTR 2471 2472 static struct configfs_attribute *uvc_attrs[] = { 2473 &f_uvc_opts_attr_streaming_interval, 2474 &f_uvc_opts_attr_streaming_maxpacket, 2475 &f_uvc_opts_attr_streaming_maxburst, 2476 NULL, 2477 }; 2478 2479 static const struct uvcg_config_group_type uvc_func_type = { 2480 .type = { 2481 .ct_item_ops = &uvc_func_item_ops, 2482 .ct_attrs = uvc_attrs, 2483 .ct_owner = THIS_MODULE, 2484 }, 2485 .name = "", 2486 .children = (const struct uvcg_config_group_type*[]) { 2487 &uvcg_control_grp_type, 2488 &uvcg_streaming_grp_type, 2489 NULL, 2490 }, 2491 }; 2492 2493 int uvcg_attach_configfs(struct f_uvc_opts *opts) 2494 { 2495 int ret; 2496 2497 config_group_init_type_name(&opts->func_inst.group, uvc_func_type.name, 2498 &uvc_func_type.type); 2499 2500 ret = uvcg_config_create_children(&opts->func_inst.group, 2501 &uvc_func_type); 2502 if (ret < 0) 2503 config_group_put(&opts->func_inst.group); 2504 2505 return ret; 2506 } 2507