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 ++target_fmt->linked; 932 933 out: 934 mutex_unlock(&opts->lock); 935 mutex_unlock(su_mutex); 936 return ret; 937 } 938 939 static void uvcg_streaming_header_drop_link(struct config_item *src, 940 struct config_item *target) 941 { 942 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 943 struct config_item *opts_item; 944 struct f_uvc_opts *opts; 945 struct uvcg_streaming_header *src_hdr; 946 struct uvcg_format *target_fmt = NULL; 947 struct uvcg_format_ptr *format_ptr, *tmp; 948 949 src_hdr = to_uvcg_streaming_header(src); 950 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 951 952 opts_item = src->ci_parent->ci_parent->ci_parent; 953 opts = to_f_uvc_opts(opts_item); 954 955 mutex_lock(&opts->lock); 956 target_fmt = container_of(to_config_group(target), struct uvcg_format, 957 group); 958 if (!target_fmt) 959 goto out; 960 961 list_for_each_entry_safe(format_ptr, tmp, &src_hdr->formats, entry) 962 if (format_ptr->fmt == target_fmt) { 963 list_del(&format_ptr->entry); 964 kfree(format_ptr); 965 --src_hdr->num_fmt; 966 break; 967 } 968 969 --target_fmt->linked; 970 971 out: 972 mutex_unlock(&opts->lock); 973 mutex_unlock(su_mutex); 974 } 975 976 static struct configfs_item_operations uvcg_streaming_header_item_ops = { 977 .release = uvcg_config_item_release, 978 .allow_link = uvcg_streaming_header_allow_link, 979 .drop_link = uvcg_streaming_header_drop_link, 980 }; 981 982 #define UVCG_STREAMING_HEADER_ATTR(cname, aname, conv) \ 983 static ssize_t uvcg_streaming_header_##cname##_show( \ 984 struct config_item *item, char *page) \ 985 { \ 986 struct uvcg_streaming_header *sh = to_uvcg_streaming_header(item); \ 987 struct f_uvc_opts *opts; \ 988 struct config_item *opts_item; \ 989 struct mutex *su_mutex = &sh->item.ci_group->cg_subsys->su_mutex;\ 990 int result; \ 991 \ 992 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 993 \ 994 opts_item = sh->item.ci_parent->ci_parent->ci_parent; \ 995 opts = to_f_uvc_opts(opts_item); \ 996 \ 997 mutex_lock(&opts->lock); \ 998 result = sprintf(page, "%d\n", conv(sh->desc.aname)); \ 999 mutex_unlock(&opts->lock); \ 1000 \ 1001 mutex_unlock(su_mutex); \ 1002 return result; \ 1003 } \ 1004 \ 1005 UVC_ATTR_RO(uvcg_streaming_header_, cname, aname) 1006 1007 #define identity_conv(x) (x) 1008 1009 UVCG_STREAMING_HEADER_ATTR(bm_info, bmInfo, identity_conv); 1010 UVCG_STREAMING_HEADER_ATTR(b_terminal_link, bTerminalLink, identity_conv); 1011 UVCG_STREAMING_HEADER_ATTR(b_still_capture_method, bStillCaptureMethod, 1012 identity_conv); 1013 UVCG_STREAMING_HEADER_ATTR(b_trigger_support, bTriggerSupport, identity_conv); 1014 UVCG_STREAMING_HEADER_ATTR(b_trigger_usage, bTriggerUsage, identity_conv); 1015 1016 #undef identity_conv 1017 1018 #undef UVCG_STREAMING_HEADER_ATTR 1019 1020 static struct configfs_attribute *uvcg_streaming_header_attrs[] = { 1021 &uvcg_streaming_header_attr_bm_info, 1022 &uvcg_streaming_header_attr_b_terminal_link, 1023 &uvcg_streaming_header_attr_b_still_capture_method, 1024 &uvcg_streaming_header_attr_b_trigger_support, 1025 &uvcg_streaming_header_attr_b_trigger_usage, 1026 NULL, 1027 }; 1028 1029 static const struct config_item_type uvcg_streaming_header_type = { 1030 .ct_item_ops = &uvcg_streaming_header_item_ops, 1031 .ct_attrs = uvcg_streaming_header_attrs, 1032 .ct_owner = THIS_MODULE, 1033 }; 1034 1035 static struct config_item 1036 *uvcg_streaming_header_make(struct config_group *group, const char *name) 1037 { 1038 struct uvcg_streaming_header *h; 1039 1040 h = kzalloc(sizeof(*h), GFP_KERNEL); 1041 if (!h) 1042 return ERR_PTR(-ENOMEM); 1043 1044 INIT_LIST_HEAD(&h->formats); 1045 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 1046 h->desc.bDescriptorSubType = UVC_VS_INPUT_HEADER; 1047 h->desc.bTerminalLink = 3; 1048 h->desc.bControlSize = UVCG_STREAMING_CONTROL_SIZE; 1049 1050 config_item_init_type_name(&h->item, name, &uvcg_streaming_header_type); 1051 1052 return &h->item; 1053 } 1054 1055 static struct configfs_group_operations uvcg_streaming_header_grp_ops = { 1056 .make_item = uvcg_streaming_header_make, 1057 }; 1058 1059 static const struct uvcg_config_group_type uvcg_streaming_header_grp_type = { 1060 .type = { 1061 .ct_item_ops = &uvcg_config_item_ops, 1062 .ct_group_ops = &uvcg_streaming_header_grp_ops, 1063 .ct_owner = THIS_MODULE, 1064 }, 1065 .name = "header", 1066 }; 1067 1068 /* ----------------------------------------------------------------------------- 1069 * streaming/<mode>/<format>/<NAME> 1070 */ 1071 1072 struct uvcg_frame { 1073 struct config_item item; 1074 enum uvcg_format_type fmt_type; 1075 struct { 1076 u8 b_length; 1077 u8 b_descriptor_type; 1078 u8 b_descriptor_subtype; 1079 u8 b_frame_index; 1080 u8 bm_capabilities; 1081 u16 w_width; 1082 u16 w_height; 1083 u32 dw_min_bit_rate; 1084 u32 dw_max_bit_rate; 1085 u32 dw_max_video_frame_buffer_size; 1086 u32 dw_default_frame_interval; 1087 u8 b_frame_interval_type; 1088 } __attribute__((packed)) frame; 1089 u32 *dw_frame_interval; 1090 }; 1091 1092 static struct uvcg_frame *to_uvcg_frame(struct config_item *item) 1093 { 1094 return container_of(item, struct uvcg_frame, item); 1095 } 1096 1097 #define UVCG_FRAME_ATTR(cname, aname, to_cpu_endian, to_little_endian, bits) \ 1098 static ssize_t uvcg_frame_##cname##_show(struct config_item *item, char *page)\ 1099 { \ 1100 struct uvcg_frame *f = to_uvcg_frame(item); \ 1101 struct f_uvc_opts *opts; \ 1102 struct config_item *opts_item; \ 1103 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ 1104 int result; \ 1105 \ 1106 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1107 \ 1108 opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ 1109 opts = to_f_uvc_opts(opts_item); \ 1110 \ 1111 mutex_lock(&opts->lock); \ 1112 result = sprintf(page, "%d\n", to_cpu_endian(f->frame.cname)); \ 1113 mutex_unlock(&opts->lock); \ 1114 \ 1115 mutex_unlock(su_mutex); \ 1116 return result; \ 1117 } \ 1118 \ 1119 static ssize_t uvcg_frame_##cname##_store(struct config_item *item, \ 1120 const char *page, size_t len)\ 1121 { \ 1122 struct uvcg_frame *f = to_uvcg_frame(item); \ 1123 struct f_uvc_opts *opts; \ 1124 struct config_item *opts_item; \ 1125 struct uvcg_format *fmt; \ 1126 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\ 1127 int ret; \ 1128 u##bits num; \ 1129 \ 1130 ret = kstrtou##bits(page, 0, &num); \ 1131 if (ret) \ 1132 return ret; \ 1133 \ 1134 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1135 \ 1136 opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent; \ 1137 opts = to_f_uvc_opts(opts_item); \ 1138 fmt = to_uvcg_format(f->item.ci_parent); \ 1139 \ 1140 mutex_lock(&opts->lock); \ 1141 if (fmt->linked || opts->refcnt) { \ 1142 ret = -EBUSY; \ 1143 goto end; \ 1144 } \ 1145 \ 1146 f->frame.cname = to_little_endian(num); \ 1147 ret = len; \ 1148 end: \ 1149 mutex_unlock(&opts->lock); \ 1150 mutex_unlock(su_mutex); \ 1151 return ret; \ 1152 } \ 1153 \ 1154 UVC_ATTR(uvcg_frame_, cname, aname); 1155 1156 static ssize_t uvcg_frame_b_frame_index_show(struct config_item *item, 1157 char *page) 1158 { 1159 struct uvcg_frame *f = to_uvcg_frame(item); 1160 struct uvcg_format *fmt; 1161 struct f_uvc_opts *opts; 1162 struct config_item *opts_item; 1163 struct config_item *fmt_item; 1164 struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex; 1165 int result; 1166 1167 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1168 1169 fmt_item = f->item.ci_parent; 1170 fmt = to_uvcg_format(fmt_item); 1171 1172 if (!fmt->linked) { 1173 result = -EBUSY; 1174 goto out; 1175 } 1176 1177 opts_item = fmt_item->ci_parent->ci_parent->ci_parent; 1178 opts = to_f_uvc_opts(opts_item); 1179 1180 mutex_lock(&opts->lock); 1181 result = sprintf(page, "%d\n", f->frame.b_frame_index); 1182 mutex_unlock(&opts->lock); 1183 1184 out: 1185 mutex_unlock(su_mutex); 1186 return result; 1187 } 1188 1189 UVC_ATTR_RO(uvcg_frame_, b_frame_index, bFrameIndex); 1190 1191 #define noop_conversion(x) (x) 1192 1193 UVCG_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion, 1194 noop_conversion, 8); 1195 UVCG_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16); 1196 UVCG_FRAME_ATTR(w_height, wHeight, le16_to_cpu, cpu_to_le16, 16); 1197 UVCG_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, le32_to_cpu, cpu_to_le32, 32); 1198 UVCG_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, le32_to_cpu, cpu_to_le32, 32); 1199 UVCG_FRAME_ATTR(dw_max_video_frame_buffer_size, dwMaxVideoFrameBufferSize, 1200 le32_to_cpu, cpu_to_le32, 32); 1201 UVCG_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval, 1202 le32_to_cpu, cpu_to_le32, 32); 1203 1204 #undef noop_conversion 1205 1206 #undef UVCG_FRAME_ATTR 1207 1208 static ssize_t uvcg_frame_dw_frame_interval_show(struct config_item *item, 1209 char *page) 1210 { 1211 struct uvcg_frame *frm = to_uvcg_frame(item); 1212 struct f_uvc_opts *opts; 1213 struct config_item *opts_item; 1214 struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex; 1215 int result, i; 1216 char *pg = page; 1217 1218 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1219 1220 opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent; 1221 opts = to_f_uvc_opts(opts_item); 1222 1223 mutex_lock(&opts->lock); 1224 for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) { 1225 result += sprintf(pg, "%d\n", 1226 le32_to_cpu(frm->dw_frame_interval[i])); 1227 pg = page + result; 1228 } 1229 mutex_unlock(&opts->lock); 1230 1231 mutex_unlock(su_mutex); 1232 return result; 1233 } 1234 1235 static inline int __uvcg_count_frm_intrv(char *buf, void *priv) 1236 { 1237 ++*((int *)priv); 1238 return 0; 1239 } 1240 1241 static inline int __uvcg_fill_frm_intrv(char *buf, void *priv) 1242 { 1243 u32 num, **interv; 1244 int ret; 1245 1246 ret = kstrtou32(buf, 0, &num); 1247 if (ret) 1248 return ret; 1249 1250 interv = priv; 1251 **interv = cpu_to_le32(num); 1252 ++*interv; 1253 1254 return 0; 1255 } 1256 1257 static int __uvcg_iter_frm_intrv(const char *page, size_t len, 1258 int (*fun)(char *, void *), void *priv) 1259 { 1260 /* sign, base 2 representation, newline, terminator */ 1261 char buf[1 + sizeof(u32) * 8 + 1 + 1]; 1262 const char *pg = page; 1263 int i, ret; 1264 1265 if (!fun) 1266 return -EINVAL; 1267 1268 while (pg - page < len) { 1269 i = 0; 1270 while (i < sizeof(buf) && (pg - page < len) && 1271 *pg != '\0' && *pg != '\n') 1272 buf[i++] = *pg++; 1273 if (i == sizeof(buf)) 1274 return -EINVAL; 1275 while ((pg - page < len) && (*pg == '\0' || *pg == '\n')) 1276 ++pg; 1277 buf[i] = '\0'; 1278 ret = fun(buf, priv); 1279 if (ret) 1280 return ret; 1281 } 1282 1283 return 0; 1284 } 1285 1286 static ssize_t uvcg_frame_dw_frame_interval_store(struct config_item *item, 1287 const char *page, size_t len) 1288 { 1289 struct uvcg_frame *ch = to_uvcg_frame(item); 1290 struct f_uvc_opts *opts; 1291 struct config_item *opts_item; 1292 struct uvcg_format *fmt; 1293 struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex; 1294 int ret = 0, n = 0; 1295 u32 *frm_intrv, *tmp; 1296 1297 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1298 1299 opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent; 1300 opts = to_f_uvc_opts(opts_item); 1301 fmt = to_uvcg_format(ch->item.ci_parent); 1302 1303 mutex_lock(&opts->lock); 1304 if (fmt->linked || opts->refcnt) { 1305 ret = -EBUSY; 1306 goto end; 1307 } 1308 1309 ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n); 1310 if (ret) 1311 goto end; 1312 1313 tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL); 1314 if (!frm_intrv) { 1315 ret = -ENOMEM; 1316 goto end; 1317 } 1318 1319 ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp); 1320 if (ret) { 1321 kfree(frm_intrv); 1322 goto end; 1323 } 1324 1325 kfree(ch->dw_frame_interval); 1326 ch->dw_frame_interval = frm_intrv; 1327 ch->frame.b_frame_interval_type = n; 1328 ret = len; 1329 1330 end: 1331 mutex_unlock(&opts->lock); 1332 mutex_unlock(su_mutex); 1333 return ret; 1334 } 1335 1336 UVC_ATTR(uvcg_frame_, dw_frame_interval, dwFrameInterval); 1337 1338 static struct configfs_attribute *uvcg_frame_attrs[] = { 1339 &uvcg_frame_attr_b_frame_index, 1340 &uvcg_frame_attr_bm_capabilities, 1341 &uvcg_frame_attr_w_width, 1342 &uvcg_frame_attr_w_height, 1343 &uvcg_frame_attr_dw_min_bit_rate, 1344 &uvcg_frame_attr_dw_max_bit_rate, 1345 &uvcg_frame_attr_dw_max_video_frame_buffer_size, 1346 &uvcg_frame_attr_dw_default_frame_interval, 1347 &uvcg_frame_attr_dw_frame_interval, 1348 NULL, 1349 }; 1350 1351 static const struct config_item_type uvcg_frame_type = { 1352 .ct_item_ops = &uvcg_config_item_ops, 1353 .ct_attrs = uvcg_frame_attrs, 1354 .ct_owner = THIS_MODULE, 1355 }; 1356 1357 static struct config_item *uvcg_frame_make(struct config_group *group, 1358 const char *name) 1359 { 1360 struct uvcg_frame *h; 1361 struct uvcg_format *fmt; 1362 struct f_uvc_opts *opts; 1363 struct config_item *opts_item; 1364 1365 h = kzalloc(sizeof(*h), GFP_KERNEL); 1366 if (!h) 1367 return ERR_PTR(-ENOMEM); 1368 1369 h->frame.b_descriptor_type = USB_DT_CS_INTERFACE; 1370 h->frame.b_frame_index = 1; 1371 h->frame.w_width = cpu_to_le16(640); 1372 h->frame.w_height = cpu_to_le16(360); 1373 h->frame.dw_min_bit_rate = cpu_to_le32(18432000); 1374 h->frame.dw_max_bit_rate = cpu_to_le32(55296000); 1375 h->frame.dw_max_video_frame_buffer_size = cpu_to_le32(460800); 1376 h->frame.dw_default_frame_interval = cpu_to_le32(666666); 1377 1378 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 1379 opts = to_f_uvc_opts(opts_item); 1380 1381 mutex_lock(&opts->lock); 1382 fmt = to_uvcg_format(&group->cg_item); 1383 if (fmt->type == UVCG_UNCOMPRESSED) { 1384 h->frame.b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED; 1385 h->fmt_type = UVCG_UNCOMPRESSED; 1386 } else if (fmt->type == UVCG_MJPEG) { 1387 h->frame.b_descriptor_subtype = UVC_VS_FRAME_MJPEG; 1388 h->fmt_type = UVCG_MJPEG; 1389 } else { 1390 mutex_unlock(&opts->lock); 1391 kfree(h); 1392 return ERR_PTR(-EINVAL); 1393 } 1394 ++fmt->num_frames; 1395 mutex_unlock(&opts->lock); 1396 1397 config_item_init_type_name(&h->item, name, &uvcg_frame_type); 1398 1399 return &h->item; 1400 } 1401 1402 static void uvcg_frame_drop(struct config_group *group, struct config_item *item) 1403 { 1404 struct uvcg_format *fmt; 1405 struct f_uvc_opts *opts; 1406 struct config_item *opts_item; 1407 1408 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; 1409 opts = to_f_uvc_opts(opts_item); 1410 1411 mutex_lock(&opts->lock); 1412 fmt = to_uvcg_format(&group->cg_item); 1413 --fmt->num_frames; 1414 mutex_unlock(&opts->lock); 1415 1416 config_item_put(item); 1417 } 1418 1419 static void uvcg_format_set_indices(struct config_group *fmt) 1420 { 1421 struct config_item *ci; 1422 unsigned int i = 1; 1423 1424 list_for_each_entry(ci, &fmt->cg_children, ci_entry) { 1425 struct uvcg_frame *frm; 1426 1427 if (ci->ci_type != &uvcg_frame_type) 1428 continue; 1429 1430 frm = to_uvcg_frame(ci); 1431 frm->frame.b_frame_index = i++; 1432 } 1433 } 1434 1435 /* ----------------------------------------------------------------------------- 1436 * streaming/uncompressed/<NAME> 1437 */ 1438 1439 struct uvcg_uncompressed { 1440 struct uvcg_format fmt; 1441 struct uvc_format_uncompressed desc; 1442 }; 1443 1444 static struct uvcg_uncompressed *to_uvcg_uncompressed(struct config_item *item) 1445 { 1446 return container_of( 1447 container_of(to_config_group(item), struct uvcg_format, group), 1448 struct uvcg_uncompressed, fmt); 1449 } 1450 1451 static struct configfs_group_operations uvcg_uncompressed_group_ops = { 1452 .make_item = uvcg_frame_make, 1453 .drop_item = uvcg_frame_drop, 1454 }; 1455 1456 static ssize_t uvcg_uncompressed_guid_format_show(struct config_item *item, 1457 char *page) 1458 { 1459 struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); 1460 struct f_uvc_opts *opts; 1461 struct config_item *opts_item; 1462 struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; 1463 1464 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1465 1466 opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; 1467 opts = to_f_uvc_opts(opts_item); 1468 1469 mutex_lock(&opts->lock); 1470 memcpy(page, ch->desc.guidFormat, sizeof(ch->desc.guidFormat)); 1471 mutex_unlock(&opts->lock); 1472 1473 mutex_unlock(su_mutex); 1474 1475 return sizeof(ch->desc.guidFormat); 1476 } 1477 1478 static ssize_t uvcg_uncompressed_guid_format_store(struct config_item *item, 1479 const char *page, size_t len) 1480 { 1481 struct uvcg_uncompressed *ch = to_uvcg_uncompressed(item); 1482 struct f_uvc_opts *opts; 1483 struct config_item *opts_item; 1484 struct mutex *su_mutex = &ch->fmt.group.cg_subsys->su_mutex; 1485 int ret; 1486 1487 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 1488 1489 opts_item = ch->fmt.group.cg_item.ci_parent->ci_parent->ci_parent; 1490 opts = to_f_uvc_opts(opts_item); 1491 1492 mutex_lock(&opts->lock); 1493 if (ch->fmt.linked || opts->refcnt) { 1494 ret = -EBUSY; 1495 goto end; 1496 } 1497 1498 memcpy(ch->desc.guidFormat, page, 1499 min(sizeof(ch->desc.guidFormat), len)); 1500 ret = sizeof(ch->desc.guidFormat); 1501 1502 end: 1503 mutex_unlock(&opts->lock); 1504 mutex_unlock(su_mutex); 1505 return ret; 1506 } 1507 1508 UVC_ATTR(uvcg_uncompressed_, guid_format, guidFormat); 1509 1510 #define UVCG_UNCOMPRESSED_ATTR_RO(cname, aname, conv) \ 1511 static ssize_t uvcg_uncompressed_##cname##_show( \ 1512 struct config_item *item, char *page) \ 1513 { \ 1514 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ 1515 struct f_uvc_opts *opts; \ 1516 struct config_item *opts_item; \ 1517 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1518 int result; \ 1519 \ 1520 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1521 \ 1522 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1523 opts = to_f_uvc_opts(opts_item); \ 1524 \ 1525 mutex_lock(&opts->lock); \ 1526 result = sprintf(page, "%d\n", conv(u->desc.aname)); \ 1527 mutex_unlock(&opts->lock); \ 1528 \ 1529 mutex_unlock(su_mutex); \ 1530 return result; \ 1531 } \ 1532 \ 1533 UVC_ATTR_RO(uvcg_uncompressed_, cname, aname); 1534 1535 #define UVCG_UNCOMPRESSED_ATTR(cname, aname, conv) \ 1536 static ssize_t uvcg_uncompressed_##cname##_show( \ 1537 struct config_item *item, char *page) \ 1538 { \ 1539 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ 1540 struct f_uvc_opts *opts; \ 1541 struct config_item *opts_item; \ 1542 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1543 int result; \ 1544 \ 1545 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1546 \ 1547 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1548 opts = to_f_uvc_opts(opts_item); \ 1549 \ 1550 mutex_lock(&opts->lock); \ 1551 result = sprintf(page, "%d\n", conv(u->desc.aname)); \ 1552 mutex_unlock(&opts->lock); \ 1553 \ 1554 mutex_unlock(su_mutex); \ 1555 return result; \ 1556 } \ 1557 \ 1558 static ssize_t \ 1559 uvcg_uncompressed_##cname##_store(struct config_item *item, \ 1560 const char *page, size_t len) \ 1561 { \ 1562 struct uvcg_uncompressed *u = to_uvcg_uncompressed(item); \ 1563 struct f_uvc_opts *opts; \ 1564 struct config_item *opts_item; \ 1565 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1566 int ret; \ 1567 u8 num; \ 1568 \ 1569 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1570 \ 1571 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1572 opts = to_f_uvc_opts(opts_item); \ 1573 \ 1574 mutex_lock(&opts->lock); \ 1575 if (u->fmt.linked || opts->refcnt) { \ 1576 ret = -EBUSY; \ 1577 goto end; \ 1578 } \ 1579 \ 1580 ret = kstrtou8(page, 0, &num); \ 1581 if (ret) \ 1582 goto end; \ 1583 \ 1584 if (num > 255) { \ 1585 ret = -EINVAL; \ 1586 goto end; \ 1587 } \ 1588 u->desc.aname = num; \ 1589 ret = len; \ 1590 end: \ 1591 mutex_unlock(&opts->lock); \ 1592 mutex_unlock(su_mutex); \ 1593 return ret; \ 1594 } \ 1595 \ 1596 UVC_ATTR(uvcg_uncompressed_, cname, aname); 1597 1598 #define identity_conv(x) (x) 1599 1600 UVCG_UNCOMPRESSED_ATTR_RO(b_format_index, bFormatIndex, identity_conv); 1601 UVCG_UNCOMPRESSED_ATTR(b_bits_per_pixel, bBitsPerPixel, identity_conv); 1602 UVCG_UNCOMPRESSED_ATTR(b_default_frame_index, bDefaultFrameIndex, 1603 identity_conv); 1604 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv); 1605 UVCG_UNCOMPRESSED_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv); 1606 UVCG_UNCOMPRESSED_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv); 1607 1608 #undef identity_conv 1609 1610 #undef UVCG_UNCOMPRESSED_ATTR 1611 #undef UVCG_UNCOMPRESSED_ATTR_RO 1612 1613 static inline ssize_t 1614 uvcg_uncompressed_bma_controls_show(struct config_item *item, char *page) 1615 { 1616 struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item); 1617 return uvcg_format_bma_controls_show(&unc->fmt, page); 1618 } 1619 1620 static inline ssize_t 1621 uvcg_uncompressed_bma_controls_store(struct config_item *item, 1622 const char *page, size_t len) 1623 { 1624 struct uvcg_uncompressed *unc = to_uvcg_uncompressed(item); 1625 return uvcg_format_bma_controls_store(&unc->fmt, page, len); 1626 } 1627 1628 UVC_ATTR(uvcg_uncompressed_, bma_controls, bmaControls); 1629 1630 static struct configfs_attribute *uvcg_uncompressed_attrs[] = { 1631 &uvcg_uncompressed_attr_b_format_index, 1632 &uvcg_uncompressed_attr_guid_format, 1633 &uvcg_uncompressed_attr_b_bits_per_pixel, 1634 &uvcg_uncompressed_attr_b_default_frame_index, 1635 &uvcg_uncompressed_attr_b_aspect_ratio_x, 1636 &uvcg_uncompressed_attr_b_aspect_ratio_y, 1637 &uvcg_uncompressed_attr_bm_interface_flags, 1638 &uvcg_uncompressed_attr_bma_controls, 1639 NULL, 1640 }; 1641 1642 static const struct config_item_type uvcg_uncompressed_type = { 1643 .ct_item_ops = &uvcg_config_item_ops, 1644 .ct_group_ops = &uvcg_uncompressed_group_ops, 1645 .ct_attrs = uvcg_uncompressed_attrs, 1646 .ct_owner = THIS_MODULE, 1647 }; 1648 1649 static struct config_group *uvcg_uncompressed_make(struct config_group *group, 1650 const char *name) 1651 { 1652 static char guid[] = { 1653 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, 1654 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 1655 }; 1656 struct uvcg_uncompressed *h; 1657 1658 h = kzalloc(sizeof(*h), GFP_KERNEL); 1659 if (!h) 1660 return ERR_PTR(-ENOMEM); 1661 1662 h->desc.bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE; 1663 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 1664 h->desc.bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED; 1665 memcpy(h->desc.guidFormat, guid, sizeof(guid)); 1666 h->desc.bBitsPerPixel = 16; 1667 h->desc.bDefaultFrameIndex = 1; 1668 h->desc.bAspectRatioX = 0; 1669 h->desc.bAspectRatioY = 0; 1670 h->desc.bmInterfaceFlags = 0; 1671 h->desc.bCopyProtect = 0; 1672 1673 h->fmt.type = UVCG_UNCOMPRESSED; 1674 config_group_init_type_name(&h->fmt.group, name, 1675 &uvcg_uncompressed_type); 1676 1677 return &h->fmt.group; 1678 } 1679 1680 static struct configfs_group_operations uvcg_uncompressed_grp_ops = { 1681 .make_group = uvcg_uncompressed_make, 1682 }; 1683 1684 static const struct uvcg_config_group_type uvcg_uncompressed_grp_type = { 1685 .type = { 1686 .ct_item_ops = &uvcg_config_item_ops, 1687 .ct_group_ops = &uvcg_uncompressed_grp_ops, 1688 .ct_owner = THIS_MODULE, 1689 }, 1690 .name = "uncompressed", 1691 }; 1692 1693 /* ----------------------------------------------------------------------------- 1694 * streaming/mjpeg/<NAME> 1695 */ 1696 1697 struct uvcg_mjpeg { 1698 struct uvcg_format fmt; 1699 struct uvc_format_mjpeg desc; 1700 }; 1701 1702 static struct uvcg_mjpeg *to_uvcg_mjpeg(struct config_item *item) 1703 { 1704 return container_of( 1705 container_of(to_config_group(item), struct uvcg_format, group), 1706 struct uvcg_mjpeg, fmt); 1707 } 1708 1709 static struct configfs_group_operations uvcg_mjpeg_group_ops = { 1710 .make_item = uvcg_frame_make, 1711 .drop_item = uvcg_frame_drop, 1712 }; 1713 1714 #define UVCG_MJPEG_ATTR_RO(cname, aname, conv) \ 1715 static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\ 1716 { \ 1717 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 1718 struct f_uvc_opts *opts; \ 1719 struct config_item *opts_item; \ 1720 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1721 int result; \ 1722 \ 1723 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1724 \ 1725 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1726 opts = to_f_uvc_opts(opts_item); \ 1727 \ 1728 mutex_lock(&opts->lock); \ 1729 result = sprintf(page, "%d\n", conv(u->desc.aname)); \ 1730 mutex_unlock(&opts->lock); \ 1731 \ 1732 mutex_unlock(su_mutex); \ 1733 return result; \ 1734 } \ 1735 \ 1736 UVC_ATTR_RO(uvcg_mjpeg_, cname, aname) 1737 1738 #define UVCG_MJPEG_ATTR(cname, aname, conv) \ 1739 static ssize_t uvcg_mjpeg_##cname##_show(struct config_item *item, char *page)\ 1740 { \ 1741 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 1742 struct f_uvc_opts *opts; \ 1743 struct config_item *opts_item; \ 1744 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1745 int result; \ 1746 \ 1747 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1748 \ 1749 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1750 opts = to_f_uvc_opts(opts_item); \ 1751 \ 1752 mutex_lock(&opts->lock); \ 1753 result = sprintf(page, "%d\n", conv(u->desc.aname)); \ 1754 mutex_unlock(&opts->lock); \ 1755 \ 1756 mutex_unlock(su_mutex); \ 1757 return result; \ 1758 } \ 1759 \ 1760 static ssize_t \ 1761 uvcg_mjpeg_##cname##_store(struct config_item *item, \ 1762 const char *page, size_t len) \ 1763 { \ 1764 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); \ 1765 struct f_uvc_opts *opts; \ 1766 struct config_item *opts_item; \ 1767 struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex; \ 1768 int ret; \ 1769 u8 num; \ 1770 \ 1771 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1772 \ 1773 opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\ 1774 opts = to_f_uvc_opts(opts_item); \ 1775 \ 1776 mutex_lock(&opts->lock); \ 1777 if (u->fmt.linked || opts->refcnt) { \ 1778 ret = -EBUSY; \ 1779 goto end; \ 1780 } \ 1781 \ 1782 ret = kstrtou8(page, 0, &num); \ 1783 if (ret) \ 1784 goto end; \ 1785 \ 1786 if (num > 255) { \ 1787 ret = -EINVAL; \ 1788 goto end; \ 1789 } \ 1790 u->desc.aname = num; \ 1791 ret = len; \ 1792 end: \ 1793 mutex_unlock(&opts->lock); \ 1794 mutex_unlock(su_mutex); \ 1795 return ret; \ 1796 } \ 1797 \ 1798 UVC_ATTR(uvcg_mjpeg_, cname, aname) 1799 1800 #define identity_conv(x) (x) 1801 1802 UVCG_MJPEG_ATTR_RO(b_format_index, bFormatIndex, identity_conv); 1803 UVCG_MJPEG_ATTR(b_default_frame_index, bDefaultFrameIndex, 1804 identity_conv); 1805 UVCG_MJPEG_ATTR_RO(bm_flags, bmFlags, identity_conv); 1806 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv); 1807 UVCG_MJPEG_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv); 1808 UVCG_MJPEG_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv); 1809 1810 #undef identity_conv 1811 1812 #undef UVCG_MJPEG_ATTR 1813 #undef UVCG_MJPEG_ATTR_RO 1814 1815 static inline ssize_t 1816 uvcg_mjpeg_bma_controls_show(struct config_item *item, char *page) 1817 { 1818 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); 1819 return uvcg_format_bma_controls_show(&u->fmt, page); 1820 } 1821 1822 static inline ssize_t 1823 uvcg_mjpeg_bma_controls_store(struct config_item *item, 1824 const char *page, size_t len) 1825 { 1826 struct uvcg_mjpeg *u = to_uvcg_mjpeg(item); 1827 return uvcg_format_bma_controls_store(&u->fmt, page, len); 1828 } 1829 1830 UVC_ATTR(uvcg_mjpeg_, bma_controls, bmaControls); 1831 1832 static struct configfs_attribute *uvcg_mjpeg_attrs[] = { 1833 &uvcg_mjpeg_attr_b_format_index, 1834 &uvcg_mjpeg_attr_b_default_frame_index, 1835 &uvcg_mjpeg_attr_bm_flags, 1836 &uvcg_mjpeg_attr_b_aspect_ratio_x, 1837 &uvcg_mjpeg_attr_b_aspect_ratio_y, 1838 &uvcg_mjpeg_attr_bm_interface_flags, 1839 &uvcg_mjpeg_attr_bma_controls, 1840 NULL, 1841 }; 1842 1843 static const struct config_item_type uvcg_mjpeg_type = { 1844 .ct_item_ops = &uvcg_config_item_ops, 1845 .ct_group_ops = &uvcg_mjpeg_group_ops, 1846 .ct_attrs = uvcg_mjpeg_attrs, 1847 .ct_owner = THIS_MODULE, 1848 }; 1849 1850 static struct config_group *uvcg_mjpeg_make(struct config_group *group, 1851 const char *name) 1852 { 1853 struct uvcg_mjpeg *h; 1854 1855 h = kzalloc(sizeof(*h), GFP_KERNEL); 1856 if (!h) 1857 return ERR_PTR(-ENOMEM); 1858 1859 h->desc.bLength = UVC_DT_FORMAT_MJPEG_SIZE; 1860 h->desc.bDescriptorType = USB_DT_CS_INTERFACE; 1861 h->desc.bDescriptorSubType = UVC_VS_FORMAT_MJPEG; 1862 h->desc.bDefaultFrameIndex = 1; 1863 h->desc.bAspectRatioX = 0; 1864 h->desc.bAspectRatioY = 0; 1865 h->desc.bmInterfaceFlags = 0; 1866 h->desc.bCopyProtect = 0; 1867 1868 h->fmt.type = UVCG_MJPEG; 1869 config_group_init_type_name(&h->fmt.group, name, 1870 &uvcg_mjpeg_type); 1871 1872 return &h->fmt.group; 1873 } 1874 1875 static struct configfs_group_operations uvcg_mjpeg_grp_ops = { 1876 .make_group = uvcg_mjpeg_make, 1877 }; 1878 1879 static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = { 1880 .type = { 1881 .ct_item_ops = &uvcg_config_item_ops, 1882 .ct_group_ops = &uvcg_mjpeg_grp_ops, 1883 .ct_owner = THIS_MODULE, 1884 }, 1885 .name = "mjpeg", 1886 }; 1887 1888 /* ----------------------------------------------------------------------------- 1889 * streaming/color_matching/default 1890 */ 1891 1892 #define UVCG_DEFAULT_COLOR_MATCHING_ATTR(cname, aname, conv) \ 1893 static ssize_t uvcg_default_color_matching_##cname##_show( \ 1894 struct config_item *item, char *page) \ 1895 { \ 1896 struct config_group *group = to_config_group(item); \ 1897 struct f_uvc_opts *opts; \ 1898 struct config_item *opts_item; \ 1899 struct mutex *su_mutex = &group->cg_subsys->su_mutex; \ 1900 struct uvc_color_matching_descriptor *cd; \ 1901 int result; \ 1902 \ 1903 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ \ 1904 \ 1905 opts_item = group->cg_item.ci_parent->ci_parent->ci_parent; \ 1906 opts = to_f_uvc_opts(opts_item); \ 1907 cd = &opts->uvc_color_matching; \ 1908 \ 1909 mutex_lock(&opts->lock); \ 1910 result = sprintf(page, "%d\n", conv(cd->aname)); \ 1911 mutex_unlock(&opts->lock); \ 1912 \ 1913 mutex_unlock(su_mutex); \ 1914 return result; \ 1915 } \ 1916 \ 1917 UVC_ATTR_RO(uvcg_default_color_matching_, cname, aname) 1918 1919 #define identity_conv(x) (x) 1920 1921 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_color_primaries, bColorPrimaries, 1922 identity_conv); 1923 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_transfer_characteristics, 1924 bTransferCharacteristics, identity_conv); 1925 UVCG_DEFAULT_COLOR_MATCHING_ATTR(b_matrix_coefficients, bMatrixCoefficients, 1926 identity_conv); 1927 1928 #undef identity_conv 1929 1930 #undef UVCG_DEFAULT_COLOR_MATCHING_ATTR 1931 1932 static struct configfs_attribute *uvcg_default_color_matching_attrs[] = { 1933 &uvcg_default_color_matching_attr_b_color_primaries, 1934 &uvcg_default_color_matching_attr_b_transfer_characteristics, 1935 &uvcg_default_color_matching_attr_b_matrix_coefficients, 1936 NULL, 1937 }; 1938 1939 static const struct uvcg_config_group_type uvcg_default_color_matching_type = { 1940 .type = { 1941 .ct_item_ops = &uvcg_config_item_ops, 1942 .ct_attrs = uvcg_default_color_matching_attrs, 1943 .ct_owner = THIS_MODULE, 1944 }, 1945 .name = "default", 1946 }; 1947 1948 /* ----------------------------------------------------------------------------- 1949 * streaming/color_matching 1950 */ 1951 1952 static const struct uvcg_config_group_type uvcg_color_matching_grp_type = { 1953 .type = { 1954 .ct_item_ops = &uvcg_config_item_ops, 1955 .ct_owner = THIS_MODULE, 1956 }, 1957 .name = "color_matching", 1958 .children = (const struct uvcg_config_group_type*[]) { 1959 &uvcg_default_color_matching_type, 1960 NULL, 1961 }, 1962 }; 1963 1964 /* ----------------------------------------------------------------------------- 1965 * streaming/class/{fs|hs|ss} 1966 */ 1967 1968 struct uvcg_streaming_class_group { 1969 struct config_group group; 1970 const char *name; 1971 }; 1972 1973 static inline struct uvc_descriptor_header 1974 ***__uvcg_get_stream_class_arr(struct config_item *i, struct f_uvc_opts *o) 1975 { 1976 struct uvcg_streaming_class_group *group = 1977 container_of(i, struct uvcg_streaming_class_group, 1978 group.cg_item); 1979 1980 if (!strcmp(group->name, "fs")) 1981 return &o->uvc_fs_streaming_cls; 1982 1983 if (!strcmp(group->name, "hs")) 1984 return &o->uvc_hs_streaming_cls; 1985 1986 if (!strcmp(group->name, "ss")) 1987 return &o->uvc_ss_streaming_cls; 1988 1989 return NULL; 1990 } 1991 1992 enum uvcg_strm_type { 1993 UVCG_HEADER = 0, 1994 UVCG_FORMAT, 1995 UVCG_FRAME 1996 }; 1997 1998 /* 1999 * Iterate over a hierarchy of streaming descriptors' config items. 2000 * The items are created by the user with configfs. 2001 * 2002 * It "processes" the header pointed to by @priv1, then for each format 2003 * that follows the header "processes" the format itself and then for 2004 * each frame inside a format "processes" the frame. 2005 * 2006 * As a "processing" function the @fun is used. 2007 * 2008 * __uvcg_iter_strm_cls() is used in two context: first, to calculate 2009 * the amount of memory needed for an array of streaming descriptors 2010 * and second, to actually fill the array. 2011 * 2012 * @h: streaming header pointer 2013 * @priv2: an "inout" parameter (the caller might want to see the changes to it) 2014 * @priv3: an "inout" parameter (the caller might want to see the changes to it) 2015 * @fun: callback function for processing each level of the hierarchy 2016 */ 2017 static int __uvcg_iter_strm_cls(struct uvcg_streaming_header *h, 2018 void *priv2, void *priv3, 2019 int (*fun)(void *, void *, void *, int, enum uvcg_strm_type type)) 2020 { 2021 struct uvcg_format_ptr *f; 2022 struct config_group *grp; 2023 struct config_item *item; 2024 struct uvcg_frame *frm; 2025 int ret, i, j; 2026 2027 if (!fun) 2028 return -EINVAL; 2029 2030 i = j = 0; 2031 ret = fun(h, priv2, priv3, 0, UVCG_HEADER); 2032 if (ret) 2033 return ret; 2034 list_for_each_entry(f, &h->formats, entry) { 2035 ret = fun(f->fmt, priv2, priv3, i++, UVCG_FORMAT); 2036 if (ret) 2037 return ret; 2038 grp = &f->fmt->group; 2039 list_for_each_entry(item, &grp->cg_children, ci_entry) { 2040 frm = to_uvcg_frame(item); 2041 ret = fun(frm, priv2, priv3, j++, UVCG_FRAME); 2042 if (ret) 2043 return ret; 2044 } 2045 } 2046 2047 return ret; 2048 } 2049 2050 /* 2051 * Count how many bytes are needed for an array of streaming descriptors. 2052 * 2053 * @priv1: pointer to a header, format or frame 2054 * @priv2: inout parameter, accumulated size of the array 2055 * @priv3: inout parameter, accumulated number of the array elements 2056 * @n: unused, this function's prototype must match @fun in __uvcg_iter_strm_cls 2057 */ 2058 static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n, 2059 enum uvcg_strm_type type) 2060 { 2061 size_t *size = priv2; 2062 size_t *count = priv3; 2063 2064 switch (type) { 2065 case UVCG_HEADER: { 2066 struct uvcg_streaming_header *h = priv1; 2067 2068 *size += sizeof(h->desc); 2069 /* bmaControls */ 2070 *size += h->num_fmt * UVCG_STREAMING_CONTROL_SIZE; 2071 } 2072 break; 2073 case UVCG_FORMAT: { 2074 struct uvcg_format *fmt = priv1; 2075 2076 if (fmt->type == UVCG_UNCOMPRESSED) { 2077 struct uvcg_uncompressed *u = 2078 container_of(fmt, struct uvcg_uncompressed, 2079 fmt); 2080 2081 *size += sizeof(u->desc); 2082 } else if (fmt->type == UVCG_MJPEG) { 2083 struct uvcg_mjpeg *m = 2084 container_of(fmt, struct uvcg_mjpeg, fmt); 2085 2086 *size += sizeof(m->desc); 2087 } else { 2088 return -EINVAL; 2089 } 2090 } 2091 break; 2092 case UVCG_FRAME: { 2093 struct uvcg_frame *frm = priv1; 2094 int sz = sizeof(frm->dw_frame_interval); 2095 2096 *size += sizeof(frm->frame); 2097 *size += frm->frame.b_frame_interval_type * sz; 2098 } 2099 break; 2100 } 2101 2102 ++*count; 2103 2104 return 0; 2105 } 2106 2107 /* 2108 * Fill an array of streaming descriptors. 2109 * 2110 * @priv1: pointer to a header, format or frame 2111 * @priv2: inout parameter, pointer into a block of memory 2112 * @priv3: inout parameter, pointer to a 2-dimensional array 2113 */ 2114 static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n, 2115 enum uvcg_strm_type type) 2116 { 2117 void **dest = priv2; 2118 struct uvc_descriptor_header ***array = priv3; 2119 size_t sz; 2120 2121 **array = *dest; 2122 ++*array; 2123 2124 switch (type) { 2125 case UVCG_HEADER: { 2126 struct uvc_input_header_descriptor *ihdr = *dest; 2127 struct uvcg_streaming_header *h = priv1; 2128 struct uvcg_format_ptr *f; 2129 2130 memcpy(*dest, &h->desc, sizeof(h->desc)); 2131 *dest += sizeof(h->desc); 2132 sz = UVCG_STREAMING_CONTROL_SIZE; 2133 list_for_each_entry(f, &h->formats, entry) { 2134 memcpy(*dest, f->fmt->bmaControls, sz); 2135 *dest += sz; 2136 } 2137 ihdr->bLength = sizeof(h->desc) + h->num_fmt * sz; 2138 ihdr->bNumFormats = h->num_fmt; 2139 } 2140 break; 2141 case UVCG_FORMAT: { 2142 struct uvcg_format *fmt = priv1; 2143 2144 if (fmt->type == UVCG_UNCOMPRESSED) { 2145 struct uvcg_uncompressed *u = 2146 container_of(fmt, struct uvcg_uncompressed, 2147 fmt); 2148 2149 u->desc.bFormatIndex = n + 1; 2150 u->desc.bNumFrameDescriptors = fmt->num_frames; 2151 memcpy(*dest, &u->desc, sizeof(u->desc)); 2152 *dest += sizeof(u->desc); 2153 } else if (fmt->type == UVCG_MJPEG) { 2154 struct uvcg_mjpeg *m = 2155 container_of(fmt, struct uvcg_mjpeg, fmt); 2156 2157 m->desc.bFormatIndex = n + 1; 2158 m->desc.bNumFrameDescriptors = fmt->num_frames; 2159 memcpy(*dest, &m->desc, sizeof(m->desc)); 2160 *dest += sizeof(m->desc); 2161 } else { 2162 return -EINVAL; 2163 } 2164 } 2165 break; 2166 case UVCG_FRAME: { 2167 struct uvcg_frame *frm = priv1; 2168 struct uvc_descriptor_header *h = *dest; 2169 2170 sz = sizeof(frm->frame); 2171 memcpy(*dest, &frm->frame, sz); 2172 *dest += sz; 2173 sz = frm->frame.b_frame_interval_type * 2174 sizeof(*frm->dw_frame_interval); 2175 memcpy(*dest, frm->dw_frame_interval, sz); 2176 *dest += sz; 2177 if (frm->fmt_type == UVCG_UNCOMPRESSED) 2178 h->bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE( 2179 frm->frame.b_frame_interval_type); 2180 else if (frm->fmt_type == UVCG_MJPEG) 2181 h->bLength = UVC_DT_FRAME_MJPEG_SIZE( 2182 frm->frame.b_frame_interval_type); 2183 } 2184 break; 2185 } 2186 2187 return 0; 2188 } 2189 2190 static int uvcg_streaming_class_allow_link(struct config_item *src, 2191 struct config_item *target) 2192 { 2193 struct config_item *streaming, *header; 2194 struct f_uvc_opts *opts; 2195 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 2196 struct uvc_descriptor_header ***class_array, **cl_arr; 2197 struct uvcg_streaming_header *target_hdr; 2198 void *data, *data_save; 2199 size_t size = 0, count = 0; 2200 int ret = -EINVAL; 2201 2202 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2203 2204 streaming = src->ci_parent->ci_parent; 2205 header = config_group_find_item(to_config_group(streaming), "header"); 2206 if (!header || target->ci_parent != header) 2207 goto out; 2208 2209 opts = to_f_uvc_opts(streaming->ci_parent); 2210 2211 mutex_lock(&opts->lock); 2212 2213 class_array = __uvcg_get_stream_class_arr(src, opts); 2214 if (!class_array || *class_array || opts->refcnt) { 2215 ret = -EBUSY; 2216 goto unlock; 2217 } 2218 2219 target_hdr = to_uvcg_streaming_header(target); 2220 ret = __uvcg_iter_strm_cls(target_hdr, &size, &count, __uvcg_cnt_strm); 2221 if (ret) 2222 goto unlock; 2223 2224 count += 2; /* color_matching, NULL */ 2225 *class_array = kcalloc(count, sizeof(void *), GFP_KERNEL); 2226 if (!*class_array) { 2227 ret = -ENOMEM; 2228 goto unlock; 2229 } 2230 2231 data = data_save = kzalloc(size, GFP_KERNEL); 2232 if (!data) { 2233 kfree(*class_array); 2234 *class_array = NULL; 2235 ret = -ENOMEM; 2236 goto unlock; 2237 } 2238 cl_arr = *class_array; 2239 ret = __uvcg_iter_strm_cls(target_hdr, &data, &cl_arr, 2240 __uvcg_fill_strm); 2241 if (ret) { 2242 kfree(*class_array); 2243 *class_array = NULL; 2244 /* 2245 * __uvcg_fill_strm() called from __uvcg_iter_stream_cls() 2246 * might have advanced the "data", so use a backup copy 2247 */ 2248 kfree(data_save); 2249 goto unlock; 2250 } 2251 *cl_arr = (struct uvc_descriptor_header *)&opts->uvc_color_matching; 2252 2253 ++target_hdr->linked; 2254 ret = 0; 2255 2256 unlock: 2257 mutex_unlock(&opts->lock); 2258 out: 2259 config_item_put(header); 2260 mutex_unlock(su_mutex); 2261 return ret; 2262 } 2263 2264 static void uvcg_streaming_class_drop_link(struct config_item *src, 2265 struct config_item *target) 2266 { 2267 struct config_item *streaming, *header; 2268 struct f_uvc_opts *opts; 2269 struct mutex *su_mutex = &src->ci_group->cg_subsys->su_mutex; 2270 struct uvc_descriptor_header ***class_array; 2271 struct uvcg_streaming_header *target_hdr; 2272 2273 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2274 2275 streaming = src->ci_parent->ci_parent; 2276 header = config_group_find_item(to_config_group(streaming), "header"); 2277 if (!header || target->ci_parent != header) 2278 goto out; 2279 2280 opts = to_f_uvc_opts(streaming->ci_parent); 2281 2282 mutex_lock(&opts->lock); 2283 2284 class_array = __uvcg_get_stream_class_arr(src, opts); 2285 if (!class_array || !*class_array) 2286 goto unlock; 2287 2288 if (opts->refcnt) 2289 goto unlock; 2290 2291 target_hdr = to_uvcg_streaming_header(target); 2292 --target_hdr->linked; 2293 kfree(**class_array); 2294 kfree(*class_array); 2295 *class_array = NULL; 2296 2297 unlock: 2298 mutex_unlock(&opts->lock); 2299 out: 2300 config_item_put(header); 2301 mutex_unlock(su_mutex); 2302 } 2303 2304 static struct configfs_item_operations uvcg_streaming_class_item_ops = { 2305 .release = uvcg_config_item_release, 2306 .allow_link = uvcg_streaming_class_allow_link, 2307 .drop_link = uvcg_streaming_class_drop_link, 2308 }; 2309 2310 static const struct config_item_type uvcg_streaming_class_type = { 2311 .ct_item_ops = &uvcg_streaming_class_item_ops, 2312 .ct_owner = THIS_MODULE, 2313 }; 2314 2315 /* ----------------------------------------------------------------------------- 2316 * streaming/class 2317 */ 2318 2319 static int uvcg_streaming_class_create_children(struct config_group *parent) 2320 { 2321 static const char * const names[] = { "fs", "hs", "ss" }; 2322 unsigned int i; 2323 2324 for (i = 0; i < ARRAY_SIZE(names); ++i) { 2325 struct uvcg_streaming_class_group *group; 2326 2327 group = kzalloc(sizeof(*group), GFP_KERNEL); 2328 if (!group) 2329 return -ENOMEM; 2330 2331 group->name = names[i]; 2332 2333 config_group_init_type_name(&group->group, group->name, 2334 &uvcg_streaming_class_type); 2335 configfs_add_default_group(&group->group, parent); 2336 } 2337 2338 return 0; 2339 } 2340 2341 static const struct uvcg_config_group_type uvcg_streaming_class_grp_type = { 2342 .type = { 2343 .ct_item_ops = &uvcg_config_item_ops, 2344 .ct_owner = THIS_MODULE, 2345 }, 2346 .name = "class", 2347 .create_children = uvcg_streaming_class_create_children, 2348 }; 2349 2350 /* ----------------------------------------------------------------------------- 2351 * streaming 2352 */ 2353 2354 static ssize_t uvcg_default_streaming_b_interface_number_show( 2355 struct config_item *item, char *page) 2356 { 2357 struct config_group *group = to_config_group(item); 2358 struct mutex *su_mutex = &group->cg_subsys->su_mutex; 2359 struct config_item *opts_item; 2360 struct f_uvc_opts *opts; 2361 int result = 0; 2362 2363 mutex_lock(su_mutex); /* for navigating configfs hierarchy */ 2364 2365 opts_item = item->ci_parent; 2366 opts = to_f_uvc_opts(opts_item); 2367 2368 mutex_lock(&opts->lock); 2369 result += sprintf(page, "%u\n", opts->streaming_interface); 2370 mutex_unlock(&opts->lock); 2371 2372 mutex_unlock(su_mutex); 2373 2374 return result; 2375 } 2376 2377 UVC_ATTR_RO(uvcg_default_streaming_, b_interface_number, bInterfaceNumber); 2378 2379 static struct configfs_attribute *uvcg_default_streaming_attrs[] = { 2380 &uvcg_default_streaming_attr_b_interface_number, 2381 NULL, 2382 }; 2383 2384 static const struct uvcg_config_group_type uvcg_streaming_grp_type = { 2385 .type = { 2386 .ct_item_ops = &uvcg_config_item_ops, 2387 .ct_attrs = uvcg_default_streaming_attrs, 2388 .ct_owner = THIS_MODULE, 2389 }, 2390 .name = "streaming", 2391 .children = (const struct uvcg_config_group_type*[]) { 2392 &uvcg_streaming_header_grp_type, 2393 &uvcg_uncompressed_grp_type, 2394 &uvcg_mjpeg_grp_type, 2395 &uvcg_color_matching_grp_type, 2396 &uvcg_streaming_class_grp_type, 2397 NULL, 2398 }, 2399 }; 2400 2401 /* ----------------------------------------------------------------------------- 2402 * UVC function 2403 */ 2404 2405 static void uvc_func_item_release(struct config_item *item) 2406 { 2407 struct f_uvc_opts *opts = to_f_uvc_opts(item); 2408 2409 uvcg_config_remove_children(to_config_group(item)); 2410 usb_put_function_instance(&opts->func_inst); 2411 } 2412 2413 static struct configfs_item_operations uvc_func_item_ops = { 2414 .release = uvc_func_item_release, 2415 }; 2416 2417 #define UVCG_OPTS_ATTR(cname, aname, conv, str2u, uxx, vnoc, limit) \ 2418 static ssize_t f_uvc_opts_##cname##_show( \ 2419 struct config_item *item, char *page) \ 2420 { \ 2421 struct f_uvc_opts *opts = to_f_uvc_opts(item); \ 2422 int result; \ 2423 \ 2424 mutex_lock(&opts->lock); \ 2425 result = sprintf(page, "%d\n", conv(opts->cname)); \ 2426 mutex_unlock(&opts->lock); \ 2427 \ 2428 return result; \ 2429 } \ 2430 \ 2431 static ssize_t \ 2432 f_uvc_opts_##cname##_store(struct config_item *item, \ 2433 const char *page, size_t len) \ 2434 { \ 2435 struct f_uvc_opts *opts = to_f_uvc_opts(item); \ 2436 int ret; \ 2437 uxx num; \ 2438 \ 2439 mutex_lock(&opts->lock); \ 2440 if (opts->refcnt) { \ 2441 ret = -EBUSY; \ 2442 goto end; \ 2443 } \ 2444 \ 2445 ret = str2u(page, 0, &num); \ 2446 if (ret) \ 2447 goto end; \ 2448 \ 2449 if (num > limit) { \ 2450 ret = -EINVAL; \ 2451 goto end; \ 2452 } \ 2453 opts->cname = vnoc(num); \ 2454 ret = len; \ 2455 end: \ 2456 mutex_unlock(&opts->lock); \ 2457 return ret; \ 2458 } \ 2459 \ 2460 UVC_ATTR(f_uvc_opts_, cname, cname) 2461 2462 #define identity_conv(x) (x) 2463 2464 UVCG_OPTS_ATTR(streaming_interval, streaming_interval, identity_conv, 2465 kstrtou8, u8, identity_conv, 16); 2466 UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, le16_to_cpu, 2467 kstrtou16, u16, le16_to_cpu, 3072); 2468 UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, identity_conv, 2469 kstrtou8, u8, identity_conv, 15); 2470 2471 #undef identity_conv 2472 2473 #undef UVCG_OPTS_ATTR 2474 2475 static struct configfs_attribute *uvc_attrs[] = { 2476 &f_uvc_opts_attr_streaming_interval, 2477 &f_uvc_opts_attr_streaming_maxpacket, 2478 &f_uvc_opts_attr_streaming_maxburst, 2479 NULL, 2480 }; 2481 2482 static const struct uvcg_config_group_type uvc_func_type = { 2483 .type = { 2484 .ct_item_ops = &uvc_func_item_ops, 2485 .ct_attrs = uvc_attrs, 2486 .ct_owner = THIS_MODULE, 2487 }, 2488 .name = "", 2489 .children = (const struct uvcg_config_group_type*[]) { 2490 &uvcg_control_grp_type, 2491 &uvcg_streaming_grp_type, 2492 NULL, 2493 }, 2494 }; 2495 2496 int uvcg_attach_configfs(struct f_uvc_opts *opts) 2497 { 2498 int ret; 2499 2500 config_group_init_type_name(&opts->func_inst.group, uvc_func_type.name, 2501 &uvc_func_type.type); 2502 2503 ret = uvcg_config_create_children(&opts->func_inst.group, 2504 &uvc_func_type); 2505 if (ret < 0) 2506 config_group_put(&opts->func_inst.group); 2507 2508 return ret; 2509 } 2510