diff options
Diffstat (limited to 'Documentation/video4linux')
-rw-r--r-- | Documentation/video4linux/API.html | 2 | ||||
-rw-r--r-- | Documentation/video4linux/CARDLIST.cx23885 | 6 | ||||
-rw-r--r-- | Documentation/video4linux/CARDLIST.em28xx | 1 | ||||
-rw-r--r-- | Documentation/video4linux/CARDLIST.saa7134 | 3 | ||||
-rw-r--r-- | Documentation/video4linux/CQcam.txt | 4 | ||||
-rw-r--r-- | Documentation/video4linux/README.cpia | 2 | ||||
-rw-r--r-- | Documentation/video4linux/README.ivtv | 2 | ||||
-rw-r--r-- | Documentation/video4linux/Zoran | 6 | ||||
-rw-r--r-- | Documentation/video4linux/bttv/Cards | 6 | ||||
-rw-r--r-- | Documentation/video4linux/bttv/MAKEDEV | 2 | ||||
-rw-r--r-- | Documentation/video4linux/bttv/Specs | 4 | ||||
-rw-r--r-- | Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt | 2 | ||||
-rw-r--r-- | Documentation/video4linux/gspca.txt | 8 | ||||
-rw-r--r-- | Documentation/video4linux/hauppauge-wintv-cx88-ir.txt | 2 | ||||
-rw-r--r-- | Documentation/video4linux/ibmcam.txt | 5 | ||||
-rw-r--r-- | Documentation/video4linux/se401.txt | 2 | ||||
-rw-r--r-- | Documentation/video4linux/v4l2-controls.txt | 648 | ||||
-rw-r--r-- | Documentation/video4linux/w9966.txt | 2 |
18 files changed, 682 insertions, 25 deletions
diff --git a/Documentation/video4linux/API.html b/Documentation/video4linux/API.html index d749d41..d72fd2a 100644 --- a/Documentation/video4linux/API.html +++ b/Documentation/video4linux/API.html @@ -17,7 +17,7 @@ </tr> <tr> <td> - <a href="http://www.linuxtv.org/downloads/video4linux/API/V4L2_API">V4L2 API</a> + <a href="http://v4l2spec.bytesex.org/spec-single/v4l2.html">V4L2 API</a> </td> <td>Should be used for new projects </td> diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885 index 16ca030..87c4634 100644 --- a/Documentation/video4linux/CARDLIST.cx23885 +++ b/Documentation/video4linux/CARDLIST.cx23885 @@ -17,9 +17,9 @@ 16 -> DVBWorld DVB-S2 2005 [0001:2005] 17 -> NetUP Dual DVB-S2 CI [1b55:2a2c] 18 -> Hauppauge WinTV-HVR1270 [0070:2211] - 19 -> Hauppauge WinTV-HVR1275 [0070:2215] - 20 -> Hauppauge WinTV-HVR1255 [0070:2251] - 21 -> Hauppauge WinTV-HVR1210 [0070:2291,0070:2295] + 19 -> Hauppauge WinTV-HVR1275 [0070:2215,0070:221d,0070:22f2] + 20 -> Hauppauge WinTV-HVR1255 [0070:2251,0070:2259,0070:22f1] + 21 -> Hauppauge WinTV-HVR1210 [0070:2291,0070:2295,0070:2299,0070:229d,0070:22f0,0070:22f3,0070:22f4,0070:22f5] 22 -> Mygica X8506 DMB-TH [14f1:8651] 23 -> Magic-Pro ProHDTV Extreme 2 [14f1:8657] 24 -> Hauppauge WinTV-HVR1850 [0070:8541] diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx index 3a623aa..5c56875 100644 --- a/Documentation/video4linux/CARDLIST.em28xx +++ b/Documentation/video4linux/CARDLIST.em28xx @@ -72,3 +72,4 @@ 73 -> Reddo DVB-C USB TV Box (em2870) 74 -> Actionmaster/LinXcel/Digitus VC211A (em2800) 75 -> Dikom DK300 (em2882) + 76 -> KWorld PlusTV 340U or UB435-Q (ATSC) (em2870) [1b80:a340] diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index 1387a69..4000c29 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -178,4 +178,5 @@ 177 -> Hawell HW-404M7 178 -> Beholder BeholdTV H7 [5ace:7190] 179 -> Beholder BeholdTV A7 [5ace:7090] -180 -> Avermedia M733A [1461:4155,1461:4255] +180 -> Avermedia PCI M733A [1461:4155,1461:4255] +181 -> TechoTrend TT-budget T-3000 [13c2:2804] diff --git a/Documentation/video4linux/CQcam.txt b/Documentation/video4linux/CQcam.txt index d230878e..8977e7c 100644 --- a/Documentation/video4linux/CQcam.txt +++ b/Documentation/video4linux/CQcam.txt @@ -203,11 +203,11 @@ The V4L2 API spec: http://v4l2spec.bytesex.org/ Some web pages about the quickcams: - http://www.dkfz-heidelberg.de/Macromol/wedemann/mini-HOWTO-cqcam.html + http://www.pingouin-land.com/howto/QuickCam-HOWTO.html http://www.crynwr.com/qcpc/ QuickCam Third-Party Drivers http://www.crynwr.com/qcpc/re.html Some Reverse Engineering - http://cse.unl.edu/~cluening/gqcam/ v4l client + http://www.wirelesscouch.net/software/gqcam/ v4l client http://phobos.illtel.denver.co.us/pub/qcread/ doesn't use v4l ftp://ftp.cs.unm.edu/pub/chris/quickcam/ Has lots of drivers http://www.cs.duke.edu/~reynolds/quickcam/ Has lots of information diff --git a/Documentation/video4linux/README.cpia b/Documentation/video4linux/README.cpia index 19cd3bf..8a747fe 100644 --- a/Documentation/video4linux/README.cpia +++ b/Documentation/video4linux/README.cpia @@ -185,7 +185,7 @@ THANKS (in no particular order): --------------------------------------------------------------------------- REFERENCES - 1. http://www.risc.uni-linz.ac.at/people/ppregler + 1. http://www.risc.uni-linz.ac.at/ mailto:Peter_Pregler@email.com 2. see the file COPYING in the top directory of the kernel tree 3. http://webcam.sourceforge.net/ diff --git a/Documentation/video4linux/README.ivtv b/Documentation/video4linux/README.ivtv index 73df22c..42b0668 100644 --- a/Documentation/video4linux/README.ivtv +++ b/Documentation/video4linux/README.ivtv @@ -10,7 +10,7 @@ Hauppauge PVR-350. NOTE: this driver requires the latest encoder firmware (version 2.06.039, size 376836 bytes). Get the firmware from here: -http://dl.ivtvdriver.org/ivtv/firmware/firmware.tar.gz +http://dl.ivtvdriver.org/ivtv/firmware/ NOTE: 'normal' TV applications do not work with this driver, you need an application that can handle MPEG input such as mplayer, xine, MythTV, diff --git a/Documentation/video4linux/Zoran b/Documentation/video4linux/Zoran index 0e89e76..00e3f92 100644 --- a/Documentation/video4linux/Zoran +++ b/Documentation/video4linux/Zoran @@ -174,7 +174,7 @@ and is used in Argentinia, Uruguay, an a few others We do not talk about how the audio is broadcast ! A rather good sites about the TV standards are: -http://www.sony.jp/ServiceArea/Voltage_map/ +http://www.sony.jp/support/ http://info.electronicwerkstatt.de/bereiche/fernsehtechnik/frequenzen_und_normen/Fernsehnormen/ and http://www.cabl.com/restaurant/channel.html @@ -330,7 +330,7 @@ These extensions are known as the v4l/mjpeg extensions. See zoran.h for details (structs/ioctls). Information - video4linux: -http://roadrunner.swansea.linux.org.uk/v4lapi.shtml +http://linux.bytesex.org/v4l2/API.html Documentation/video4linux/API.html /usr/include/linux/videodev.h @@ -390,7 +390,7 @@ BUZIOC_G_STATUS Get the status of the input lines (video source connected/norm). For programming example, please, look at lavrec.c and lavplay.c code in -lavtools-1.2p2 package (URL: http://www.cicese.mx/~mirsev/DC10plus/) +lavtools-1.2p2 package (URL: http://www.cicese.mx/) and the 'examples' directory in the original Buz driver distribution. Additional notes for software developers: diff --git a/Documentation/video4linux/bttv/Cards b/Documentation/video4linux/bttv/Cards index d338965..12217fc 100644 --- a/Documentation/video4linux/bttv/Cards +++ b/Documentation/video4linux/bttv/Cards @@ -802,7 +802,7 @@ Kworld (www.kworld.com.tw) -JTT/ Justy Corp.http://www.justy.co.jp/ (www.jtt.com.jp website down) +JTT/ Justy Corp.(http://www.jtt.ne.jp/) --------------------------------------------------------------------- JTT-02 (JTT TV) "TV watchmate pro" (bt848) @@ -828,7 +828,7 @@ Eline www.eline-net.com/ Eline Vision TVMaster / TVMaster FM (ELV-TVM/ ELV-TVM-FM) = LR26 (bt878) Eline Vision TVMaster-2000 (ELV-TVM-2000, ELV-TVM-2000-FM)= LR138 (saa713x) -Spirit http://www.spiritmodems.com.au/ +Spirit ------ Spirit TV Tuner/Video Capture Card (bt848) @@ -959,6 +959,6 @@ Asus www.asuscom.com Hoontech -------- -http://www.hoontech.com/korean/download/down_driver_list03.html +http://www.hoontech.de/ HART Vision 848 (H-ART Vision 848) HART Vision 878 (H-Art Vision 878) diff --git a/Documentation/video4linux/bttv/MAKEDEV b/Documentation/video4linux/bttv/MAKEDEV index 6c29ba4..9d112f7 100644 --- a/Documentation/video4linux/bttv/MAKEDEV +++ b/Documentation/video4linux/bttv/MAKEDEV @@ -14,7 +14,7 @@ function makedev () { ln -s /dev/${1}0 /dev/$1 } -# see http://roadrunner.swansea.uk.linux.org/v4lapi.shtml +# see http://linux.bytesex.org/v4l2/API.html echo "*** new device names ***" makedev video 0 diff --git a/Documentation/video4linux/bttv/Specs b/Documentation/video4linux/bttv/Specs index 79b9e57..f32466c 100644 --- a/Documentation/video4linux/bttv/Specs +++ b/Documentation/video4linux/bttv/Specs @@ -1,3 +1,3 @@ Philips http://www.Semiconductors.COM/pip/ -Conexant http://www.conexant.com/techinfo/default.asp -Micronas http://www.micronas.de/pages/product_documentation/index.html +Conexant http://www.conexant.com/ +Micronas http://www.micronas.com/en/home/index.html diff --git a/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt b/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt index faccee6..f4329a3 100644 --- a/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt +++ b/Documentation/video4linux/cx88/hauppauge-wintv-cx88-ir.txt @@ -44,7 +44,7 @@ http://www.atmel.com/dyn/resources/prod_documents/doc2817.pdf This data sheet (google search) seems to have a lovely description of the RC5 basics -http://users.pandora.be/nenya/electronics/rc5/ and more data +http://www.nenya.be/beor/electronics/rc5.htm and more data http://www.ee.washington.edu/circuit_archive/text/ir_decode.txt and even a reference to how to decode a bi-phase data stream. diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt index f13eb03..56ba7bb 100644 --- a/Documentation/video4linux/gspca.txt +++ b/Documentation/video4linux/gspca.txt @@ -29,8 +29,12 @@ zc3xx 041e:4029 Creative WebCam Vista Pro zc3xx 041e:4034 Creative Instant P0620 zc3xx 041e:4035 Creative Instant P0620D zc3xx 041e:4036 Creative Live ! +sq930x 041e:4038 Creative Joy-IT zc3xx 041e:403a Creative Nx Pro 2 spca561 041e:403b Creative Webcam Vista (VF0010) +sq930x 041e:403c Creative Live! Ultra +sq930x 041e:403d Creative Live! Ultra for Notebooks +sq930x 041e:4041 Creative Live! Motion zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250) ov519 041e:4052 Creative Live! VISTA IM zc3xx 041e:4053 Creative Live!Cam Video IM @@ -138,6 +142,7 @@ finepix 04cb:013d Fujifilm FinePix unknown model finepix 04cb:013f Fujifilm FinePix F420 sunplus 04f1:1001 JVC GC A50 spca561 04fc:0561 Flexcam 100 +spca1528 04fc:1528 Sunplus MD80 clone sunplus 04fc:500c Sunplus CA500C sunplus 04fc:504a Aiptek Mini PenCam 1.3 sunplus 04fc:504b Maxell MaxPocket LE 1.3 @@ -253,6 +258,7 @@ pac7302 093a:2620 Apollo AC-905 pac7302 093a:2621 PAC731x pac7302 093a:2622 Genius Eye 312 pac7302 093a:2624 PAC7302 +pac7302 093a:2625 Genius iSlim 310 pac7302 093a:2626 Labtec 2200 pac7302 093a:2628 Genius iLook 300 pac7302 093a:2629 Genious iSlim 300 @@ -362,6 +368,8 @@ sq905c 2770:9052 Disney pix micro 2 (VGA) sq905c 2770:905c All 11 known cameras with this ID sq905 2770:9120 All 24 known cameras with this ID sq905c 2770:913d All 4 known cameras with this ID +sq930x 2770:930b Sweex Motion Tracking / I-Tec iCam Tracer +sq930x 2770:930c Trust WB-3500T / NSG Robbie 2.0 spca500 2899:012c Toptro Industrial ov519 8020:ef04 ov519 spca508 8086:0110 Intel Easy PC Camera diff --git a/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt b/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt index faccee6..a2fd363 100644 --- a/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt +++ b/Documentation/video4linux/hauppauge-wintv-cx88-ir.txt @@ -44,7 +44,7 @@ http://www.atmel.com/dyn/resources/prod_documents/doc2817.pdf This data sheet (google search) seems to have a lovely description of the RC5 basics -http://users.pandora.be/nenya/electronics/rc5/ and more data +http://www.nenya.be/beor/electronics/rc5.htm and more data http://www.ee.washington.edu/circuit_archive/text/ir_decode.txt and even a reference to how to decode a bi-phase data stream. diff --git a/Documentation/video4linux/ibmcam.txt b/Documentation/video4linux/ibmcam.txt index 397a94e..a510552 100644 --- a/Documentation/video4linux/ibmcam.txt +++ b/Documentation/video4linux/ibmcam.txt @@ -27,9 +27,8 @@ SUPPORTED CAMERAS: Xirlink "C-It" camera, also known as "IBM PC Camera". The device uses proprietary ASIC (and compression method); -it is manufactured by Xirlink. See http://www.xirlink.com/ -(renamed to http://www.veo.com), http://www.ibmpccamera.com, -or http://www.c-itnow.com/ for details and pictures. +it is manufactured by Xirlink. See http://xirlinkwebcam.sourceforge.net, +http://www.ibmpccamera.com, or http://www.c-itnow.com/ for details and pictures. This very chipset ("X Chip", as marked at the factory) is used in several other cameras, and they are supported diff --git a/Documentation/video4linux/se401.txt b/Documentation/video4linux/se401.txt index 7b9d1c9..bd6526e 100644 --- a/Documentation/video4linux/se401.txt +++ b/Documentation/video4linux/se401.txt @@ -49,6 +49,6 @@ order to increase the throughput (and thus framerate). HELP: The latest info on this driver can be found at: -http://www.chello.nl/~j.vreeken/se401/ +http://members.chello.nl/~j.vreeken/se401/ And questions to me can be send to: pe1rxq@amsat.org diff --git a/Documentation/video4linux/v4l2-controls.txt b/Documentation/video4linux/v4l2-controls.txt new file mode 100644 index 0000000..8773778 --- /dev/null +++ b/Documentation/video4linux/v4l2-controls.txt @@ -0,0 +1,648 @@ +Introduction +============ + +The V4L2 control API seems simple enough, but quickly becomes very hard to +implement correctly in drivers. But much of the code needed to handle controls +is actually not driver specific and can be moved to the V4L core framework. + +After all, the only part that a driver developer is interested in is: + +1) How do I add a control? +2) How do I set the control's value? (i.e. s_ctrl) + +And occasionally: + +3) How do I get the control's value? (i.e. g_volatile_ctrl) +4) How do I validate the user's proposed control value? (i.e. try_ctrl) + +All the rest is something that can be done centrally. + +The control framework was created in order to implement all the rules of the +V4L2 specification with respect to controls in a central place. And to make +life as easy as possible for the driver developer. + +Note that the control framework relies on the presence of a struct v4l2_device +for V4L2 drivers and struct v4l2_subdev for sub-device drivers. + + +Objects in the framework +======================== + +There are two main objects: + +The v4l2_ctrl object describes the control properties and keeps track of the +control's value (both the current value and the proposed new value). + +v4l2_ctrl_handler is the object that keeps track of controls. It maintains a +list of v4l2_ctrl objects that it owns and another list of references to +controls, possibly to controls owned by other handlers. + + +Basic usage for V4L2 and sub-device drivers +=========================================== + +1) Prepare the driver: + +1.1) Add the handler to your driver's top-level struct: + + struct foo_dev { + ... + struct v4l2_ctrl_handler ctrl_handler; + ... + }; + + struct foo_dev *foo; + +1.2) Initialize the handler: + + v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls); + + The second argument is a hint telling the function how many controls this + handler is expected to handle. It will allocate a hashtable based on this + information. It is a hint only. + +1.3) Hook the control handler into the driver: + +1.3.1) For V4L2 drivers do this: + + struct foo_dev { + ... + struct v4l2_device v4l2_dev; + ... + struct v4l2_ctrl_handler ctrl_handler; + ... + }; + + foo->v4l2_dev.ctrl_handler = &foo->ctrl_handler; + + Where foo->v4l2_dev is of type struct v4l2_device. + + Finally, remove all control functions from your v4l2_ioctl_ops: + vidioc_queryctrl, vidioc_querymenu, vidioc_g_ctrl, vidioc_s_ctrl, + vidioc_g_ext_ctrls, vidioc_try_ext_ctrls and vidioc_s_ext_ctrls. + Those are now no longer needed. + +1.3.2) For sub-device drivers do this: + + struct foo_dev { + ... + struct v4l2_subdev sd; + ... + struct v4l2_ctrl_handler ctrl_handler; + ... + }; + + foo->sd.ctrl_handler = &foo->ctrl_handler; + + Where foo->sd is of type struct v4l2_subdev. + + And set all core control ops in your struct v4l2_subdev_core_ops to these + helpers: + + .queryctrl = v4l2_subdev_queryctrl, + .querymenu = v4l2_subdev_querymenu, + .g_ctrl = v4l2_subdev_g_ctrl, + .s_ctrl = v4l2_subdev_s_ctrl, + .g_ext_ctrls = v4l2_subdev_g_ext_ctrls, + .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, + .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, + + Note: this is a temporary solution only. Once all V4L2 drivers that depend + on subdev drivers are converted to the control framework these helpers will + no longer be needed. + +1.4) Clean up the handler at the end: + + v4l2_ctrl_handler_free(&foo->ctrl_handler); + + +2) Add controls: + +You add non-menu controls by calling v4l2_ctrl_new_std: + + struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_ops *ops, + u32 id, s32 min, s32 max, u32 step, s32 def); + +Menu controls are added by calling v4l2_ctrl_new_std_menu: + + struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl, + const struct v4l2_ctrl_ops *ops, + u32 id, s32 max, s32 skip_mask, s32 def); + +These functions are typically called right after the v4l2_ctrl_handler_init: + + v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls); + v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops, + V4L2_CID_BRIGHTNESS, 0, 255, 1, 128); + v4l2_ctrl_new_std(&foo->ctrl_handler, &foo_ctrl_ops, + V4L2_CID_CONTRAST, 0, 255, 1, 128); + v4l2_ctrl_new_std_menu(&foo->ctrl_handler, &foo_ctrl_ops, + V4L2_CID_POWER_LINE_FREQUENCY, + V4L2_CID_POWER_LINE_FREQUENCY_60HZ, 0, + V4L2_CID_POWER_LINE_FREQUENCY_DISABLED); + ... + if (foo->ctrl_handler.error) { + int err = foo->ctrl_handler.error; + + v4l2_ctrl_handler_free(&foo->ctrl_handler); + return err; + } + +The v4l2_ctrl_new_std function returns the v4l2_ctrl pointer to the new +control, but if you do not need to access the pointer outside the control ops, +then there is no need to store it. + +The v4l2_ctrl_new_std function will fill in most fields based on the control +ID except for the min, max, step and default values. These are passed in the +last four arguments. These values are driver specific while control attributes +like type, name, flags are all global. The control's current value will be set +to the default value. + +The v4l2_ctrl_new_std_menu function is very similar but it is used for menu +controls. There is no min argument since that is always 0 for menu controls, +and instead of a step there is a skip_mask argument: if bit X is 1, then menu +item X is skipped. + +Note that if something fails, the function will return NULL or an error and +set ctrl_handler->error to the error code. If ctrl_handler->error was already +set, then it will just return and do nothing. This is also true for +v4l2_ctrl_handler_init if it cannot allocate the internal data structure. + +This makes it easy to init the handler and just add all controls and only check +the error code at the end. Saves a lot of repetitive error checking. + +It is recommended to add controls in ascending control ID order: it will be +a bit faster that way. + +3) Optionally force initial control setup: + + v4l2_ctrl_handler_setup(&foo->ctrl_handler); + +This will call s_ctrl for all controls unconditionally. Effectively this +initializes the hardware to the default control values. It is recommended +that you do this as this ensures that both the internal data structures and +the hardware are in sync. + +4) Finally: implement the v4l2_ctrl_ops + + static const struct v4l2_ctrl_ops foo_ctrl_ops = { + .s_ctrl = foo_s_ctrl, + }; + +Usually all you need is s_ctrl: + + static int foo_s_ctrl(struct v4l2_ctrl *ctrl) + { + struct foo *state = container_of(ctrl->handler, struct foo, ctrl_handler); + + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + write_reg(0x123, ctrl->val); + break; + case V4L2_CID_CONTRAST: + write_reg(0x456, ctrl->val); + break; + } + return 0; + } + +The control ops are called with the v4l2_ctrl pointer as argument. +The new control value has already been validated, so all you need to do is +to actually update the hardware registers. + +You're done! And this is sufficient for most of the drivers we have. No need +to do any validation of control values, or implement QUERYCTRL/QUERYMENU. And +G/S_CTRL as well as G/TRY/S_EXT_CTRLS are automatically supported. + + +============================================================================== + +The remainder of this document deals with more advanced topics and scenarios. +In practice the basic usage as described above is sufficient for most drivers. + +=============================================================================== + + +Inheriting Controls +=================== + +When a sub-device is registered with a V4L2 driver by calling +v4l2_device_register_subdev() and the ctrl_handler fields of both v4l2_subdev +and v4l2_device are set, then the controls of the subdev will become +automatically available in the V4L2 driver as well. If the subdev driver +contains controls that already exist in the V4L2 driver, then those will be +skipped (so a V4L2 driver can always override a subdev control). + +What happens here is that v4l2_device_register_subdev() calls +v4l2_ctrl_add_handler() adding the controls of the subdev to the controls +of v4l2_device. + + +Accessing Control Values +======================== + +The v4l2_ctrl struct contains these two unions: + + /* The current control value. */ + union { + s32 val; + s64 val64; + char *string; + } cur; + + /* The new control value. */ + union { + s32 val; + s64 val64; + char *string; + }; + +Within the control ops you can freely use these. The val and val64 speak for +themselves. The string pointers point to character buffers of length +ctrl->maximum + 1, and are always 0-terminated. + +In most cases 'cur' contains the current cached control value. When you create +a new control this value is made identical to the default value. After calling +v4l2_ctrl_handler_setup() this value is passed to the hardware. It is generally +a good idea to call this function. + +Whenever a new value is set that new value is automatically cached. This means +that most drivers do not need to implement the g_volatile_ctrl() op. The +exception is for controls that return a volatile register such as a signal +strength read-out that changes continuously. In that case you will need to +implement g_volatile_ctrl like this: + + static int foo_g_volatile_ctrl(struct v4l2_ctrl *ctrl) + { + switch (ctrl->id) { + case V4L2_CID_BRIGHTNESS: + ctrl->cur.val = read_reg(0x123); + break; + } + } + +The 'new value' union is not used in g_volatile_ctrl. In general controls +that need to implement g_volatile_ctrl are read-only controls. + +To mark a control as volatile you have to set the is_volatile flag: + + ctrl = v4l2_ctrl_new_std(&sd->ctrl_handler, ...); + if (ctrl) + ctrl->is_volatile = 1; + +For try/s_ctrl the new values (i.e. as passed by the user) are filled in and +you can modify them in try_ctrl or set them in s_ctrl. The 'cur' union +contains the current value, which you can use (but not change!) as well. + +If s_ctrl returns 0 (OK), then the control framework will copy the new final +values to the 'cur' union. + +While in g_volatile/s/try_ctrl you can access the value of all controls owned +by the same handler since the handler's lock is held. If you need to access +the value of controls owned by other handlers, then you have to be very careful +not to introduce deadlocks. + +Outside of the control ops you have to go through to helper functions to get +or set a single control value safely in your driver: + + s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl); + int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val); + +These functions go through the control framework just as VIDIOC_G/S_CTRL ioctls +do. Don't use these inside the control ops g_volatile/s/try_ctrl, though, that +will result in a deadlock since these helpers lock the handler as well. + +You can also take the handler lock yourself: + + mutex_lock(&state->ctrl_handler.lock); + printk(KERN_INFO "String value is '%s'\n", ctrl1->cur.string); + printk(KERN_INFO "Integer value is '%s'\n", ctrl2->cur.val); + mutex_unlock(&state->ctrl_handler.lock); + + +Menu Controls +============= + +The v4l2_ctrl struct contains this union: + + union { + u32 step; + u32 menu_skip_mask; + }; + +For menu controls menu_skip_mask is used. What it does is that it allows you +to easily exclude certain menu items. This is used in the VIDIOC_QUERYMENU +implementation where you can return -EINVAL if a certain menu item is not +present. Note that VIDIOC_QUERYCTRL always returns a step value of 1 for +menu controls. + +A good example is the MPEG Audio Layer II Bitrate menu control where the +menu is a list of standardized possible bitrates. But in practice hardware +implementations will only support a subset of those. By setting the skip +mask you can tell the framework which menu items should be skipped. Setting +it to 0 means that all menu items are supported. + +You set this mask either through the v4l2_ctrl_config struct for a custom +control, or by calling v4l2_ctrl_new_std_menu(). + + +Custom Controls +=============== + +Driver specific controls can be created using v4l2_ctrl_new_custom(): + + static const struct v4l2_ctrl_config ctrl_filter = { + .ops = &ctrl_custom_ops, + .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER, + .name = "Spatial Filter", + .type = V4L2_CTRL_TYPE_INTEGER, + .flags = V4L2_CTRL_FLAG_SLIDER, + .max = 15, + .step = 1, + }; + + ctrl = v4l2_ctrl_new_custom(&foo->ctrl_handler, &ctrl_filter, NULL); + +The last argument is the priv pointer which can be set to driver-specific +private data. + +The v4l2_ctrl_config struct also has fields to set the is_private and is_volatile +flags. + +If the name field is not set, then the framework will assume this is a standard +control and will fill in the name, type and flags fields accordingly. + + +Active and Grabbed Controls +=========================== + +If you get more complex relationships between controls, then you may have to +activate and deactivate controls. For example, if the Chroma AGC control is +on, then the Chroma Gain control is inactive. That is, you may set it, but +the value will not be used by the hardware as long as the automatic gain +control is on. Typically user interfaces can disable such input fields. + +You can set the 'active' status using v4l2_ctrl_activate(). By default all +controls are active. Note that the framework does not check for this flag. +It is meant purely for GUIs. The function is typically called from within +s_ctrl. + +The other flag is the 'grabbed' flag. A grabbed control means that you cannot +change it because it is in use by some resource. Typical examples are MPEG +bitrate controls that cannot be changed while capturing is in progress. + +If a control is set to 'grabbed' using v4l2_ctrl_grab(), then the framework +will return -EBUSY if an attempt is made to set this control. The +v4l2_ctrl_grab() function is typically called from the driver when it +starts or stops streaming. + + +Control Clusters +================ + +By default all controls are independent from the others. But in more +complex scenarios you can get dependencies from one control to another. +In that case you need to 'cluster' them: + + struct foo { + struct v4l2_ctrl_handler ctrl_handler; +#define AUDIO_CL_VOLUME (0) +#define AUDIO_CL_MUTE (1) + struct v4l2_ctrl *audio_cluster[2]; + ... + }; + + state->audio_cluster[AUDIO_CL_VOLUME] = + v4l2_ctrl_new_std(&state->ctrl_handler, ...); + state->audio_cluster[AUDIO_CL_MUTE] = + v4l2_ctrl_new_std(&state->ctrl_handler, ...); + v4l2_ctrl_cluster(ARRAY_SIZE(state->audio_cluster), state->audio_cluster); + +From now on whenever one or more of the controls belonging to the same +cluster is set (or 'gotten', or 'tried'), only the control ops of the first +control ('volume' in this example) is called. You effectively create a new +composite control. Similar to how a 'struct' works in C. + +So when s_ctrl is called with V4L2_CID_AUDIO_VOLUME as argument, you should set +all two controls belonging to the audio_cluster: + + static int foo_s_ctrl(struct v4l2_ctrl *ctrl) + { + struct foo *state = container_of(ctrl->handler, struct foo, ctrl_handler); + + switch (ctrl->id) { + case V4L2_CID_AUDIO_VOLUME: { + struct v4l2_ctrl *mute = ctrl->cluster[AUDIO_CL_MUTE]; + + write_reg(0x123, mute->val ? 0 : ctrl->val); + break; + } + case V4L2_CID_CONTRAST: + write_reg(0x456, ctrl->val); + break; + } + return 0; + } + +In the example above the following are equivalent for the VOLUME case: + + ctrl == ctrl->cluster[AUDIO_CL_VOLUME] == state->audio_cluster[AUDIO_CL_VOLUME] + ctrl->cluster[AUDIO_CL_MUTE] == state->audio_cluster[AUDIO_CL_MUTE] + +Note that controls in a cluster may be NULL. For example, if for some +reason mute was never added (because the hardware doesn't support that +particular feature), then mute will be NULL. So in that case we have a +cluster of 2 controls, of which only 1 is actually instantiated. The +only restriction is that the first control of the cluster must always be +present, since that is the 'master' control of the cluster. The master +control is the one that identifies the cluster and that provides the +pointer to the v4l2_ctrl_ops struct that is used for that cluster. + +Obviously, all controls in the cluster array must be initialized to either +a valid control or to NULL. + + +VIDIOC_LOG_STATUS Support +========================= + +This ioctl allow you to dump the current status of a driver to the kernel log. +The v4l2_ctrl_handler_log_status(ctrl_handler, prefix) can be used to dump the +value of the controls owned by the given handler to the log. You can supply a +prefix as well. If the prefix didn't end with a space, then ': ' will be added +for you. + + +Different Handlers for Different Video Nodes +============================================ + +Usually the V4L2 driver has just one control handler that is global for +all video nodes. But you can also specify different control handlers for +different video nodes. You can do that by manually setting the ctrl_handler +field of struct video_device. + +That is no problem if there are no subdevs involved but if there are, then +you need to block the automatic merging of subdev controls to the global +control handler. You do that by simply setting the ctrl_handler field in +struct v4l2_device to NULL. Now v4l2_device_register_subdev() will no longer +merge subdev controls. + +After each subdev was added, you will then have to call v4l2_ctrl_add_handler +manually to add the subdev's control handler (sd->ctrl_handler) to the desired +control handler. This control handler may be specific to the video_device or +for a subset of video_device's. For example: the radio device nodes only have +audio controls, while the video and vbi device nodes share the same control +handler for the audio and video controls. + +If you want to have one handler (e.g. for a radio device node) have a subset +of another handler (e.g. for a video device node), then you should first add +the controls to the first handler, add the other controls to the second +handler and finally add the first handler to the second. For example: + + v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_VOLUME, ...); + v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...); + v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...); + v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_CONTRAST, ...); + v4l2_ctrl_add_handler(&video_ctrl_handler, &radio_ctrl_handler); + +Or you can add specific controls to a handler: + + volume = v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_AUDIO_VOLUME, ...); + v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_BRIGHTNESS, ...); + v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_CONTRAST, ...); + v4l2_ctrl_add_ctrl(&radio_ctrl_handler, volume); + +What you should not do is make two identical controls for two handlers. +For example: + + v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...); + v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_AUDIO_MUTE, ...); + +This would be bad since muting the radio would not change the video mute +control. The rule is to have one control for each hardware 'knob' that you +can twiddle. + + +Finding Controls +================ + +Normally you have created the controls yourself and you can store the struct +v4l2_ctrl pointer into your own struct. + +But sometimes you need to find a control from another handler that you do +not own. For example, if you have to find a volume control from a subdev. + +You can do that by calling v4l2_ctrl_find: + + struct v4l2_ctrl *volume; + + volume = v4l2_ctrl_find(sd->ctrl_handler, V4L2_CID_AUDIO_VOLUME); + +Since v4l2_ctrl_find will lock the handler you have to be careful where you +use it. For example, this is not a good idea: + + struct v4l2_ctrl_handler ctrl_handler; + + v4l2_ctrl_new_std(&ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...); + v4l2_ctrl_new_std(&ctrl_handler, &video_ops, V4L2_CID_CONTRAST, ...); + +...and in video_ops.s_ctrl: + + case V4L2_CID_BRIGHTNESS: + contrast = v4l2_find_ctrl(&ctrl_handler, V4L2_CID_CONTRAST); + ... + +When s_ctrl is called by the framework the ctrl_handler.lock is already taken, so +attempting to find another control from the same handler will deadlock. + +It is recommended not to use this function from inside the control ops. + + +Inheriting Controls +=================== + +When one control handler is added to another using v4l2_ctrl_add_handler, then +by default all controls from one are merged to the other. But a subdev might +have low-level controls that make sense for some advanced embedded system, but +not when it is used in consumer-level hardware. In that case you want to keep +those low-level controls local to the subdev. You can do this by simply +setting the 'is_private' flag of the control to 1: + + static const struct v4l2_ctrl_config ctrl_private = { + .ops = &ctrl_custom_ops, + .id = V4L2_CID_..., + .name = "Some Private Control", + .type = V4L2_CTRL_TYPE_INTEGER, + .max = 15, + .step = 1, + .is_private = 1, + }; + + ctrl = v4l2_ctrl_new_custom(&foo->ctrl_handler, &ctrl_private, NULL); + +These controls will now be skipped when v4l2_ctrl_add_handler is called. + + +V4L2_CTRL_TYPE_CTRL_CLASS Controls +================================== + +Controls of this type can be used by GUIs to get the name of the control class. +A fully featured GUI can make a dialog with multiple tabs with each tab +containing the controls belonging to a particular control class. The name of +each tab can be found by querying a special control with ID <control class | 1>. + +Drivers do not have to care about this. The framework will automatically add +a control of this type whenever the first control belonging to a new control +class is added. + + +Differences from the Spec +========================= + +There are a few places where the framework acts slightly differently from the +V4L2 Specification. Those differences are described in this section. We will +have to see whether we need to adjust the spec or not. + +1) It is no longer required to have all controls contained in a +v4l2_ext_control array be from the same control class. The framework will be +able to handle any type of control in the array. You need to set ctrl_class +to 0 in order to enable this. If ctrl_class is non-zero, then it will still +check that all controls belong to that control class. + +If you set ctrl_class to 0 and count to 0, then it will only return an error +if there are no controls at all. + +2) Clarified the way error_idx works. For get and set it will be equal to +count if nothing was done yet. If it is less than count then only the controls +up to error_idx-1 were successfully applied. + +3) When attempting to read a button control the framework will return -EACCES +instead of -EINVAL as stated in the spec. It seems to make more sense since +button controls are write-only controls. + +4) Attempting to write to a read-only control will return -EACCES instead of +-EINVAL as the spec says. + +5) The spec does not mention what should happen when you try to set/get a +control class controls. ivtv currently returns -EINVAL (indicating that the +control ID does not exist) while the framework will return -EACCES, which +makes more sense. + + +Proposals for Extensions +======================== + +Some ideas for future extensions to the spec: + +1) Add a V4L2_CTRL_FLAG_HEX to have values shown as hexadecimal instead of +decimal. Useful for e.g. video_mute_yuv. + +2) It is possible to mark in the controls array which controls have been +successfully written and which failed by for example adding a bit to the +control ID. Not sure if it is worth the effort, though. + +3) Trying to set volatile inactive controls should result in -EACCESS. + +4) Add a new flag to mark volatile controls. Any application that wants +to store the state of the controls can then skip volatile inactive controls. +Currently it is not possible to detect such controls. diff --git a/Documentation/video4linux/w9966.txt b/Documentation/video4linux/w9966.txt index 78a6512..8550245 100644 --- a/Documentation/video4linux/w9966.txt +++ b/Documentation/video4linux/w9966.txt @@ -24,7 +24,7 @@ where every two pixels take 4 bytes. In SDL (www.libsdl.org) this format is called VIDEO_PALETTE_YUV422 (16 bpp). A minimal test application (with source) is available from: - http://hem.fyristorg.com/mogul/w9966.html + http://www.slackwaresupport.com/howtos/Webcam-HOWTO The slow framerate is due to missing DMA ECP read support in the parport drivers. I might add working EPP support later. |