Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (442 commits) [media] videobuf2-dma-contig: make cookie() return a pointer to dma_addr_t [media] sh_mobile_ceu_camera: Do not call vb2's mem_ops directly [media] V4L: soc-camera: explicitly require V4L2_BUF_TYPE_VIDEO_CAPTURE [media] v4l: soc-camera: Store negotiated buffer settings [media] rc: interim support for 32-bit NEC-ish scancodes [media] mceusb: topseed 0x0011 needs gen3 init for tx to work [media] lirc_zilog: error out if buffer read bytes != chunk size [media] lirc: silence some compile warnings [media] hdpvr: use same polling interval as other OS [media] ir-kbd-i2c: pass device code w/key in hauppauge case [media] rc/keymaps: Remove the obsolete rc-rc5-tv keymap [media] remove the old RC_MAP_HAUPPAUGE_NEW RC map [media] rc/keymaps: Rename Hauppauge table as rc-hauppauge [media] rc-rc5-hauppauge-new: Fix Hauppauge Grey mapping [media] rc-rc5-hauppauge-new: Add support for the old Black RC [media] rc-rc5-hauppauge-new: Add the old control to the table [media] rc-winfast: Fix the keycode tables [media] a800: Fix a few wrong IR key assignments [media] opera1: Use multimedia keys instead of an app-specific mapping [media] dw2102: Use multimedia keys instead of an app-specific mapping ... Fix up trivial conflicts (remove/modify and some real conflicts) in: arch/arm/mach-omap2/devices.c drivers/staging/Kconfig drivers/staging/Makefile drivers/staging/dabusb/dabusb.c drivers/staging/dabusb/dabusb.h drivers/staging/easycap/easycap_ioctl.c drivers/staging/usbvideo/usbvideo.c drivers/staging/usbvideo/vicam.c
This commit is contained in:
@@ -36,8 +36,7 @@ Additional features for the PVR-350 (CX23415 based):
|
||||
* Provides comprehensive OSD (On Screen Display: ie. graphics overlaying the
|
||||
video signal)
|
||||
* Provides a framebuffer (allowing X applications to appear on the video
|
||||
device) (this framebuffer is not yet part of the kernel. In the meantime it
|
||||
is available from www.ivtvdriver.org).
|
||||
device)
|
||||
* Supports raw YUV output.
|
||||
|
||||
IMPORTANT: In case of problems first read this page:
|
||||
|
@@ -103,6 +103,7 @@ spca561 046d:092d Logitech QC Elch2
|
||||
spca561 046d:092e Logitech QC Elch2
|
||||
spca561 046d:092f Logitech QuickCam Express Plus
|
||||
sunplus 046d:0960 Logitech ClickSmart 420
|
||||
nw80x 046d:d001 Logitech QuickCam Pro (dark focus ring)
|
||||
sunplus 0471:0322 Philips DMVC1300K
|
||||
zc3xx 0471:0325 Philips SPC 200 NC
|
||||
zc3xx 0471:0326 Philips SPC 300 NC
|
||||
@@ -150,10 +151,12 @@ sunplus 04fc:5330 Digitrex 2110
|
||||
sunplus 04fc:5360 Sunplus Generic
|
||||
spca500 04fc:7333 PalmPixDC85
|
||||
sunplus 04fc:ffff Pure DigitalDakota
|
||||
nw80x 0502:d001 DVC V6
|
||||
spca501 0506:00df 3Com HomeConnect Lite
|
||||
sunplus 052b:1507 Megapixel 5 Pretec DC-1007
|
||||
sunplus 052b:1513 Megapix V4
|
||||
sunplus 052b:1803 MegaImage VI
|
||||
nw80x 052b:d001 EZCam Pro p35u
|
||||
tv8532 0545:808b Veo Stingray
|
||||
tv8532 0545:8333 Veo Stingray
|
||||
sunplus 0546:3155 Polaroid PDC3070
|
||||
@@ -177,6 +180,7 @@ sunplus 055f:c530 Mustek Gsmart LCD 3
|
||||
sunplus 055f:c540 Gsmart D30
|
||||
sunplus 055f:c630 Mustek MDC4000
|
||||
sunplus 055f:c650 Mustek MDC5500Z
|
||||
nw80x 055f:d001 Mustek Wcam 300 mini
|
||||
zc3xx 055f:d003 Mustek WCam300A
|
||||
zc3xx 055f:d004 Mustek WCam300 AN
|
||||
conex 0572:0041 Creative Notebook cx11646
|
||||
@@ -195,14 +199,20 @@ gl860 05e3:0503 Genesys Logic PC Camera
|
||||
gl860 05e3:f191 Genesys Logic PC Camera
|
||||
spca561 060b:a001 Maxell Compact Pc PM3
|
||||
zc3xx 0698:2003 CTX M730V built in
|
||||
nw80x 06a5:0000 Typhoon Webcam 100 USB
|
||||
nw80x 06a5:d001 Divio based webcams
|
||||
nw80x 06a5:d800 Divio Chicony TwinkleCam, Trust SpaceCam
|
||||
spca500 06bd:0404 Agfa CL20
|
||||
spca500 06be:0800 Optimedia
|
||||
nw80x 06be:d001 EZCam Pro p35u
|
||||
sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom
|
||||
spca506 06e1:a190 ADS Instant VCD
|
||||
ov534 06f8:3002 Hercules Blog Webcam
|
||||
ov534_9 06f8:3003 Hercules Dualpix HD Weblog
|
||||
sonixj 06f8:3004 Hercules Classic Silver
|
||||
sonixj 06f8:3008 Hercules Deluxe Optical Glass
|
||||
pac7302 06f8:3009 Hercules Classic Link
|
||||
nw80x 0728:d001 AVerMedia Camguard
|
||||
spca508 0733:0110 ViewQuest VQ110
|
||||
spca501 0733:0401 Intel Create and Share
|
||||
spca501 0733:0402 ViewQuest M318B
|
||||
|
278
Documentation/video4linux/omap3isp.txt
Normal file
278
Documentation/video4linux/omap3isp.txt
Normal file
@@ -0,0 +1,278 @@
|
||||
OMAP 3 Image Signal Processor (ISP) driver
|
||||
|
||||
Copyright (C) 2010 Nokia Corporation
|
||||
Copyright (C) 2009 Texas Instruments, Inc.
|
||||
|
||||
Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
Sakari Ailus <sakari.ailus@iki.fi>
|
||||
David Cohen <dacohen@gmail.com>
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This file documents the Texas Instruments OMAP 3 Image Signal Processor (ISP)
|
||||
driver located under drivers/media/video/omap3isp. The original driver was
|
||||
written by Texas Instruments but since that it has been rewritten (twice) at
|
||||
Nokia.
|
||||
|
||||
The driver has been successfully used on the following versions of OMAP 3:
|
||||
|
||||
3430
|
||||
3530
|
||||
3630
|
||||
|
||||
The driver implements V4L2, Media controller and v4l2_subdev interfaces.
|
||||
Sensor, lens and flash drivers using the v4l2_subdev interface in the kernel
|
||||
are supported.
|
||||
|
||||
|
||||
Split to subdevs
|
||||
================
|
||||
|
||||
The OMAP 3 ISP is split into V4L2 subdevs, each of the blocks inside the ISP
|
||||
having one subdev to represent it. Each of the subdevs provide a V4L2 subdev
|
||||
interface to userspace.
|
||||
|
||||
OMAP3 ISP CCP2
|
||||
OMAP3 ISP CSI2a
|
||||
OMAP3 ISP CCDC
|
||||
OMAP3 ISP preview
|
||||
OMAP3 ISP resizer
|
||||
OMAP3 ISP AEWB
|
||||
OMAP3 ISP AF
|
||||
OMAP3 ISP histogram
|
||||
|
||||
Each possible link in the ISP is modelled by a link in the Media controller
|
||||
interface. For an example program see [2].
|
||||
|
||||
|
||||
Controlling the OMAP 3 ISP
|
||||
==========================
|
||||
|
||||
In general, the settings given to the OMAP 3 ISP take effect at the beginning
|
||||
of the following frame. This is done when the module becomes idle during the
|
||||
vertical blanking period on the sensor. In memory-to-memory operation the pipe
|
||||
is run one frame at a time. Applying the settings is done between the frames.
|
||||
|
||||
All the blocks in the ISP, excluding the CSI-2 and possibly the CCP2 receiver,
|
||||
insist on receiving complete frames. Sensors must thus never send the ISP
|
||||
partial frames.
|
||||
|
||||
Autoidle does have issues with some ISP blocks on the 3430, at least.
|
||||
Autoidle is only enabled on 3630 when the omap3isp module parameter autoidle
|
||||
is non-zero.
|
||||
|
||||
|
||||
Events
|
||||
======
|
||||
|
||||
The OMAP 3 ISP driver does support the V4L2 event interface on CCDC and
|
||||
statistics (AEWB, AF and histogram) subdevs.
|
||||
|
||||
The CCDC subdev produces V4L2_EVENT_OMAP3ISP_HS_VS type event on HS_VS
|
||||
interrupt which is used to signal frame start. The event is triggered exactly
|
||||
when the reception of the first line of the frame starts in the CCDC module.
|
||||
The event can be subscribed on the CCDC subdev.
|
||||
|
||||
(When using parallel interface one must pay account to correct configuration
|
||||
of the VS signal polarity. This is automatically correct when using the serial
|
||||
receivers.)
|
||||
|
||||
Each of the statistics subdevs is able to produce events. An event is
|
||||
generated whenever a statistics buffer can be dequeued by a user space
|
||||
application using the VIDIOC_OMAP3ISP_STAT_REQ IOCTL. The events available
|
||||
are:
|
||||
|
||||
V4L2_EVENT_OMAP3ISP_AEWB
|
||||
V4L2_EVENT_OMAP3ISP_AF
|
||||
V4L2_EVENT_OMAP3ISP_HIST
|
||||
|
||||
The type of the event data is struct omap3isp_stat_event_status for these
|
||||
ioctls. If there is an error calculating the statistics, there will be an
|
||||
event as usual, but no related statistics buffer. In this case
|
||||
omap3isp_stat_event_status.buf_err is set to non-zero.
|
||||
|
||||
|
||||
Private IOCTLs
|
||||
==============
|
||||
|
||||
The OMAP 3 ISP driver supports standard V4L2 IOCTLs and controls where
|
||||
possible and practical. Much of the functions provided by the ISP, however,
|
||||
does not fall under the standard IOCTLs --- gamma tables and configuration of
|
||||
statistics collection are examples of such.
|
||||
|
||||
In general, there is a private ioctl for configuring each of the blocks
|
||||
containing hardware-dependent functions.
|
||||
|
||||
The following private IOCTLs are supported:
|
||||
|
||||
VIDIOC_OMAP3ISP_CCDC_CFG
|
||||
VIDIOC_OMAP3ISP_PRV_CFG
|
||||
VIDIOC_OMAP3ISP_AEWB_CFG
|
||||
VIDIOC_OMAP3ISP_HIST_CFG
|
||||
VIDIOC_OMAP3ISP_AF_CFG
|
||||
VIDIOC_OMAP3ISP_STAT_REQ
|
||||
VIDIOC_OMAP3ISP_STAT_EN
|
||||
|
||||
The parameter structures used by these ioctls are described in
|
||||
include/linux/omap3isp.h. The detailed functions of the ISP itself related to
|
||||
a given ISP block is described in the Technical Reference Manuals (TRMs) ---
|
||||
see the end of the document for those.
|
||||
|
||||
While it is possible to use the ISP driver without any use of these private
|
||||
IOCTLs it is not possible to obtain optimal image quality this way. The AEWB,
|
||||
AF and histogram modules cannot be used without configuring them using the
|
||||
appropriate private IOCTLs.
|
||||
|
||||
|
||||
CCDC and preview block IOCTLs
|
||||
=============================
|
||||
|
||||
The VIDIOC_OMAP3ISP_CCDC_CFG and VIDIOC_OMAP3ISP_PRV_CFG IOCTLs are used to
|
||||
configure, enable and disable functions in the CCDC and preview blocks,
|
||||
respectively. Both IOCTLs control several functions in the blocks they
|
||||
control. VIDIOC_OMAP3ISP_CCDC_CFG IOCTL accepts a pointer to struct
|
||||
omap3isp_ccdc_update_config as its argument. Similarly VIDIOC_OMAP3ISP_PRV_CFG
|
||||
accepts a pointer to struct omap3isp_prev_update_config. The definition of
|
||||
both structures is available in [1].
|
||||
|
||||
The update field in the structures tells whether to update the configuration
|
||||
for the specific function and the flag tells whether to enable or disable the
|
||||
function.
|
||||
|
||||
The update and flag bit masks accept the following values. Each separate
|
||||
functions in the CCDC and preview blocks is associated with a flag (either
|
||||
disable or enable; part of the flag field in the structure) and a pointer to
|
||||
configuration data for the function.
|
||||
|
||||
Valid values for the update and flag fields are listed here for
|
||||
VIDIOC_OMAP3ISP_CCDC_CFG. Values may be or'ed to configure more than one
|
||||
function in the same IOCTL call.
|
||||
|
||||
OMAP3ISP_CCDC_ALAW
|
||||
OMAP3ISP_CCDC_LPF
|
||||
OMAP3ISP_CCDC_BLCLAMP
|
||||
OMAP3ISP_CCDC_BCOMP
|
||||
OMAP3ISP_CCDC_FPC
|
||||
OMAP3ISP_CCDC_CULL
|
||||
OMAP3ISP_CCDC_CONFIG_LSC
|
||||
OMAP3ISP_CCDC_TBL_LSC
|
||||
|
||||
The corresponding values for the VIDIOC_OMAP3ISP_PRV_CFG are here:
|
||||
|
||||
OMAP3ISP_PREV_LUMAENH
|
||||
OMAP3ISP_PREV_INVALAW
|
||||
OMAP3ISP_PREV_HRZ_MED
|
||||
OMAP3ISP_PREV_CFA
|
||||
OMAP3ISP_PREV_CHROMA_SUPP
|
||||
OMAP3ISP_PREV_WB
|
||||
OMAP3ISP_PREV_BLKADJ
|
||||
OMAP3ISP_PREV_RGB2RGB
|
||||
OMAP3ISP_PREV_COLOR_CONV
|
||||
OMAP3ISP_PREV_YC_LIMIT
|
||||
OMAP3ISP_PREV_DEFECT_COR
|
||||
OMAP3ISP_PREV_GAMMABYPASS
|
||||
OMAP3ISP_PREV_DRK_FRM_CAPTURE
|
||||
OMAP3ISP_PREV_DRK_FRM_SUBTRACT
|
||||
OMAP3ISP_PREV_LENS_SHADING
|
||||
OMAP3ISP_PREV_NF
|
||||
OMAP3ISP_PREV_GAMMA
|
||||
|
||||
The associated configuration pointer for the function may not be NULL when
|
||||
enabling the function. When disabling a function the configuration pointer is
|
||||
ignored.
|
||||
|
||||
|
||||
Statistic blocks IOCTLs
|
||||
=======================
|
||||
|
||||
The statistics subdevs do offer more dynamic configuration options than the
|
||||
other subdevs. They can be enabled, disable and reconfigured when the pipeline
|
||||
is in streaming state.
|
||||
|
||||
The statistics blocks always get the input image data from the CCDC (as the
|
||||
histogram memory read isn't implemented). The statistics are dequeueable by
|
||||
the user from the statistics subdev nodes using private IOCTLs.
|
||||
|
||||
The private IOCTLs offered by the AEWB, AF and histogram subdevs are heavily
|
||||
reflected by the register level interface offered by the ISP hardware. There
|
||||
are aspects that are purely related to the driver implementation and these are
|
||||
discussed next.
|
||||
|
||||
VIDIOC_OMAP3ISP_STAT_EN
|
||||
-----------------------
|
||||
|
||||
This private IOCTL enables/disables a statistic module. If this request is
|
||||
done before streaming, it will take effect as soon as the pipeline starts to
|
||||
stream. If the pipeline is already streaming, it will take effect as soon as
|
||||
the CCDC becomes idle.
|
||||
|
||||
VIDIOC_OMAP3ISP_AEWB_CFG, VIDIOC_OMAP3ISP_HIST_CFG and VIDIOC_OMAP3ISP_AF_CFG
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Those IOCTLs are used to configure the modules. They require user applications
|
||||
to have an in-depth knowledge of the hardware. Most of the fields explanation
|
||||
can be found on OMAP's TRMs. The two following fields common to all the above
|
||||
configure private IOCTLs require explanation for better understanding as they
|
||||
are not part of the TRM.
|
||||
|
||||
omap3isp_[h3a_af/h3a_aewb/hist]_config.buf_size:
|
||||
|
||||
The modules handle their buffers internally. The necessary buffer size for the
|
||||
module's data output depends on the requested configuration. Although the
|
||||
driver supports reconfiguration while streaming, it does not support a
|
||||
reconfiguration which requires bigger buffer size than what is already
|
||||
internally allocated if the module is enabled. It will return -EBUSY on this
|
||||
case. In order to avoid such condition, either disable/reconfigure/enable the
|
||||
module or request the necessary buffer size during the first configuration
|
||||
while the module is disabled.
|
||||
|
||||
The internal buffer size allocation considers the requested configuration's
|
||||
minimum buffer size and the value set on buf_size field. If buf_size field is
|
||||
out of [minimum, maximum] buffer size range, it's clamped to fit in there.
|
||||
The driver then selects the biggest value. The corrected buf_size value is
|
||||
written back to user application.
|
||||
|
||||
omap3isp_[h3a_af/h3a_aewb/hist]_config.config_counter:
|
||||
|
||||
As the configuration doesn't take effect synchronously to the request, the
|
||||
driver must provide a way to track this information to provide more accurate
|
||||
data. After a configuration is requested, the config_counter returned to user
|
||||
space application will be an unique value associated to that request. When
|
||||
user application receives an event for buffer availability or when a new
|
||||
buffer is requested, this config_counter is used to match a buffer data and a
|
||||
configuration.
|
||||
|
||||
VIDIOC_OMAP3ISP_STAT_REQ
|
||||
------------------------
|
||||
|
||||
Send to user space the oldest data available in the internal buffer queue and
|
||||
discards such buffer afterwards. The field omap3isp_stat_data.frame_number
|
||||
matches with the video buffer's field_count.
|
||||
|
||||
|
||||
Technical reference manuals (TRMs) and other documentation
|
||||
==========================================================
|
||||
|
||||
OMAP 3430 TRM:
|
||||
<URL:http://focus.ti.com/pdfs/wtbu/OMAP34xx_ES3.1.x_PUBLIC_TRM_vZM.zip>
|
||||
Referenced 2011-03-05.
|
||||
|
||||
OMAP 35xx TRM:
|
||||
<URL:http://www.ti.com/litv/pdf/spruf98o> Referenced 2011-03-05.
|
||||
|
||||
OMAP 3630 TRM:
|
||||
<URL:http://focus.ti.com/pdfs/wtbu/OMAP36xx_ES1.x_PUBLIC_TRM_vQ.zip>
|
||||
Referenced 2011-03-05.
|
||||
|
||||
DM 3730 TRM:
|
||||
<URL:http://www.ti.com/litv/pdf/sprugn4h> Referenced 2011-03-06.
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
[1] include/linux/omap3isp.h
|
||||
|
||||
[2] http://git.ideasonboard.org/?p=media-ctl.git;a=summary
|
@@ -71,6 +71,10 @@ sub-device instances, the video_device struct stores V4L2 device node data
|
||||
and in the future a v4l2_fh struct will keep track of filehandle instances
|
||||
(this is not yet implemented).
|
||||
|
||||
The V4L2 framework also optionally integrates with the media framework. If a
|
||||
driver sets the struct v4l2_device mdev field, sub-devices and video nodes
|
||||
will automatically appear in the media framework as entities.
|
||||
|
||||
|
||||
struct v4l2_device
|
||||
------------------
|
||||
@@ -83,11 +87,20 @@ You must register the device instance:
|
||||
|
||||
v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
|
||||
|
||||
Registration will initialize the v4l2_device struct and link dev->driver_data
|
||||
to v4l2_dev. If v4l2_dev->name is empty then it will be set to a value derived
|
||||
from dev (driver name followed by the bus_id, to be precise). If you set it
|
||||
up before calling v4l2_device_register then it will be untouched. If dev is
|
||||
NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register.
|
||||
Registration will initialize the v4l2_device struct. If the dev->driver_data
|
||||
field is NULL, it will be linked to v4l2_dev.
|
||||
|
||||
Drivers that want integration with the media device framework need to set
|
||||
dev->driver_data manually to point to the driver-specific device structure
|
||||
that embed the struct v4l2_device instance. This is achieved by a
|
||||
dev_set_drvdata() call before registering the V4L2 device instance. They must
|
||||
also set the struct v4l2_device mdev field to point to a properly initialized
|
||||
and registered media_device instance.
|
||||
|
||||
If v4l2_dev->name is empty then it will be set to a value derived from dev
|
||||
(driver name followed by the bus_id, to be precise). If you set it up before
|
||||
calling v4l2_device_register then it will be untouched. If dev is NULL, then
|
||||
you *must* setup v4l2_dev->name before calling v4l2_device_register.
|
||||
|
||||
You can use v4l2_device_set_name() to set the name based on a driver name and
|
||||
a driver-global atomic_t instance. This will generate names like ivtv0, ivtv1,
|
||||
@@ -108,6 +121,7 @@ You unregister with:
|
||||
|
||||
v4l2_device_unregister(struct v4l2_device *v4l2_dev);
|
||||
|
||||
If the dev->driver_data field points to v4l2_dev, it will be reset to NULL.
|
||||
Unregistering will also automatically unregister all subdevs from the device.
|
||||
|
||||
If you have a hotpluggable device (e.g. a USB device), then when a disconnect
|
||||
@@ -167,6 +181,21 @@ static int __devinit drv_probe(struct pci_dev *pdev,
|
||||
state->instance = atomic_inc_return(&drv_instance) - 1;
|
||||
}
|
||||
|
||||
If you have multiple device nodes then it can be difficult to know when it is
|
||||
safe to unregister v4l2_device. For this purpose v4l2_device has refcounting
|
||||
support. The refcount is increased whenever video_register_device is called and
|
||||
it is decreased whenever that device node is released. When the refcount reaches
|
||||
zero, then the v4l2_device release() callback is called. You can do your final
|
||||
cleanup there.
|
||||
|
||||
If other device nodes (e.g. ALSA) are created, then you can increase and
|
||||
decrease the refcount manually as well by calling:
|
||||
|
||||
void v4l2_device_get(struct v4l2_device *v4l2_dev);
|
||||
|
||||
or:
|
||||
|
||||
int v4l2_device_put(struct v4l2_device *v4l2_dev);
|
||||
|
||||
struct v4l2_subdev
|
||||
------------------
|
||||
@@ -254,6 +283,26 @@ A sub-device driver initializes the v4l2_subdev struct using:
|
||||
Afterwards you need to initialize subdev->name with a unique name and set the
|
||||
module owner. This is done for you if you use the i2c helper functions.
|
||||
|
||||
If integration with the media framework is needed, you must initialize the
|
||||
media_entity struct embedded in the v4l2_subdev struct (entity field) by
|
||||
calling media_entity_init():
|
||||
|
||||
struct media_pad *pads = &my_sd->pads;
|
||||
int err;
|
||||
|
||||
err = media_entity_init(&sd->entity, npads, pads, 0);
|
||||
|
||||
The pads array must have been previously initialized. There is no need to
|
||||
manually set the struct media_entity type and name fields, but the revision
|
||||
field must be initialized if needed.
|
||||
|
||||
A reference to the entity will be automatically acquired/released when the
|
||||
subdev device node (if any) is opened/closed.
|
||||
|
||||
Don't forget to cleanup the media entity before the sub-device is destroyed:
|
||||
|
||||
media_entity_cleanup(&sd->entity);
|
||||
|
||||
A device (bridge) driver needs to register the v4l2_subdev with the
|
||||
v4l2_device:
|
||||
|
||||
@@ -263,6 +312,9 @@ This can fail if the subdev module disappeared before it could be registered.
|
||||
After this function was called successfully the subdev->dev field points to
|
||||
the v4l2_device.
|
||||
|
||||
If the v4l2_device parent device has a non-NULL mdev field, the sub-device
|
||||
entity will be automatically registered with the media device.
|
||||
|
||||
You can unregister a sub-device using:
|
||||
|
||||
v4l2_device_unregister_subdev(sd);
|
||||
@@ -319,6 +371,61 @@ controlled through GPIO pins. This distinction is only relevant when setting
|
||||
up the device, but once the subdev is registered it is completely transparent.
|
||||
|
||||
|
||||
V4L2 sub-device userspace API
|
||||
-----------------------------
|
||||
|
||||
Beside exposing a kernel API through the v4l2_subdev_ops structure, V4L2
|
||||
sub-devices can also be controlled directly by userspace applications.
|
||||
|
||||
Device nodes named v4l-subdevX can be created in /dev to access sub-devices
|
||||
directly. If a sub-device supports direct userspace configuration it must set
|
||||
the V4L2_SUBDEV_FL_HAS_DEVNODE flag before being registered.
|
||||
|
||||
After registering sub-devices, the v4l2_device driver can create device nodes
|
||||
for all registered sub-devices marked with V4L2_SUBDEV_FL_HAS_DEVNODE by calling
|
||||
v4l2_device_register_subdev_nodes(). Those device nodes will be automatically
|
||||
removed when sub-devices are unregistered.
|
||||
|
||||
The device node handles a subset of the V4L2 API.
|
||||
|
||||
VIDIOC_QUERYCTRL
|
||||
VIDIOC_QUERYMENU
|
||||
VIDIOC_G_CTRL
|
||||
VIDIOC_S_CTRL
|
||||
VIDIOC_G_EXT_CTRLS
|
||||
VIDIOC_S_EXT_CTRLS
|
||||
VIDIOC_TRY_EXT_CTRLS
|
||||
|
||||
The controls ioctls are identical to the ones defined in V4L2. They
|
||||
behave identically, with the only exception that they deal only with
|
||||
controls implemented in the sub-device. Depending on the driver, those
|
||||
controls can be also be accessed through one (or several) V4L2 device
|
||||
nodes.
|
||||
|
||||
VIDIOC_DQEVENT
|
||||
VIDIOC_SUBSCRIBE_EVENT
|
||||
VIDIOC_UNSUBSCRIBE_EVENT
|
||||
|
||||
The events ioctls are identical to the ones defined in V4L2. They
|
||||
behave identically, with the only exception that they deal only with
|
||||
events generated by the sub-device. Depending on the driver, those
|
||||
events can also be reported by one (or several) V4L2 device nodes.
|
||||
|
||||
Sub-device drivers that want to use events need to set the
|
||||
V4L2_SUBDEV_USES_EVENTS v4l2_subdev::flags and initialize
|
||||
v4l2_subdev::nevents to events queue depth before registering the
|
||||
sub-device. After registration events can be queued as usual on the
|
||||
v4l2_subdev::devnode device node.
|
||||
|
||||
To properly support events, the poll() file operation is also
|
||||
implemented.
|
||||
|
||||
Private ioctls
|
||||
|
||||
All ioctls not in the above list are passed directly to the sub-device
|
||||
driver through the core::ioctl operation.
|
||||
|
||||
|
||||
I2C sub-device drivers
|
||||
----------------------
|
||||
|
||||
@@ -457,6 +564,10 @@ You should also set these fields:
|
||||
Otherwise you give it a pointer to a struct mutex_lock and before any
|
||||
of the v4l2_file_operations is called this lock will be taken by the
|
||||
core and released afterwards.
|
||||
- prio: keeps track of the priorities. Used to implement VIDIOC_G/S_PRIORITY.
|
||||
If left to NULL, then it will use the struct v4l2_prio_state in v4l2_device.
|
||||
If you want to have a separate priority state per (group of) device node(s),
|
||||
then you can point it to your own struct v4l2_prio_state.
|
||||
- parent: you only set this if v4l2_device was registered with NULL as
|
||||
the parent device struct. This only happens in cases where one hardware
|
||||
device has multiple PCI devices that all share the same v4l2_device core.
|
||||
@@ -466,13 +577,34 @@ You should also set these fields:
|
||||
(cx8802). Since the v4l2_device cannot be associated with a particular
|
||||
PCI device it is setup without a parent device. But when the struct
|
||||
video_device is setup you do know which parent PCI device to use.
|
||||
- flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework
|
||||
handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct
|
||||
v4l2_fh. Eventually this flag will disappear once all drivers use the core
|
||||
priority handling. But for now it has to be set explicitly.
|
||||
|
||||
If you use v4l2_ioctl_ops, then you should set either .unlocked_ioctl or
|
||||
.ioctl to video_ioctl2 in your v4l2_file_operations struct.
|
||||
If you use v4l2_ioctl_ops, then you should set .unlocked_ioctl to video_ioctl2
|
||||
in your v4l2_file_operations struct.
|
||||
|
||||
Do not use .ioctl! This is deprecated and will go away in the future.
|
||||
|
||||
The v4l2_file_operations struct is a subset of file_operations. The main
|
||||
difference is that the inode argument is omitted since it is never used.
|
||||
|
||||
If integration with the media framework is needed, you must initialize the
|
||||
media_entity struct embedded in the video_device struct (entity field) by
|
||||
calling media_entity_init():
|
||||
|
||||
struct media_pad *pad = &my_vdev->pad;
|
||||
int err;
|
||||
|
||||
err = media_entity_init(&vdev->entity, 1, pad, 0);
|
||||
|
||||
The pads array must have been previously initialized. There is no need to
|
||||
manually set the struct media_entity type and name fields.
|
||||
|
||||
A reference to the entity will be automatically acquired/released when the
|
||||
video device is opened/closed.
|
||||
|
||||
v4l2_file_operations and locking
|
||||
--------------------------------
|
||||
|
||||
@@ -502,6 +634,9 @@ for you.
|
||||
return err;
|
||||
}
|
||||
|
||||
If the v4l2_device parent device has a non-NULL mdev field, the video device
|
||||
entity will be automatically registered with the media device.
|
||||
|
||||
Which device is registered depends on the type argument. The following
|
||||
types exist:
|
||||
|
||||
@@ -577,6 +712,13 @@ release, of course) will return an error as well.
|
||||
When the last user of the video device node exits, then the vdev->release()
|
||||
callback is called and you can do the final cleanup there.
|
||||
|
||||
Don't forget to cleanup the media entity associated with the video device if
|
||||
it has been initialized:
|
||||
|
||||
media_entity_cleanup(&vdev->entity);
|
||||
|
||||
This can be done from the release callback.
|
||||
|
||||
|
||||
video_device helper functions
|
||||
-----------------------------
|
||||
@@ -636,39 +778,25 @@ struct v4l2_fh
|
||||
--------------
|
||||
|
||||
struct v4l2_fh provides a way to easily keep file handle specific data
|
||||
that is used by the V4L2 framework. Using v4l2_fh is optional for
|
||||
drivers.
|
||||
that is used by the V4L2 framework. New drivers must use struct v4l2_fh
|
||||
since it is also used to implement priority handling (VIDIOC_G/S_PRIORITY)
|
||||
if the video_device flag V4L2_FL_USE_FH_PRIO is also set.
|
||||
|
||||
The users of v4l2_fh (in the V4L2 framework, not the driver) know
|
||||
whether a driver uses v4l2_fh as its file->private_data pointer by
|
||||
testing the V4L2_FL_USES_V4L2_FH bit in video_device->flags.
|
||||
|
||||
Useful functions:
|
||||
|
||||
- v4l2_fh_init()
|
||||
|
||||
Initialise the file handle. This *MUST* be performed in the driver's
|
||||
v4l2_file_operations->open() handler.
|
||||
|
||||
- v4l2_fh_add()
|
||||
|
||||
Add a v4l2_fh to video_device file handle list. May be called after
|
||||
initialising the file handle.
|
||||
|
||||
- v4l2_fh_del()
|
||||
|
||||
Unassociate the file handle from video_device(). The file handle
|
||||
exit function may now be called.
|
||||
|
||||
- v4l2_fh_exit()
|
||||
|
||||
Uninitialise the file handle. After uninitialisation the v4l2_fh
|
||||
memory can be freed.
|
||||
testing the V4L2_FL_USES_V4L2_FH bit in video_device->flags. This bit is
|
||||
set whenever v4l2_fh_init() is called.
|
||||
|
||||
struct v4l2_fh is allocated as a part of the driver's own file handle
|
||||
structure and is set to file->private_data in the driver's open
|
||||
function by the driver. Drivers can extract their own file handle
|
||||
structure by using the container_of macro. Example:
|
||||
structure and file->private_data is set to it in the driver's open
|
||||
function by the driver.
|
||||
|
||||
In many cases the struct v4l2_fh will be embedded in a larger structure.
|
||||
In that case you should call v4l2_fh_init+v4l2_fh_add in open() and
|
||||
v4l2_fh_del+v4l2_fh_exit in release().
|
||||
|
||||
Drivers can extract their own file handle structure by using the container_of
|
||||
macro. Example:
|
||||
|
||||
struct my_fh {
|
||||
int blah;
|
||||
@@ -685,15 +813,21 @@ int my_open(struct file *file)
|
||||
|
||||
...
|
||||
|
||||
ret = v4l2_fh_init(&my_fh->fh, vfd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
v4l2_fh_add(&my_fh->fh);
|
||||
|
||||
file->private_data = &my_fh->fh;
|
||||
my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);
|
||||
|
||||
...
|
||||
|
||||
ret = v4l2_fh_init(&my_fh->fh, vfd);
|
||||
if (ret) {
|
||||
kfree(my_fh);
|
||||
return ret;
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
file->private_data = &my_fh->fh;
|
||||
v4l2_fh_add(&my_fh->fh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int my_release(struct file *file)
|
||||
@@ -702,8 +836,65 @@ int my_release(struct file *file)
|
||||
struct my_fh *my_fh = container_of(fh, struct my_fh, fh);
|
||||
|
||||
...
|
||||
v4l2_fh_del(&my_fh->fh);
|
||||
v4l2_fh_exit(&my_fh->fh);
|
||||
kfree(my_fh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Below is a short description of the v4l2_fh functions used:
|
||||
|
||||
int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
|
||||
|
||||
Initialise the file handle. This *MUST* be performed in the driver's
|
||||
v4l2_file_operations->open() handler.
|
||||
|
||||
void v4l2_fh_add(struct v4l2_fh *fh)
|
||||
|
||||
Add a v4l2_fh to video_device file handle list. Must be called once the
|
||||
file handle is completely initialized.
|
||||
|
||||
void v4l2_fh_del(struct v4l2_fh *fh)
|
||||
|
||||
Unassociate the file handle from video_device(). The file handle
|
||||
exit function may now be called.
|
||||
|
||||
void v4l2_fh_exit(struct v4l2_fh *fh)
|
||||
|
||||
Uninitialise the file handle. After uninitialisation the v4l2_fh
|
||||
memory can be freed.
|
||||
|
||||
|
||||
If struct v4l2_fh is not embedded, then you can use these helper functions:
|
||||
|
||||
int v4l2_fh_open(struct file *filp)
|
||||
|
||||
This allocates a struct v4l2_fh, initializes it and adds it to the struct
|
||||
video_device associated with the file struct.
|
||||
|
||||
int v4l2_fh_release(struct file *filp)
|
||||
|
||||
This deletes it from the struct video_device associated with the file
|
||||
struct, uninitialised the v4l2_fh and frees it.
|
||||
|
||||
These two functions can be plugged into the v4l2_file_operation's open() and
|
||||
release() ops.
|
||||
|
||||
|
||||
Several drivers need to do something when the first file handle is opened and
|
||||
when the last file handle closes. Two helper functions were added to check
|
||||
whether the v4l2_fh struct is the only open filehandle of the associated
|
||||
device node:
|
||||
|
||||
int v4l2_fh_is_singular(struct v4l2_fh *fh)
|
||||
|
||||
Returns 1 if the file handle is the only open file handle, else 0.
|
||||
|
||||
int v4l2_fh_is_singular_file(struct file *filp)
|
||||
|
||||
Same, but it calls v4l2_fh_is_singular with filp->private_data.
|
||||
|
||||
|
||||
V4L2 events
|
||||
-----------
|
||||
|
||||
|
Reference in New Issue
Block a user