.. | .. |
---|
7 | 7 | * Copyright (c) 2014 Samsung Electronics Co., Ltd. |
---|
8 | 8 | * http://www.samsung.com |
---|
9 | 9 | * |
---|
10 | | - * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> |
---|
| 10 | + * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com> |
---|
11 | 11 | */ |
---|
12 | 12 | |
---|
13 | 13 | #include <linux/sort.h> |
---|
.. | .. |
---|
506 | 506 | UVCG_DEFAULT_OUTPUT_ATTR(b_terminal_id, bTerminalID, 8); |
---|
507 | 507 | UVCG_DEFAULT_OUTPUT_ATTR(w_terminal_type, wTerminalType, 16); |
---|
508 | 508 | UVCG_DEFAULT_OUTPUT_ATTR(b_assoc_terminal, bAssocTerminal, 8); |
---|
509 | | -UVCG_DEFAULT_OUTPUT_ATTR(b_source_id, bSourceID, 8); |
---|
510 | 509 | UVCG_DEFAULT_OUTPUT_ATTR(i_terminal, iTerminal, 8); |
---|
511 | 510 | |
---|
512 | 511 | #undef UVCG_DEFAULT_OUTPUT_ATTR |
---|
| 512 | + |
---|
| 513 | +static ssize_t uvcg_default_output_b_source_id_show(struct config_item *item, |
---|
| 514 | + char *page) |
---|
| 515 | +{ |
---|
| 516 | + struct config_group *group = to_config_group(item); |
---|
| 517 | + struct f_uvc_opts *opts; |
---|
| 518 | + struct config_item *opts_item; |
---|
| 519 | + struct mutex *su_mutex = &group->cg_subsys->su_mutex; |
---|
| 520 | + struct uvc_output_terminal_descriptor *cd; |
---|
| 521 | + int result; |
---|
| 522 | + |
---|
| 523 | + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ |
---|
| 524 | + |
---|
| 525 | + opts_item = group->cg_item.ci_parent->ci_parent-> |
---|
| 526 | + ci_parent->ci_parent; |
---|
| 527 | + opts = to_f_uvc_opts(opts_item); |
---|
| 528 | + cd = &opts->uvc_output_terminal; |
---|
| 529 | + |
---|
| 530 | + mutex_lock(&opts->lock); |
---|
| 531 | + result = sprintf(page, "%u\n", le8_to_cpu(cd->bSourceID)); |
---|
| 532 | + mutex_unlock(&opts->lock); |
---|
| 533 | + |
---|
| 534 | + mutex_unlock(su_mutex); |
---|
| 535 | + |
---|
| 536 | + return result; |
---|
| 537 | +} |
---|
| 538 | + |
---|
| 539 | +static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item, |
---|
| 540 | + const char *page, size_t len) |
---|
| 541 | +{ |
---|
| 542 | + struct config_group *group = to_config_group(item); |
---|
| 543 | + struct f_uvc_opts *opts; |
---|
| 544 | + struct config_item *opts_item; |
---|
| 545 | + struct mutex *su_mutex = &group->cg_subsys->su_mutex; |
---|
| 546 | + struct uvc_output_terminal_descriptor *cd; |
---|
| 547 | + int result; |
---|
| 548 | + u8 num; |
---|
| 549 | + |
---|
| 550 | + result = kstrtou8(page, 0, &num); |
---|
| 551 | + if (result) |
---|
| 552 | + return result; |
---|
| 553 | + |
---|
| 554 | + mutex_lock(su_mutex); /* for navigating configfs hierarchy */ |
---|
| 555 | + |
---|
| 556 | + opts_item = group->cg_item.ci_parent->ci_parent-> |
---|
| 557 | + ci_parent->ci_parent; |
---|
| 558 | + opts = to_f_uvc_opts(opts_item); |
---|
| 559 | + cd = &opts->uvc_output_terminal; |
---|
| 560 | + |
---|
| 561 | + mutex_lock(&opts->lock); |
---|
| 562 | + cd->bSourceID = num; |
---|
| 563 | + mutex_unlock(&opts->lock); |
---|
| 564 | + |
---|
| 565 | + mutex_unlock(su_mutex); |
---|
| 566 | + |
---|
| 567 | + return len; |
---|
| 568 | +} |
---|
| 569 | +UVC_ATTR(uvcg_default_output_, b_source_id, bSourceID); |
---|
513 | 570 | |
---|
514 | 571 | static struct configfs_attribute *uvcg_default_output_attrs[] = { |
---|
515 | 572 | &uvcg_default_output_attr_b_terminal_id, |
---|
.. | .. |
---|
1607 | 1664 | if (ret) \ |
---|
1608 | 1665 | goto end; \ |
---|
1609 | 1666 | \ |
---|
1610 | | - if (num > 255) { \ |
---|
1611 | | - ret = -EINVAL; \ |
---|
1612 | | - goto end; \ |
---|
1613 | | - } \ |
---|
1614 | 1667 | u->desc.aname = num; \ |
---|
1615 | 1668 | ret = len; \ |
---|
1616 | 1669 | end: \ |
---|
.. | .. |
---|
1804 | 1857 | if (ret) \ |
---|
1805 | 1858 | goto end; \ |
---|
1806 | 1859 | \ |
---|
1807 | | - if (num > 255) { \ |
---|
1808 | | - ret = -EINVAL; \ |
---|
1809 | | - goto end; \ |
---|
1810 | | - } \ |
---|
1811 | 1860 | u->desc.aname = num; \ |
---|
1812 | 1861 | ret = len; \ |
---|
1813 | 1862 | end: \ |
---|
.. | .. |
---|
2774 | 2823 | UVCG_OPTS_ATTR(streaming_interval, streaming_interval, 16); |
---|
2775 | 2824 | UVCG_OPTS_ATTR(streaming_maxpacket, streaming_maxpacket, 3072); |
---|
2776 | 2825 | UVCG_OPTS_ATTR(streaming_maxburst, streaming_maxburst, 15); |
---|
2777 | | -UVCG_OPTS_ATTR(uvc_num_request, uvc_num_request, UVC_MAX_NUM_REQUESTS); |
---|
2778 | 2826 | UVCG_OPTS_ATTR(pm_qos_latency, pm_qos_latency, PM_QOS_LATENCY_ANY); |
---|
| 2827 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
---|
| 2828 | +UVCG_OPTS_ATTR(uvc_num_request, uvc_num_request, 64); |
---|
| 2829 | +UVCG_OPTS_ATTR(uvc_zero_copy, uvc_zero_copy, 1); |
---|
| 2830 | +#endif |
---|
2779 | 2831 | |
---|
2780 | 2832 | #undef UVCG_OPTS_ATTR |
---|
2781 | 2833 | |
---|
| 2834 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
---|
2782 | 2835 | static ssize_t f_uvc_opts_device_name_show(struct config_item *item, |
---|
2783 | 2836 | char *page) |
---|
2784 | 2837 | { |
---|
.. | .. |
---|
2832 | 2885 | return ret; |
---|
2833 | 2886 | } |
---|
2834 | 2887 | UVC_ATTR(f_uvc_opts_, device_name, device_name); |
---|
| 2888 | +#endif |
---|
| 2889 | + |
---|
| 2890 | +#define UVCG_OPTS_STRING_ATTR(cname, aname) \ |
---|
| 2891 | +static ssize_t f_uvc_opts_string_##cname##_show(struct config_item *item,\ |
---|
| 2892 | + char *page) \ |
---|
| 2893 | +{ \ |
---|
| 2894 | + struct f_uvc_opts *opts = to_f_uvc_opts(item); \ |
---|
| 2895 | + int result; \ |
---|
| 2896 | + \ |
---|
| 2897 | + mutex_lock(&opts->lock); \ |
---|
| 2898 | + result = snprintf(page, sizeof(opts->aname), "%s", opts->aname);\ |
---|
| 2899 | + mutex_unlock(&opts->lock); \ |
---|
| 2900 | + \ |
---|
| 2901 | + return result; \ |
---|
| 2902 | +} \ |
---|
| 2903 | + \ |
---|
| 2904 | +static ssize_t f_uvc_opts_string_##cname##_store(struct config_item *item,\ |
---|
| 2905 | + const char *page, size_t len) \ |
---|
| 2906 | +{ \ |
---|
| 2907 | + struct f_uvc_opts *opts = to_f_uvc_opts(item); \ |
---|
| 2908 | + int size = min(sizeof(opts->aname), len + 1); \ |
---|
| 2909 | + int ret = 0; \ |
---|
| 2910 | + \ |
---|
| 2911 | + mutex_lock(&opts->lock); \ |
---|
| 2912 | + if (opts->refcnt) { \ |
---|
| 2913 | + ret = -EBUSY; \ |
---|
| 2914 | + goto end; \ |
---|
| 2915 | + } \ |
---|
| 2916 | + \ |
---|
| 2917 | + ret = strscpy(opts->aname, page, size); \ |
---|
| 2918 | + if (ret == -E2BIG) \ |
---|
| 2919 | + ret = size - 1; \ |
---|
| 2920 | + \ |
---|
| 2921 | +end: \ |
---|
| 2922 | + mutex_unlock(&opts->lock); \ |
---|
| 2923 | + return ret; \ |
---|
| 2924 | +} \ |
---|
| 2925 | + \ |
---|
| 2926 | +UVC_ATTR(f_uvc_opts_string_, cname, aname) |
---|
| 2927 | + |
---|
| 2928 | +UVCG_OPTS_STRING_ATTR(function_name, function_name); |
---|
| 2929 | + |
---|
| 2930 | +#undef UVCG_OPTS_STRING_ATTR |
---|
2835 | 2931 | |
---|
2836 | 2932 | static struct configfs_attribute *uvc_attrs[] = { |
---|
2837 | 2933 | &f_uvc_opts_attr_streaming_bulk, |
---|
2838 | 2934 | &f_uvc_opts_attr_streaming_interval, |
---|
2839 | 2935 | &f_uvc_opts_attr_streaming_maxpacket, |
---|
2840 | 2936 | &f_uvc_opts_attr_streaming_maxburst, |
---|
2841 | | - &f_uvc_opts_attr_uvc_num_request, |
---|
2842 | 2937 | &f_uvc_opts_attr_pm_qos_latency, |
---|
| 2938 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
---|
2843 | 2939 | &f_uvc_opts_attr_device_name, |
---|
| 2940 | + &f_uvc_opts_attr_uvc_num_request, |
---|
| 2941 | + &f_uvc_opts_attr_uvc_zero_copy, |
---|
| 2942 | +#endif |
---|
| 2943 | + &f_uvc_opts_string_attr_function_name, |
---|
2844 | 2944 | NULL, |
---|
2845 | 2945 | }; |
---|
2846 | 2946 | |
---|