├── .gitignore ├── LICENSE ├── Makefile ├── README ├── Readme.md ├── doc ├── Readme.md ├── configfs_start.txt ├── gadget-testing.txt └── gadget_configfs.txt ├── uvc-gadget.c └── uvc.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | uvc-gadget 3 | .vscode 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CROSS_COMPILE ?= 2 | ARCH ?= x86 3 | KERNEL_DIR ?= /usr/src/linux 4 | 5 | CC := $(CROSS_COMPILE)gcc 6 | KERNEL_INCLUDE := -I$(KERNEL_DIR)/include -I$(KERNEL_DIR)/arch/$(ARCH)/include 7 | CFLAGS := -W -Wall -g $(KERNEL_INCLUDE) 8 | LDFLAGS := -g 9 | 10 | all: uvc-gadget 11 | 12 | uvc-gadget: uvc-gadget.o 13 | $(CC) $(LDFLAGS) -o $@ $^ 14 | 15 | clean: 16 | rm -f *.o 17 | rm -f uvc-gadget 18 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | UVC gadget test application Readme 2 | 3 | Copyright (C) 2010 Ideas on board SPRL 4 | Copyright (C) 2013 ST Microelectronics Ltd. 5 | 6 | Contacts: 7 | Laurent Pinchart 8 | Bhupesh Sharma 9 | 10 | Introduction 11 | ============ 12 | 13 | This README file documents the UVC gadget test application available 14 | here git://git.ideasonboard.org/uvc-gadget.git, which can be used to 15 | test the UVC webcam gadget driver located under drivers/usb/gadget 16 | directory. 17 | 18 | Possible Use-Case scenarios 19 | =========================== 20 | 21 | There can be a number of scenarios under which the UVC webcam gadget can 22 | be used and each use-case can vary in the following ways: 23 | 24 | - Video streaming endpoint choice: 25 | -------------------------------- 26 | 27 | As per UVC specifications (Revision 1.1), either Bulk or Isochronous 28 | USB endpoints can be used are for implementing UVC Video streaming 29 | interface. Both have there unique challenges as: 30 | 31 | Isochronous video streaming interface will have two 32 | alt-settings: 33 | - Alt-setting 0 for zero-bandwidth mode, and 34 | - Alt-setting 1 for full-bandwidth mode. 35 | 36 | This requires us to ACK status stage of SET_ALT(alt-setting = 37 | 1), only when we have video frames available which can be queued 38 | to UVC domain. 39 | 40 | Bulk video streaming interface, on the other hand will have only 41 | one alt-setting. 42 | 43 | This requires us to prepare UVC gadget for streaming when we 44 | receive a a UVC_VS_COMMIT_CONTROL command from USB host and 45 | actually start streaming as soon as we have video frames 46 | available which can be queued to UVC domain. 47 | 48 | - Availability of a video capture device: 49 | --------------------------------------- 50 | 51 | To emulate a real UVC webcam gadget (capturing live video from a video 52 | capture source and sending it over USB bus), it is possible to 53 | integrate a V4L2 based video-capture device driver with the UVC gadget 54 | test application acting as an interface between the UVC based 55 | video-output device and V4L2 based video-capture device. 56 | 57 | Accordingly, there can be the following scenarios possible: 58 | 59 | - No video capture device available: 60 | 61 | In this case, there is no video capture device available 62 | and the UVC webcam gadget is working in an standalone 63 | environment. 64 | 65 | It is possible in this case to stream a dummy test 66 | pattern from the UVC webcam gadget and view the same on 67 | the Linux/Windows USB Host machine using standard video 68 | capture utilities like CHEESE. 69 | 70 | - VIVI (Virtual Video driver) acting as a video capture source: 71 | 72 | In case we don't have a real video capture hardware 73 | (e.g. sensor) available, it is still possible to 74 | exercise the complete path from the V4L2 based 75 | video-capture domain to UVC based video-output domain, 76 | using the Virtual Video driver (VIVI) available here: 77 | drivers/media/platform/vivi.c 78 | 79 | It is possible in this case to stream changing vertical 80 | color bar pattern pattern from the VIVI capture device 81 | and send it to UVC webcam gadget, which will eventually 82 | send these frames over USB bus. 83 | 84 | Similar to the case above, it is possible to view the 85 | frames on the Linux/Windows USB Host machine using 86 | standard video capture utilities like CHEESE. 87 | 88 | - Real video capture hardware and corresponding V4L2 driver 89 | available: 90 | 91 | In this case, we have a real video capture hardware 92 | (e.g. CCD / CMOS sensor) available. 93 | 94 | Here, it is possible to exercise the complete path from 95 | the V4L2 based video-capture driver domain to UVC based 96 | video-output domain, using the UVC gadget test 97 | application. 98 | 99 | It is possible in this case to stream real video/still 100 | images from capture source and send it to UVC webcam 101 | gadget, which will eventually send these frames over USB 102 | bus. 103 | 104 | - IO methods supported: 105 | -------------------- 106 | 107 | V4L2 framework supports a number of IO methods and to achieve 108 | zero-memcpy of video frames as they pass from V4L2 video-capture 109 | domain to UVC video-output domain, it is important to select 110 | appropriate IO methods for working on videobuffers. 111 | 112 | Accordingly we can have the following scenarios possible: 113 | 114 | - UVC webcam standalone, supporting IO_METHOD_MMAP method: 115 | 116 | In this case, there is no video capture device available 117 | and the UVC webcam gadget is working in an standalone 118 | environment. 119 | 120 | It is supporting IO_MMAP method, which implies that the 121 | videobuffers are allocated by the UVC webcam gadget 122 | itself and they are filled with dummy test pattern by 123 | UVC gadget test application. 124 | 125 | - UVC webcam standalone, supporting IO_METHOD_USERPTR method: 126 | 127 | In this case, there is no video capture device available 128 | and the UVC webcam gadget is working in an standalone 129 | environment. 130 | 131 | It is supporting IO_METHOD_USERPTR method, which implies 132 | that the videobuffers are allocated and filled with 133 | dummy test pattern by the UVC gadget test application 134 | and UVC webcam gadget operates on a USERPTR of these 135 | videobuffers. 136 | 137 | - UVC webcam integrated with V4L2 video-capture driver, with 138 | V4L2 video-capture driver supporting IO_METHOD_MMAP method and 139 | UVC webcam supporting IO_METHOD_USERPTR: 140 | 141 | In this case, either VIVI or another V4L2 based driver 142 | (working on real HW) is available as a video capture 143 | device and is integrated with the UVC webcam gadget via 144 | UVC gadget test application, with V4L2 video-capture 145 | driver supporting IO_METHOD_MMAP method and UVC webcam 146 | supporting IO_METHOD_USERPTR. 147 | 148 | Here, the videobuffers are allocated in the V4L2 149 | video-capture domain and UVC gadget test application 150 | acts as a means to pass a USERPTR of these videobuffers 151 | to the UVC webcam gadget domain, without requiring any 152 | memcpy from the CPU. 153 | 154 | - UVC webcam integrated with V4L2 video-capture driver, with 155 | V4L2 video-capture driver supporting IO_METHOD_USERPTR method 156 | and UVC webcam supporting IO_METHOD_MMAP: 157 | 158 | In this case, either VIVI or another V4L2 based driver 159 | (working on real HW) is available as a video capture 160 | device and is integrated with the UVC webcam gadget via 161 | UVC gadget test application, with V4L2 video-capture 162 | driver supporting IO_METHOD_USERPTR method and UVC 163 | webcam supporting IO_METHOD_MMAP. 164 | 165 | Here, the videobuffers are allocated in the UVC webcam 166 | gadget domain and UVC gadget test application acts as a 167 | means to pass a USERPTR of these videobuffers to the 168 | V4L2 video-capture domain, without requiring any memcpy 169 | from the CPU. 170 | 171 | Modifying UVC gadget test application 172 | ===================================== 173 | 174 | The UVC webcam gadget kernel driver located under drivers/usb/gadget 175 | directory and compilable as g_webcam.ko kernel module, supports 360p and 176 | 720p frame resolutions and YUV4:2:2 and MJPEG frame formats by default. 177 | 178 | So, the video capture device must be aligned to support similar frame 179 | format and resolutions. 180 | 181 | In case the video capture device supports other resolutions and frame 182 | formats, we need to replace the default values used in the UVC gadget 183 | test application with the same and also update the UVC webcam gadget 184 | kernel driver. 185 | 186 | Keeping USBCV's UVC test-suite happy 187 | ==================================== 188 | 189 | The UVC webcam gadget kernel driver located under drivers/usb/gadget 190 | directory and compilable as g_webcam.ko kernel module, supports changing 191 | the Brightness attribute of the Processing Unit (PU) by default. 192 | 193 | If the underlying video capture device supports changing the Brightness 194 | attribute of the image being acquired (like the Virtual Video, VIVI 195 | driver does), then we should route this UVC request to the respective 196 | video capture device. 197 | 198 | Incase, there is no actual video capture device associated with the UVC 199 | gadget and we wish to use this application as the final destination of 200 | the UVC specific requests then we should return pre-cooked (static) 201 | responses to GET_CUR(BRIGHTNESS) and SET_CUR(BRIGHTNESS) commands to 202 | keep command verifier test tools like UVC class specific test suite of 203 | USBCV, happy. 204 | 205 | Note that the values used in UVC gadget test application are in sync 206 | with the VIVI driver and must be changed for your specific video capture 207 | device. These values also work well in case there in no actual video 208 | capture device. 209 | 210 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | **Upstream Latest Version: http://git.ideasonboard.org/uvc-gadget.git** 2 | 3 | ## uvc-gadget 4 | 5 | **Upstream project [uvc-gadget](http://git.ideasonboard.org/uvc-gadget.git) has been updated and continuous maintenance** 6 | 7 | UVC gadget userspace enhancement sample application 8 | 9 | Fork from 10 | [uvc-gadget.git](http://git.ideasonboard.org/uvc-gadget.git) 11 | Apply enhancement Bhupesh Sharma's patchset 12 | [UVC gadget test application enhancements](https://www.spinics.net/lists/linux-usb/msg84376.html) 13 | and Robert Baldyga's patchset 14 | [Bugfixes for UVC gadget test application](https://www.spinics.net/lists/linux-usb/msg99220.html) 15 | 16 | ## How to use 17 | 18 | Usage: ./uvc-gadget [options] 19 | 20 | Available options are 21 | -b Use bulk mode 22 | -d Do not use any real V4L2 capture device 23 | -f Select frame format 24 | 0 = V4L2_PIX_FMT_YUYV 25 | 1 = V4L2_PIX_FMT_MJPEG 26 | -h Print this help screen and exit 27 | -i image MJPEG image 28 | -m Streaming mult for ISOC (b/w 0 and 2) 29 | -n Number of Video buffers (b/w 2 and 32) 30 | -o Select UVC IO method: 31 | 0 = MMAP 32 | 1 = USER_PTR 33 | -r Select frame resolution: 34 | 0 = 360p, VGA (640x360) 35 | 1 = 720p, WXGA (1280x720) 36 | -s Select USB bus speed (b/w 0 and 2) 37 | 0 = Full Speed (FS) 38 | 1 = High Speed (HS) 39 | 2 = Super Speed (SS) 40 | -t Streaming burst (b/w 0 and 15) 41 | -u device UVC Video Output device 42 | -v device V4L2 Video Capture device 43 | 44 | ## Build 45 | 46 | - host: 47 | make 48 | - Cross compile: 49 | make ARCH=arch CROSS_COMPILE=cross_compiler 50 | eg: 51 | make ARCH=arm CROSS_COMPILE=arm-hisiv600-linux- 52 | - or: 53 | set ARCH, CROSS_COMPILE, KERNEL_DIR in Makefile 54 | 55 | ## Change log 56 | 57 | - Apply patchset [Bugfixes for UVC gadget test application](https://www.spinics.net/lists/linux-usb/msg99220.html) 58 | 59 | - Apply patchset [UVC gadget test application enhancements](https://www.spinics.net/lists/linux-usb/msg84376.html) 60 | 61 | - Add Readme/.gitignore and documentations 62 | Copy linux-3.18.y/drivers/usb/gadget/function/uvc.h into repository, change include path for build 63 | 64 | ### Initial 65 | 66 | - Fork(copy) from [uvc-gadget.git](http://git.ideasonboard.org/uvc-gadget.git) 67 | -------------------------------------------------------------------------------- /doc/Readme.md: -------------------------------------------------------------------------------- 1 | ## Documentation 2 | 3 | - [linux/Documentation/usb/gadget-testing.txt](https://github.com/torvalds/linux/blob/master/Documentation/usb/gadget-testing.txt) 4 | 5 | - [linux/Documentation/usb/gadget_configfs.txt](https://github.com/torvalds/linux/blob/master/Documentation/usb/gadget_configfs.txt) 6 | 7 | - [configfs_start](http://www.spinics.net/lists/linux-usb/msg76388.html) 8 | 9 | - [usb gadget](https://github.com/torvalds/linux/tree/master/Documentation/usb) 10 | 11 | - [configfs](https://github.com/torvalds/linux/tree/master/Documentation/filesystems/configfs) -------------------------------------------------------------------------------- /doc/configfs_start.txt: -------------------------------------------------------------------------------- 1 | The start of the configfs interface 2 | 3 | (The original post describing the first function 4 | made available through configfs can be seen here: 5 | http://www.spinics.net/lists/linux-usb/msg76388.html) 6 | 7 | ########################################################## 8 | 9 | |# modprobe dummy_hcd num=2 10 | |# modprobe libcomposite 11 | 12 | |# lsmod 13 | |Module Size Used by 14 | |libcomposite 31648 0 15 | |dummy_hcd 19871 0 16 | 17 | |# mkdir /sys/kernel/config/usb_gadget/oha 18 | |# cd /sys/kernel/config/usb_gadget/oha 19 | |# mkdir configs/def.1 20 | |# mkdir configs/def.2 21 | |# mkdir functions/acm.ttyS1 22 | |# mkdir strings/0x1 23 | |mkdir: cannot create directory `strings/0x1': Invalid argument 24 | |# mkdir strings/0x409 25 | |# mkdir strings/1033 26 | |mkdir: cannot create directory `strings/1033': File exists 27 | |# mkdir strings/1032 28 | |# mkdir configs/def.1/strings/0x409 29 | |# mkdir configs/def.2/strings/0x409 30 | 31 | |#find . -ls 32 | | 975 0 drwxr-xr-x 5 root root 0 Dec 23 17:40 . 33 | | 978 0 drwxr-xr-x 4 root root 0 Dec 23 17:43 ./strings 34 | | 4100 0 drwxr-xr-x 2 root root 0 Dec 23 17:43 ./strings/1032 35 | | 995 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./strings/1032/serialnumber 36 | | 996 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./strings/1032/product 37 | | 997 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./strings/1032/manufacturer 38 | | 2002 0 drwxr-xr-x 2 root root 0 Dec 23 17:41 ./strings/0x409 39 | | 998 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./strings/0x409/serialnumber 40 | | 999 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./strings/0x409/product 41 | | 1000 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./strings/0x409/manufacturer 42 | | 977 0 drwxr-xr-x 4 root root 0 Dec 23 17:41 ./configs 43 | | 4081 0 drwxr-xr-x 3 root root 0 Dec 23 17:41 ./configs/def.2 44 | | 4082 0 drwxr-xr-x 3 root root 0 Dec 23 17:42 ./configs/def.2/strings 45 | | 2016 0 drwxr-xr-x 2 root root 0 Dec 23 17:42 ./configs/def.2/strings/0x409 46 | | 1001 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./configs/def.2/strings/0x409/configuration 47 | | 1002 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./configs/def.2/bmAttributes 48 | | 1003 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./configs/def.2/MaxPower 49 | | 979 0 drwxr-xr-x 3 root root 0 Dec 23 17:42 ./configs/def.1 50 | | 980 0 drwxr-xr-x 3 root root 0 Dec 23 17:42 ./configs/def.1/strings 51 | | 5122 0 drwxr-xr-x 2 root root 0 Dec 23 17:42 ./configs/def.1/strings/0x409 52 | | 1004 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./configs/def.1/strings/0x409/configuration 53 | | 1005 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./configs/def.1/bmAttributes 54 | | 1006 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./configs/def.1/MaxPower 55 | | 976 0 drwxr-xr-x 3 root root 0 Dec 23 17:41 ./functions 56 | | 981 0 drwxr-xr-x 2 root root 0 Dec 23 17:41 ./functions/acm.ttyS1 57 | | 1007 0 -r--r--r-- 1 root root 4096 Dec 23 17:43 ./functions/acm.ttyS1/port_num 58 | | 1008 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./UDC 59 | | 1009 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./bcdUSB 60 | | 1010 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./bcdDevice 61 | | 1011 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./idProduct 62 | | 1012 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./idVendor 63 | | 1013 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./bMaxPacketSize0 64 | | 1014 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./bDeviceProtocol 65 | | 1015 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./bDeviceSubClass 66 | | 1016 0 -rw-r--r-- 1 root root 4096 Dec 23 17:43 ./bDeviceClass 67 | 68 | |# cat functions/acm.ttyS1/port_num 69 | |0 70 | |# ls -lah /dev/ttyGS* 71 | |crw-rw---T 1 root dialout 252, 0 Dec 23 17:41 /dev/ttyGS0 72 | | 73 | |# echo 0x1234 > idProduct 74 | |# echo 0xabcd > idVendor 75 | |# echo 1122 > strings/0x409/serialnumber 76 | |# echo "The manufacturer" > strings/0x409/manufacturer 77 | |# echo 1 > strings/1032/manufacturer 78 | |# echo 1sa > strings/1032/product 79 | |# echo tada > strings/1032/serialnumber 80 | |echo "Primary configuration" > configs/def.1/strings/0x409/configuration 81 | |# echo "Secondary configuration" > configs/def.2/strings/0x409/configuration 82 | |# ln -s functions/acm.ttyS1 configs/def.1/ 83 | |# ln -s functions/acm.ttyS1 configs/def.2/ 84 | |find configs/def.1/ -ls 85 | | 979 0 drwxr-xr-x 3 root root 0 Dec 23 17:49 configs/def.1/ 86 | | 6264 0 lrwxrwxrwx 1 root root 0 Dec 23 17:48 configs/def.1/acm.ttyS1 -> ../../../../usb_gadget/oha/functions/acm.ttyS1 87 | | 980 0 drwxr-xr-x 3 root root 0 Dec 23 17:42 configs/def.1/strings 88 | | 5122 0 drwxr-xr-x 2 root root 0 Dec 23 17:49 configs/def.1/strings/0x409 89 | | 6284 0 -rw-r--r-- 1 root root 4096 Dec 23 17:47 configs/def.1/strings/0x409/configuration 90 | | 6285 0 -rw-r--r-- 1 root root 4096 Dec 23 17:49 configs/def.1/bmAttributes 91 | | 6286 0 -rw-r--r-- 1 root root 4096 Dec 23 17:49 configs/def.1/MaxPower 92 | | 93 | |echo 120 > configs/def.1/MaxPower 94 | | 95 | |# ls -lh /sys/class/udc/ 96 | |total 0 97 | |lrwxrwxrwx 1 root root 0 Dec 23 17:50 dummy_udc.0 -> ../../devices/platform/dummy_udc.0/udc/dummy_udc.0 98 | |lrwxrwxrwx 1 root root 0 Dec 23 17:50 dummy_udc.1 -> ../../devices/platform/dummy_udc.1/udc/dummy_udc.1 99 | |# echo dummy_udc.0 > UDC 100 | |# lsusb 101 | |Bus 001 Device 002: ID abcd:1234 Unknown 102 | | 103 | |lsusb -d abcd:1234 -v 104 | |Device Descriptor: 105 | … 106 | | idVendor 0xabcd Unknown 107 | | idProduct 0x1234 108 | | bcdDevice 3.06 109 | | iManufacturer 1 The manufacturer 110 | | iProduct 2 111 | | iSerial 3 1122 112 | | bNumConfigurations 2 113 | … 114 | |echo "" > UDC 115 | 116 | v5…v6 117 | - wired up strings with usb_gstrings_attach() 118 | - add UDC attribe. Write "udc-name" will bind the gadget. Write an empty 119 | string (it should contain \n since 0 bytes write get optimzed away) 120 | will unbind the UDC from the gadget. The name of available UDCs can be 121 | obtained from /sys/class/udc/ 122 | 123 | v4…v5 124 | - string rework. This will add a strings folder incl. language code like 125 | strings/409/manufacturer 126 | as suggested by Alan. 127 | - rebased ontop reworked functions.c which has usb_function_instance 128 | which is used prior after "mkdir acm.instance" and can be directly 129 | used for configuration via configfs. 130 | 131 | v3…v4 132 | - moved functions from the root folde down to the gadget as suggested 133 | by Michał 134 | - configs have now their own configs folder as suggested by Michał. 135 | The folder is still name.bConfigurationValue where name becomes the 136 | sConfiguration. Is this usefull should we just stilc 137 | configs/bConfigurationValue/ ? 138 | - added configfs support to the ACM function. The port_num attribute is 139 | exported by f_acm. An argument has been added to the USB alloc 140 | function to distinguish between "old" (use facm_configure() to 141 | configure and configfs interface (expose a config_node). 142 | The port_num is currently a dumb counter. It will 143 | require some function re-work to make it work. 144 | 145 | scheduled for v5: 146 | - sym linking function into config. 147 | 148 | v2…v3 149 | - replaced one ifndef by ifdef as suggested by Micahał 150 | - strstr()/strchr() function_make as suggested by Micahł 151 | - replace [iSerialNumber|iProduct|iManufacturer] with 152 | [sSerialNumber|sProduct|sManufacturer] as suggested by Alan 153 | - added creation of config descriptors 154 | 155 | v1…v2 156 | - moved gadgets from configfs' root directory into /udcs/ within our 157 | "usb_gadget" folder. Requested by Andrzej & Michał 158 | - use a dot as a delimiter between function's name and its instance's name 159 | as suggested by Michał 160 | - renamed all config_item_type, configfs_group_operations, make_group, 161 | drop_item as suggested by suggested by Andrzej to remain consisten 162 | within this file and within other configfs users 163 | - Since configfs.c and functions.c are now part of the udc-core module, 164 | the module itself is now called udc. Also added a tiny ifdef around 165 | init code becuase udc-core is subsys init and this is too early for 166 | configfs in the built-in case. In the module case, we can only have 167 | one init function. -------------------------------------------------------------------------------- /doc/gadget-testing.txt: -------------------------------------------------------------------------------- 1 | This file summarizes information on basic testing of USB functions 2 | provided by gadgets. 3 | 4 | 1. ACM function 5 | 2. ECM function 6 | 3. ECM subset function 7 | 4. EEM function 8 | 5. FFS function 9 | 6. HID function 10 | 7. LOOPBACK function 11 | 8. MASS STORAGE function 12 | 9. MIDI function 13 | 10. NCM function 14 | 11. OBEX function 15 | 12. PHONET function 16 | 13. RNDIS function 17 | 14. SERIAL function 18 | 15. SOURCESINK function 19 | 16. UAC1 function (legacy implementation) 20 | 17. UAC2 function 21 | 18. UVC function 22 | 19. PRINTER function 23 | 20. UAC1 function (new API) 24 | 25 | 26 | 1. ACM function 27 | =============== 28 | 29 | The function is provided by usb_f_acm.ko module. 30 | 31 | Function-specific configfs interface 32 | ------------------------------------ 33 | 34 | The function name to use when creating the function directory is "acm". 35 | The ACM function provides just one attribute in its function directory: 36 | 37 | port_num 38 | 39 | The attribute is read-only. 40 | 41 | There can be at most 4 ACM/generic serial/OBEX ports in the system. 42 | 43 | 44 | Testing the ACM function 45 | ------------------------ 46 | 47 | On the host: cat > /dev/ttyACM 48 | On the device : cat /dev/ttyGS 49 | 50 | then the other way round 51 | 52 | On the device: cat > /dev/ttyGS 53 | On the host: cat /dev/ttyACM 54 | 55 | 2. ECM function 56 | =============== 57 | 58 | The function is provided by usb_f_ecm.ko module. 59 | 60 | Function-specific configfs interface 61 | ------------------------------------ 62 | 63 | The function name to use when creating the function directory is "ecm". 64 | The ECM function provides these attributes in its function directory: 65 | 66 | ifname - network device interface name associated with this 67 | function instance 68 | qmult - queue length multiplier for high and super speed 69 | host_addr - MAC address of host's end of this 70 | Ethernet over USB link 71 | dev_addr - MAC address of device's end of this 72 | Ethernet over USB link 73 | 74 | and after creating the functions/ecm. they contain default 75 | values: qmult is 5, dev_addr and host_addr are randomly selected. 76 | Except for ifname they can be written to until the function is linked to a 77 | configuration. The ifname is read-only and contains the name of the interface 78 | which was assigned by the net core, e. g. usb0. 79 | 80 | Testing the ECM function 81 | ------------------------ 82 | 83 | Configure IP addresses of the device and the host. Then: 84 | 85 | On the device: ping 86 | On the host: ping 87 | 88 | 3. ECM subset function 89 | ====================== 90 | 91 | The function is provided by usb_f_ecm_subset.ko module. 92 | 93 | Function-specific configfs interface 94 | ------------------------------------ 95 | 96 | The function name to use when creating the function directory is "geth". 97 | The ECM subset function provides these attributes in its function directory: 98 | 99 | ifname - network device interface name associated with this 100 | function instance 101 | qmult - queue length multiplier for high and super speed 102 | host_addr - MAC address of host's end of this 103 | Ethernet over USB link 104 | dev_addr - MAC address of device's end of this 105 | Ethernet over USB link 106 | 107 | and after creating the functions/ecm. they contain default 108 | values: qmult is 5, dev_addr and host_addr are randomly selected. 109 | Except for ifname they can be written to until the function is linked to a 110 | configuration. The ifname is read-only and contains the name of the interface 111 | which was assigned by the net core, e. g. usb0. 112 | 113 | Testing the ECM subset function 114 | ------------------------------- 115 | 116 | Configure IP addresses of the device and the host. Then: 117 | 118 | On the device: ping 119 | On the host: ping 120 | 121 | 4. EEM function 122 | =============== 123 | 124 | The function is provided by usb_f_eem.ko module. 125 | 126 | Function-specific configfs interface 127 | ------------------------------------ 128 | 129 | The function name to use when creating the function directory is "eem". 130 | The EEM function provides these attributes in its function directory: 131 | 132 | ifname - network device interface name associated with this 133 | function instance 134 | qmult - queue length multiplier for high and super speed 135 | host_addr - MAC address of host's end of this 136 | Ethernet over USB link 137 | dev_addr - MAC address of device's end of this 138 | Ethernet over USB link 139 | 140 | and after creating the functions/eem. they contain default 141 | values: qmult is 5, dev_addr and host_addr are randomly selected. 142 | Except for ifname they can be written to until the function is linked to a 143 | configuration. The ifname is read-only and contains the name of the interface 144 | which was assigned by the net core, e. g. usb0. 145 | 146 | Testing the EEM function 147 | ------------------------ 148 | 149 | Configure IP addresses of the device and the host. Then: 150 | 151 | On the device: ping 152 | On the host: ping 153 | 154 | 5. FFS function 155 | =============== 156 | 157 | The function is provided by usb_f_fs.ko module. 158 | 159 | Function-specific configfs interface 160 | ------------------------------------ 161 | 162 | The function name to use when creating the function directory is "ffs". 163 | The function directory is intentionally empty and not modifiable. 164 | 165 | After creating the directory there is a new instance (a "device") of FunctionFS 166 | available in the system. Once a "device" is available, the user should follow 167 | the standard procedure for using FunctionFS (mount it, run the userspace 168 | process which implements the function proper). The gadget should be enabled 169 | by writing a suitable string to usb_gadget//UDC. 170 | 171 | Testing the FFS function 172 | ------------------------ 173 | 174 | On the device: start the function's userspace daemon, enable the gadget 175 | On the host: use the USB function provided by the device 176 | 177 | 6. HID function 178 | =============== 179 | 180 | The function is provided by usb_f_hid.ko module. 181 | 182 | Function-specific configfs interface 183 | ------------------------------------ 184 | 185 | The function name to use when creating the function directory is "hid". 186 | The HID function provides these attributes in its function directory: 187 | 188 | protocol - HID protocol to use 189 | report_desc - data to be used in HID reports, except data 190 | passed with /dev/hidg 191 | report_length - HID report length 192 | subclass - HID subclass to use 193 | 194 | For a keyboard the protocol and the subclass are 1, the report_length is 8, 195 | while the report_desc is: 196 | 197 | $ hd my_report_desc 198 | 00000000 05 01 09 06 a1 01 05 07 19 e0 29 e7 15 00 25 01 |..........)...%.| 199 | 00000010 75 01 95 08 81 02 95 01 75 08 81 03 95 05 75 01 |u.......u.....u.| 200 | 00000020 05 08 19 01 29 05 91 02 95 01 75 03 91 03 95 06 |....).....u.....| 201 | 00000030 75 08 15 00 25 65 05 07 19 00 29 65 81 00 c0 |u...%e....)e...| 202 | 0000003f 203 | 204 | Such a sequence of bytes can be stored to the attribute with echo: 205 | 206 | $ echo -ne \\x05\\x01\\x09\\x06\\xa1..... 207 | 208 | Testing the HID function 209 | ------------------------ 210 | 211 | Device: 212 | - create the gadget 213 | - connect the gadget to a host, preferably not the one used 214 | to control the gadget 215 | - run a program which writes to /dev/hidg, e.g. 216 | a userspace program found in Documentation/usb/gadget_hid.txt: 217 | 218 | $ ./hid_gadget_test /dev/hidg0 keyboard 219 | 220 | Host: 221 | - observe the keystrokes from the gadget 222 | 223 | 7. LOOPBACK function 224 | ==================== 225 | 226 | The function is provided by usb_f_ss_lb.ko module. 227 | 228 | Function-specific configfs interface 229 | ------------------------------------ 230 | 231 | The function name to use when creating the function directory is "Loopback". 232 | The LOOPBACK function provides these attributes in its function directory: 233 | 234 | qlen - depth of loopback queue 235 | bulk_buflen - buffer length 236 | 237 | Testing the LOOPBACK function 238 | ----------------------------- 239 | 240 | device: run the gadget 241 | host: test-usb (tools/usb/testusb.c) 242 | 243 | 8. MASS STORAGE function 244 | ======================== 245 | 246 | The function is provided by usb_f_mass_storage.ko module. 247 | 248 | Function-specific configfs interface 249 | ------------------------------------ 250 | 251 | The function name to use when creating the function directory is "mass_storage". 252 | The MASS STORAGE function provides these attributes in its directory: 253 | files: 254 | 255 | stall - Set to permit function to halt bulk endpoints. 256 | Disabled on some USB devices known not to work 257 | correctly. You should set it to true. 258 | num_buffers - Number of pipeline buffers. Valid numbers 259 | are 2..4. Available only if 260 | CONFIG_USB_GADGET_DEBUG_FILES is set. 261 | 262 | and a default lun.0 directory corresponding to SCSI LUN #0. 263 | 264 | A new lun can be added with mkdir: 265 | 266 | $ mkdir functions/mass_storage.0/partition.5 267 | 268 | Lun numbering does not have to be continuous, except for lun #0 which is 269 | created by default. A maximum of 8 luns can be specified and they all must be 270 | named following the . scheme. The numbers can be 0..8. 271 | Probably a good convention is to name the luns "lun.", 272 | although it is not mandatory. 273 | 274 | In each lun directory there are the following attribute files: 275 | 276 | file - The path to the backing file for the LUN. 277 | Required if LUN is not marked as removable. 278 | ro - Flag specifying access to the LUN shall be 279 | read-only. This is implied if CD-ROM emulation 280 | is enabled as well as when it was impossible 281 | to open "filename" in R/W mode. 282 | removable - Flag specifying that LUN shall be indicated as 283 | being removable. 284 | cdrom - Flag specifying that LUN shall be reported as 285 | being a CD-ROM. 286 | nofua - Flag specifying that FUA flag 287 | in SCSI WRITE(10,12) 288 | 289 | Testing the MASS STORAGE function 290 | --------------------------------- 291 | 292 | device: connect the gadget, enable it 293 | host: dmesg, see the USB drives appear (if system configured to automatically 294 | mount) 295 | 296 | 9. MIDI function 297 | ================ 298 | 299 | The function is provided by usb_f_midi.ko module. 300 | 301 | Function-specific configfs interface 302 | ------------------------------------ 303 | 304 | The function name to use when creating the function directory is "midi". 305 | The MIDI function provides these attributes in its function directory: 306 | 307 | buflen - MIDI buffer length 308 | id - ID string for the USB MIDI adapter 309 | in_ports - number of MIDI input ports 310 | index - index value for the USB MIDI adapter 311 | out_ports - number of MIDI output ports 312 | qlen - USB read request queue length 313 | 314 | Testing the MIDI function 315 | ------------------------- 316 | 317 | There are two cases: playing a mid from the gadget to 318 | the host and playing a mid from the host to the gadget. 319 | 320 | 1) Playing a mid from the gadget to the host 321 | host) 322 | 323 | $ arecordmidi -l 324 | Port Client name Port name 325 | 14:0 Midi Through Midi Through Port-0 326 | 24:0 MIDI Gadget MIDI Gadget MIDI 1 327 | $ arecordmidi -p 24:0 from_gadget.mid 328 | 329 | gadget) 330 | 331 | $ aplaymidi -l 332 | Port Client name Port name 333 | 20:0 f_midi f_midi 334 | 335 | $ aplaymidi -p 20:0 to_host.mid 336 | 337 | 2) Playing a mid from the host to the gadget 338 | gadget) 339 | 340 | $ arecordmidi -l 341 | Port Client name Port name 342 | 20:0 f_midi f_midi 343 | 344 | $ arecordmidi -p 20:0 from_host.mid 345 | 346 | host) 347 | 348 | $ aplaymidi -l 349 | Port Client name Port name 350 | 14:0 Midi Through Midi Through Port-0 351 | 24:0 MIDI Gadget MIDI Gadget MIDI 1 352 | 353 | $ aplaymidi -p24:0 to_gadget.mid 354 | 355 | The from_gadget.mid should sound identical to the to_host.mid. 356 | The from_host.id should sound identical to the to_gadget.mid. 357 | 358 | MIDI files can be played to speakers/headphones with e.g. timidity installed 359 | 360 | $ aplaymidi -l 361 | Port Client name Port name 362 | 14:0 Midi Through Midi Through Port-0 363 | 24:0 MIDI Gadget MIDI Gadget MIDI 1 364 | 128:0 TiMidity TiMidity port 0 365 | 128:1 TiMidity TiMidity port 1 366 | 128:2 TiMidity TiMidity port 2 367 | 128:3 TiMidity TiMidity port 3 368 | 369 | $ aplaymidi -p 128:0 file.mid 370 | 371 | MIDI ports can be logically connected using the aconnect utility, e.g.: 372 | 373 | $ aconnect 24:0 128:0 # try it on the host 374 | 375 | After the gadget's MIDI port is connected to timidity's MIDI port, 376 | whatever is played at the gadget side with aplaymidi -l is audible 377 | in host's speakers/headphones. 378 | 379 | 10. NCM function 380 | ================ 381 | 382 | The function is provided by usb_f_ncm.ko module. 383 | 384 | Function-specific configfs interface 385 | ------------------------------------ 386 | 387 | The function name to use when creating the function directory is "ncm". 388 | The NCM function provides these attributes in its function directory: 389 | 390 | ifname - network device interface name associated with this 391 | function instance 392 | qmult - queue length multiplier for high and super speed 393 | host_addr - MAC address of host's end of this 394 | Ethernet over USB link 395 | dev_addr - MAC address of device's end of this 396 | Ethernet over USB link 397 | 398 | and after creating the functions/ncm. they contain default 399 | values: qmult is 5, dev_addr and host_addr are randomly selected. 400 | Except for ifname they can be written to until the function is linked to a 401 | configuration. The ifname is read-only and contains the name of the interface 402 | which was assigned by the net core, e. g. usb0. 403 | 404 | Testing the NCM function 405 | ------------------------ 406 | 407 | Configure IP addresses of the device and the host. Then: 408 | 409 | On the device: ping 410 | On the host: ping 411 | 412 | 11. OBEX function 413 | ================= 414 | 415 | The function is provided by usb_f_obex.ko module. 416 | 417 | Function-specific configfs interface 418 | ------------------------------------ 419 | 420 | The function name to use when creating the function directory is "obex". 421 | The OBEX function provides just one attribute in its function directory: 422 | 423 | port_num 424 | 425 | The attribute is read-only. 426 | 427 | There can be at most 4 ACM/generic serial/OBEX ports in the system. 428 | 429 | Testing the OBEX function 430 | ------------------------- 431 | 432 | On device: seriald -f /dev/ttyGS -s 1024 433 | On host: serialc -v -p -i -a1 -s1024 \ 434 | -t -r 435 | 436 | where seriald and serialc are Felipe's utilities found here: 437 | 438 | https://github.com/felipebalbi/usb-tools.git master 439 | 440 | 12. PHONET function 441 | =================== 442 | 443 | The function is provided by usb_f_phonet.ko module. 444 | 445 | Function-specific configfs interface 446 | ------------------------------------ 447 | 448 | The function name to use when creating the function directory is "phonet". 449 | The PHONET function provides just one attribute in its function directory: 450 | 451 | ifname - network device interface name associated with this 452 | function instance 453 | 454 | Testing the PHONET function 455 | --------------------------- 456 | 457 | It is not possible to test the SOCK_STREAM protocol without a specific piece 458 | of hardware, so only SOCK_DGRAM has been tested. For the latter to work, 459 | in the past I had to apply the patch mentioned here: 460 | 461 | http://www.spinics.net/lists/linux-usb/msg85689.html 462 | 463 | These tools are required: 464 | 465 | git://git.gitorious.org/meego-cellular/phonet-utils.git 466 | 467 | On the host: 468 | 469 | $ ./phonet -a 0x10 -i usbpn0 470 | $ ./pnroute add 0x6c usbpn0 471 | $./pnroute add 0x10 usbpn0 472 | $ ifconfig usbpn0 up 473 | 474 | On the device: 475 | 476 | $ ./phonet -a 0x6c -i upnlink0 477 | $ ./pnroute add 0x10 upnlink0 478 | $ ifconfig upnlink0 up 479 | 480 | Then a test program can be used: 481 | 482 | http://www.spinics.net/lists/linux-usb/msg85690.html 483 | 484 | On the device: 485 | 486 | $ ./pnxmit -a 0x6c -r 487 | 488 | On the host: 489 | 490 | $ ./pnxmit -a 0x10 -s 0x6c 491 | 492 | As a result some data should be sent from host to device. 493 | Then the other way round: 494 | 495 | On the host: 496 | 497 | $ ./pnxmit -a 0x10 -r 498 | 499 | On the device: 500 | 501 | $ ./pnxmit -a 0x6c -s 0x10 502 | 503 | 13. RNDIS function 504 | ================== 505 | 506 | The function is provided by usb_f_rndis.ko module. 507 | 508 | Function-specific configfs interface 509 | ------------------------------------ 510 | 511 | The function name to use when creating the function directory is "rndis". 512 | The RNDIS function provides these attributes in its function directory: 513 | 514 | ifname - network device interface name associated with this 515 | function instance 516 | qmult - queue length multiplier for high and super speed 517 | host_addr - MAC address of host's end of this 518 | Ethernet over USB link 519 | dev_addr - MAC address of device's end of this 520 | Ethernet over USB link 521 | 522 | and after creating the functions/rndis. they contain default 523 | values: qmult is 5, dev_addr and host_addr are randomly selected. 524 | Except for ifname they can be written to until the function is linked to a 525 | configuration. The ifname is read-only and contains the name of the interface 526 | which was assigned by the net core, e. g. usb0. 527 | 528 | Testing the RNDIS function 529 | -------------------------- 530 | 531 | Configure IP addresses of the device and the host. Then: 532 | 533 | On the device: ping 534 | On the host: ping 535 | 536 | 14. SERIAL function 537 | =================== 538 | 539 | The function is provided by usb_f_gser.ko module. 540 | 541 | Function-specific configfs interface 542 | ------------------------------------ 543 | 544 | The function name to use when creating the function directory is "gser". 545 | The SERIAL function provides just one attribute in its function directory: 546 | 547 | port_num 548 | 549 | The attribute is read-only. 550 | 551 | There can be at most 4 ACM/generic serial/OBEX ports in the system. 552 | 553 | Testing the SERIAL function 554 | --------------------------- 555 | 556 | On host: insmod usbserial 557 | echo VID PID >/sys/bus/usb-serial/drivers/generic/new_id 558 | On host: cat > /dev/ttyUSB 559 | On target: cat /dev/ttyGS 560 | 561 | then the other way round 562 | 563 | On target: cat > /dev/ttyGS 564 | On host: cat /dev/ttyUSB 565 | 566 | 15. SOURCESINK function 567 | ======================= 568 | 569 | The function is provided by usb_f_ss_lb.ko module. 570 | 571 | Function-specific configfs interface 572 | ------------------------------------ 573 | 574 | The function name to use when creating the function directory is "SourceSink". 575 | The SOURCESINK function provides these attributes in its function directory: 576 | 577 | pattern - 0 (all zeros), 1 (mod63), 2 (none) 578 | isoc_interval - 1..16 579 | isoc_maxpacket - 0 - 1023 (fs), 0 - 1024 (hs/ss) 580 | isoc_mult - 0..2 (hs/ss only) 581 | isoc_maxburst - 0..15 (ss only) 582 | bulk_buflen - buffer length 583 | bulk_qlen - depth of queue for bulk 584 | iso_qlen - depth of queue for iso 585 | 586 | Testing the SOURCESINK function 587 | ------------------------------- 588 | 589 | device: run the gadget 590 | host: test-usb (tools/usb/testusb.c) 591 | 592 | 593 | 16. UAC1 function (legacy implementation) 594 | ================= 595 | 596 | The function is provided by usb_f_uac1_legacy.ko module. 597 | 598 | Function-specific configfs interface 599 | ------------------------------------ 600 | 601 | The function name to use when creating the function directory 602 | is "uac1_legacy". 603 | The uac1 function provides these attributes in its function directory: 604 | 605 | audio_buf_size - audio buffer size 606 | fn_cap - capture pcm device file name 607 | fn_cntl - control device file name 608 | fn_play - playback pcm device file name 609 | req_buf_size - ISO OUT endpoint request buffer size 610 | req_count - ISO OUT endpoint request count 611 | 612 | The attributes have sane default values. 613 | 614 | Testing the UAC1 function 615 | ------------------------- 616 | 617 | device: run the gadget 618 | host: aplay -l # should list our USB Audio Gadget 619 | 620 | 17. UAC2 function 621 | ================= 622 | 623 | The function is provided by usb_f_uac2.ko module. 624 | 625 | Function-specific configfs interface 626 | ------------------------------------ 627 | 628 | The function name to use when creating the function directory is "uac2". 629 | The uac2 function provides these attributes in its function directory: 630 | 631 | c_chmask - capture channel mask 632 | c_srate - capture sampling rate 633 | c_ssize - capture sample size (bytes) 634 | p_chmask - playback channel mask 635 | p_srate - playback sampling rate 636 | p_ssize - playback sample size (bytes) 637 | req_number - the number of pre-allocated request for both capture 638 | and playback 639 | 640 | The attributes have sane default values. 641 | 642 | Testing the UAC2 function 643 | ------------------------- 644 | 645 | device: run the gadget 646 | host: aplay -l # should list our USB Audio Gadget 647 | 648 | This function does not require real hardware support, it just 649 | sends a stream of audio data to/from the host. In order to 650 | actually hear something at the device side, a command similar 651 | to this must be used at the device side: 652 | 653 | $ arecord -f dat -t wav -D hw:2,0 | aplay -D hw:0,0 & 654 | 655 | e.g.: 656 | 657 | $ arecord -f dat -t wav -D hw:CARD=UAC2Gadget,DEV=0 | \ 658 | aplay -D default:CARD=OdroidU3 659 | 660 | 18. UVC function 661 | ================ 662 | 663 | The function is provided by usb_f_uvc.ko module. 664 | 665 | Function-specific configfs interface 666 | ------------------------------------ 667 | 668 | The function name to use when creating the function directory is "uvc". 669 | The uvc function provides these attributes in its function directory: 670 | 671 | streaming_interval - interval for polling endpoint for data transfers 672 | streaming_maxburst - bMaxBurst for super speed companion descriptor 673 | streaming_maxpacket - maximum packet size this endpoint is capable of 674 | sending or receiving when this configuration is 675 | selected 676 | 677 | There are also "control" and "streaming" subdirectories, each of which contain 678 | a number of their subdirectories. There are some sane defaults provided, but 679 | the user must provide the following: 680 | 681 | control header - create in control/header, link from control/class/fs 682 | and/or control/class/ss 683 | streaming header - create in streaming/header, link from 684 | streaming/class/fs and/or streaming/class/hs and/or 685 | streaming/class/ss 686 | format description - create in streaming/mjpeg and/or 687 | streaming/uncompressed 688 | frame description - create in streaming/mjpeg/ and/or in 689 | streaming/uncompressed/ 690 | 691 | Each frame description contains frame interval specification, and each 692 | such specification consists of a number of lines with an inverval value 693 | in each line. The rules stated above are best illustrated with an example: 694 | 695 | # mkdir functions/uvc.usb0/control/header/h 696 | # cd functions/uvc.usb0/control/header/h 697 | # ln -s header/h class/fs 698 | # ln -s header/h class/ss 699 | # mkdir -p functions/uvc.usb0/streaming/uncompressed/u/360p 700 | # cat < functions/uvc.usb0/streaming/uncompressed/u/360p/dwFrameInterval 701 | 666666 702 | 1000000 703 | 5000000 704 | EOF 705 | # cd $GADGET_CONFIGFS_ROOT 706 | # mkdir functions/uvc.usb0/streaming/header/h 707 | # cd functions/uvc.usb0/streaming/header/h 708 | # ln -s ../../uncompressed/u 709 | # cd ../../class/fs 710 | # ln -s ../../header/h 711 | # cd ../../class/hs 712 | # ln -s ../../header/h 713 | # cd ../../class/ss 714 | # ln -s ../../header/h 715 | 716 | 717 | Testing the UVC function 718 | ------------------------ 719 | 720 | device: run the gadget, modprobe vivid 721 | 722 | # uvc-gadget -u /dev/video -v /dev/video 723 | 724 | where uvc-gadget is this program: 725 | http://git.ideasonboard.org/uvc-gadget.git 726 | 727 | with these patches: 728 | http://www.spinics.net/lists/linux-usb/msg99220.html 729 | 730 | host: luvcview -f yuv 731 | 732 | 19. PRINTER function 733 | ==================== 734 | 735 | The function is provided by usb_f_printer.ko module. 736 | 737 | Function-specific configfs interface 738 | ------------------------------------ 739 | 740 | The function name to use when creating the function directory is "printer". 741 | The printer function provides these attributes in its function directory: 742 | 743 | pnp_string - Data to be passed to the host in pnp string 744 | q_len - Number of requests per endpoint 745 | 746 | Testing the PRINTER function 747 | ---------------------------- 748 | 749 | The most basic testing: 750 | 751 | device: run the gadget 752 | # ls -l /devices/virtual/usb_printer_gadget/ 753 | 754 | should show g_printer. 755 | 756 | If udev is active, then /dev/g_printer should appear automatically. 757 | 758 | host: 759 | 760 | If udev is active, then e.g. /dev/usb/lp0 should appear. 761 | 762 | host->device transmission: 763 | 764 | device: 765 | # cat /dev/g_printer 766 | host: 767 | # cat > /dev/usb/lp0 768 | 769 | device->host transmission: 770 | 771 | # cat > /dev/g_printer 772 | host: 773 | # cat /dev/usb/lp0 774 | 775 | More advanced testing can be done with the prn_example 776 | described in Documentation/usb/gadget_printer.txt. 777 | 778 | 779 | 20. UAC1 function (virtual ALSA card, using u_audio API) 780 | ================= 781 | 782 | The function is provided by usb_f_uac1.ko module. 783 | It will create a virtual ALSA card and the audio streams are simply 784 | sinked to and sourced from it. 785 | 786 | Function-specific configfs interface 787 | ------------------------------------ 788 | 789 | The function name to use when creating the function directory is "uac1". 790 | The uac1 function provides these attributes in its function directory: 791 | 792 | c_chmask - capture channel mask 793 | c_srate - capture sampling rate 794 | c_ssize - capture sample size (bytes) 795 | p_chmask - playback channel mask 796 | p_srate - playback sampling rate 797 | p_ssize - playback sample size (bytes) 798 | req_number - the number of pre-allocated request for both capture 799 | and playback 800 | 801 | The attributes have sane default values. 802 | 803 | Testing the UAC1 function 804 | ------------------------- 805 | 806 | device: run the gadget 807 | host: aplay -l # should list our USB Audio Gadget 808 | 809 | This function does not require real hardware support, it just 810 | sends a stream of audio data to/from the host. In order to 811 | actually hear something at the device side, a command similar 812 | to this must be used at the device side: 813 | 814 | $ arecord -f dat -t wav -D hw:2,0 | aplay -D hw:0,0 & 815 | 816 | e.g.: 817 | 818 | $ arecord -f dat -t wav -D hw:CARD=UAC1Gadget,DEV=0 | \ 819 | aplay -D default:CARD=OdroidU3 -------------------------------------------------------------------------------- /doc/gadget_configfs.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Linux USB gadget configured through configfs 6 | 7 | 8 | 25th April 2013 9 | 10 | 11 | 12 | 13 | Overview 14 | ======== 15 | 16 | A USB Linux Gadget is a device which has a UDC (USB Device Controller) and can 17 | be connected to a USB Host to extend it with additional functions like a serial 18 | port or a mass storage capability. 19 | 20 | A gadget is seen by its host as a set of configurations, each of which contains 21 | a number of interfaces which, from the gadget's perspective, are known as 22 | functions, each function representing e.g. a serial connection or a SCSI disk. 23 | 24 | Linux provides a number of functions for gadgets to use. 25 | 26 | Creating a gadget means deciding what configurations there will be 27 | and which functions each configuration will provide. 28 | 29 | Configfs (please see Documentation/filesystems/configfs/*) lends itself nicely 30 | for the purpose of telling the kernel about the above mentioned decision. 31 | This document is about how to do it. 32 | 33 | It also describes how configfs integration into gadget is designed. 34 | 35 | 36 | 37 | 38 | Requirements 39 | ============ 40 | 41 | In order for this to work configfs must be available, so CONFIGFS_FS must be 42 | 'y' or 'm' in .config. As of this writing USB_LIBCOMPOSITE selects CONFIGFS_FS. 43 | 44 | 45 | 46 | 47 | Usage 48 | ===== 49 | 50 | (The original post describing the first function 51 | made available through configfs can be seen here: 52 | http://www.spinics.net/lists/linux-usb/msg76388.html) 53 | 54 | $ modprobe libcomposite 55 | $ mount none $CONFIGFS_HOME -t configfs 56 | 57 | where CONFIGFS_HOME is the mount point for configfs 58 | 59 | 1. Creating the gadgets 60 | ----------------------- 61 | 62 | For each gadget to be created its corresponding directory must be created: 63 | 64 | $ mkdir $CONFIGFS_HOME/usb_gadget/ 65 | 66 | e.g.: 67 | 68 | $ mkdir $CONFIGFS_HOME/usb_gadget/g1 69 | 70 | ... 71 | ... 72 | ... 73 | 74 | $ cd $CONFIGFS_HOME/usb_gadget/g1 75 | 76 | Each gadget needs to have its vendor id and product id specified: 77 | 78 | $ echo > idVendor 79 | $ echo > idProduct 80 | 81 | A gadget also needs its serial number, manufacturer and product strings. 82 | In order to have a place to store them, a strings subdirectory must be created 83 | for each language, e.g.: 84 | 85 | $ mkdir strings/0x409 86 | 87 | Then the strings can be specified: 88 | 89 | $ echo > strings/0x409/serialnumber 90 | $ echo > strings/0x409/manufacturer 91 | $ echo > strings/0x409/product 92 | 93 | 2. Creating the configurations 94 | ------------------------------ 95 | 96 | Each gadget will consist of a number of configurations, their corresponding 97 | directories must be created: 98 | 99 | $ mkdir configs/. 100 | 101 | where can be any string which is legal in a filesystem and the 102 | is the configuration's number, e.g.: 103 | 104 | $ mkdir configs/c.1 105 | 106 | ... 107 | ... 108 | ... 109 | 110 | Each configuration also needs its strings, so a subdirectory must be created 111 | for each language, e.g.: 112 | 113 | $ mkdir configs/c.1/strings/0x409 114 | 115 | Then the configuration string can be specified: 116 | 117 | $ echo > configs/c.1/strings/0x409/configuration 118 | 119 | Some attributes can also be set for a configuration, e.g.: 120 | 121 | $ echo 120 > configs/c.1/MaxPower 122 | 123 | 3. Creating the functions 124 | ------------------------- 125 | 126 | The gadget will provide some functions, for each function its corresponding 127 | directory must be created: 128 | 129 | $ mkdir functions/. 130 | 131 | where corresponds to one of allowed function names and instance name 132 | is an arbitrary string allowed in a filesystem, e.g.: 133 | 134 | $ mkdir functions/ncm.usb0 # usb_f_ncm.ko gets loaded with request_module() 135 | 136 | ... 137 | ... 138 | ... 139 | 140 | Each function provides its specific set of attributes, with either read-only 141 | or read-write access. Where applicable they need to be written to as 142 | appropriate. 143 | Please refer to Documentation/ABI/*/configfs-usb-gadget* for more information. 144 | 145 | 4. Associating the functions with their configurations 146 | ------------------------------------------------------ 147 | 148 | At this moment a number of gadgets is created, each of which has a number of 149 | configurations specified and a number of functions available. What remains 150 | is specifying which function is available in which configuration (the same 151 | function can be used in multiple configurations). This is achieved with 152 | creating symbolic links: 153 | 154 | $ ln -s functions/. configs/. 155 | 156 | e.g.: 157 | 158 | $ ln -s functions/ncm.usb0 configs/c.1 159 | 160 | ... 161 | ... 162 | ... 163 | 164 | 5. Enabling the gadget 165 | ---------------------- 166 | 167 | All the above steps serve the purpose of composing the gadget of 168 | configurations and functions. 169 | 170 | An example directory structure might look like this: 171 | 172 | . 173 | ./strings 174 | ./strings/0x409 175 | ./strings/0x409/serialnumber 176 | ./strings/0x409/product 177 | ./strings/0x409/manufacturer 178 | ./configs 179 | ./configs/c.1 180 | ./configs/c.1/ncm.usb0 -> ../../../../usb_gadget/g1/functions/ncm.usb0 181 | ./configs/c.1/strings 182 | ./configs/c.1/strings/0x409 183 | ./configs/c.1/strings/0x409/configuration 184 | ./configs/c.1/bmAttributes 185 | ./configs/c.1/MaxPower 186 | ./functions 187 | ./functions/ncm.usb0 188 | ./functions/ncm.usb0/ifname 189 | ./functions/ncm.usb0/qmult 190 | ./functions/ncm.usb0/host_addr 191 | ./functions/ncm.usb0/dev_addr 192 | ./UDC 193 | ./bcdUSB 194 | ./bcdDevice 195 | ./idProduct 196 | ./idVendor 197 | ./bMaxPacketSize0 198 | ./bDeviceProtocol 199 | ./bDeviceSubClass 200 | ./bDeviceClass 201 | 202 | 203 | Such a gadget must be finally enabled so that the USB host can enumerate it. 204 | In order to enable the gadget it must be bound to a UDC (USB Device Controller). 205 | 206 | $ echo > UDC 207 | 208 | where is one of those found in /sys/class/udc/* 209 | e.g.: 210 | 211 | $ echo s3c-hsotg > UDC 212 | 213 | 214 | 6. Disabling the gadget 215 | ----------------------- 216 | 217 | $ echo "" > UDC 218 | 219 | 7. Cleaning up 220 | -------------- 221 | 222 | Remove functions from configurations: 223 | 224 | $ rm configs/./ 225 | 226 | where . specify the configuration and is 227 | a symlink to a function being removed from the configuration, e.g.: 228 | 229 | $ rm configfs/c.1/ncm.usb0 230 | 231 | ... 232 | ... 233 | ... 234 | 235 | Remove strings directories in configurations 236 | 237 | $ rmdir configs/./strings/ 238 | 239 | e.g.: 240 | 241 | $ rmdir configs/c.1/strings/0x409 242 | 243 | ... 244 | ... 245 | ... 246 | 247 | and remove the configurations 248 | 249 | $ rmdir configs/. 250 | 251 | e.g.: 252 | 253 | rmdir configs/c.1 254 | 255 | ... 256 | ... 257 | ... 258 | 259 | Remove functions (function modules are not unloaded, though) 260 | 261 | $ rmdir functions/. 262 | 263 | e.g.: 264 | 265 | $ rmdir functions/ncm.usb0 266 | 267 | ... 268 | ... 269 | ... 270 | 271 | Remove strings directories in the gadget 272 | 273 | $ rmdir strings/ 274 | 275 | e.g.: 276 | 277 | $ rmdir strings/0x409 278 | 279 | and finally remove the gadget: 280 | 281 | $ cd .. 282 | $ rmdir 283 | 284 | e.g.: 285 | 286 | $ rmdir g1 287 | 288 | 289 | 290 | 291 | Implementation design 292 | ===================== 293 | 294 | Below the idea of how configfs works is presented. 295 | In configfs there are items and groups, both represented as directories. 296 | The difference between an item and a group is that a group can contain 297 | other groups. In the picture below only an item is shown. 298 | Both items and groups can have attributes, which are represented as files. 299 | The user can create and remove directories, but cannot remove files, 300 | which can be read-only or read-write, depending on what they represent. 301 | 302 | The filesystem part of configfs operates on config_items/groups and 303 | configfs_attributes which are generic and of the same type for all 304 | configured elements. However, they are embedded in usage-specific 305 | larger structures. In the picture below there is a "cs" which contains 306 | a config_item and an "sa" which contains a configfs_attribute. 307 | 308 | The filesystem view would be like this: 309 | 310 | ./ 311 | ./cs (directory) 312 | | 313 | +--sa (file) 314 | | 315 | . 316 | . 317 | . 318 | 319 | Whenever a user reads/writes the "sa" file, a function is called 320 | which accepts a struct config_item and a struct configfs_attribute. 321 | In the said function the "cs" and "sa" are retrieved using the well 322 | known container_of technique and an appropriate sa's function (show or 323 | store) is called and passed the "cs" and a character buffer. The "show" 324 | is for displaying the file's contents (copy data from the cs to the 325 | buffer), while the "store" is for modifying the file's contents (copy data 326 | from the buffer to the cs), but it is up to the implementer of the 327 | two functions to decide what they actually do. 328 | 329 | typedef struct configured_structure cs; 330 | typedef struct specific_attribute sa; 331 | 332 | sa 333 | +----------------------------------+ 334 | cs | (*show)(cs *, buffer); | 335 | +-----------------+ | (*store)(cs *, buffer, length); | 336 | | | | | 337 | | +-------------+ | | +------------------+ | 338 | | | struct |-|----|------>|struct | | 339 | | | config_item | | | |configfs_attribute| | 340 | | +-------------+ | | +------------------+ | 341 | | | +----------------------------------+ 342 | | data to be set | . 343 | | | . 344 | +-----------------+ . 345 | 346 | The file names are decided by the config item/group designer, while 347 | the directories in general can be named at will. A group can have 348 | a number of its default sub-groups created automatically. 349 | 350 | For more information on configfs please see 351 | Documentation/filesystems/configfs/*. 352 | 353 | The concepts described above translate to USB gadgets like this: 354 | 355 | 1. A gadget has its config group, which has some attributes (idVendor, 356 | idProduct etc) and default sub-groups (configs, functions, strings). 357 | Writing to the attributes causes the information to be stored in 358 | appropriate locations. In the configs, functions and strings sub-groups 359 | a user can create their sub-groups to represent configurations, functions, 360 | and groups of strings in a given language. 361 | 362 | 2. The user creates configurations and functions, in the configurations 363 | creates symbolic links to functions. This information is used when the 364 | gadget's UDC attribute is written to, which means binding the gadget 365 | to the UDC. The code in drivers/usb/gadget/configfs.c iterates over 366 | all configurations, and in each configuration it iterates over all 367 | functions and binds them. This way the whole gadget is bound. 368 | 369 | 3. The file drivers/usb/gadget/configfs.c contains code for 370 | 371 | - gadget's config_group 372 | - gadget's default groups (configs, functions, strings) 373 | - associating functions with configurations (symlinks) 374 | 375 | 4. Each USB function naturally has its own view of what it wants 376 | configured, so config_groups for particular functions are defined 377 | in the functions implementation files drivers/usb/gadget/f_*.c. 378 | 379 | 5. Funciton's code is written in such a way that it uses 380 | 381 | usb_get_function_instance(), which, in turn, calls request_module. 382 | So, provided that modprobe works, modules for particular functions 383 | are loaded automatically. Please note that the converse is not true: 384 | after a gadget is disabled and torn down, the modules remain loaded. 385 | -------------------------------------------------------------------------------- /uvc-gadget.c: -------------------------------------------------------------------------------- 1 | /* 2 | * UVC gadget test application 3 | * 4 | * Copyright (C) 2010 Ideas on board SPRL 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License along 17 | * with this program; if not, write to the Free Software Foundation, Inc., 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | #include "uvc.h" 40 | 41 | /* Enable debug prints. */ 42 | #undef ENABLE_BUFFER_DEBUG 43 | #undef ENABLE_USB_REQUEST_DEBUG 44 | 45 | #define CLEAR(x) memset(&(x), 0, sizeof(x)) 46 | #define max(a, b) (((a) > (b)) ? (a) : (b)) 47 | 48 | #define clamp(val, min, max) \ 49 | ({ \ 50 | typeof(val) __val = (val); \ 51 | typeof(min) __min = (min); \ 52 | typeof(max) __max = (max); \ 53 | (void)(&__val == &__min); \ 54 | (void)(&__val == &__max); \ 55 | __val = __val < __min ? __min : __val; \ 56 | __val > __max ? __max : __val; \ 57 | }) 58 | 59 | #define ARRAY_SIZE(a) ((sizeof(a) / sizeof(a[0]))) 60 | #define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, ((x) >> 24) & 0xff 61 | 62 | /* 63 | * The UVC webcam gadget kernel driver (g_webcam.ko) supports changing 64 | * the Brightness attribute of the Processing Unit (PU). by default. If 65 | * the underlying video capture device supports changing the Brightness 66 | * attribute of the image being acquired (like the Virtual Video, VIVI 67 | * driver), then we should route this UVC request to the respective 68 | * video capture device. 69 | * 70 | * Incase, there is no actual video capture device associated with the 71 | * UVC gadget and we wish to use this application as the final 72 | * destination of the UVC specific requests then we should return 73 | * pre-cooked (static) responses to GET_CUR(BRIGHTNESS) and 74 | * SET_CUR(BRIGHTNESS) commands to keep command verifier test tools like 75 | * UVC class specific test suite of USBCV, happy. 76 | * 77 | * Note that the values taken below are in sync with the VIVI driver and 78 | * must be changed for your specific video capture device. These values 79 | * also work well in case there in no actual video capture device. 80 | */ 81 | #define PU_BRIGHTNESS_MIN_VAL 0 82 | #define PU_BRIGHTNESS_MAX_VAL 255 83 | #define PU_BRIGHTNESS_STEP_SIZE 1 84 | #define PU_BRIGHTNESS_DEFAULT_VAL 127 85 | 86 | /* --------------------------------------------------------------------------- 87 | * Generic stuff 88 | */ 89 | 90 | /* IO methods supported */ 91 | enum io_method { 92 | IO_METHOD_MMAP, 93 | IO_METHOD_USERPTR, 94 | }; 95 | 96 | /* Buffer representing one video frame */ 97 | struct buffer { 98 | struct v4l2_buffer buf; 99 | void *start; 100 | size_t length; 101 | }; 102 | 103 | /* --------------------------------------------------------------------------- 104 | * UVC specific stuff 105 | */ 106 | 107 | struct uvc_frame_info { 108 | unsigned int width; 109 | unsigned int height; 110 | unsigned int intervals[8]; 111 | }; 112 | 113 | struct uvc_format_info { 114 | unsigned int fcc; 115 | const struct uvc_frame_info *frames; 116 | }; 117 | 118 | static const struct uvc_frame_info uvc_frames_yuyv[] = { 119 | { 120 | 640, 121 | 360, 122 | {666666, 10000000, 50000000, 0}, 123 | }, 124 | { 125 | 1280, 126 | 720, 127 | {50000000, 0}, 128 | }, 129 | { 130 | 0, 131 | 0, 132 | { 133 | 0, 134 | }, 135 | }, 136 | }; 137 | 138 | static const struct uvc_frame_info uvc_frames_mjpeg[] = { 139 | { 140 | 640, 141 | 360, 142 | {666666, 10000000, 50000000, 0}, 143 | }, 144 | { 145 | 1280, 146 | 720, 147 | {50000000, 0}, 148 | }, 149 | { 150 | 0, 151 | 0, 152 | { 153 | 0, 154 | }, 155 | }, 156 | }; 157 | 158 | static const struct uvc_format_info uvc_formats[] = { 159 | {V4L2_PIX_FMT_YUYV, uvc_frames_yuyv}, 160 | {V4L2_PIX_FMT_MJPEG, uvc_frames_mjpeg}, 161 | }; 162 | 163 | /* --------------------------------------------------------------------------- 164 | * V4L2 and UVC device instances 165 | */ 166 | 167 | /* Represents a V4L2 based video capture device */ 168 | struct v4l2_device { 169 | /* v4l2 device specific */ 170 | int v4l2_fd; 171 | int is_streaming; 172 | char *v4l2_devname; 173 | 174 | /* v4l2 buffer specific */ 175 | enum io_method io; 176 | struct buffer *mem; 177 | unsigned int nbufs; 178 | 179 | /* v4l2 buffer queue and dequeue counters */ 180 | unsigned long long int qbuf_count; 181 | unsigned long long int dqbuf_count; 182 | 183 | /* uvc device hook */ 184 | struct uvc_device *udev; 185 | }; 186 | 187 | /* Represents a UVC based video output device */ 188 | struct uvc_device { 189 | /* uvc device specific */ 190 | int uvc_fd; 191 | int is_streaming; 192 | int run_standalone; 193 | char *uvc_devname; 194 | 195 | /* uvc control request specific */ 196 | 197 | struct uvc_streaming_control probe; 198 | struct uvc_streaming_control commit; 199 | int control; 200 | struct uvc_request_data request_error_code; 201 | unsigned int brightness_val; 202 | 203 | /* uvc buffer specific */ 204 | enum io_method io; 205 | struct buffer *mem; 206 | struct buffer *dummy_buf; 207 | unsigned int nbufs; 208 | unsigned int fcc; 209 | unsigned int width; 210 | unsigned int height; 211 | 212 | unsigned int bulk; 213 | uint8_t color; 214 | unsigned int imgsize; 215 | void *imgdata; 216 | 217 | /* USB speed specific */ 218 | int mult; 219 | int burst; 220 | int maxpkt; 221 | enum usb_device_speed speed; 222 | 223 | /* uvc specific flags */ 224 | int first_buffer_queued; 225 | int uvc_shutdown_requested; 226 | 227 | /* uvc buffer queue and dequeue counters */ 228 | unsigned long long int qbuf_count; 229 | unsigned long long int dqbuf_count; 230 | 231 | /* v4l2 device hook */ 232 | struct v4l2_device *vdev; 233 | }; 234 | 235 | /* forward declarations */ 236 | static int uvc_video_stream(struct uvc_device *dev, int enable); 237 | 238 | /* --------------------------------------------------------------------------- 239 | * V4L2 streaming related 240 | */ 241 | 242 | static int v4l2_uninit_device(struct v4l2_device *dev) 243 | { 244 | unsigned int i; 245 | int ret; 246 | 247 | switch (dev->io) { 248 | case IO_METHOD_MMAP: 249 | for (i = 0; i < dev->nbufs; ++i) { 250 | ret = munmap(dev->mem[i].start, dev->mem[i].length); 251 | if (ret < 0) { 252 | printf("V4L2: munmap failed\n"); 253 | return ret; 254 | } 255 | } 256 | 257 | free(dev->mem); 258 | break; 259 | 260 | case IO_METHOD_USERPTR: 261 | default: 262 | break; 263 | } 264 | 265 | return 0; 266 | } 267 | 268 | static int v4l2_reqbufs_mmap(struct v4l2_device *dev, int nbufs) 269 | { 270 | struct v4l2_requestbuffers req; 271 | unsigned int i = 0; 272 | int ret; 273 | 274 | CLEAR(req); 275 | 276 | req.count = nbufs; 277 | req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 278 | req.memory = V4L2_MEMORY_MMAP; 279 | 280 | ret = ioctl(dev->v4l2_fd, VIDIOC_REQBUFS, &req); 281 | if (ret < 0) { 282 | if (ret == -EINVAL) 283 | printf("V4L2: does not support memory mapping\n"); 284 | else 285 | printf("V4L2: VIDIOC_REQBUFS error %s (%d).\n", strerror(errno), errno); 286 | goto err; 287 | } 288 | 289 | if (!req.count) 290 | return 0; 291 | 292 | if (req.count < 2) { 293 | printf("V4L2: Insufficient buffer memory.\n"); 294 | ret = -EINVAL; 295 | goto err; 296 | } 297 | 298 | /* Map the buffers. */ 299 | dev->mem = calloc(req.count, sizeof dev->mem[0]); 300 | if (!dev->mem) { 301 | printf("V4L2: Out of memory\n"); 302 | ret = -ENOMEM; 303 | goto err; 304 | } 305 | 306 | for (i = 0; i < req.count; ++i) { 307 | memset(&dev->mem[i].buf, 0, sizeof(dev->mem[i].buf)); 308 | 309 | dev->mem[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 310 | dev->mem[i].buf.memory = V4L2_MEMORY_MMAP; 311 | dev->mem[i].buf.index = i; 312 | 313 | ret = ioctl(dev->v4l2_fd, VIDIOC_QUERYBUF, &(dev->mem[i].buf)); 314 | if (ret < 0) { 315 | printf( 316 | "V4L2: VIDIOC_QUERYBUF failed for buf %d: " 317 | "%s (%d).\n", 318 | i, strerror(errno), errno); 319 | ret = -EINVAL; 320 | goto err_free; 321 | } 322 | 323 | dev->mem[i].start = 324 | mmap(NULL /* start anywhere */, dev->mem[i].buf.length, PROT_READ | PROT_WRITE /* required */, 325 | MAP_SHARED /* recommended */, dev->v4l2_fd, dev->mem[i].buf.m.offset); 326 | 327 | if (MAP_FAILED == dev->mem[i].start) { 328 | printf("V4L2: Unable to map buffer %u: %s (%d).\n", i, strerror(errno), errno); 329 | dev->mem[i].length = 0; 330 | ret = -EINVAL; 331 | goto err_free; 332 | } 333 | 334 | dev->mem[i].length = dev->mem[i].buf.length; 335 | printf("V4L2: Buffer %u mapped at address %p.\n", i, dev->mem[i].start); 336 | } 337 | 338 | dev->nbufs = req.count; 339 | printf("V4L2: %u buffers allocated.\n", req.count); 340 | 341 | return 0; 342 | 343 | err_free: 344 | free(dev->mem); 345 | err: 346 | return ret; 347 | } 348 | 349 | static int v4l2_reqbufs_userptr(struct v4l2_device *dev, int nbufs) 350 | { 351 | struct v4l2_requestbuffers req; 352 | int ret; 353 | 354 | CLEAR(req); 355 | 356 | req.count = nbufs; 357 | req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 358 | req.memory = V4L2_MEMORY_USERPTR; 359 | 360 | ret = ioctl(dev->v4l2_fd, VIDIOC_REQBUFS, &req); 361 | if (ret < 0) { 362 | if (ret == -EINVAL) 363 | printf("V4L2: does not support user pointer i/o\n"); 364 | else 365 | printf("V4L2: VIDIOC_REQBUFS error %s (%d).\n", strerror(errno), errno); 366 | return ret; 367 | } 368 | 369 | dev->nbufs = req.count; 370 | printf("V4L2: %u buffers allocated.\n", req.count); 371 | 372 | return 0; 373 | } 374 | 375 | static int v4l2_reqbufs(struct v4l2_device *dev, int nbufs) 376 | { 377 | int ret = 0; 378 | 379 | switch (dev->io) { 380 | case IO_METHOD_MMAP: 381 | ret = v4l2_reqbufs_mmap(dev, nbufs); 382 | break; 383 | 384 | case IO_METHOD_USERPTR: 385 | ret = v4l2_reqbufs_userptr(dev, nbufs); 386 | break; 387 | 388 | default: 389 | ret = -EINVAL; 390 | break; 391 | } 392 | 393 | return ret; 394 | } 395 | 396 | static int v4l2_qbuf_mmap(struct v4l2_device *dev) 397 | { 398 | unsigned int i; 399 | int ret; 400 | 401 | for (i = 0; i < dev->nbufs; ++i) { 402 | memset(&dev->mem[i].buf, 0, sizeof(dev->mem[i].buf)); 403 | 404 | dev->mem[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 405 | dev->mem[i].buf.memory = V4L2_MEMORY_MMAP; 406 | dev->mem[i].buf.index = i; 407 | 408 | ret = ioctl(dev->v4l2_fd, VIDIOC_QBUF, &(dev->mem[i].buf)); 409 | if (ret < 0) { 410 | printf("V4L2: VIDIOC_QBUF failed : %s (%d).\n", strerror(errno), errno); 411 | return ret; 412 | } 413 | 414 | dev->qbuf_count++; 415 | } 416 | 417 | return 0; 418 | } 419 | 420 | static int v4l2_qbuf(struct v4l2_device *dev) 421 | { 422 | int ret = 0; 423 | 424 | switch (dev->io) { 425 | case IO_METHOD_MMAP: 426 | ret = v4l2_qbuf_mmap(dev); 427 | break; 428 | 429 | case IO_METHOD_USERPTR: 430 | /* Empty. */ 431 | ret = 0; 432 | break; 433 | 434 | default: 435 | ret = -EINVAL; 436 | break; 437 | } 438 | 439 | return ret; 440 | } 441 | 442 | static int v4l2_process_data(struct v4l2_device *dev) 443 | { 444 | int ret; 445 | struct v4l2_buffer vbuf; 446 | struct v4l2_buffer ubuf; 447 | 448 | /* Return immediately if V4l2 streaming has not yet started. */ 449 | if (!dev->is_streaming) 450 | return 0; 451 | 452 | if (dev->udev->first_buffer_queued) 453 | if (dev->dqbuf_count >= dev->qbuf_count) 454 | return 0; 455 | 456 | /* Dequeue spent buffer rom V4L2 domain. */ 457 | CLEAR(vbuf); 458 | 459 | vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 460 | switch (dev->io) { 461 | case IO_METHOD_USERPTR: 462 | vbuf.memory = V4L2_MEMORY_USERPTR; 463 | break; 464 | 465 | case IO_METHOD_MMAP: 466 | default: 467 | vbuf.memory = V4L2_MEMORY_MMAP; 468 | break; 469 | } 470 | 471 | ret = ioctl(dev->v4l2_fd, VIDIOC_DQBUF, &vbuf); 472 | if (ret < 0) { 473 | return ret; 474 | } 475 | 476 | dev->dqbuf_count++; 477 | 478 | #ifdef ENABLE_BUFFER_DEBUG 479 | printf("Dequeueing buffer at V4L2 side = %d\n", vbuf.index); 480 | #endif 481 | 482 | /* Queue video buffer to UVC domain. */ 483 | CLEAR(ubuf); 484 | 485 | ubuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 486 | switch (dev->udev->io) { 487 | case IO_METHOD_MMAP: 488 | ubuf.memory = V4L2_MEMORY_MMAP; 489 | ubuf.length = vbuf.length; 490 | ubuf.index = vbuf.index; 491 | ubuf.bytesused = vbuf.bytesused; 492 | break; 493 | 494 | case IO_METHOD_USERPTR: 495 | default: 496 | ubuf.memory = V4L2_MEMORY_USERPTR; 497 | ubuf.m.userptr = (unsigned long)dev->mem[vbuf.index].start; 498 | ubuf.length = dev->mem[vbuf.index].length; 499 | ubuf.index = vbuf.index; 500 | ubuf.bytesused = vbuf.bytesused; 501 | break; 502 | } 503 | 504 | ret = ioctl(dev->udev->uvc_fd, VIDIOC_QBUF, &ubuf); 505 | if (ret < 0) { 506 | /* Check for a USB disconnect/shutdown event. */ 507 | if (errno == ENODEV) { 508 | dev->udev->uvc_shutdown_requested = 1; 509 | printf( 510 | "UVC: Possible USB shutdown requested from " 511 | "Host, seen during VIDIOC_QBUF\n"); 512 | return 0; 513 | } else { 514 | return ret; 515 | } 516 | } 517 | 518 | dev->udev->qbuf_count++; 519 | 520 | #ifdef ENABLE_BUFFER_DEBUG 521 | printf("Queueing buffer at UVC side = %d\n", ubuf.index); 522 | #endif 523 | 524 | if (!dev->udev->first_buffer_queued && !dev->udev->run_standalone) { 525 | uvc_video_stream(dev->udev, 1); 526 | dev->udev->first_buffer_queued = 1; 527 | dev->udev->is_streaming = 1; 528 | } 529 | 530 | return 0; 531 | } 532 | 533 | /* --------------------------------------------------------------------------- 534 | * V4L2 generic stuff 535 | */ 536 | 537 | static int v4l2_get_format(struct v4l2_device *dev) 538 | { 539 | struct v4l2_format fmt; 540 | int ret; 541 | 542 | CLEAR(fmt); 543 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 544 | 545 | ret = ioctl(dev->v4l2_fd, VIDIOC_G_FMT, &fmt); 546 | if (ret < 0) { 547 | return ret; 548 | } 549 | 550 | printf("V4L2: Getting current format: %c%c%c%c %ux%u\n", pixfmtstr(fmt.fmt.pix.pixelformat), fmt.fmt.pix.width, 551 | fmt.fmt.pix.height); 552 | 553 | return 0; 554 | } 555 | 556 | static int v4l2_set_format(struct v4l2_device *dev, struct v4l2_format *fmt) 557 | { 558 | int ret; 559 | 560 | ret = ioctl(dev->v4l2_fd, VIDIOC_S_FMT, fmt); 561 | if (ret < 0) { 562 | printf("V4L2: Unable to set format %s (%d).\n", strerror(errno), errno); 563 | return ret; 564 | } 565 | 566 | printf("V4L2: Setting format to: %c%c%c%c %ux%u\n", pixfmtstr(fmt->fmt.pix.pixelformat), fmt->fmt.pix.width, 567 | fmt->fmt.pix.height); 568 | 569 | return 0; 570 | } 571 | 572 | static int v4l2_set_ctrl(struct v4l2_device *dev, int new_val, int ctrl) 573 | { 574 | struct v4l2_queryctrl queryctrl; 575 | struct v4l2_control control; 576 | int ret; 577 | 578 | CLEAR(queryctrl); 579 | 580 | switch (ctrl) { 581 | case V4L2_CID_BRIGHTNESS: 582 | queryctrl.id = V4L2_CID_BRIGHTNESS; 583 | ret = ioctl(dev->v4l2_fd, VIDIOC_QUERYCTRL, &queryctrl); 584 | if (-1 == ret) { 585 | if (errno != EINVAL) 586 | printf( 587 | "V4L2: VIDIOC_QUERYCTRL" 588 | " failed: %s (%d).\n", 589 | strerror(errno), errno); 590 | else 591 | printf( 592 | "V4L2_CID_BRIGHTNESS is not" 593 | " supported: %s (%d).\n", 594 | strerror(errno), errno); 595 | 596 | return ret; 597 | } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { 598 | printf("V4L2_CID_BRIGHTNESS is not supported.\n"); 599 | ret = -EINVAL; 600 | return ret; 601 | } else { 602 | CLEAR(control); 603 | control.id = V4L2_CID_BRIGHTNESS; 604 | control.value = new_val; 605 | 606 | ret = ioctl(dev->v4l2_fd, VIDIOC_S_CTRL, &control); 607 | if (-1 == ret) { 608 | printf("V4L2: VIDIOC_S_CTRL failed: %s (%d).\n", strerror(errno), errno); 609 | return ret; 610 | } 611 | } 612 | printf("V4L2: Brightness control changed to value = 0x%x\n", new_val); 613 | break; 614 | 615 | default: 616 | /* TODO: We don't support any other controls. */ 617 | return -EINVAL; 618 | } 619 | 620 | return 0; 621 | } 622 | 623 | static int v4l2_start_capturing(struct v4l2_device *dev) 624 | { 625 | int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 626 | int ret; 627 | 628 | ret = ioctl(dev->v4l2_fd, VIDIOC_STREAMON, &type); 629 | if (ret < 0) { 630 | printf("V4L2: Unable to start streaming: %s (%d).\n", strerror(errno), errno); 631 | return ret; 632 | } 633 | 634 | printf("V4L2: Starting video stream.\n"); 635 | 636 | return 0; 637 | } 638 | 639 | static int v4l2_stop_capturing(struct v4l2_device *dev) 640 | { 641 | enum v4l2_buf_type type; 642 | int ret; 643 | 644 | switch (dev->io) { 645 | case IO_METHOD_MMAP: 646 | type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 647 | 648 | ret = ioctl(dev->v4l2_fd, VIDIOC_STREAMOFF, &type); 649 | if (ret < 0) { 650 | printf("V4L2: VIDIOC_STREAMOFF failed: %s (%d).\n", strerror(errno), errno); 651 | return ret; 652 | } 653 | 654 | break; 655 | default: 656 | /* Nothing to do. */ 657 | break; 658 | } 659 | 660 | return 0; 661 | } 662 | static int v4l2_open(struct v4l2_device **v4l2, char *devname, struct v4l2_format *s_fmt) 663 | { 664 | struct v4l2_device *dev; 665 | struct v4l2_capability cap; 666 | int fd; 667 | int ret = -EINVAL; 668 | 669 | fd = open(devname, O_RDWR | O_NONBLOCK, 0); 670 | if (fd == -1) { 671 | printf("V4L2: device open failed: %s (%d).\n", strerror(errno), errno); 672 | return ret; 673 | } 674 | 675 | ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); 676 | if (ret < 0) { 677 | printf("V4L2: VIDIOC_QUERYCAP failed: %s (%d).\n", strerror(errno), errno); 678 | goto err; 679 | } 680 | 681 | if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { 682 | printf("V4L2: %s is no video capture device\n", devname); 683 | goto err; 684 | } 685 | 686 | if (!(cap.capabilities & V4L2_CAP_STREAMING)) { 687 | printf("V4L2: %s does not support streaming i/o\n", devname); 688 | goto err; 689 | } 690 | 691 | dev = calloc(1, sizeof *dev); 692 | if (dev == NULL) { 693 | ret = -ENOMEM; 694 | goto err; 695 | } 696 | 697 | printf("V4L2 device is %s on bus %s\n", cap.card, cap.bus_info); 698 | 699 | dev->v4l2_fd = fd; 700 | 701 | /* Get the default image format supported. */ 702 | ret = v4l2_get_format(dev); 703 | if (ret < 0) 704 | goto err_free; 705 | 706 | /* 707 | * Set the desired image format. 708 | * Note: VIDIOC_S_FMT may change width and height. 709 | */ 710 | ret = v4l2_set_format(dev, s_fmt); 711 | if (ret < 0) 712 | goto err_free; 713 | 714 | /* Get the changed image format. */ 715 | ret = v4l2_get_format(dev); 716 | if (ret < 0) 717 | goto err_free; 718 | 719 | printf("v4l2 open succeeded, file descriptor = %d\n", fd); 720 | 721 | *v4l2 = dev; 722 | 723 | return 0; 724 | 725 | err_free: 726 | free(dev); 727 | err: 728 | close(fd); 729 | 730 | return ret; 731 | } 732 | 733 | static void v4l2_close(struct v4l2_device *dev) 734 | { 735 | close(dev->v4l2_fd); 736 | free(dev); 737 | } 738 | 739 | /* --------------------------------------------------------------------------- 740 | * UVC generic stuff 741 | */ 742 | 743 | static int uvc_video_set_format(struct uvc_device *dev) 744 | { 745 | struct v4l2_format fmt; 746 | int ret; 747 | 748 | CLEAR(fmt); 749 | 750 | fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 751 | fmt.fmt.pix.width = dev->width; 752 | fmt.fmt.pix.height = dev->height; 753 | fmt.fmt.pix.pixelformat = dev->fcc; 754 | fmt.fmt.pix.field = V4L2_FIELD_NONE; 755 | if (dev->fcc == V4L2_PIX_FMT_MJPEG) 756 | fmt.fmt.pix.sizeimage = dev->imgsize * 1.5; 757 | 758 | ret = ioctl(dev->uvc_fd, VIDIOC_S_FMT, &fmt); 759 | if (ret < 0) { 760 | printf("UVC: Unable to set format %s (%d).\n", strerror(errno), errno); 761 | return ret; 762 | } 763 | 764 | printf("UVC: Setting format to: %c%c%c%c %ux%u\n", pixfmtstr(dev->fcc), dev->width, dev->height); 765 | 766 | return 0; 767 | } 768 | 769 | static int uvc_video_stream(struct uvc_device *dev, int enable) 770 | { 771 | int type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 772 | int ret; 773 | 774 | if (!enable) { 775 | ret = ioctl(dev->uvc_fd, VIDIOC_STREAMOFF, &type); 776 | if (ret < 0) { 777 | printf("UVC: VIDIOC_STREAMOFF failed: %s (%d).\n", strerror(errno), errno); 778 | return ret; 779 | } 780 | 781 | printf("UVC: Stopping video stream.\n"); 782 | 783 | return 0; 784 | } 785 | 786 | ret = ioctl(dev->uvc_fd, VIDIOC_STREAMON, &type); 787 | if (ret < 0) { 788 | printf("UVC: Unable to start streaming %s (%d).\n", strerror(errno), errno); 789 | return ret; 790 | } 791 | 792 | printf("UVC: Starting video stream.\n"); 793 | 794 | dev->uvc_shutdown_requested = 0; 795 | 796 | return 0; 797 | } 798 | 799 | static int uvc_uninit_device(struct uvc_device *dev) 800 | { 801 | unsigned int i; 802 | int ret; 803 | 804 | switch (dev->io) { 805 | case IO_METHOD_MMAP: 806 | for (i = 0; i < dev->nbufs; ++i) { 807 | ret = munmap(dev->mem[i].start, dev->mem[i].length); 808 | if (ret < 0) { 809 | printf("UVC: munmap failed\n"); 810 | return ret; 811 | } 812 | } 813 | 814 | free(dev->mem); 815 | break; 816 | 817 | case IO_METHOD_USERPTR: 818 | default: 819 | if (dev->run_standalone) { 820 | for (i = 0; i < dev->nbufs; ++i) 821 | free(dev->dummy_buf[i].start); 822 | 823 | free(dev->dummy_buf); 824 | } 825 | break; 826 | } 827 | 828 | return 0; 829 | } 830 | static int uvc_open(struct uvc_device **uvc, char *devname) 831 | { 832 | struct uvc_device *dev; 833 | struct v4l2_capability cap; 834 | int fd; 835 | int ret = -EINVAL; 836 | 837 | fd = open(devname, O_RDWR | O_NONBLOCK); 838 | if (fd == -1) { 839 | printf("UVC: device open failed: %s (%d).\n", strerror(errno), errno); 840 | return ret; 841 | } 842 | 843 | ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); 844 | if (ret < 0) { 845 | printf("UVC: unable to query uvc device: %s (%d)\n", strerror(errno), errno); 846 | goto err; 847 | } 848 | 849 | if (!(cap.capabilities & V4L2_CAP_VIDEO_OUTPUT)) { 850 | printf("UVC: %s is no video output device\n", devname); 851 | goto err; 852 | } 853 | 854 | dev = calloc(1, sizeof *dev); 855 | if (dev == NULL) { 856 | ret = -ENOMEM; 857 | goto err; 858 | } 859 | 860 | printf("uvc device is %s on bus %s\n", cap.card, cap.bus_info); 861 | printf("uvc open succeeded, file descriptor = %d\n", fd); 862 | 863 | dev->uvc_fd = fd; 864 | *uvc = dev; 865 | 866 | return 0; 867 | 868 | err: 869 | close(fd); 870 | return ret; 871 | } 872 | 873 | static void uvc_close(struct uvc_device *dev) 874 | { 875 | close(dev->uvc_fd); 876 | free(dev->imgdata); 877 | free(dev); 878 | } 879 | 880 | /* --------------------------------------------------------------------------- 881 | * UVC streaming related 882 | */ 883 | 884 | static void uvc_video_fill_buffer(struct uvc_device *dev, struct v4l2_buffer *buf) 885 | { 886 | unsigned int bpl; 887 | unsigned int i; 888 | 889 | switch (dev->fcc) { 890 | case V4L2_PIX_FMT_YUYV: 891 | /* Fill the buffer with video data. */ 892 | bpl = dev->width * 2; 893 | for (i = 0; i < dev->height; ++i) 894 | memset(dev->mem[buf->index].start + i * bpl, dev->color++, bpl); 895 | 896 | buf->bytesused = bpl * dev->height; 897 | break; 898 | 899 | case V4L2_PIX_FMT_MJPEG: 900 | memcpy(dev->mem[buf->index].start, dev->imgdata, dev->imgsize); 901 | buf->bytesused = dev->imgsize; 902 | break; 903 | } 904 | } 905 | 906 | static int uvc_video_process(struct uvc_device *dev) 907 | { 908 | struct v4l2_buffer ubuf; 909 | struct v4l2_buffer vbuf; 910 | unsigned int i; 911 | int ret; 912 | /* 913 | * Return immediately if UVC video output device has not started 914 | * streaming yet. 915 | */ 916 | if (!dev->is_streaming) 917 | return 0; 918 | /* Prepare a v4l2 buffer to be dequeued from UVC domain. */ 919 | CLEAR(ubuf); 920 | 921 | ubuf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 922 | switch (dev->io) { 923 | case IO_METHOD_MMAP: 924 | ubuf.memory = V4L2_MEMORY_MMAP; 925 | break; 926 | 927 | case IO_METHOD_USERPTR: 928 | default: 929 | ubuf.memory = V4L2_MEMORY_USERPTR; 930 | break; 931 | } 932 | if (dev->run_standalone) { 933 | /* UVC stanalone setup. */ 934 | ret = ioctl(dev->uvc_fd, VIDIOC_DQBUF, &ubuf); 935 | if (ret < 0) 936 | return ret; 937 | 938 | dev->dqbuf_count++; 939 | #ifdef ENABLE_BUFFER_DEBUG 940 | printf("DeQueued buffer at UVC side = %d\n", ubuf.index); 941 | #endif 942 | uvc_video_fill_buffer(dev, &ubuf); 943 | 944 | ret = ioctl(dev->uvc_fd, VIDIOC_QBUF, &ubuf); 945 | if (ret < 0) 946 | return ret; 947 | 948 | dev->qbuf_count++; 949 | 950 | #ifdef ENABLE_BUFFER_DEBUG 951 | printf("ReQueueing buffer at UVC side = %d\n", ubuf.index); 952 | #endif 953 | } else { 954 | /* UVC - V4L2 integrated path. */ 955 | 956 | /* 957 | * Return immediately if V4L2 video capture device has not 958 | * started streaming yet or if QBUF was not called even once on 959 | * the UVC side. 960 | */ 961 | if (!dev->vdev->is_streaming || !dev->first_buffer_queued) 962 | return 0; 963 | 964 | /* 965 | * Do not dequeue buffers from UVC side until there are atleast 966 | * 2 buffers available at UVC domain. 967 | */ 968 | if (!dev->uvc_shutdown_requested) 969 | if ((dev->dqbuf_count + 1) >= dev->qbuf_count) 970 | return 0; 971 | 972 | /* Dequeue the spent buffer from UVC domain */ 973 | ret = ioctl(dev->uvc_fd, VIDIOC_DQBUF, &ubuf); 974 | if (ret < 0) { 975 | printf("UVC: Unable to dequeue buffer: %s (%d).\n", strerror(errno), errno); 976 | return ret; 977 | } 978 | 979 | if (dev->io == IO_METHOD_USERPTR) 980 | for (i = 0; i < dev->nbufs; ++i) 981 | if (ubuf.m.userptr == (unsigned long)dev->vdev->mem[i].start && ubuf.length == dev->vdev->mem[i].length) 982 | break; 983 | 984 | dev->dqbuf_count++; 985 | 986 | #ifdef ENABLE_BUFFER_DEBUG 987 | printf("DeQueued buffer at UVC side=%d\n", ubuf.index); 988 | #endif 989 | 990 | /* 991 | * If the dequeued buffer was marked with state ERROR by the 992 | * underlying UVC driver gadget, do not queue the same to V4l2 993 | * and wait for a STREAMOFF event on UVC side corresponding to 994 | * set_alt(0). So, now all buffers pending at UVC end will be 995 | * dequeued one-by-one and we will enter a state where we once 996 | * again wait for a set_alt(1) command from the USB host side. 997 | */ 998 | if (ubuf.flags & V4L2_BUF_FLAG_ERROR) { 999 | dev->uvc_shutdown_requested = 1; 1000 | printf( 1001 | "UVC: Possible USB shutdown requested from " 1002 | "Host, seen during VIDIOC_DQBUF\n"); 1003 | return 0; 1004 | } 1005 | 1006 | /* Queue the buffer to V4L2 domain */ 1007 | CLEAR(vbuf); 1008 | 1009 | vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1010 | vbuf.memory = V4L2_MEMORY_MMAP; 1011 | vbuf.index = ubuf.index; 1012 | 1013 | ret = ioctl(dev->vdev->v4l2_fd, VIDIOC_QBUF, &vbuf); 1014 | if (ret < 0) 1015 | return ret; 1016 | 1017 | dev->vdev->qbuf_count++; 1018 | 1019 | #ifdef ENABLE_BUFFER_DEBUG 1020 | printf("ReQueueing buffer at V4L2 side = %d\n", vbuf.index); 1021 | #endif 1022 | } 1023 | 1024 | return 0; 1025 | } 1026 | 1027 | static int uvc_video_qbuf_mmap(struct uvc_device *dev) 1028 | { 1029 | unsigned int i; 1030 | int ret; 1031 | 1032 | for (i = 0; i < dev->nbufs; ++i) { 1033 | memset(&dev->mem[i].buf, 0, sizeof(dev->mem[i].buf)); 1034 | 1035 | dev->mem[i].buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 1036 | dev->mem[i].buf.memory = V4L2_MEMORY_MMAP; 1037 | dev->mem[i].buf.index = i; 1038 | 1039 | /* UVC standalone setup. */ 1040 | if (dev->run_standalone) 1041 | uvc_video_fill_buffer(dev, &(dev->mem[i].buf)); 1042 | 1043 | ret = ioctl(dev->uvc_fd, VIDIOC_QBUF, &(dev->mem[i].buf)); 1044 | if (ret < 0) { 1045 | printf("UVC: VIDIOC_QBUF failed : %s (%d).\n", strerror(errno), errno); 1046 | return ret; 1047 | } 1048 | 1049 | dev->qbuf_count++; 1050 | } 1051 | 1052 | return 0; 1053 | } 1054 | 1055 | static int uvc_video_qbuf_userptr(struct uvc_device *dev) 1056 | { 1057 | unsigned int i; 1058 | int ret; 1059 | 1060 | /* UVC standalone setup. */ 1061 | if (dev->run_standalone) { 1062 | for (i = 0; i < dev->nbufs; ++i) { 1063 | struct v4l2_buffer buf; 1064 | 1065 | CLEAR(buf); 1066 | buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 1067 | buf.memory = V4L2_MEMORY_USERPTR; 1068 | buf.m.userptr = (unsigned long)dev->dummy_buf[i].start; 1069 | buf.length = dev->dummy_buf[i].length; 1070 | buf.index = i; 1071 | 1072 | ret = ioctl(dev->uvc_fd, VIDIOC_QBUF, &buf); 1073 | if (ret < 0) { 1074 | printf("UVC: VIDIOC_QBUF failed : %s (%d).\n", strerror(errno), errno); 1075 | return ret; 1076 | } 1077 | 1078 | dev->qbuf_count++; 1079 | } 1080 | } 1081 | 1082 | return 0; 1083 | } 1084 | 1085 | static int uvc_video_qbuf(struct uvc_device *dev) 1086 | { 1087 | int ret = 0; 1088 | 1089 | switch (dev->io) { 1090 | case IO_METHOD_MMAP: 1091 | ret = uvc_video_qbuf_mmap(dev); 1092 | break; 1093 | 1094 | case IO_METHOD_USERPTR: 1095 | ret = uvc_video_qbuf_userptr(dev); 1096 | break; 1097 | 1098 | default: 1099 | ret = -EINVAL; 1100 | break; 1101 | } 1102 | 1103 | return ret; 1104 | } 1105 | 1106 | static int uvc_video_reqbufs_mmap(struct uvc_device *dev, int nbufs) 1107 | { 1108 | struct v4l2_requestbuffers rb; 1109 | unsigned int i; 1110 | int ret; 1111 | 1112 | CLEAR(rb); 1113 | 1114 | rb.count = nbufs; 1115 | rb.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 1116 | rb.memory = V4L2_MEMORY_MMAP; 1117 | 1118 | ret = ioctl(dev->uvc_fd, VIDIOC_REQBUFS, &rb); 1119 | if (ret < 0) { 1120 | if (ret == -EINVAL) 1121 | printf("UVC: does not support memory mapping\n"); 1122 | else 1123 | printf("UVC: Unable to allocate buffers: %s (%d).\n", strerror(errno), errno); 1124 | goto err; 1125 | } 1126 | 1127 | if (!rb.count) 1128 | return 0; 1129 | 1130 | if (rb.count < 2) { 1131 | printf("UVC: Insufficient buffer memory.\n"); 1132 | ret = -EINVAL; 1133 | goto err; 1134 | } 1135 | 1136 | /* Map the buffers. */ 1137 | dev->mem = calloc(rb.count, sizeof dev->mem[0]); 1138 | if (!dev->mem) { 1139 | printf("UVC: Out of memory\n"); 1140 | ret = -ENOMEM; 1141 | goto err; 1142 | } 1143 | 1144 | for (i = 0; i < rb.count; ++i) { 1145 | memset(&dev->mem[i].buf, 0, sizeof(dev->mem[i].buf)); 1146 | 1147 | dev->mem[i].buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 1148 | dev->mem[i].buf.memory = V4L2_MEMORY_MMAP; 1149 | dev->mem[i].buf.index = i; 1150 | 1151 | ret = ioctl(dev->uvc_fd, VIDIOC_QUERYBUF, &(dev->mem[i].buf)); 1152 | if (ret < 0) { 1153 | printf( 1154 | "UVC: VIDIOC_QUERYBUF failed for buf %d: " 1155 | "%s (%d).\n", 1156 | i, strerror(errno), errno); 1157 | ret = -EINVAL; 1158 | goto err_free; 1159 | } 1160 | dev->mem[i].start = 1161 | mmap(NULL /* start anywhere */, dev->mem[i].buf.length, PROT_READ | PROT_WRITE /* required */, 1162 | MAP_SHARED /* recommended */, dev->uvc_fd, dev->mem[i].buf.m.offset); 1163 | 1164 | if (MAP_FAILED == dev->mem[i].start) { 1165 | printf("UVC: Unable to map buffer %u: %s (%d).\n", i, strerror(errno), errno); 1166 | dev->mem[i].length = 0; 1167 | ret = -EINVAL; 1168 | goto err_free; 1169 | } 1170 | 1171 | dev->mem[i].length = dev->mem[i].buf.length; 1172 | printf("UVC: Buffer %u mapped at address %p.\n", i, dev->mem[i].start); 1173 | } 1174 | 1175 | dev->nbufs = rb.count; 1176 | printf("UVC: %u buffers allocated.\n", rb.count); 1177 | 1178 | return 0; 1179 | 1180 | err_free: 1181 | free(dev->mem); 1182 | err: 1183 | return ret; 1184 | } 1185 | 1186 | static int uvc_video_reqbufs_userptr(struct uvc_device *dev, int nbufs) 1187 | { 1188 | struct v4l2_requestbuffers rb; 1189 | unsigned int i, j, bpl, payload_size; 1190 | int ret; 1191 | 1192 | CLEAR(rb); 1193 | 1194 | rb.count = nbufs; 1195 | rb.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 1196 | rb.memory = V4L2_MEMORY_USERPTR; 1197 | 1198 | ret = ioctl(dev->uvc_fd, VIDIOC_REQBUFS, &rb); 1199 | if (ret < 0) { 1200 | if (ret == -EINVAL) 1201 | printf("UVC: does not support user pointer i/o\n"); 1202 | else 1203 | printf("UVC: VIDIOC_REQBUFS error %s (%d).\n", strerror(errno), errno); 1204 | goto err; 1205 | } 1206 | 1207 | if (!rb.count) 1208 | return 0; 1209 | 1210 | dev->nbufs = rb.count; 1211 | printf("UVC: %u buffers allocated.\n", rb.count); 1212 | 1213 | if (dev->run_standalone) { 1214 | /* Allocate buffers to hold dummy data pattern. */ 1215 | dev->dummy_buf = calloc(rb.count, sizeof dev->dummy_buf[0]); 1216 | if (!dev->dummy_buf) { 1217 | printf("UVC: Out of memory\n"); 1218 | ret = -ENOMEM; 1219 | goto err; 1220 | } 1221 | 1222 | switch (dev->fcc) { 1223 | case V4L2_PIX_FMT_YUYV: 1224 | bpl = dev->width * 2; 1225 | payload_size = dev->width * dev->height * 2; 1226 | break; 1227 | case V4L2_PIX_FMT_MJPEG: 1228 | payload_size = dev->imgsize; 1229 | break; 1230 | } 1231 | 1232 | for (i = 0; i < rb.count; ++i) { 1233 | dev->dummy_buf[i].length = payload_size; 1234 | dev->dummy_buf[i].start = malloc(payload_size); 1235 | if (!dev->dummy_buf[i].start) { 1236 | printf("UVC: Out of memory\n"); 1237 | ret = -ENOMEM; 1238 | goto err; 1239 | } 1240 | 1241 | if (V4L2_PIX_FMT_YUYV == dev->fcc) 1242 | for (j = 0; j < dev->height; ++j) 1243 | memset(dev->dummy_buf[i].start + j * bpl, dev->color++, bpl); 1244 | 1245 | if (V4L2_PIX_FMT_MJPEG == dev->fcc) 1246 | memcpy(dev->dummy_buf[i].start, dev->imgdata, dev->imgsize); 1247 | } 1248 | 1249 | dev->mem = dev->dummy_buf; 1250 | } 1251 | 1252 | return 0; 1253 | 1254 | err: 1255 | return ret; 1256 | } 1257 | 1258 | static int uvc_video_reqbufs(struct uvc_device *dev, int nbufs) 1259 | { 1260 | int ret = 0; 1261 | 1262 | switch (dev->io) { 1263 | case IO_METHOD_MMAP: 1264 | ret = uvc_video_reqbufs_mmap(dev, nbufs); 1265 | break; 1266 | 1267 | case IO_METHOD_USERPTR: 1268 | ret = uvc_video_reqbufs_userptr(dev, nbufs); 1269 | break; 1270 | 1271 | default: 1272 | ret = -EINVAL; 1273 | break; 1274 | } 1275 | 1276 | return ret; 1277 | } 1278 | 1279 | /* 1280 | * This function is called in response to either: 1281 | * - A SET_ALT(interface 1, alt setting 1) command from USB host, 1282 | * if the UVC gadget supports an ISOCHRONOUS video streaming endpoint 1283 | * or, 1284 | * 1285 | * - A UVC_VS_COMMIT_CONTROL command from USB host, if the UVC gadget 1286 | * supports a BULK type video streaming endpoint. 1287 | */ 1288 | static int uvc_handle_streamon_event(struct uvc_device *dev) 1289 | { 1290 | int ret; 1291 | 1292 | ret = uvc_video_reqbufs(dev, dev->nbufs); 1293 | if (ret < 0) 1294 | goto err; 1295 | 1296 | if (!dev->run_standalone) { 1297 | /* UVC - V4L2 integrated path. */ 1298 | if (IO_METHOD_USERPTR == dev->vdev->io) { 1299 | /* 1300 | * Ensure that the V4L2 video capture device has already 1301 | * some buffers queued. 1302 | */ 1303 | ret = v4l2_reqbufs(dev->vdev, dev->vdev->nbufs); 1304 | if (ret < 0) 1305 | goto err; 1306 | } 1307 | 1308 | ret = v4l2_qbuf(dev->vdev); 1309 | if (ret < 0) 1310 | goto err; 1311 | 1312 | /* Start V4L2 capturing now. */ 1313 | ret = v4l2_start_capturing(dev->vdev); 1314 | if (ret < 0) 1315 | goto err; 1316 | 1317 | dev->vdev->is_streaming = 1; 1318 | } 1319 | 1320 | /* Common setup. */ 1321 | 1322 | /* Queue buffers to UVC domain and start streaming. */ 1323 | ret = uvc_video_qbuf(dev); 1324 | if (ret < 0) 1325 | goto err; 1326 | 1327 | if (dev->run_standalone) { 1328 | uvc_video_stream(dev, 1); 1329 | dev->first_buffer_queued = 1; 1330 | dev->is_streaming = 1; 1331 | } 1332 | 1333 | return 0; 1334 | 1335 | err: 1336 | return ret; 1337 | } 1338 | 1339 | /* --------------------------------------------------------------------------- 1340 | * UVC Request processing 1341 | */ 1342 | 1343 | static void 1344 | uvc_fill_streaming_control(struct uvc_device *dev, struct uvc_streaming_control *ctrl, int iframe, int iformat) 1345 | { 1346 | const struct uvc_format_info *format; 1347 | const struct uvc_frame_info *frame; 1348 | unsigned int nframes; 1349 | 1350 | if (iformat < 0) 1351 | iformat = ARRAY_SIZE(uvc_formats) + iformat; 1352 | if (iformat < 0 || iformat >= (int)ARRAY_SIZE(uvc_formats)) 1353 | return; 1354 | format = &uvc_formats[iformat]; 1355 | 1356 | nframes = 0; 1357 | while (format->frames[nframes].width != 0) 1358 | ++nframes; 1359 | 1360 | if (iframe < 0) 1361 | iframe = nframes + iframe; 1362 | if (iframe < 0 || iframe >= (int)nframes) 1363 | return; 1364 | frame = &format->frames[iframe]; 1365 | 1366 | memset(ctrl, 0, sizeof *ctrl); 1367 | 1368 | ctrl->bmHint = 1; 1369 | ctrl->bFormatIndex = iformat + 1; 1370 | ctrl->bFrameIndex = iframe + 1; 1371 | ctrl->dwFrameInterval = frame->intervals[0]; 1372 | switch (format->fcc) { 1373 | case V4L2_PIX_FMT_YUYV: 1374 | ctrl->dwMaxVideoFrameSize = frame->width * frame->height * 2; 1375 | break; 1376 | case V4L2_PIX_FMT_MJPEG: 1377 | ctrl->dwMaxVideoFrameSize = dev->imgsize; 1378 | break; 1379 | } 1380 | 1381 | /* TODO: the UVC maxpayload transfer size should be filled 1382 | * by the driver. 1383 | */ 1384 | if (!dev->bulk) 1385 | ctrl->dwMaxPayloadTransferSize = (dev->maxpkt) * (dev->mult + 1) * (dev->burst + 1); 1386 | else 1387 | ctrl->dwMaxPayloadTransferSize = ctrl->dwMaxVideoFrameSize; 1388 | 1389 | ctrl->bmFramingInfo = 3; 1390 | ctrl->bPreferedVersion = 1; 1391 | ctrl->bMaxVersion = 1; 1392 | } 1393 | 1394 | static void 1395 | uvc_events_process_standard(struct uvc_device *dev, struct usb_ctrlrequest *ctrl, struct uvc_request_data *resp) 1396 | { 1397 | printf("standard request\n"); 1398 | (void)dev; 1399 | (void)ctrl; 1400 | (void)resp; 1401 | } 1402 | 1403 | static void uvc_events_process_control( 1404 | struct uvc_device *dev, uint8_t req, uint8_t cs, uint8_t entity_id, uint8_t len, struct uvc_request_data *resp) 1405 | { 1406 | switch (entity_id) { 1407 | case 0: 1408 | switch (cs) { 1409 | case UVC_VC_REQUEST_ERROR_CODE_CONTROL: 1410 | /* Send the request error code last prepared. */ 1411 | resp->data[0] = dev->request_error_code.data[0]; 1412 | resp->length = dev->request_error_code.length; 1413 | break; 1414 | 1415 | default: 1416 | /* 1417 | * If we were not supposed to handle this 1418 | * 'cs', prepare an error code response. 1419 | */ 1420 | dev->request_error_code.data[0] = 0x06; 1421 | dev->request_error_code.length = 1; 1422 | break; 1423 | } 1424 | break; 1425 | 1426 | /* Camera terminal unit 'UVC_VC_INPUT_TERMINAL'. */ 1427 | case 1: 1428 | switch (cs) { 1429 | /* 1430 | * We support only 'UVC_CT_AE_MODE_CONTROL' for CAMERA 1431 | * terminal, as our bmControls[0] = 2 for CT. Also we 1432 | * support only auto exposure. 1433 | */ 1434 | case UVC_CT_AE_MODE_CONTROL: 1435 | switch (req) { 1436 | case UVC_SET_CUR: 1437 | /* Incase of auto exposure, attempts to 1438 | * programmatically set the auto-adjusted 1439 | * controls are ignored. 1440 | */ 1441 | resp->data[0] = 0x01; 1442 | resp->length = 1; 1443 | /* 1444 | * For every successfully handled control 1445 | * request set the request error code to no 1446 | * error. 1447 | */ 1448 | dev->request_error_code.data[0] = 0x00; 1449 | dev->request_error_code.length = 1; 1450 | break; 1451 | 1452 | case UVC_GET_INFO: 1453 | /* 1454 | * TODO: We support Set and Get requests, but 1455 | * don't support async updates on an video 1456 | * status (interrupt) endpoint as of 1457 | * now. 1458 | */ 1459 | resp->data[0] = 0x03; 1460 | resp->length = 1; 1461 | /* 1462 | * For every successfully handled control 1463 | * request set the request error code to no 1464 | * error. 1465 | */ 1466 | dev->request_error_code.data[0] = 0x00; 1467 | dev->request_error_code.length = 1; 1468 | break; 1469 | 1470 | case UVC_GET_CUR: 1471 | case UVC_GET_DEF: 1472 | case UVC_GET_RES: 1473 | /* Auto Mode – auto Exposure Time, auto Iris. */ 1474 | resp->data[0] = 0x02; 1475 | resp->length = 1; 1476 | /* 1477 | * For every successfully handled control 1478 | * request set the request error code to no 1479 | * error. 1480 | */ 1481 | dev->request_error_code.data[0] = 0x00; 1482 | dev->request_error_code.length = 1; 1483 | break; 1484 | default: 1485 | /* 1486 | * We don't support this control, so STALL the 1487 | * control ep. 1488 | */ 1489 | resp->length = -EL2HLT; 1490 | /* 1491 | * For every unsupported control request 1492 | * set the request error code to appropriate 1493 | * value. 1494 | */ 1495 | dev->request_error_code.data[0] = 0x07; 1496 | dev->request_error_code.length = 1; 1497 | break; 1498 | } 1499 | break; 1500 | 1501 | default: 1502 | /* 1503 | * We don't support this control, so STALL the control 1504 | * ep. 1505 | */ 1506 | resp->length = -EL2HLT; 1507 | /* 1508 | * If we were not supposed to handle this 1509 | * 'cs', prepare a Request Error Code response. 1510 | */ 1511 | dev->request_error_code.data[0] = 0x06; 1512 | dev->request_error_code.length = 1; 1513 | break; 1514 | } 1515 | break; 1516 | 1517 | /* processing unit 'UVC_VC_PROCESSING_UNIT' */ 1518 | case 2: 1519 | switch (cs) { 1520 | /* 1521 | * We support only 'UVC_PU_BRIGHTNESS_CONTROL' for Processing 1522 | * Unit, as our bmControls[0] = 1 for PU. 1523 | */ 1524 | case UVC_PU_BRIGHTNESS_CONTROL: 1525 | switch (req) { 1526 | case UVC_SET_CUR: 1527 | resp->data[0] = 0x0; 1528 | resp->length = len; 1529 | /* 1530 | * For every successfully handled control 1531 | * request set the request error code to no 1532 | * error 1533 | */ 1534 | dev->request_error_code.data[0] = 0x00; 1535 | dev->request_error_code.length = 1; 1536 | break; 1537 | case UVC_GET_MIN: 1538 | resp->data[0] = PU_BRIGHTNESS_MIN_VAL; 1539 | resp->length = 2; 1540 | /* 1541 | * For every successfully handled control 1542 | * request set the request error code to no 1543 | * error 1544 | */ 1545 | dev->request_error_code.data[0] = 0x00; 1546 | dev->request_error_code.length = 1; 1547 | break; 1548 | case UVC_GET_MAX: 1549 | resp->data[0] = PU_BRIGHTNESS_MAX_VAL; 1550 | resp->length = 2; 1551 | /* 1552 | * For every successfully handled control 1553 | * request set the request error code to no 1554 | * error 1555 | */ 1556 | dev->request_error_code.data[0] = 0x00; 1557 | dev->request_error_code.length = 1; 1558 | break; 1559 | case UVC_GET_CUR: 1560 | resp->length = 2; 1561 | memcpy(&resp->data[0], &dev->brightness_val, resp->length); 1562 | /* 1563 | * For every successfully handled control 1564 | * request set the request error code to no 1565 | * error 1566 | */ 1567 | dev->request_error_code.data[0] = 0x00; 1568 | dev->request_error_code.length = 1; 1569 | break; 1570 | case UVC_GET_INFO: 1571 | /* 1572 | * We support Set and Get requests and don't 1573 | * support async updates on an interrupt endpt 1574 | */ 1575 | resp->data[0] = 0x03; 1576 | resp->length = 1; 1577 | /* 1578 | * For every successfully handled control 1579 | * request, set the request error code to no 1580 | * error. 1581 | */ 1582 | dev->request_error_code.data[0] = 0x00; 1583 | dev->request_error_code.length = 1; 1584 | break; 1585 | case UVC_GET_DEF: 1586 | resp->data[0] = PU_BRIGHTNESS_DEFAULT_VAL; 1587 | resp->length = 2; 1588 | /* 1589 | * For every successfully handled control 1590 | * request, set the request error code to no 1591 | * error. 1592 | */ 1593 | dev->request_error_code.data[0] = 0x00; 1594 | dev->request_error_code.length = 1; 1595 | break; 1596 | case UVC_GET_RES: 1597 | resp->data[0] = PU_BRIGHTNESS_STEP_SIZE; 1598 | resp->length = 2; 1599 | /* 1600 | * For every successfully handled control 1601 | * request, set the request error code to no 1602 | * error. 1603 | */ 1604 | dev->request_error_code.data[0] = 0x00; 1605 | dev->request_error_code.length = 1; 1606 | break; 1607 | default: 1608 | /* 1609 | * We don't support this control, so STALL the 1610 | * default control ep. 1611 | */ 1612 | resp->length = -EL2HLT; 1613 | /* 1614 | * For every unsupported control request 1615 | * set the request error code to appropriate 1616 | * code. 1617 | */ 1618 | dev->request_error_code.data[0] = 0x07; 1619 | dev->request_error_code.length = 1; 1620 | break; 1621 | } 1622 | break; 1623 | 1624 | default: 1625 | /* 1626 | * We don't support this control, so STALL the control 1627 | * ep. 1628 | */ 1629 | resp->length = -EL2HLT; 1630 | /* 1631 | * If we were not supposed to handle this 1632 | * 'cs', prepare a Request Error Code response. 1633 | */ 1634 | dev->request_error_code.data[0] = 0x06; 1635 | dev->request_error_code.length = 1; 1636 | break; 1637 | } 1638 | 1639 | break; 1640 | 1641 | default: 1642 | /* 1643 | * If we were not supposed to handle this 1644 | * 'cs', prepare a Request Error Code response. 1645 | */ 1646 | dev->request_error_code.data[0] = 0x06; 1647 | dev->request_error_code.length = 1; 1648 | break; 1649 | } 1650 | 1651 | printf("control request (req %02x cs %02x)\n", req, cs); 1652 | } 1653 | 1654 | static void uvc_events_process_streaming(struct uvc_device *dev, uint8_t req, uint8_t cs, struct uvc_request_data *resp) 1655 | { 1656 | struct uvc_streaming_control *ctrl; 1657 | 1658 | printf("streaming request (req %02x cs %02x)\n", req, cs); 1659 | 1660 | if (cs != UVC_VS_PROBE_CONTROL && cs != UVC_VS_COMMIT_CONTROL) 1661 | return; 1662 | 1663 | ctrl = (struct uvc_streaming_control *)&resp->data; 1664 | resp->length = sizeof *ctrl; 1665 | 1666 | switch (req) { 1667 | case UVC_SET_CUR: 1668 | dev->control = cs; 1669 | resp->length = 34; 1670 | break; 1671 | 1672 | case UVC_GET_CUR: 1673 | if (cs == UVC_VS_PROBE_CONTROL) 1674 | memcpy(ctrl, &dev->probe, sizeof *ctrl); 1675 | else 1676 | memcpy(ctrl, &dev->commit, sizeof *ctrl); 1677 | break; 1678 | 1679 | case UVC_GET_MIN: 1680 | case UVC_GET_MAX: 1681 | case UVC_GET_DEF: 1682 | uvc_fill_streaming_control(dev, ctrl, req == UVC_GET_MAX ? -1 : 0, req == UVC_GET_MAX ? -1 : 0); 1683 | break; 1684 | 1685 | case UVC_GET_RES: 1686 | CLEAR(ctrl); 1687 | break; 1688 | 1689 | case UVC_GET_LEN: 1690 | resp->data[0] = 0x00; 1691 | resp->data[1] = 0x22; 1692 | resp->length = 2; 1693 | break; 1694 | 1695 | case UVC_GET_INFO: 1696 | resp->data[0] = 0x03; 1697 | resp->length = 1; 1698 | break; 1699 | } 1700 | } 1701 | 1702 | static void 1703 | uvc_events_process_class(struct uvc_device *dev, struct usb_ctrlrequest *ctrl, struct uvc_request_data *resp) 1704 | { 1705 | if ((ctrl->bRequestType & USB_RECIP_MASK) != USB_RECIP_INTERFACE) 1706 | return; 1707 | 1708 | switch (ctrl->wIndex & 0xff) { 1709 | case UVC_INTF_CONTROL: 1710 | uvc_events_process_control(dev, ctrl->bRequest, ctrl->wValue >> 8, ctrl->wIndex >> 8, ctrl->wLength, resp); 1711 | break; 1712 | 1713 | case UVC_INTF_STREAMING: 1714 | uvc_events_process_streaming(dev, ctrl->bRequest, ctrl->wValue >> 8, resp); 1715 | break; 1716 | 1717 | default: 1718 | break; 1719 | } 1720 | } 1721 | static void 1722 | uvc_events_process_setup(struct uvc_device *dev, struct usb_ctrlrequest *ctrl, struct uvc_request_data *resp) 1723 | { 1724 | dev->control = 0; 1725 | 1726 | #ifdef ENABLE_USB_REQUEST_DEBUG 1727 | printf( 1728 | "\nbRequestType %02x bRequest %02x wValue %04x wIndex %04x " 1729 | "wLength %04x\n", 1730 | ctrl->bRequestType, ctrl->bRequest, ctrl->wValue, ctrl->wIndex, ctrl->wLength); 1731 | #endif 1732 | switch (ctrl->bRequestType & USB_TYPE_MASK) { 1733 | case USB_TYPE_STANDARD: 1734 | uvc_events_process_standard(dev, ctrl, resp); 1735 | break; 1736 | 1737 | case USB_TYPE_CLASS: 1738 | uvc_events_process_class(dev, ctrl, resp); 1739 | break; 1740 | 1741 | default: 1742 | break; 1743 | } 1744 | } 1745 | 1746 | static int 1747 | uvc_events_process_control_data(struct uvc_device *dev, uint8_t cs, uint8_t entity_id, struct uvc_request_data *data) 1748 | { 1749 | switch (entity_id) { 1750 | /* Processing unit 'UVC_VC_PROCESSING_UNIT'. */ 1751 | case 2: 1752 | switch (cs) { 1753 | /* 1754 | * We support only 'UVC_PU_BRIGHTNESS_CONTROL' for Processing 1755 | * Unit, as our bmControls[0] = 1 for PU. 1756 | */ 1757 | case UVC_PU_BRIGHTNESS_CONTROL: 1758 | memcpy(&dev->brightness_val, data->data, data->length); 1759 | /* UVC - V4L2 integrated path. */ 1760 | if (!dev->run_standalone) 1761 | /* 1762 | * Try to change the Brightness attribute on 1763 | * Video capture device. Note that this try may 1764 | * succeed or end up with some error on the 1765 | * video capture side. By default to keep tools 1766 | * like USBCV's UVC test suite happy, we are 1767 | * maintaining a local copy of the current 1768 | * brightness value in 'dev->brightness_val' 1769 | * variable and we return the same value to the 1770 | * Host on receiving a GET_CUR(BRIGHTNESS) 1771 | * control request. 1772 | * 1773 | * FIXME: Keeping in view the point discussed 1774 | * above, notice that we ignore the return value 1775 | * from the function call below. To be strictly 1776 | * compliant, we should return the same value 1777 | * accordingly. 1778 | */ 1779 | v4l2_set_ctrl(dev->vdev, dev->brightness_val, V4L2_CID_BRIGHTNESS); 1780 | break; 1781 | 1782 | default: 1783 | break; 1784 | } 1785 | 1786 | break; 1787 | 1788 | default: 1789 | break; 1790 | } 1791 | 1792 | printf("Control Request data phase (cs %02x entity %02x)\n", cs, entity_id); 1793 | 1794 | return 0; 1795 | } 1796 | 1797 | static int uvc_events_process_data(struct uvc_device *dev, struct uvc_request_data *data) 1798 | { 1799 | struct uvc_streaming_control *target; 1800 | struct uvc_streaming_control *ctrl; 1801 | struct v4l2_format fmt; 1802 | const struct uvc_format_info *format; 1803 | const struct uvc_frame_info *frame; 1804 | const unsigned int *interval; 1805 | unsigned int iformat, iframe; 1806 | unsigned int nframes; 1807 | unsigned int *val = (unsigned int *)data->data; 1808 | int ret; 1809 | 1810 | switch (dev->control) { 1811 | case UVC_VS_PROBE_CONTROL: 1812 | printf("setting probe control, length = %d\n", data->length); 1813 | target = &dev->probe; 1814 | break; 1815 | 1816 | case UVC_VS_COMMIT_CONTROL: 1817 | printf("setting commit control, length = %d\n", data->length); 1818 | target = &dev->commit; 1819 | break; 1820 | 1821 | default: 1822 | printf("setting unknown control, length = %d\n", data->length); 1823 | 1824 | /* 1825 | * As we support only BRIGHTNESS control, this request is 1826 | * for setting BRIGHTNESS control. 1827 | * Check for any invalid SET_CUR(BRIGHTNESS) requests 1828 | * from Host. Note that we support Brightness levels 1829 | * from 0x0 to 0x10 in a step of 0x1. So, any request 1830 | * with value greater than 0x10 is invalid. 1831 | */ 1832 | if (*val > PU_BRIGHTNESS_MAX_VAL) { 1833 | return -EINVAL; 1834 | } else { 1835 | ret = uvc_events_process_control_data(dev, UVC_PU_BRIGHTNESS_CONTROL, 2, data); 1836 | if (ret < 0) 1837 | goto err; 1838 | 1839 | return 0; 1840 | } 1841 | } 1842 | 1843 | ctrl = (struct uvc_streaming_control *)&data->data; 1844 | iformat = clamp((unsigned int)ctrl->bFormatIndex, 1U, (unsigned int)ARRAY_SIZE(uvc_formats)); 1845 | format = &uvc_formats[iformat - 1]; 1846 | 1847 | nframes = 0; 1848 | while (format->frames[nframes].width != 0) 1849 | ++nframes; 1850 | 1851 | iframe = clamp((unsigned int)ctrl->bFrameIndex, 1U, nframes); 1852 | frame = &format->frames[iframe - 1]; 1853 | interval = frame->intervals; 1854 | 1855 | while (interval[0] < ctrl->dwFrameInterval && interval[1]) 1856 | ++interval; 1857 | 1858 | target->bFormatIndex = iformat; 1859 | target->bFrameIndex = iframe; 1860 | switch (format->fcc) { 1861 | case V4L2_PIX_FMT_YUYV: 1862 | target->dwMaxVideoFrameSize = frame->width * frame->height * 2; 1863 | break; 1864 | case V4L2_PIX_FMT_MJPEG: 1865 | if (dev->imgsize == 0) 1866 | printf("WARNING: MJPEG requested and no image loaded.\n"); 1867 | target->dwMaxVideoFrameSize = dev->imgsize; 1868 | break; 1869 | } 1870 | target->dwFrameInterval = *interval; 1871 | 1872 | if (dev->control == UVC_VS_COMMIT_CONTROL) { 1873 | dev->fcc = format->fcc; 1874 | dev->width = frame->width; 1875 | dev->height = frame->height; 1876 | } 1877 | 1878 | return 0; 1879 | 1880 | err: 1881 | return ret; 1882 | } 1883 | 1884 | static void uvc_events_process(struct uvc_device *dev) 1885 | { 1886 | struct v4l2_event v4l2_event; 1887 | struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; 1888 | struct uvc_request_data resp; 1889 | int ret; 1890 | 1891 | ret = ioctl(dev->uvc_fd, VIDIOC_DQEVENT, &v4l2_event); 1892 | if (ret < 0) { 1893 | printf("VIDIOC_DQEVENT failed: %s (%d)\n", strerror(errno), errno); 1894 | return; 1895 | } 1896 | 1897 | memset(&resp, 0, sizeof resp); 1898 | resp.length = -EL2HLT; 1899 | 1900 | switch (v4l2_event.type) { 1901 | case UVC_EVENT_CONNECT: 1902 | return; 1903 | 1904 | case UVC_EVENT_DISCONNECT: 1905 | dev->uvc_shutdown_requested = 1; 1906 | printf( 1907 | "UVC: Possible USB shutdown requested from " 1908 | "Host, seen via UVC_EVENT_DISCONNECT\n"); 1909 | return; 1910 | 1911 | case UVC_EVENT_SETUP: 1912 | uvc_events_process_setup(dev, &uvc_event->req, &resp); 1913 | break; 1914 | 1915 | case UVC_EVENT_DATA: 1916 | ret = uvc_events_process_data(dev, &uvc_event->data); 1917 | if (ret < 0) 1918 | break; 1919 | return; 1920 | 1921 | case UVC_EVENT_STREAMON: 1922 | if (!dev->bulk) 1923 | uvc_handle_streamon_event(dev); 1924 | return; 1925 | 1926 | case UVC_EVENT_STREAMOFF: 1927 | /* Stop V4L2 streaming... */ 1928 | if (!dev->run_standalone && dev->vdev->is_streaming) { 1929 | /* UVC - V4L2 integrated path. */ 1930 | v4l2_stop_capturing(dev->vdev); 1931 | dev->vdev->is_streaming = 0; 1932 | } 1933 | 1934 | /* ... and now UVC streaming.. */ 1935 | if (dev->is_streaming) { 1936 | uvc_video_stream(dev, 0); 1937 | uvc_uninit_device(dev); 1938 | uvc_video_reqbufs(dev, 0); 1939 | dev->is_streaming = 0; 1940 | dev->first_buffer_queued = 0; 1941 | } 1942 | 1943 | return; 1944 | } 1945 | 1946 | ret = ioctl(dev->uvc_fd, UVCIOC_SEND_RESPONSE, &resp); 1947 | if (ret < 0) { 1948 | printf("UVCIOC_S_EVENT failed: %s (%d)\n", strerror(errno), errno); 1949 | return; 1950 | } 1951 | } 1952 | 1953 | static void uvc_events_init(struct uvc_device *dev) 1954 | { 1955 | struct v4l2_event_subscription sub; 1956 | unsigned int payload_size; 1957 | 1958 | switch (dev->fcc) { 1959 | case V4L2_PIX_FMT_YUYV: 1960 | payload_size = dev->width * dev->height * 2; 1961 | break; 1962 | case V4L2_PIX_FMT_MJPEG: 1963 | payload_size = dev->imgsize; 1964 | break; 1965 | } 1966 | 1967 | uvc_fill_streaming_control(dev, &dev->probe, 0, 0); 1968 | uvc_fill_streaming_control(dev, &dev->commit, 0, 0); 1969 | 1970 | if (dev->bulk) { 1971 | /* FIXME Crude hack, must be negotiated with the driver. */ 1972 | dev->probe.dwMaxPayloadTransferSize = dev->commit.dwMaxPayloadTransferSize = payload_size; 1973 | } 1974 | 1975 | memset(&sub, 0, sizeof sub); 1976 | sub.type = UVC_EVENT_SETUP; 1977 | ioctl(dev->uvc_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 1978 | sub.type = UVC_EVENT_DATA; 1979 | ioctl(dev->uvc_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 1980 | sub.type = UVC_EVENT_STREAMON; 1981 | ioctl(dev->uvc_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 1982 | sub.type = UVC_EVENT_STREAMOFF; 1983 | ioctl(dev->uvc_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 1984 | } 1985 | 1986 | /* --------------------------------------------------------------------------- 1987 | * main 1988 | */ 1989 | 1990 | static void image_load(struct uvc_device *dev, const char *img) 1991 | { 1992 | int fd = -1; 1993 | 1994 | if (img == NULL) 1995 | return; 1996 | 1997 | fd = open(img, O_RDONLY); 1998 | if (fd == -1) { 1999 | printf("Unable to open MJPEG image '%s'\n", img); 2000 | return; 2001 | } 2002 | 2003 | dev->imgsize = lseek(fd, 0, SEEK_END); 2004 | lseek(fd, 0, SEEK_SET); 2005 | dev->imgdata = malloc(dev->imgsize); 2006 | if (dev->imgdata == NULL) { 2007 | printf("Unable to allocate memory for MJPEG image\n"); 2008 | dev->imgsize = 0; 2009 | return; 2010 | } 2011 | 2012 | read(fd, dev->imgdata, dev->imgsize); 2013 | close(fd); 2014 | } 2015 | 2016 | static void usage(const char *argv0) 2017 | { 2018 | fprintf(stderr, "Usage: %s [options]\n", argv0); 2019 | fprintf(stderr, "Available options are\n"); 2020 | fprintf(stderr, " -b Use bulk mode\n"); 2021 | fprintf(stderr, " -d Do not use any real V4L2 capture device\n"); 2022 | fprintf(stderr, 2023 | " -f Select frame format\n\t" 2024 | "0 = V4L2_PIX_FMT_YUYV\n\t" 2025 | "1 = V4L2_PIX_FMT_MJPEG\n"); 2026 | fprintf(stderr, " -h Print this help screen and exit\n"); 2027 | fprintf(stderr, " -i image MJPEG image\n"); 2028 | fprintf(stderr, " -m Streaming mult for ISOC (b/w 0 and 2)\n"); 2029 | fprintf(stderr, " -n Number of Video buffers (b/w 2 and 32)\n"); 2030 | fprintf(stderr, 2031 | " -o Select UVC IO method:\n\t" 2032 | "0 = MMAP\n\t" 2033 | "1 = USER_PTR\n"); 2034 | fprintf(stderr, 2035 | " -r Select frame resolution:\n\t" 2036 | "0 = 360p, VGA (640x360)\n\t" 2037 | "1 = 720p, WXGA (1280x720)\n"); 2038 | fprintf(stderr, 2039 | " -s Select USB bus speed (b/w 0 and 2)\n\t" 2040 | "0 = Full Speed (FS)\n\t" 2041 | "1 = High Speed (HS)\n\t" 2042 | "2 = Super Speed (SS)\n"); 2043 | fprintf(stderr, " -t Streaming burst (b/w 0 and 15)\n"); 2044 | fprintf(stderr, " -u device UVC Video Output device\n"); 2045 | fprintf(stderr, " -v device V4L2 Video Capture device\n"); 2046 | } 2047 | 2048 | int main(int argc, char *argv[]) 2049 | { 2050 | struct uvc_device *udev; 2051 | struct v4l2_device *vdev; 2052 | struct timeval tv; 2053 | struct v4l2_format fmt; 2054 | char *uvc_devname = "/dev/video0"; 2055 | char *v4l2_devname = "/dev/video1"; 2056 | char *mjpeg_image = NULL; 2057 | 2058 | fd_set fdsv, fdsu; 2059 | int ret, opt, nfds; 2060 | int bulk_mode = 0; 2061 | int dummy_data_gen_mode = 0; 2062 | /* Frame format/resolution related params. */ 2063 | int default_format = 0; /* V4L2_PIX_FMT_YUYV */ 2064 | int default_resolution = 0; /* VGA 360p */ 2065 | int nbufs = 2; /* Ping-Pong buffers */ 2066 | /* USB speed related params */ 2067 | int mult = 0; 2068 | int burst = 0; 2069 | enum usb_device_speed speed = USB_SPEED_SUPER; /* High-Speed */ 2070 | enum io_method uvc_io_method = IO_METHOD_USERPTR; 2071 | 2072 | while ((opt = getopt(argc, argv, "bdf:hi:m:n:o:r:s:t:u:v:")) != -1) { 2073 | switch (opt) { 2074 | case 'b': 2075 | bulk_mode = 1; 2076 | break; 2077 | 2078 | case 'd': 2079 | dummy_data_gen_mode = 1; 2080 | break; 2081 | 2082 | case 'f': 2083 | if (atoi(optarg) < 0 || atoi(optarg) > 1) { 2084 | usage(argv[0]); 2085 | return 1; 2086 | } 2087 | 2088 | default_format = atoi(optarg); 2089 | break; 2090 | 2091 | case 'h': 2092 | usage(argv[0]); 2093 | return 1; 2094 | 2095 | case 'i': 2096 | mjpeg_image = optarg; 2097 | break; 2098 | 2099 | case 'm': 2100 | if (atoi(optarg) < 0 || atoi(optarg) > 2) { 2101 | usage(argv[0]); 2102 | return 1; 2103 | } 2104 | 2105 | mult = atoi(optarg); 2106 | printf("Requested Mult value = %d\n", mult); 2107 | break; 2108 | 2109 | case 'n': 2110 | if (atoi(optarg) < 2 || atoi(optarg) > 32) { 2111 | usage(argv[0]); 2112 | return 1; 2113 | } 2114 | 2115 | nbufs = atoi(optarg); 2116 | printf("Number of buffers requested = %d\n", nbufs); 2117 | break; 2118 | 2119 | case 'o': 2120 | if (atoi(optarg) < 0 || atoi(optarg) > 1) { 2121 | usage(argv[0]); 2122 | return 1; 2123 | } 2124 | 2125 | uvc_io_method = atoi(optarg); 2126 | printf("UVC: IO method requested is %s\n", (uvc_io_method == IO_METHOD_MMAP) ? "MMAP" : "USER_PTR"); 2127 | break; 2128 | 2129 | case 'r': 2130 | if (atoi(optarg) < 0 || atoi(optarg) > 1) { 2131 | usage(argv[0]); 2132 | return 1; 2133 | } 2134 | 2135 | default_resolution = atoi(optarg); 2136 | break; 2137 | 2138 | case 's': 2139 | if (atoi(optarg) < 0 || atoi(optarg) > 2) { 2140 | usage(argv[0]); 2141 | return 1; 2142 | } 2143 | 2144 | speed = atoi(optarg); 2145 | break; 2146 | 2147 | case 't': 2148 | if (atoi(optarg) < 0 || atoi(optarg) > 15) { 2149 | usage(argv[0]); 2150 | return 1; 2151 | } 2152 | 2153 | burst = atoi(optarg); 2154 | printf("Requested Burst value = %d\n", burst); 2155 | break; 2156 | 2157 | case 'u': 2158 | uvc_devname = optarg; 2159 | break; 2160 | 2161 | case 'v': 2162 | v4l2_devname = optarg; 2163 | break; 2164 | 2165 | default: 2166 | printf("Invalid option '-%c'\n", opt); 2167 | usage(argv[0]); 2168 | return 1; 2169 | } 2170 | } 2171 | 2172 | if (!dummy_data_gen_mode && !mjpeg_image) { 2173 | /* 2174 | * Try to set the default format at the V4L2 video capture 2175 | * device as requested by the user. 2176 | */ 2177 | CLEAR(fmt); 2178 | fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2179 | fmt.fmt.pix.width = (default_resolution == 0) ? 640 : 1280; 2180 | fmt.fmt.pix.height = (default_resolution == 0) ? 360 : 720; 2181 | fmt.fmt.pix.sizeimage = (default_format == 0) ? (fmt.fmt.pix.width * fmt.fmt.pix.height * 2) 2182 | : (fmt.fmt.pix.width * fmt.fmt.pix.height * 1.5); 2183 | fmt.fmt.pix.pixelformat = (default_format == 0) ? V4L2_PIX_FMT_YUYV : V4L2_PIX_FMT_MJPEG; 2184 | fmt.fmt.pix.field = V4L2_FIELD_ANY; 2185 | 2186 | /* Open the V4L2 device. */ 2187 | ret = v4l2_open(&vdev, v4l2_devname, &fmt); 2188 | if (vdev == NULL || ret < 0) 2189 | return 1; 2190 | } 2191 | 2192 | /* Open the UVC device. */ 2193 | ret = uvc_open(&udev, uvc_devname); 2194 | if (udev == NULL || ret < 0) 2195 | return 1; 2196 | 2197 | udev->uvc_devname = uvc_devname; 2198 | 2199 | if (!dummy_data_gen_mode && !mjpeg_image) { 2200 | vdev->v4l2_devname = v4l2_devname; 2201 | /* Bind UVC and V4L2 devices. */ 2202 | udev->vdev = vdev; 2203 | vdev->udev = udev; 2204 | } 2205 | 2206 | /* Set parameters as passed by user. */ 2207 | udev->width = (default_resolution == 0) ? 640 : 1280; 2208 | udev->height = (default_resolution == 0) ? 360 : 720; 2209 | udev->imgsize = (default_format == 0) ? (udev->width * udev->height * 2) : (udev->width * udev->height * 1.5); 2210 | udev->fcc = (default_format == 0) ? V4L2_PIX_FMT_YUYV : V4L2_PIX_FMT_MJPEG; 2211 | udev->io = uvc_io_method; 2212 | udev->bulk = bulk_mode; 2213 | udev->nbufs = nbufs; 2214 | udev->mult = mult; 2215 | udev->burst = burst; 2216 | udev->speed = speed; 2217 | 2218 | if (dummy_data_gen_mode || mjpeg_image) 2219 | /* UVC standalone setup. */ 2220 | udev->run_standalone = 1; 2221 | 2222 | if (!dummy_data_gen_mode && !mjpeg_image) { 2223 | /* UVC - V4L2 integrated path */ 2224 | vdev->nbufs = nbufs; 2225 | 2226 | /* 2227 | * IO methods used at UVC and V4L2 domains must be 2228 | * complementary to avoid any memcpy from the CPU. 2229 | */ 2230 | switch (uvc_io_method) { 2231 | case IO_METHOD_MMAP: 2232 | vdev->io = IO_METHOD_USERPTR; 2233 | break; 2234 | 2235 | case IO_METHOD_USERPTR: 2236 | default: 2237 | vdev->io = IO_METHOD_MMAP; 2238 | break; 2239 | } 2240 | } 2241 | 2242 | switch (speed) { 2243 | case USB_SPEED_FULL: 2244 | /* Full Speed. */ 2245 | if (bulk_mode) 2246 | udev->maxpkt = 64; 2247 | else 2248 | udev->maxpkt = 1023; 2249 | break; 2250 | 2251 | case USB_SPEED_HIGH: 2252 | /* High Speed. */ 2253 | if (bulk_mode) 2254 | udev->maxpkt = 512; 2255 | else 2256 | udev->maxpkt = 1024; 2257 | break; 2258 | 2259 | case USB_SPEED_SUPER: 2260 | default: 2261 | /* Super Speed. */ 2262 | if (bulk_mode) 2263 | udev->maxpkt = 1024; 2264 | else 2265 | udev->maxpkt = 1024; 2266 | break; 2267 | } 2268 | 2269 | if (!dummy_data_gen_mode && !mjpeg_image && (IO_METHOD_MMAP == vdev->io)) { 2270 | /* 2271 | * Ensure that the V4L2 video capture device has already some 2272 | * buffers queued. 2273 | */ 2274 | v4l2_reqbufs(vdev, vdev->nbufs); 2275 | } 2276 | 2277 | if (mjpeg_image) 2278 | image_load(udev, mjpeg_image); 2279 | 2280 | /* Init UVC events. */ 2281 | uvc_events_init(udev); 2282 | 2283 | while (1) { 2284 | if (!dummy_data_gen_mode && !mjpeg_image) 2285 | FD_ZERO(&fdsv); 2286 | 2287 | FD_ZERO(&fdsu); 2288 | 2289 | /* We want both setup and data events on UVC interface.. */ 2290 | FD_SET(udev->uvc_fd, &fdsu); 2291 | 2292 | fd_set efds = fdsu; 2293 | fd_set dfds = fdsu; 2294 | 2295 | /* ..but only data events on V4L2 interface */ 2296 | if (!dummy_data_gen_mode && !mjpeg_image) 2297 | FD_SET(vdev->v4l2_fd, &fdsv); 2298 | 2299 | /* Timeout. */ 2300 | tv.tv_sec = 2; 2301 | tv.tv_usec = 0; 2302 | 2303 | if (!dummy_data_gen_mode && !mjpeg_image) { 2304 | nfds = max(vdev->v4l2_fd, udev->uvc_fd); 2305 | ret = select(nfds + 1, &fdsv, &dfds, &efds, &tv); 2306 | } else { 2307 | ret = select(udev->uvc_fd + 1, NULL, &dfds, &efds, NULL); 2308 | } 2309 | 2310 | if (-1 == ret) { 2311 | printf("select error %d, %s\n", errno, strerror(errno)); 2312 | if (EINTR == errno) 2313 | continue; 2314 | 2315 | break; 2316 | } 2317 | 2318 | if (0 == ret) { 2319 | printf("select timeout\n"); 2320 | break; 2321 | } 2322 | 2323 | if (FD_ISSET(udev->uvc_fd, &efds)) 2324 | uvc_events_process(udev); 2325 | if (FD_ISSET(udev->uvc_fd, &dfds)) 2326 | uvc_video_process(udev); 2327 | if (!dummy_data_gen_mode && !mjpeg_image) 2328 | if (FD_ISSET(vdev->v4l2_fd, &fdsv)) 2329 | v4l2_process_data(vdev); 2330 | } 2331 | 2332 | if (!dummy_data_gen_mode && !mjpeg_image && vdev->is_streaming) { 2333 | /* Stop V4L2 streaming... */ 2334 | v4l2_stop_capturing(vdev); 2335 | v4l2_uninit_device(vdev); 2336 | v4l2_reqbufs(vdev, 0); 2337 | vdev->is_streaming = 0; 2338 | } 2339 | 2340 | if (udev->is_streaming) { 2341 | /* ... and now UVC streaming.. */ 2342 | uvc_video_stream(udev, 0); 2343 | uvc_uninit_device(udev); 2344 | uvc_video_reqbufs(udev, 0); 2345 | udev->is_streaming = 0; 2346 | } 2347 | 2348 | if (!dummy_data_gen_mode && !mjpeg_image) 2349 | v4l2_close(vdev); 2350 | 2351 | uvc_close(udev); 2352 | return 0; 2353 | } 2354 | -------------------------------------------------------------------------------- /uvc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * uvc_gadget.h -- USB Video Class Gadget driver 3 | * 4 | * Copyright (C) 2009-2010 5 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | */ 12 | 13 | #ifndef _UVC_GADGET_H_ 14 | #define _UVC_GADGET_H_ 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #define UVC_EVENT_FIRST (V4L2_EVENT_PRIVATE_START + 0) 21 | #define UVC_EVENT_CONNECT (V4L2_EVENT_PRIVATE_START + 0) 22 | #define UVC_EVENT_DISCONNECT (V4L2_EVENT_PRIVATE_START + 1) 23 | #define UVC_EVENT_STREAMON (V4L2_EVENT_PRIVATE_START + 2) 24 | #define UVC_EVENT_STREAMOFF (V4L2_EVENT_PRIVATE_START + 3) 25 | #define UVC_EVENT_SETUP (V4L2_EVENT_PRIVATE_START + 4) 26 | #define UVC_EVENT_DATA (V4L2_EVENT_PRIVATE_START + 5) 27 | #define UVC_EVENT_LAST (V4L2_EVENT_PRIVATE_START + 5) 28 | 29 | struct uvc_request_data 30 | { 31 | __s32 length; 32 | __u8 data[60]; 33 | }; 34 | 35 | struct uvc_event 36 | { 37 | union { 38 | enum usb_device_speed speed; 39 | struct usb_ctrlrequest req; 40 | struct uvc_request_data data; 41 | }; 42 | }; 43 | 44 | #define UVCIOC_SEND_RESPONSE _IOW('U', 1, struct uvc_request_data) 45 | 46 | #define UVC_INTF_CONTROL 0 47 | #define UVC_INTF_STREAMING 1 48 | 49 | /* ------------------------------------------------------------------------ 50 | * Debugging, printing and logging 51 | */ 52 | 53 | #ifdef __KERNEL__ 54 | 55 | #include /* For usb_endpoint_* */ 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | 63 | #include "uvc_queue.h" 64 | 65 | #define UVC_TRACE_PROBE (1 << 0) 66 | #define UVC_TRACE_DESCR (1 << 1) 67 | #define UVC_TRACE_CONTROL (1 << 2) 68 | #define UVC_TRACE_FORMAT (1 << 3) 69 | #define UVC_TRACE_CAPTURE (1 << 4) 70 | #define UVC_TRACE_CALLS (1 << 5) 71 | #define UVC_TRACE_IOCTL (1 << 6) 72 | #define UVC_TRACE_FRAME (1 << 7) 73 | #define UVC_TRACE_SUSPEND (1 << 8) 74 | #define UVC_TRACE_STATUS (1 << 9) 75 | 76 | #define UVC_WARN_MINMAX 0 77 | #define UVC_WARN_PROBE_DEF 1 78 | 79 | extern unsigned int uvc_gadget_trace_param; 80 | 81 | #define uvc_trace(flag, msg...) \ 82 | do { \ 83 | if (uvc_gadget_trace_param & flag) \ 84 | printk(KERN_DEBUG "uvcvideo: " msg); \ 85 | } while (0) 86 | 87 | #define uvc_warn_once(dev, warn, msg...) \ 88 | do { \ 89 | if (!test_and_set_bit(warn, &dev->warnings)) \ 90 | printk(KERN_INFO "uvcvideo: " msg); \ 91 | } while (0) 92 | 93 | #define uvc_printk(level, msg...) \ 94 | printk(level "uvcvideo: " msg) 95 | 96 | /* ------------------------------------------------------------------------ 97 | * Driver specific constants 98 | */ 99 | 100 | #define UVC_NUM_REQUESTS 4 101 | #define UVC_MAX_REQUEST_SIZE 64 102 | #define UVC_MAX_EVENTS 4 103 | 104 | /* ------------------------------------------------------------------------ 105 | * Structures 106 | */ 107 | 108 | struct uvc_video 109 | { 110 | struct usb_ep *ep; 111 | 112 | /* Frame parameters */ 113 | u8 bpp; 114 | u32 fcc; 115 | unsigned int width; 116 | unsigned int height; 117 | unsigned int imagesize; 118 | 119 | /* Requests */ 120 | unsigned int req_size; 121 | struct usb_request *req[UVC_NUM_REQUESTS]; 122 | __u8 *req_buffer[UVC_NUM_REQUESTS]; 123 | struct list_head req_free; 124 | spinlock_t req_lock; 125 | 126 | void (*encode) (struct usb_request *req, struct uvc_video *video, 127 | struct uvc_buffer *buf); 128 | 129 | /* Context data used by the completion handler */ 130 | __u32 payload_size; 131 | __u32 max_payload_size; 132 | 133 | struct uvc_video_queue queue; 134 | unsigned int fid; 135 | }; 136 | 137 | enum uvc_state 138 | { 139 | UVC_STATE_DISCONNECTED, 140 | UVC_STATE_CONNECTED, 141 | UVC_STATE_STREAMING, 142 | }; 143 | 144 | struct uvc_device 145 | { 146 | struct video_device *vdev; 147 | struct v4l2_device v4l2_dev; 148 | enum uvc_state state; 149 | struct usb_function func; 150 | struct uvc_video video; 151 | 152 | /* Descriptors */ 153 | struct { 154 | const struct uvc_descriptor_header * const *fs_control; 155 | const struct uvc_descriptor_header * const *ss_control; 156 | const struct uvc_descriptor_header * const *fs_streaming; 157 | const struct uvc_descriptor_header * const *hs_streaming; 158 | const struct uvc_descriptor_header * const *ss_streaming; 159 | } desc; 160 | 161 | unsigned int control_intf; 162 | struct usb_ep *control_ep; 163 | struct usb_request *control_req; 164 | void *control_buf; 165 | 166 | unsigned int streaming_intf; 167 | 168 | /* Events */ 169 | unsigned int event_length; 170 | unsigned int event_setup_out : 1; 171 | }; 172 | 173 | static inline struct uvc_device *to_uvc(struct usb_function *f) 174 | { 175 | return container_of(f, struct uvc_device, func); 176 | } 177 | 178 | struct uvc_file_handle 179 | { 180 | struct v4l2_fh vfh; 181 | struct uvc_video *device; 182 | }; 183 | 184 | #define to_uvc_file_handle(handle) \ 185 | container_of(handle, struct uvc_file_handle, vfh) 186 | 187 | /* ------------------------------------------------------------------------ 188 | * Functions 189 | */ 190 | 191 | extern void uvc_function_setup_continue(struct uvc_device *uvc); 192 | extern void uvc_endpoint_stream(struct uvc_device *dev); 193 | 194 | extern void uvc_function_connect(struct uvc_device *uvc); 195 | extern void uvc_function_disconnect(struct uvc_device *uvc); 196 | 197 | #endif /* __KERNEL__ */ 198 | 199 | #endif /* _UVC_GADGET_H_ */ 200 | 201 | --------------------------------------------------------------------------------