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