linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH]Documentation: Chinese translation of Documentation/video4linux/v4l2-framework.txt
@ 2012-09-01 16:51 Ninja Tekkaman
       [not found] ` <606bebba.1234f.139870aedda.Coremail.rafaman@126.com>
  0 siblings, 1 reply; 2+ messages in thread
From: Ninja Tekkaman @ 2012-09-01 16:51 UTC (permalink / raw)
  To: Harry Wei
  Cc: Greg-Kroah-Hartman, linux-kernel, linux-doc,
	Mauro Carvalho Chehab, kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=GB2312, Size: 33073 bytes --]

This is a Chinese translated version of
Documentation/video4linux/v4l2-framework.txt

Signed-off-by: Fu Wei <tekkamanninja@gmail.com>
---
 Documentation/zh_CN/video4linux/v4l2-framework.txt |  983 ++++++++++++++++++++
 1 file changed, 983 insertions(+)
 create mode 100644 Documentation/zh_CN/video4linux/v4l2-framework.txt

diff --git a/Documentation/zh_CN/video4linux/v4l2-framework.txt
b/Documentation/zh_CN/video4linux/v4l2-framework.txt
new file mode 100644
index 0000000..3e74f13
--- /dev/null
+++ b/Documentation/zh_CN/video4linux/v4l2-framework.txt
@@ -0,0 +1,983 @@
+Chinese translated version of Documentation/video4linux/v4l2-framework.txt
+
+If you have any comment or update to the content, please contact the
+original document maintainer directly.  However, if you have a problem
+communicating in English you can also ask the Chinese maintainer for
+help.  Contact the Chinese maintainer if this translation is outdated
+or if there is a problem with the translation.
+
+Maintainer: Mauro Carvalho Chehab <mchehab@infradead.org>
+Chinese maintainer: Fu Wei <tekkamanninja@gmail.com>
+---------------------------------------------------------------------
+Documentation/video4linux/v4l2-framework.txt µÄÖÐÎÄ·­Òë
+
+Èç¹ûÏëÆÀÂÛ»ò¸üб¾ÎĵÄÄÚÈÝ£¬ÇëÖ±½ÓÁªÏµÔ­ÎĵµµÄά»¤Õß¡£Èç¹ûÄãʹÓÃÓ¢ÎÄ
+½»Á÷ÓÐÀ§ÄѵĻ°£¬Ò²¿ÉÒÔÏòÖÐÎÄ°æά»¤ÕßÇóÖú¡£Èç¹û±¾·­Òë¸üв»¼°Ê±»òÕß·­
+Òë´æÔÚÎÊÌ⣬ÇëÁªÏµÖÐÎÄ°æά»¤Õß¡£
+Ó¢ÎÄ°æά»¤Õߣº Mauro Carvalho Chehab <mchehab@infradead.org>
+ÖÐÎÄ°æά»¤Õߣº ¸µì¿ Fu Wei <tekkamanninja@gmail.com>
+ÖÐÎÄ°æ·­ÒëÕߣº ¸µì¿ Fu Wei <tekkamanninja@gmail.com>
+ÖÐÎÄ°æУÒëÕߣº ¸µì¿ Fu Wei <tekkamanninja@gmail.com>
+
+
+ÒÔÏÂΪÕýÎÄ
+---------------------------------------------------------------------
+V4L2 Çý¶¯¿ò¼Ü¸ÅÀÀ
+==============
+
+±¾ÎĵµÃèÊö V4L2 ¿ò¼ÜËùÌṩµÄ¸÷ÖֽṹºÍËüÃÇÖ®¼äµÄ¹Øϵ¡£
+
+
+½éÉÜ
+----
+
+´ó²¿·ÖÏÖ´ú V4L2 É豸Óɶà¸ö IC ×é³É£¬ÔÚ /dev ϵ¼³ö¶à¸öÉ豸½Úµã£¬
+²¢Í¬Ê±´´½¨·Ç V4L2 É豸£¨Èç DVB¡¢ALSA¡¢FB¡¢I2C ºÍºìÍâÊäÈëÉ豸£©¡£
+ÓÉÓÚÕâÖÖÓ²¼þµÄ¸´ÔÓÐÔ£¬V4L2 Çý¶¯Ò²±äµÃ·Ç³£¸´ÔÓ¡£
+
+ÓÈÆäÊÇ V4L2 ±ØÐëÖ§³Ö IC ʵÏÖÒôÊÓƵµÄ¶à·¸´Óúͱà½âÂ룬Õâ¾Í¸üÔö¼ÓÁËÆä
+¸´ÔÓÐÔ¡£Í¨³£ÕâЩ IC ͨ¹ýÒ»¸ö»ò¶à¸ö I2C ×ÜÏßÁ¬½Óµ½Ö÷ÇÅÇý¶¯Æ÷£¬µ«Ò²¿É
+ʹÓÃÆäËû×ÜÏß¡£ÕâЩÉ豸³ÆΪ¡°×ÓÉ豸¡±¡£
+
+³¤ÆÚÒÔÀ´£¬Õâ¸ö¿ò¼Ü½öÏÞÓÚͨ¹ý video_device ½á¹¹Ìå´´½¨ V4L É豸½Úµã£¬
+²¢Ê¹Óà video_buf ´¦ÀíÊÓƵ»º³å£¨×¢£º±¾ÎIJ»ÌÖÂÛ video_buf ¿ò¼Ü£©¡£
+
+ÕâÒâζ×ÅËùÓÐÇý¶¯±ØÐë×Ô¼ºÉèÖÃÉ豸ʵÀý²¢Á¬½Óµ½×ÓÉ豸¡£ÆäÖÐÒ»²¿·ÖÒªÕýÈ·µØ
+Íê³ÉÊDZȽϸ´Ôӵģ¬Ê¹µÃÐí¶àÇý¶¯¶¼Ã»ÓÐÕýÈ·µØʵÏÖ¡£
+
+ÓÉÓÚ¿ò¼ÜµÄȱʧ£¬ÓкܶàͨÓôúÂ붼²»¿ÉÖظ´ÀûÓá£
+
+Òò´Ë£¬Õâ¸ö¿ò¼Ü¹¹½¨ËùÓÐÇý¶¯¶¼ÐèÒªµÄ»ù±¾½á¹¹¿é£¬¶øͳһµÄ¿ò¼Ü½«Ê¹Í¨ÓôúÂë
+´´½¨³ÉʵÓú¯Êý²¢ÔÚËùÓÐÇý¶¯Öй²Ïí±äµÃ¸ü¼ÓÈÝÒס£
+
+
+Çý¶¯½á¹¹
+-------
+
+ËùÓÐ V4L2 Çý¶¯¶¼ÓÐÈçϽṹ£º
+
+1) ÿ¸öÉ豸ʵÀýµÄ½á¹¹Ìå--°üº¬ÆäÉ豸״̬¡£
+
+2) ³õʼ»¯ºÍ¿ØÖÆ×ÓÉ豸µÄ·½·¨£¨Èç¹ûÓУ©¡£
+
+3) ´´½¨ V4L2 É豸½Úµã (/dev/videoX¡¢/dev/vbiX ºÍ /dev/radioX)
+   ²¢¸ú×ÙÉ豸½ÚµãµÄÌض¨Êý¾Ý¡£
+
+4) Ìض¨Îļþ¾ä±ú½á¹¹Ìå--°üº¬Ã¿¸öÎļþ¾ä±úµÄÊý¾Ý¡£
+
+5) ÊÓƵ»º³å´¦Àí¡£
+
+ÒÔÏÂÊÇËüÃǵijõÂÔ¹Øϵͼ£º
+
+    device instances£¨É豸ʵÀý£©
+      |
+      +-sub-device instances£¨×ÓÉ豸ʵÀý£©
+      |
+      \-V4L2 device nodes£¨V4L2 É豸½Úµã£©
+	  |
+	  \-filehandle instances£¨Îļþ¾ä±úʵÀý£©
+
+
+¿ò¼Ü½á¹¹
+-------
+
+¸Ã¿ò¼Ü·Ç³£ÀàËÆÇý¶¯½á¹¹£ºËüÓÐÒ»¸ö v4l2_device ½á¹¹ÓÃÓÚ±£´æÉ豸
+ʵÀýµÄÊý¾Ý£»Ò»¸ö v4l2_subdev ½á¹¹Ìå´ú±í×ÓÉ豸ʵÀý£»video_device
+½á¹¹Ìå±£´æ V4L2 É豸½ÚµãµÄÊý¾Ý£»½«À´ v4l2_fh ½á¹¹Ì彫¸ú×ÙÎļþ¾ä±ú
+ʵÀý£¨ÔÝδÉÐδʵÏÖ£©¡£
+
+V4L2 ¿ò¼ÜÒ²¿ÉÓëýÌå¿ò¼ÜÕûºÏ£¨¿ÉÑ¡µÄ£©¡£Èç¹ûÇý¶¯ÉèÖÃÁË v4l2_device
+½á¹¹ÌåµÄ mdev Óò£¬×ÓÉ豸ºÍÊÓƵ½ÚµãµÄÈë¿Ú½«×Ô¶¯³öÏÖÔÚýÌå¿ò¼ÜÖС£
+
+
+v4l2_device ½á¹¹Ìå
+----------------
+
+ÿ¸öÉ豸ʵÀý¶¼Í¨¹ý v4l2_device (v4l2-device.h)½á¹¹ÌåÀ´±íʾ¡£
+¼òµ¥É豸¿ÉÒÔ½ö·ÖÅäÕâ¸ö½á¹¹Ì壬µ«ÔÚ´ó¶àÊýÇé¿öÏ£¬¶¼»á½«Õâ¸ö½á¹¹Ìå
+ǶÈëµ½Ò»¸ö¸ü´óµÄ½á¹¹ÌåÖС£
+
+Äã±ØÐë×¢²áÕâ¸öÉ豸ʵÀý£º
+
+	v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
+
+×¢²á²Ù×÷½«»á³õʼ»¯ v4l2_device ½á¹¹Ìå¡£Èç¹û dev->driver_data Óò
+Ϊ NULL£¬¾Í½«ÆäÖ¸Ïò v4l2_dev¡£
+
+ÐèÒªÓëýÌå¿ò¼ÜÕûºÏµÄÇý¶¯±ØÐëÊÖ¶¯ÉèÖà dev->driver_data£¬Ö¸Ïò°üº¬
+v4l2_device ½á¹¹ÌåʵÀýµÄÇý¶¯Ìض¨É豸½á¹¹Ìå¡£Õâ¿ÉÒÔÔÚ×¢²á V4L2 É豸
+ʵÀýǰͨ¹ý dev_set_drvdata() º¯ÊýÍê³É¡£Í¬Ê±±ØÐëÉèÖà v4l2_device
+½á¹¹ÌåµÄ mdev Óò£¬Ö¸ÏòÊʵ±µÄ³õʼ»¯²¢×¢²á¹ýµÄ media_device ʵÀý¡£
+
+Èç¹û v4l2_dev->name Ϊ¿Õ£¬ÔòËü½«±»ÉèÖÃΪ´Ó dev ÖÐÑÜÉú³öµÄÖµ£¨ÎªÁË
+¸ü¼Ó¾«È·£¬ÐÎʽΪÇý¶¯Ãûºó¸ú bus_id£©¡£Èç¹ûÄãÔÚµ÷Óà v4l2_device_register
+Ç°ÒѾ­ÉèÖúÃÁË£¬Ôò²»»á±»Ð޸ġ£Èç¹û dev Ϊ NULL£¬ÔòÄã*±ØÐë*ÔÚµ÷ÓÃ
+v4l2_device_register Ç°ÉèÖÃ v4l2_dev->name¡£
+
+Äã¿ÉÒÔ»ùÓÚÇý¶¯ÃûºÍÇý¶¯µÄÈ«¾Ö atomic_t ÀàÐ͵ÄʵÀý±àºÅ£¬Í¨¹ý
+v4l2_device_set_name() ÉèÖà name¡£ÕâÑù»áÉú³ÉÀàËÆ ivtv0¡¢ivtv1 µÈ
+Ãû×Ö¡£ÈôÇý¶¯ÃûÒÔÊý×Ö½á⣬Ôò»áÔÚ±àºÅºÍÇý¶¯Ãû¼ä²åÈëÒ»¸öÆÆÕۺţ¬È磺
+cx18-0¡¢cx18-1 µÈ¡£´Ëº¯Êý·µ»ØʵÀý±àºÅ¡£
+
+µÚÒ»¸ö ¡°dev¡± ²ÎÊýͨ³£ÊÇÒ»¸öÖ¸Ïò pci_dev¡¢usb_interface »ò
+platform_device µÄÖ¸Õë¡£ºÜÉÙʹÆäΪ NULL£¬³ý·ÇÊÇÒ»¸öISAÉ豸»òÕß
+µ±Ò»¸öÉ豸´´½¨Á˶à¸ö PCI É豸£¬Ê¹µÃ v4l2_dev ÎÞ·¨ÓëÒ»¸öÌض¨µÄ¸¸É豸
+¹ØÁª¡£
+
+ÄãÒ²¿ÉÒÔÌṩһ¸ö notify() »Øµ÷£¬Ê¹×ÓÉ豸¿ÉÒÔµ÷ÓÃËüʵÏÖʼþ֪ͨ¡£
+µ«Õâ¸öÉèÖÃÓë×ÓÉ豸Ïà¹Ø¡£×ÓÉ豸֧³ÖµÄÈκÎ֪ͨ±ØÐëÔÚ
+include/media/<subdevice>.h Öж¨ÒåÒ»¸öÏûϢͷ¡£
+
+×¢Ïú v4l2_device ʹÓÃÈçϺ¯Êý£º
+
+	v4l2_device_unregister(struct v4l2_device *v4l2_dev);
+
+Èç¹û dev->driver_data ÓòÖ¸Ïò v4l2_dev£¬½«»á±»ÖØÖÃΪ NULL¡£×¢Ïúͬʱ
+»á×Ô¶¯´ÓÉ豸ÖÐ×¢ÏúËùÓÐ×ÓÉ豸¡£
+
+Èç¹ûÄãÓÐÒ»¸öÈȲå°ÎÉ豸£¨ÈçUSBÉ豸£©£¬Ôòµ±¶Ï¿ª·¢Éúʱ£¬¸¸É豸½«ÎÞЧ¡£
+ÓÉÓÚ v4l2_device ÓÐÒ»¸öÖ¸Ïò¸¸É豸µÄÖ¸Õë±ØÐë±»Çå³ý£¬Í¬Ê±±êÖ¾¸¸É豸
+ÒÑÏûʧ£¬ËùÒÔ±ØÐëµ÷ÓÃÒÔϺ¯Êý£º
+
+	v4l2_device_disconnect(struct v4l2_device *v4l2_dev);
+
+Õâ¸öº¯Êý²¢*²»*×¢Ïú×ÓÉ豸£¬Òò´ËÄãÒÀȻҪµ÷Óà v4l2_device_unregister()
+º¯Êý¡£Èç¹ûÄãµÄÇý¶¯Æ÷²¢·ÇÈȲå°ÎµÄ£¬¾ÍûÓбØÒªµ÷Óà v4l2_device_disconnect()¡£
+
+ÓÐʱÄãÐèÒª±éÀúËùÓб»Ìض¨Çý¶¯×¢²áµÄÉ豸¡£Õâͨ³£·¢ÉúÔÚ¶à¸öÉ豸Çý¶¯Ê¹ÓÃ
+ͬһ¸öÓ²¼þµÄÇé¿öÏ¡£È磺ivtvfb Çý¶¯ÊÇÒ»¸öʹÓà ivtv Ó²¼þµÄÖ¡»º³åÇý¶¯£¬
+ͬʱ alsa Çý¶¯Ò²Ê¹ÓôËÓ²¼þ¡£
+
+Äã¿ÉÒÔʹÓÃÈçÏÂÀý³Ì±éÀúËùÓÐ×¢²áµÄÉ豸£º
+
+static int callback(struct device *dev, void *p)
+{
+	struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
+
+	/* ²âÊÔÕâ¸öÉ豸ÊÇ·ñÒѾ­³õʼ»¯ */
+	if (v4l2_dev == NULL)
+		return 0;
+	...
+	return 0;
+}
+
+int iterate(void *p)
+{
+	struct device_driver *drv;
+	int err;
+
+	/* ÔÚPCI ×ÜÏßÉϲéÕÒivtvÇý¶¯¡£
+	   pci_bus_typeÊÇÈ«¾ÖµÄ. ¶ÔÓÚUSB×ÜÏßʹÓÃusb_bus_type¡£ */
+	drv = driver_find("ivtv", &pci_bus_type);
+	/* ±éÀúËùÓеÄivtvÉ豸ʵÀý */
+	err = driver_for_each_device(drv, NULL, p, callback);
+	put_driver(drv);
+	return err;
+}
+
+ÓÐʱÄãÐèÒªÒ»¸öÉ豸ʵÀýµÄÔËÐмÆÊý¡£Õâ¸öͨ³£ÓÃÓÚÓ³ÉäÒ»¸öÉ豸ʵÀýµ½Ò»¸ö
+Ä£¿éÑ¡ÔñÊý×éµÄË÷Òý¡£
+
+ÍƼö·½·¨ÈçÏ£º
+
+static atomic_t drv_instance = ATOMIC_INIT(0);
+
+static int __devinit drv_probe(struct pci_dev *pdev,
+				const struct pci_device_id *pci_id)
+{
+	...
+	state->instance = atomic_inc_return(&drv_instance) - 1;
+}
+
+Èç¹ûÄãÓжà¸öÉ豸½Úµã£¬¶ÔÓÚÈȲå°ÎÉ豸£¬ÖªµÀºÎʱעÏú v4l2_device ½á¹¹Ìå
+¾Í±È½ÏÀ§ÄÑ¡£Îª´Ë v4l2_device ÓÐÒýÓüÆÊýÖ§³Ö¡£µ±µ÷Óà video_register_device
+ʱÔö¼ÓÒýÓüÆÊý£¬¶øÉ豸½ÚµãÊÍ·Åʱ¼õСÒýÓüÆÊý¡£µ±ÒýÓüÆÊýΪÁ㣬Ôò
+v4l2_device µÄrelease() »Øµ÷½«±»Ö´ÐС£Äã¾Í¿ÉÒÔÔÚ´Ëʱ×ö×îºóµÄÇåÀí¹¤×÷¡£
+
+Èç¹û´´½¨ÁËÆäËûÉ豸½Úµã£¨±ÈÈç ALSA£©£¬ÔòÄã¿ÉÒÔͨ¹ýÒÔϺ¯ÊýÊÖ¶¯Ôö¼õ
+ÒýÓüÆÊý£º
+
+void v4l2_device_get(struct v4l2_device *v4l2_dev);
+
+»ò:
+
+int v4l2_device_put(struct v4l2_device *v4l2_dev);
+
+ÓÉÓÚÒýÓü¼Êõ³õʼ»¯Îª 1 £¬ÄãÒ²ÐèÒªÔÚ disconnect() »Øµ÷£¨¶ÔÓÚ USB É豸£©ÖÐ
+µ÷Óà v4l2_device_put£¬»òÕß remove() »Øµ÷£¨ÀýÈç¶ÔÓÚ PCI É豸£©£¬·ñÔò
+ÒýÓüÆÊý½«ÓÀÔ¶²»»áΪ 0 ¡£
+
+v4l2_subdev½á¹¹Ìå
+------------------
+
+Ðí¶àÇý¶¯ÐèÒªÓë×ÓÉ豸ͨÐÅ¡£ÕâЩÉ豸¿ÉÒÔÍê³É¸÷ÖÖÈÎÎñ£¬µ«Í¨³£ËûÃǸºÔð
+ÒôÊÓƵ¸´Óúͱà½âÂë¡£ÈçÍøÂçÉãÏñÍ·µÄ×ÓÉ豸ͨ³£ÊÇ´«¸ÐÆ÷ºÍÉãÏñÍ·¿ØÖÆÆ÷¡£
+
+ÕâЩһ°ãΪ I2C ½Ó¿ÚÉ豸£¬µ«²¢²»Ò»¶¨¶¼ÊÇ¡£ÎªÁ˸øÇý¶¯Ìṩµ÷ÓÃ×ÓÉ豸µÄ
+ͳһ½Ó¿Ú£¬v4l2_subdev ½á¹¹Ì壨v4l2-subdev.h£©²úÉúÁË¡£
+
+ÿ¸ö×ÓÉ豸Çý¶¯¶¼±ØÐëÓÐÒ»¸ö v4l2_subdev ½á¹¹Ìå¡£Õâ¸ö½á¹¹Ìå¿ÉÒÔµ¥¶À
+´ú±íÒ»¸ö¼òµ¥µÄ×ÓÉ豸£¬Ò²¿ÉÒÔǶÈëµ½Ò»¸ö¸ü´óµÄ½á¹¹ÌåÖУ¬Óë¸ü¶àÉ豸״̬
+ÐÅÏ¢±£´æÔÚÒ»Æð¡£Í¨³£ÓÐÒ»¸öϼ¶É豸½á¹¹Ì壨±ÈÈ磺i2c_client£©°üº¬ÁË
+Äں˴´½¨µÄÉ豸Êý¾Ý¡£½¨ÒéʹÓà v4l2_set_subdevdata() ½«Õâ¸ö½á¹¹ÌåµÄ
+Ö¸Õë±£´æÔÚ v4l2_subdev µÄ˽ÓÐÊý¾ÝÓò(dev_priv)ÖС£ÕâʹµÃͨ¹ý v4l2_subdev
+ÕÒµ½Êµ¼ÊµÄµÍ²ã×ÜÏßÌض¨É豸Êý¾Ý±äµÃÈÝÒס£
+
+ÄãͬʱÐèÒªÒ»¸ö´ÓµÍ²ã½á¹¹Ìå»ñÈ¡ v4l2_subdev Ö¸ÕëµÄ·½·¨¡£¶ÔÓÚ³£ÓõÄ
+i2c_client ½á¹¹Ì壬i2c_set_clientdata() º¯Êý¿ÉÓÃÓÚ±£´æÒ»¸ö v4l2_subdev
+Ö¸Õ룻¶ÔÓÚÆäËû×ÜÏßÄã¿ÉÄÜÐèҪʹÓÃÆäËûÏà¹Øº¯Êý¡£
+
+ÇÅÇý¶¯ÖÐÒ²Ó¦±£´æÿ¸ö×ÓÉ豸µÄ˽ÓÐÊý¾Ý£¬±ÈÈçÒ»¸öÖ¸ÏòÌض¨Çŵĸ÷É豸˽ÓÐ
+Êý¾ÝµÄÖ¸Õ롣Ϊ´Ë v4l2_subdev ½á¹¹ÌåÌṩÖ÷»ú˽ÓÐÊý¾ÝÓò(host_priv)£¬
+²¢¿Éͨ¹ý v4l2_get_subdev_hostdata() ºÍ v4l2_set_subdev_hostdata()
+·ÃÎÊ¡£
+
+´Ó×ÜÏßÇÅÇý¶¯µÄÊӽǣ¬Çý¶¯¼ÓÔØ×ÓÉ豸ģ¿é²¢ÒÔijÖÖ·½Ê½»ñµÃ v4l2_subdev
+½á¹¹ÌåÖ¸Õë¡£¶ÔÓÚ i2c ×ÜÏßÉ豸Ïà¶Ô¼òµ¥£ºµ÷Óà i2c_get_clientdata()¡£
+¶ÔÓÚÆäËû×ÜÏßÒ²ÐèÒª×öÀàËƵIJÙ×÷¡£Õë¶Ô I2C ×ÜÏßÉϵÄ×ÓÉ豸¸¨Öúº¯Êý°ïÄã
+Íê³ÉÁ˴󲿷ָ´ÔӵŤ×÷¡£
+
+ÿ¸ö v4l2_subdev ¶¼°üº¬×ÓÉ豸Çý¶¯ÐèҪʵÏֵĺ¯ÊýÖ¸Õ루Èç¹û¶Ô´ËÉ豸
+²»ÊÊÓ㬿ÉΪNULL£©¡£ÓÉÓÚ×ÓÉ豸¿ÉÍê³ÉÐí¶à²»Í¬µÄ¹¤×÷£¬¶øÔÚÒ»¸öÅÓ´óµÄ
+º¯ÊýÖ¸Õë½á¹¹ÌåÖÐͨ³£½öÓÐÉÙÊýÓÐÓõĺ¯ÊýʵÏÖÆ书Äܿ϶¨²»ºÏÊÊ¡£ËùÒÔ£¬
+º¯ÊýÖ¸Õë¸ù¾ÝÆäʵÏֵŦÄܱ»·ÖÀ࣬ÿһÀ඼ÓÐ×Ô¼ºµÄº¯ÊýÖ¸Õë½á¹¹Ìå¡£
+
+¶¥²ãº¯ÊýÖ¸Õë½á¹¹Ìå°üº¬ÁËÖ¸Ïò¸÷ÀຯÊýÖ¸Õë½á¹¹ÌåµÄÖ¸Õ룬Èç¹û×ÓÉ豸Çý¶¯
+²»Ö§³Ö¸ÃÀຯÊýÖеÄÈκÎÒ»¸ö¹¦ÄÜ£¬ÔòÖ¸Ïò¸ÃÀà½á¹¹ÌåµÄÖ¸ÕëΪNULL¡£
+
+ÕâЩ½á¹¹Ì嶨ÒåÈçÏ£º
+
+struct v4l2_subdev_core_ops {
+	int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
+	int (*log_status)(struct v4l2_subdev *sd);
+	int (*init)(struct v4l2_subdev *sd, u32 val);
+	...
+};
+
+struct v4l2_subdev_tuner_ops {
+	...
+};
+
+struct v4l2_subdev_audio_ops {
+	...
+};
+
+struct v4l2_subdev_video_ops {
+	...
+};
+
+struct v4l2_subdev_pad_ops {
+	...
+};
+
+struct v4l2_subdev_ops {
+	const struct v4l2_subdev_core_ops  *core;
+	const struct v4l2_subdev_tuner_ops *tuner;
+	const struct v4l2_subdev_audio_ops *audio;
+	const struct v4l2_subdev_video_ops *video;
+	const struct v4l2_subdev_pad_ops *video;
+};
+
+ÆäÖÐ core£¨ºËÐÄ£©º¯Êý¼¯Í¨³£¿ÉÓÃÓÚËùÓÐ×ÓÉ豸£¬ÆäËûÀà±ðµÄʵÏÖÒÀÀµÓÚ
+×ÓÉ豸¡£ÈçÊÓƵÉ豸¿ÉÄܲ»Ö§³ÖÒôƵ²Ù×÷º¯Êý£¬·´Ö®ÒàÈ»¡£
+
+ÕâÑùµÄÉèÖÃÔÚÏÞÖÆÁ˺¯ÊýÖ¸ÕëÊýÁ¿µÄͬʱ£¬»¹Ê¹Ôö¼ÓеIJÙ×÷º¯ÊýºÍ·ÖÀà
+±äµÃ½ÏΪÈÝÒס£
+
+×ÓÉ豸Çý¶¯¿ÉʹÓÃÈçϺ¯Êý³õʼ»¯ v4l2_subdev ½á¹¹Ì壺
+
+	v4l2_subdev_init(sd, &ops);
+
+È»ºó£¬Äã±ØÐëÓÃÒ»¸öΨһµÄÃû×Ö³õʼ»¯ subdev->name£¬²¢³õʼ»¯Ä£¿éµÄ
+owner Óò¡£ÈôʹÓà i2c ¸¨Öúº¯Êý£¬ÕâЩ¶¼»á°ïÄã´¦ÀíºÃ¡£
+
+ÈôÐèͬýÌå¿ò¼ÜÕûºÏ£¬Äã±ØÐëµ÷Óà media_entity_init() ³õʼ»¯ v4l2_subdev
+½á¹¹ÌåÖÐµÄ media_entity ½á¹¹Ì壨entity Óò£©£º
+
+	struct media_pad *pads = &my_sd->pads;
+	int err;
+
+	err = media_entity_init(&sd->entity, npads, pads, 0);
+
+pads Êý×é±ØÐëÔ¤Ïȳõʼ»¯¡£ÎÞÐëÊÖ¶¯ÉèÖà media_entity µÄ type ºÍ
+name Óò£¬µ«ÈçÓбØÒª£¬revision Óò±ØÐë³õʼ»¯¡£
+
+µ±£¨ÈκΣ©×ÓÉ豸½Úµã±»´ò¿ª/¹Ø±Õ£¬¶Ô entity µÄÒýÓý«±»×Ô¶¯»ñÈ¡/ÊÍ·Å¡£
+
+ÔÚ×ÓÉ豸±»×¢ÏúÖ®ºó£¬²»ÒªÍü¼ÇÇåÀí media_entity ½á¹¹Ì壺
+
+	media_entity_cleanup(&sd->entity);
+
+Èç¹û×ÓÉ豸Çý¶¯Ç÷ÏòÓÚ´¦ÀíÊÓƵ²¢ÕûºÏ½øÁËýÌå¿ò¼Ü£¬±ØÐëʹÓà v4l2_subdev_pad_ops
+Ìæ´ú v4l2_subdev_video_ops ʵÏÖ¸ñʽÏà¹ØµÄ¹¦ÄÜ¡£
+
+ÕâÖÖÇé¿öÏ£¬×ÓÉ豸Çý¶¯Ó¦¸ÃÉèÖà link_validate Óò£¬ÒÔÌṩËü×ÔÉíµÄÁ´½Ó
+ÑéÖ¤º¯Êý¡£Á´½ÓÑéÖ¤º¯ÊýÓ¦¶Ô¹ÜµÀ£¨Á½¶ËÁ´½ÓµÄ¶¼ÊÇ V4L2 ×ÓÉ豸£©ÖеÄÿ¸ö
+Á´½Óµ÷Óá£Çý¶¯»¹Òª¸ºÔðÑéÖ¤×ÓÉ豸ºÍÊÓƵ½Úµã¼ä¸ñʽÅäÖõÄÕýÈ·ÐÔ¡£
+
+Èç¹û link_validate ²Ù×÷ûÓÐÉèÖã¬Ä¬È쵀 v4l2_subdev_link_validate_default()
+º¯Êý½«»á±»µ÷Óá£Õâ¸öº¯Êý±£Ö¤¿í¡¢¸ßºÍýÌå×ÜÏßÏñËظñʽÔÚÁ´½ÓµÄÊÕ·¢Á½¶Ë
+¶¼Ò»Ö¡£×ÓÉ豸Çý¶¯³ýÁËËüÃÇ×Ô¼ºµÄ¼ì²âÍ⣬Ҳ¿ÉÒÔ×ÔÓÉʹÓÃÕâ¸öº¯ÊýÒÔÖ´ÐÐ
+ÉÏÃæÌáµ½µÄ¼ì²é¡£
+
+É豸£¨ÇÅ£©Çý¶¯³ÌÐò±ØÐëÏò v4l2_device ×¢²á v4l2_subdev£º
+
+	int err = v4l2_device_register_subdev(v4l2_dev, sd);
+
+Èç¹û×ÓÉ豸ģ¿éÔÚËü×¢²áÇ°Ïûʧ£¬Õâ¸ö²Ù×÷¿ÉÄÜʧ°Ü¡£ÔÚÕâ¸öº¯Êý³É¹¦·µ»Øºó£¬
+subdev->dev Óò¾ÍÖ¸ÏòÁË v4l2_device¡£
+
+Èç¹û v4l2_device ¸¸É豸µÄ mdev ÓòΪ·Ç NULL Öµ£¬Ôò×ÓÉ豸ʵÌ彫±»×Ô¶¯
+×¢²áΪýÌåÉ豸¡£
+
+×¢Ïú×ÓÉ豸Ôò¿ÉÓÃÈçϺ¯Êý£º
+
+	v4l2_device_unregister_subdev(sd);
+
+´Ëºó£¬×ÓÉ豸ģ¿é¾Í¿ÉжÔØ£¬ÇÒ sd->dev == NULL¡£
+
+×¢²áÖ®É豸ºó£¬¿Éͨ¹ýÒÔÏ·½Ê½Ö±½Óµ÷ÓÃÆä²Ù×÷º¯Êý£º
+
+	err = sd->ops->core->g_chip_ident(sd, &chip);
+
+µ«Ê¹ÓÃÈçϺê»á±È½ÏÈÝÒ×ÇÒºÏÊÊ£º
+
+	err = v4l2_subdev_call(sd, core, g_chip_ident, &chip);
+
+Õâ¸öºê½«»á×ö NULL Ö¸Õë¼ì²é£¬Èç¹û subdev Ϊ NULL£¬Ôò·µ»Ø-ENODEV£»Èç¹û
+subdev->core »ò subdev->core->g_chip_ident Ϊ NULL£¬Ôò·µ»Ø -ENOIOCTLCMD£»
+·ñÔò½«·µ»Ø subdev->ops->core->g_chip_ident ops µ÷ÓõÄʵ¼Ê½á¹û¡£
+
+ÓÐʱҲ¿ÉÄÜͬʱµ÷ÓÃËùÓлòһϵÁÐ×ÓÉ豸µÄij¸ö²Ù×÷º¯Êý£º
+
+	v4l2_device_call_all(v4l2_dev, 0, core, g_chip_ident, &chip);
+
+Èκβ»Ö§³Ö´Ë²Ù×÷µÄ×ÓÉ豸¶¼»á±»Ìø¹ý£¬²¢ºöÂÔ´íÎó·µ»ØÖµ¡£µ«Èç¹ûÄãÐèÒª
+¼ì²é³ö´íÂ룬Ôò¿ÉʹÓÃÈçϺ¯Êý£º
+
+	err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_chip_ident, &chip);
+
+³ý -ENOIOCTLCMD ÍâµÄÈκδíÎ󶼻áÌø³öÑ­»·²¢·µ»Ø´íÎóÖµ¡£Èç¹û£¨³ý -ENOIOCTLCMD
+Í⣩ûÓдíÎó·¢Éú£¬Ôò·µ»Ø 0¡£
+
+¶ÔÓÚÒÔÉÏÁ½¸öº¯ÊýµÄµÚ¶þ¸ö²ÎÊýΪ×é ID¡£Èç¹ûΪ 0£¬ÔòËùÓÐ×ÓÉ豸¶¼»áÖ´ÐÐ
+Õâ¸ö²Ù×÷¡£Èç¹ûΪ·Ç 0 Öµ£¬ÔòÖ»ÓÐÄÇЩ×é ID Æ¥ÅäµÄ×ÓÉ豸²Å»áÖ´Ðд˲Ù×÷¡£
+ÔÚÇÅÇý¶¯×¢²áÒ»¸ö×ÓÉ豸ǰ£¬¿ÉÒÔÉèÖà sd->grp_id ΪÈκÎÆÚÍûÖµ£¨Ä¬ÈÏֵΪ
+0£©¡£Õâ¸öÖµÊôÓÚÇÅÇý¶¯£¬ÇÒ×ÓÉ豸Çý¶¯½«²»»áÐ޸ĺÍʹÓÃËü¡£
+
+×é ID ¸³ÓèÁËÇÅÇý¶¯¸ü¶à¶ÔÓÚÈçºÎµ÷Óûص÷µÄ¿ØÖÆ¡£ÀýÈ磬µç·°åÉÏÓжà¸ö
+ÒôƵоƬ£¬Ã¿¸ö¶¼ÓиıäÒôÁ¿µÄÄÜÁ¦¡£µ«µ±Óû§ÏëÒª¸Ä±äÒôÁ¿µÄʱºò£¬Í¨³£
+Ö»ÓÐÒ»¸ö»á±»Êµ¼ÊʹÓá£Äã¿ÉÒÔ¶ÔÕâÑùµÄ×ÓÉ豸ÉèÖÃ×é ID Ϊ£¨ÀýÈç AUDIO_CONTROLLER£©
+²¢ÔÚµ÷Óà v4l2_device_call_all() ʱָ¶¨ËüΪ×é ID Öµ¡£Õâ¾Í±£Ö¤ÁËÖ»ÓÐ
+ÐèÒªµÄ×ÓÉ豸²Å»áÖ´ÐÐÕâ¸ö»Øµ÷¡£
+
+Èç¹û×ÓÉ豸ÐèҪ֪ͨËüµÄ v4l2_device ¸¸É豸һ¸öʼþ£¬¿ÉÒÔµ÷ÓÃ
+v4l2_subdev_notify(sd, notification, arg)¡£Õâ¸öºê¼ì²éÊÇ·ñÓÐÒ»¸ö
+notify() »Øµ÷±»×¢²á£¬Èç¹ûûÓУ¬·µ»Ø -ENODEV¡£·ñÔò·µ»Ø notify() µ÷ÓÃ
+½á¹û¡£
+
+ʹÓà v4l2_subdev µÄºÃ´¦ÔÚÓÚËüÊÇÒ»¸öͨÓýṹÌ壬ÇÒ²»°üº¬ÈκεײãÓ²¼þ
+ÐÅÏ¢¡£ËùÓÐÇý¶¯¿ÉÒÔ°üº¬¶à¸ö I2C ×ÜÏßµÄ×ÓÉ豸£¬µ«Ò²ÓÐ×ÓÉ豸ÊÇͨ¹ý GPIO
+¿ØÖÆ¡£Õâ¸öÇø±ð½öÔÚÅäÖÃÉ豸ʱÓйØϵ£¬Ò»µ©×ÓÉ豸ע²áÍê³É£¬¶ÔÓÚ v4l2
+×ÓϵͳÀ´Ëµ¾ÍÍêȫ͸Ã÷ÁË¡£
+
+
+V4L2 ×ÓÉ豸Óû§¿Õ¼äAPI
+--------------------
+
+³ýÁËͨ¹ý v4l2_subdev_ops ½á¹¹µ¼³öµÄÄÚºË API£¬V4L2 ×ÓÉ豸Ҳ¿ÉÒÔÖ±½Ó
+ͨ¹ýÓû§¿Õ¼äÓ¦ÓóÌÐòÀ´¿ØÖÆ¡£
+
+¿ÉÒÔÔÚ /dev Öд´½¨ÃûΪ v4l-subdevX É豸½Úµã£¬ÒÔͨ¹ýÆäÖ±½Ó·ÃÎÊ×ÓÉ豸¡£
+Èç¹û×ÓÉ豸֧³ÖÓû§¿Õ¼äÖ±½ÓÅäÖ㬱ØÐëÔÚ×¢²áÇ°ÉèÖà V4L2_SUBDEV_FL_HAS_DEVNODE
+±êÖ¾¡£
+
+×¢²á×ÓÉ豸֮ºó£¬ v4l2_device Çý¶¯»áͨ¹ýµ÷Óà v4l2_device_register_subdev_nodes()
+º¯ÊýΪËùÓÐÒÑ×¢²á²¢ÉèÖÃÁË V4L2_SUBDEV_FL_HAS_DEVNODE µÄ×ÓÉ豸´´½¨
+É豸½Úµã¡£ÕâЩÉ豸½Úµã»áÔÚ×ÓÉ豸עÏúʱ×Ô¶¯É¾³ý¡£
+
+ÕâЩÉ豸½Úµã´¦Àí V4L2 API µÄÒ»¸ö×Ó¼¯¡£
+
+VIDIOC_QUERYCTRL
+VIDIOC_QUERYMENU
+VIDIOC_G_CTRL
+VIDIOC_S_CTRL
+VIDIOC_G_EXT_CTRLS
+VIDIOC_S_EXT_CTRLS
+VIDIOC_TRY_EXT_CTRLS
+
+	ÕâЩ ioctls ¿ØÖÆÓë V4L2 Öж¨ÒåµÄÒ»Ö¡£ËûÃÇÐÐΪÏàͬ£¬Î¨Ò»µÄ
+	²»Í¬ÊÇËûÃÇÖ»´¦Àí×ÓÉ豸µÄ¿ØÖÆʵÏÖ¡£¸ù¾ÝÇý¶¯³ÌÐò£¬ÕâЩ¿ØÖÆÒ²
+	¿ÉÒÔͨ¹ýÒ»¸ö£¨»ò¶à¸ö£© V4L2 É豸½Úµã·ÃÎÊ¡£
+
+VIDIOC_DQEVENT
+VIDIOC_SUBSCRIBE_EVENT
+VIDIOC_UNSUBSCRIBE_EVENT
+
+	ÕâЩ  ioctls ʼþÓë V4L2 Öж¨ÒåµÄÒ»Ö¡£ËûÃÇÐÐΪÏàͬ£¬Î¨Ò»µÄ
+	²»Í¬ÊÇËûÃÇÖ»´¦Àí×ÓÉ豸²úÉúµÄʼþ¡£¸ù¾ÝÇý¶¯³ÌÐò£¬ÕâЩʼþÒ²
+	¿ÉÒÔͨ¹ýÒ»¸ö£¨»ò¶à¸ö£© V4L2 É豸½ÚµãÉϱ¨¡£
+
+	ҪʹÓÃʼþ֪ͨµÄ×ÓÉ豸Çý¶¯£¬ÔÚ×¢²á×ÓÉ豸ǰ±ØÐëÔÚ v4l2_subdev::flags
+	ÖÐÉèÖÃ V4L2_SUBDEV_USES_EVENTS ²¢ÔÚ v4l2_subdev::nevents
+	Öгõʼ»¯Ê¼þ¶ÓÁÐÉî¶È¡£×¢²áÍê³Éºó£¬Ê¼þ»áÔÚ v4l2_subdev::devnode
+	É豸½ÚµãÖÐÏñͨ³£Ò»Ñù±»ÅŶӡ£
+
+	ΪÕýÈ·Ö§³Öʼþ»úÖÆ£¬poll() Îļþ²Ù×÷Ò²Ó¦±»ÊµÏÖ¡£
+
+˽ÓÐ ioctls
+
+	²»ÔÚÒÔÉÏÁбíÖеÄËùÓÐ ioctls »áͨ¹ý core::ioctl ²Ù×÷Ö±½Ó´«µÝ
+	¸ø×ÓÉ豸Çý¶¯¡£
+
+
+I2C ×ÓÉ豸Çý¶¯
+-------------
+
+ÓÉÓÚÕâЩÇý¶¯ºÜ³£¼û£¬ËùÒÔÄÚÌØÌṩÁËÌض¨µÄ¸¨Öúº¯Êý(v4l2-common.h)ÈÃÕâЩ
+É豸µÄʹÓøü¼ÓÈÝÒס£
+
+Ìí¼Ó v4l2_subdev Ö§³ÖµÄÍƼö·½·¨ÊÇÈà I2C Çý¶¯½« v4l2_subdev ½á¹¹Ìå
+ǶÈ뵽Ϊÿ¸ö I2C É豸ʵÀý´´½¨µÄ״̬½á¹¹ÌåÖС£¶ø×î¼òµ¥µÄÉ豸ûÓÐ״̬
+½á¹¹Ì壬´Ëʱ¿ÉÒÔÖ±½Ó´´½¨Ò»¸ö v4l2_subdev ½á¹¹Ìå¡£
+
+Ò»¸öµäÐ͵Ä״̬½á¹¹ÌåÈçÏÂËùʾ£¨¡®chipname¡¯ÓÃоƬÃû´úÌ棩£º
+
+struct chipname_state {
+	struct v4l2_subdev sd;
+	...  /* ¸½¼ÓµÄ״̬Óò*/
+};
+
+³õʼ»¯ v4l2_subdev ½á¹¹ÌåµÄ·½·¨ÈçÏ£º
+
+	v4l2_i2c_subdev_init(&state->sd, client, subdev_ops);
+
+Õâ¸öº¯Êý½«Ìî³ä v4l2_subdev ½á¹¹ÌåÖеÄËùÓÐÓò£¬²¢±£Ö¤ v4l2_subdev ºÍ
+i2c_client ¶¼Ö¸Ïò±Ë´Ë¡£
+
+ͬʱ£¬ÄãÒ²Ó¦¸ÃΪ´Ó v4l2_subdev Ö¸ÕëÕÒµ½ chipname_state ½á¹¹ÌåÖ¸Õë
+Ìí¼ÓÒ»¸ö¸¨ÖúÄÚÁªº¯Êý¡£
+
+static inline struct chipname_state *to_state(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct chipname_state, sd);
+}
+
+ʹÓÃÒÔϺ¯Êý¿ÉÒÔͨ¹ý v4l2_subdev ½á¹¹ÌåÖ¸Õë»ñµÃ i2c_client ½á¹¹Ìå
+Ö¸Õ룺
+
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+¶øÒÔϺ¯ÊýÔòÏà·´£¬Í¨¹ý i2c_client ½á¹¹ÌåÖ¸Õë»ñµÃ v4l2_subdev ½á¹¹Ìå
+Ö¸Õ룺
+
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+µ± remove()º¯Êý±»µ÷ÓÃÇ°£¬±ØÐë±£Ö¤Ïȵ÷Óà v4l2_device_unregister_subdev(sd)¡£
+´Ë²Ù×÷½«»á´ÓÇÅÇý¶¯ÖÐ×¢Ïú×ÓÉ豸¡£¼´Ê¹×ÓÉ豸ûÓÐ×¢²á£¬µ÷Óô˺¯ÊýÒ²ÊÇ
+°²È«µÄ¡£
+
+±ØÐëÕâÑù×öµÄÔ­ÒòÊÇ£ºµ±ÇÅÇý¶¯×¢Ïú i2c ÊÊÅäÆ÷ʱ£¬remove()»Øµ÷º¯Êý
+»á±»ÄǸöÊÊÅäÆ÷É쵀 i2c É豸µ÷Óᣴ˺ó£¬ÏàÓ¦µÄ v4l2_subdev ½á¹¹Ìå
+¾Í²»´æÔÚÁË£¬ËùÓÐËüÃDZØÐëÏȱ»×¢Ïú¡£ÔÚ remove()»Øµ÷º¯ÊýÖе÷ÓÃ
+v4l2_device_unregister_subdev(sd)£¬¿ÉÒÔ±£Ö¤Ö´ÐÐ×ÜÊÇÕýÈ·µÄ¡£
+
+
+ÇÅÇý¶¯Ò²ÓÐһЩ¸¨×麯Êý¿ÉÓãº
+
+struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter,
+	       "module_foo", "chipid", 0x36, NULL);
+
+Õâ¸öº¯Êý»á¼ÓÔظø¶¨µÄÄ£¿é£¨Èç¹ûûÓÐÄ£¿éÐèÒª¼ÓÔØ£¬¿ÉÒÔΪ NULL£©£¬
+²¢Óøø¶¨µÄ i2c ÊÊÅäÆ÷½á¹¹ÌåÖ¸Õ루i2c_adapter£©ºÍ Æ÷¼þµØÖ·£¨chip/address£©
+×÷Ϊ²ÎÊýµ÷Óà i2c_new_device()¡£Èç¹ûÒ»ÇÐ˳Àû£¬Ôò¾ÍÔÚ v4l2_device
+ÖÐ×¢²áÁË×ÓÉ豸¡£
+
+ÄãÒ²¿ÉÒÔÀûÓà v4l2_i2c_new_subdev()µÄ×îºóÒ»¸ö²ÎÊý£¬´«µÝÒ»¸ö¿ÉÄܵÄ
+I2C µØÖ·Êý×飬Èú¯Êý×Ô¶¯Ì½²â¡£ÕâЩ̽²âµØÖ·Ö»ÓÐÔÚÇ°Ò»¸ö²ÎÊýΪ 0 µÄ
+Çé¿öÏÂʹÓ᣷ÇÁã²ÎÊýÒâζ×ÅÄãÖªµÀ׼ȷµÄ i2c µØÖ·£¬ËùÒÔ´ËʱÎÞÐë½øÐÐ
+̽²â¡£
+
+Èç¹û³ö´í£¬Á½¸öº¯Êý¶¼·µ»Ø NULL¡£
+
+×¢Ò⣺´«µÝ¸ø v4l2_i2c_new_subdev()µÄ chipid ͨ³£ÓëÄ£¿éÃûÒ»Ö¡£
+ËüÔÊÐíÄãÖ¸¶¨Ò»¸öоƬµÄ±äÌ壬±ÈÈç¡°saa7114¡±»ò¡°saa7115¡±¡£Ò»°ãͨ¹ý
+i2c Çý¶¯×Ô¶¯Ì½²â¡£chipid µÄʹÓÃÊÇÔÚ½ñºóÐèÒªÉîÈëÁ˽âµÄÊÂÇé¡£Õâ¸öÓë
+i2c Çý¶¯²»Í¬£¬½ÏÈÝÒ×»ìÏý¡£ÒªÖªµÀÖ§³ÖÄÄЩоƬ±äÌ壬Äã¿ÉÒÔ²éÔÄ i2c
+Çý¶¯´úÂëµÄ i2c_device_id ±í£¬ÉÏÃæÁгöÁËËùÓпÉÄÜÖ§³ÖµÄоƬ¡£
+
+»¹ÓÐÁ½¸ö¸¨Öúº¯Êý£º
+
+v4l2_i2c_new_subdev_cfg£ºÕâ¸öº¯ÊýÌí¼ÓÐ嵀 irq ºÍ platform_data
+²ÎÊý£¬²¢ÓС®addr¡¯ºÍ¡®probed_addrs¡¯²ÎÊý£ºÈç¹û addr ·ÇÁ㣬Ôò±»Ê¹ÓÃ
+£¨²»Ì½²â±äÌ壩£¬·ñÔò probed_addrs ÖеĵØÖ·½«ÓÃÓÚ×Ô¶¯Ì½²â¡£
+
+ÀýÈ磺ÒÔÏ´úÂ뽫»á̽²âµØÖ·£¨0x10£©£º
+
+struct v4l2_subdev *sd = v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter,
+	       "module_foo", "chipid", 0, NULL, 0, I2C_ADDRS(0x10));
+
+v4l2_i2c_new_subdev_board ʹÓÃÒ»¸ö i2c_board_info ½á¹¹Ì壬½«Æä
+Ìæ´ú irq¡¢platform_data ºÍ add r²ÎÊý´«µÝ¸ø i2c Çý¶¯¡£
+
+Èç¹û×ÓÉ豸֧³Ö s_config ºËÐIJÙ×÷£¬Õâ¸ö²Ù×÷»áÔÚ×ÓÉ豸ÅäÖúÃÖ®ºóÒÔ irq ºÍ
+platform_data Ϊ²ÎÊýµ÷Óá£ÔçÆÚµÄ v4l2_i2c_new_(probed_)subdev º¯Êý
+ͬÑùÒ²»áµ÷Óà s_config£¬µ«½öÔÚ irq Ϊ 0 ÇÒ platform_data Ϊ NULL ʱ¡£
+
+video_device½á¹¹Ìå
+-----------------
+
+ÔÚ /dev Ŀ¼ÏµÄʵ¼ÊÉ豸½Úµã¸ù¾Ý video_device ½á¹¹Ìå(v4l2-dev.h)
+´´½¨¡£´Ë½á¹¹Ìå¼È¿ÉÒÔ¶¯Ì¬·ÖÅäÒ²¿ÉÒÔǶÈëµ½Ò»¸ö¸ü´óµÄ½á¹¹ÌåÖС£
+
+¶¯Ì¬·ÖÅä·½·¨ÈçÏ£º
+
+	struct video_device *vdev = video_device_alloc();
+
+	if (vdev == NULL)
+		return -ENOMEM;
+
+	vdev->release = video_device_release;
+
+Èç¹û½«ÆäǶÈëµ½Ò»¸ö´ó½á¹¹ÌåÖУ¬Ôò±ØÐë×Ô¼ºÊµÏÖ release()»Øµ÷¡£
+
+	struct video_device *vdev = &my_vdev->vdev;
+
+	vdev->release = my_vdev_release;
+
+release()»Øµ÷±ØÐë±»ÉèÖã¬ÇÒÔÚ×îºóÒ»¸ö video_device Óû§Í˳öÖ®ºó
+±»µ÷Óá£
+
+ĬÈ쵀 video_device_release()»Øµ÷Ö»Êǵ÷Óà kfree À´ÊÍ·Å֮ǰ·ÖÅäµÄ
+ÄÚ´æ¡£
+
+ÄãÓ¦¸ÃÉèÖÃÕâЩÓò£º
+
+- v4l2_dev: ÉèÖÃΪ v4l2_device ¸¸É豸¡£
+
+- name: ÉèÖÃΪΨһµÄÃèÊöÐÔÉ豸Ãû¡£
+
+- fops: ÉèÖÃΪÒÑÓÐµÄ v4l2_file_operations ½á¹¹Ìå¡£
+
+- ioctl_ops: Èç¹ûÄãʹÓÃv4l2_ioctl_ops À´¼ò»¯ ioctl µÄά»¤
+  (Ç¿ÁÒ½¨ÒéʹÓã¬ÇÒ½«À´¿ÉÄܱäΪǿÖÆÐÔµÄ!)£¬È»ºóÉèÖÃÄã×Ô¼ºµÄ
+  v4l2_ioctl_ops ½á¹¹Ìå.
+
+- lock: Èç¹ûÄãÒªÔÚÇý¶¯ÖÐʵÏÖËùÓеÄËø²Ù×÷£¬ÔòÉèΪ NULL ¡£·ñÔò
+  ¾ÍÒªÉèÖÃÒ»¸öÖ¸Ïò struct mutex_lock ½á¹¹ÌåµÄÖ¸Õ룬Õâ¸öËø½«
+  ÔÚ unlocked_ioctl Îļþ²Ù×÷±»µ÷ÓÃÇ°ÓÉÄں˻ñµÃ£¬²¢ÔÚµ÷Ó÷µ»Øºó
+  ÊÍ·Å¡£Ïê¼ûÏÂÒ»½Ú¡£
+
+- prio: ±£³Ö¶ÔÓÅÏȼ¶µÄ¸ú×Ù¡£ÓÃÓÚʵÏÖ VIDIOC_G/S_PRIORITY¡£Èç¹û
+  ÉèÖÃΪ NULL£¬Ôò»áʹÓà v4l2_device ÖÐµÄ v4l2_prio_state ½á¹¹Ìå¡£
+  Èç¹ûÒª¶Ôÿ¸öÉ豸½Úµã£¨×飩ʵÏÖ¶ÀÁ¢µÄÓÅÏȼ¶£¬¿ÉÒÔ½«ÆäÖ¸Ïò×Ô¼º
+  ʵÏÖµÄ v4l2_prio_state ½á¹¹Ìå¡£
+
+- parent: ½öÔÚʹÓà NULL ×÷Ϊ¸¸É豸½á¹¹Ìå²ÎÊý×¢²á v4l2_device ʱ
+  ÉèÖô˲ÎÊý¡£Ö»ÓÐÔÚÒ»¸öÓ²¼þÉ豸°üº¬¶àÒ»¸ö PCI É豸£¬¹²Ïíͬһ¸ö
+  v4l2_device ºËÐÄʱ²Å»á·¢Éú¡£
+
+  cx88 Çý¶¯¾ÍÊÇÒ»¸öÀý×Ó£ºÒ»¸ö v4l2_device ½á¹¹ÌåºËÐÄ£¬±»Ò»¸öÂãµÄ
+  ÊÓƵ PCI É豸(cx8800)ºÍÒ»¸ö MPEG PCI É豸(cx8802)¹²Óá£ÓÉÓÚ
+  v4l2_device ÎÞ·¨ÓëÌض¨µÄ PCI É豸¹ØÁª£¬ËùÓÐûÓÐÉèÖø¸É豸¡£µ«µ±
+  video_device ÅäÖú󣬾ÍÖªµÀʹÓÃÄĸö¸¸ PCI É豸ÁË¡£
+
+- flags£º¿ÉÑ¡¡£Èç¹ûÄãÒªÈÿò¼Ü´¦ÀíÉèÖà VIDIOC_G/S_PRIORITY ioctls£¬
+  ÇëÉèÖà V4L2_FL_USE_FH_PRIO¡£ÕâÒªÇóÄãʹÓà v4l2_fh ½á¹¹Ìå¡£
+  Ò»µ©ËùÓÐÇý¶¯Ê¹ÓÃÁ˺ËÐĵÄÓÅÏȼ¶´¦Àí£¬×îÖÕÕâ¸ö±êÖ¾½«Ïûʧ¡£µ«ÏÖÔÚËü
+  ±ØÐë±»ÏÔʽÉèÖá£
+
+Èç¹ûÄãʹÓà v4l2_ioctl_ops£¬ÔòÓ¦¸ÃÔÚ v4l2_file_operations ½á¹¹ÌåÖÐ
+ÉèÖà .unlocked_ioctl Ö¸Ïò video_ioctl2¡£
+
+ÇëÎðʹÓà .ioctl£¡ËüÒѱ»·ÏÆú£¬½ñºó½«Ïûʧ¡£
+
+ijЩÇé¿öÏÂÄãÒª¸æËߺËÐÄ£ºÄãÔÚ v4l2_ioctl_ops Ö¸¶¨µÄij¸öº¯ÊýÓ¦±»ºöÂÔ¡£
+Äã¿ÉÒÔÔÚ video_device_register ±»µ÷ÓÃǰͨ¹ýÒÔϺ¯Êý±ê¼ÇÕâ¸ö ioctls¡£
+
+void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd);
+
+»ùÓÚÍⲿÒòËØ£¨ÀýÈçij¸ö°å¿¨Òѱ»Ê¹Óã©£¬ÔÚ²»´´½¨Ð½ṹÌåµÄÇé¿öÏ£¬ÄãÏë
+Òª¹Ø±Õ v4l2_ioctl_ops ÖÐij¸öÌØÐÔÍùÍùÐèÒªÕâ¸ö»úÖÆ¡£
+
+v4l2_file_operations ½á¹¹ÌåÊÇ file_operations µÄÒ»¸ö×Ó¼¯¡£ÆäÖ÷Òª
+Çø±ðÔÚÓÚ£ºÒò inode ²ÎÊý´Óδ±»Ê¹Óã¬Ëü½«±»ºöÂÔ¡£
+
+Èç¹ûÐèÒªÓëýÌå¿ò¼ÜÕûºÏ£¬Äã±ØÐëͨ¹ýµ÷Óà media_entity_init() ³õʼ»¯
+ǶÈëÔÚ video_device ½á¹¹ÌåÖÐµÄ media_entity£¨entity Óò£©½á¹¹Ì壺
+
+	struct media_pad *pad = &my_vdev->pad;
+	int err;
+
+	err = media_entity_init(&vdev->entity, 1, pad, 0);
+
+pads Êý×é±ØÐëÔ¤Ïȳõʼ»¯¡£Ã»ÓбØÒªÊÖ¶¯ÉèÖà media_entity µÄ type ºÍ
+name Óò¡£
+
+µ±£¨ÈκΣ©×ÓÉ豸½Úµã±»´ò¿ª/¹Ø±Õ£¬¶Ô entity µÄÒýÓý«±»×Ô¶¯»ñÈ¡/ÊÍ·Å¡£
+
+v4l2_file_operations ÓëËø
+--------------------------
+
+Äã¿ÉÒÔÔÚ video_device ½á¹¹ÌåÖÐÉèÖÃÒ»¸öÖ¸Ïò mutex_lock µÄÖ¸Õ롣ͨ³£
+Õâ¼È¿ÉÊÇÒ»¸ö¶¥²ã»¥³âËøÒ²¿ÉΪÉ豸½Úµã×ÔÉíµÄ»¥³âËø¡£Ä¬ÈÏÇé¿öÏ£¬´ËËø
+ÓÃÓÚ unlocked_ioctl£¬µ«ÎªÁËʹÓà ioctls Äãͨ¹ýÒÔϺ¯Êý¿É½ûÓÃËø¶¨£º
+
+	void v4l2_disable_ioctl_locking(struct video_device *vdev, unsigned int cmd);
+
+ÀýÈç: v4l2_disable_ioctl_locking(vdev, VIDIOC_DQBUF);
+
+Äã±ØÐëÔÚ×¢²á video_device Ç°µ÷ÓÃÕâ¸öº¯Êý¡£
+
+ÌرðÊǶÔÓÚ USB Çý¶¯³ÌÐò£¬Ä³Ð©ÃüÁÈçÉèÖÿØÖÆ£©ÐèÒªºÜ³¤µÄʱ¼ä£¬¿ÉÄÜ
+ÐèÒª×ÔÐÐΪ»º³åÇø¶ÓÁÐµÄ ioctls ʵÏÖËø¶¨¡£
+
+Èç¹ûÄãÐèÒª¸üϸÁ£¶ÈµÄËø£¬Äã±ØÐëÉèÖà mutex_lock Ϊ NULL£¬²¢ÍêÈ«×Ô¼ºÊµÏÖ
+Ëø»úÖÆ¡£
+
+ÕâÍêÈ«ÓÉÇý¶¯¿ª·¢Õß¾ö¶¨Ê¹ÓúÎÖÖ·½·¨¡£È»¶ø£¬Èç¹ûÄãµÄÇý¶¯´æÔÚ³¤ÑÓʱ²Ù×÷
+£¨ÀýÈ磬¸Ä±ä USB ÉãÏñÍ·µÄÆعâʱ¼ä¿ÉÄÜÐèÒª½Ï³¤Ê±¼ä£©£¬¶øÄãÓÖÏëÈÃÓû§
+Ôڵȴý³¤ÑÓʱ²Ù×÷Íê³ÉÆÚ¼ä×öÆäËûµÄÊ£¬ÔòÄã×îºÃ×Ô¼ºÊµÏÖËø»úÖÆ¡£
+
+Èç¹ûÖ¸¶¨Ò»¸öËø£¬ÔòËùÓÐ ioctl ²Ù×÷½«ÔÚÕâ¸öËøµÄ×÷ÓÃÏ´®ÐÐÖ´ÐС£Èç¹ûÄã
+ʹÓà videobuf£¬Ôò±ØÐ뽫ͬһ¸öËø´«µÝ¸ø videobuf ¶ÓÁгõʼ»¯º¯Êý£»Èç
+videobuf ±ØÐëµÈ´ýÒ»Ö¡µÄµ½´ï£¬Ôò¿ÉÁÙʱ½âËø²¢ÔÚÕâÖ®ºóÖØÐÂÉÏËø¡£Èç¹ûÇý¶¯
+Ò²ÔÚ´úÂëÖ´ÐÐÆÚ¼äµÈ´ý£¬Ôò¿É×öͬÑùµÄ¹¤×÷£¨ÁÙʱ½âËø£¬ÔÙÉÏËø£©ÈÃÆäËû½ø³Ì
+¿ÉÒÔÔÚµÚÒ»¸ö½ø³Ì×èÈûʱ·ÃÎÊÉ豸½Úµã¡£
+
+ÔÚʹÓà videobuf2 µÄÇé¿öÏ£¬±ØÐëʵÏÖ wait_prepare ºÍ wait_finish »Øµ÷
+ÔÚÊʵ±µÄʱºò½âËø/¼ÓËø¡£½øÒ»²½À´Ëµ£¬Èç¹ûÄãÔÚ video_device ½á¹¹ÌåÖÐʹÓÃ
+Ëø£¬Ôò±ØÐëÔÚ wait_prepare ºÍ wait_finish ÖжÔÕâ¸ö»¥³âËø½øÐнâËø/¼ÓËø¡£
+
+ÈȲå°ÎµÄ¶Ï¿ªÊµÏÖÒ²±ØÐëÔÚµ÷Óà v4l2_device_disconnect Ç°»ñµÃËø¡£
+
+video_device×¢²á
+---------------
+
+½ÓÏÂÀ´ÄãÐèҪע²áÊÓƵÉ豸£ºÕâ»áΪÄã´´½¨Ò»¸ö×Ö·ûÉ豸¡£
+
+	err = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
+	if (err) {
+		video_device_release(vdev); /* or kfree(my_vdev); */
+		return err;
+	}
+
+Èç¹û v4l2_device ¸¸É豸µÄ mdev ÓòΪ·Ç NULL Öµ£¬ÊÓƵÉ豸ʵÌ彫×Ô¶¯
+×¢²áΪýÌåÉ豸¡£
+
+×¢²áÄÄÖÖÉ豸ÊǸù¾ÝÀàÐÍ£¨type£©²ÎÊý¡£´æÔÚÒÔÏÂÀàÐÍ£º
+
+VFL_TYPE_GRABBER: ÓÃÓÚÊÓƵÊäÈë/Êä³öÉ豸µÄ videoX
+VFL_TYPE_VBI: ÓÃÓÚ´¹Ö±ÏûÒþÊý¾ÝµÄ vbiX (ÀýÈ磬Òþ²Øʽ×ÖÄ»£¬Í¼ÎĵçÊÓ)
+VFL_TYPE_RADIO: ÓÃÓڹ㲥µ÷гÆ÷µÄ radioX
+
+×îºóÒ»¸ö²ÎÊýÈÃÄãÈ·¶¨Ò»¸öËù¿ØÖÆÉ豸µÄÉ豸½ÚµãºÅÊýÁ¿(ÀýÈç videoX ÖÐµÄ X)¡£
+ͨ³£Äã¿ÉÒÔ´«Èë-1£¬Èà v4l2 ¿ò¼Ü×Ô¼ºÑ¡ÔñµÚÒ»¸ö¿ÕÏеıàºÅ¡£µ«ÊÇÓÐʱÓû§
+ÐèҪѡÔñÒ»¸öÌض¨µÄ½ÚµãºÅ¡£Çý¶¯ÔÊÐíÓû§Í¨¹ýÇý¶¯Ä£¿é²ÎÊýÑ¡ÔñÒ»¸öÌض¨µÄ
+É豸½ÚµãºÅÊǺÜÆÕ±éµÄ¡£Õâ¸ö±àºÅ½«»á´«µÝ¸øÕâ¸öº¯Êý£¬ÇÒ video_register_device
+½«»áÊÔͼѡÔñÕâ¸öÉ豸½ÚµãºÅ¡£Èç¹ûÕâ¸ö±àºÅ±»Õ¼Óã¬ÏÂÒ»¸ö¿ÕÏеÄÉ豸½Úµã
+±àºÅ½«±»Ñ¡ÖУ¬²¢ÏòÄÚºËÈÕÖ¾Öз¢ËÍÒ»¸ö¾¯¸æÐÅÏ¢¡£
+
+ÁíÒ»¸öʹÓó¡¾°Êǵ±Çý¶¯´´½¨¶à¸öÉ豸ʱ¡£ÕâÖÖÇé¿öÏ£¬¶Ô²»Í¬µÄÊÓƵÉ豸ÔÚ
+±àºÅÉÏʹÓò»Í¬µÄ·¶Î§ÊǺÜÓÐÓõġ£ÀýÈ磬ÊÓƵ²¶»ñÉ豸´Ó 0 ¿ªÊ¼£¬ÊÓƵ
+Êä³öÉ豸´Ó 16 ¿ªÊ¼¡£ËùÒÔÄã¿ÉÒÔʹÓÃ×îºóÒ»¸ö²ÎÊýÀ´Ö¸¶¨É豸½ÚµãºÅ×îСֵ£¬
+¶ø v4l2 ¿ò¼Ü»áÊÔͼѡÔñµÚÒ»¸öµÄ¿ÕÏбàºÅ£¨µÈÓÚ»ò´óÓÚÄãÌṩµÄ±àºÅ£©¡£
+Èç¹ûʧ°Ü£¬ÔòËü»á¾ÍÑ¡ÔñµÚÒ»¸ö¿ÕÏеıàºÅ¡£
+
+ÓÉÓÚÕâÖÖÇé¿öÏ£¬Äã»áºöÂÔÎÞ·¨Ñ¡ÔñÌض¨É豸½ÚµãºÅµÄ¾¯¸æ£¬Ôò¿Éµ÷ÓÃ
+video_register_device_no_warn() º¯Êý±ÜÃ⾯¸æÐÅÏ¢µÄ²úÉú¡£
+
+Ö»ÒªÉ豸½Úµã±»´´½¨£¬Ò»Ð©ÊôÐÔÒ²»áͬʱ´´½¨¡£ÔÚ /sys/class/video4linux
+Ŀ¼ÖÐÄã»áÕÒµ½ÕâЩÉ豸¡£ÀýÈç½øÈëÆäÖÐµÄ video0 Ŀ¼£¬Äã»á¿´µ½¡®name¡¯ºÍ
+¡®index¡¯ÊôÐÔ¡£¡®name¡¯ÊôÐÔÖµ¾ÍÊÇ video_device ½á¹¹ÌåÖеġ®name¡¯Óò¡£
+
+¡®index¡¯ÊôÐÔÖµ¾ÍÊÇÉ豸½ÚµãµÄË÷ÒýÖµ£ºÃ¿´Îµ÷Óà video_register_device()£¬
+Ë÷ÒýÖµ¶¼µÝÔö 1 ¡£µÚÒ»¸öÊÓƵÉ豸½Úµã×ÜÊÇ´ÓË÷ÒýÖµ 0 ¿ªÊ¼¡£
+
+Óû§¿ÉÒÔÉèÖà udev ¹æÔò£¬ÀûÓÃË÷ÒýÊôÐÔÉú³É»¨ÉÚµÄÉ豸Ãû£¨ÀýÈ磺Óá®mpegX¡¯
+´ú±í MPEG ÊÓƵ²¶»ñÉ豸½Úµã£©¡£
+
+ÔÚÉ豸³É¹¦×¢²áºó£¬¾Í¿ÉÒÔʹÓÃÕâЩÓò£º
+
+- vfl_type: ´«µÝ¸ø video_register_device µÄÉ豸ÀàÐÍ¡£
+- minor: ÒÑÖ¸ÅɵĴÎÉ豸ºÅ¡£
+- num: É豸½Úµã±àºÅ (ÀýÈç videoX ÖÐµÄ X)¡£
+- index: É豸Ë÷ÒýºÅ¡£
+
+Èç¹û×¢²áʧ°Ü£¬Äã±ØÐëµ÷Óà video_device_release() À´ÊÍ·ÅÒÑ·ÖÅäµÄ
+video_device ½á¹¹Ì壻Èç¹û video_device ÊÇǶÈëÔÚ×Ô¼º´´½¨µÄ½á¹¹ÌåÖУ¬
+ÄãÒ²±ØÐëÊÍ·ÅËü¡£vdev->release() »Øµ÷²»»áÔÚ×¢²áʧ°ÜÖ®ºó±»µ÷Óã¬
+ÄãÒ²²»Ó¦ÊÔͼÔÚ×¢²áʧ°Üºó×¢ÏúÉ豸¡£
+
+
+video_device ×¢Ïú
+----------------
+
+µ±ÊÓƵÉ豸½ÚµãÒѱ»ÒƳý£¬²»ÂÛÊÇжÔØÇý¶¯»¹ÊÇUSBÉ豸¶Ï¿ª£¬Ä㶼ӦעÏú
+ËüÃÇ£º
+
+	video_unregister_device(vdev);
+
+Õâ¸ö²Ù×÷½«´Ó sysfs ÖÐÒƳýÉ豸½Úµã£¨µ¼Ö udev ½«Æä´Ó /dev ÖÐÒƳý£©¡£
+
+video_unregister_device() ·µ»ØÖ®ºó£¬¾ÍÎÞ·¨Íê³É´ò¿ª²Ù×÷¡£¾¡¹ÜÈç´Ë£¬
+USB É豸µÄÇé¿öÔò²»Í¬£¬Ä³Ð©Ó¦ÓóÌÐò¿ÉÄÜÒÀÈ»´ò¿ª×ÅÆäÖÐÒ»¸öÒÑ×¢ÏúÉ豸
+½Úµã¡£ËùÒÔÔÚ×¢ÏúÖ®ºó£¬ËùÓÐÎļþ²Ù×÷£¨µ±È»³ýÁË release £©Ò²Ó¦·µ»Ø´íÎóÖµ¡£
+
+µ±×îºóÒ»¸öÊÓƵÉ豸½ÚµãµÄÓû§Í˳ö£¬Ôò vdev->release() »Øµ÷»á±»µ÷Óã¬
+²¢ÇÒÄã¿ÉÒÔ×ö×îºóµÄÇåÀí²Ù×÷¡£
+
+²»ÒªÍü¼ÇÇåÀíÓëÊÓƵÉ豸Ïà¹ØµÄýÌåÈë¿Ú£¨Èç¹û±»³õʼ»¯¹ý£©£º
+
+	media_entity_cleanup(&vdev->entity);
+
+Õâ¿ÉÒÔÔÚ release »Øµ÷ÖÐÍê³É¡£
+
+
+video_device ¸¨Öúº¯Êý
+---------------------
+
+һЩÓÐÓõĸ¨Öúº¯ÊýÈçÏ£º
+
+- file/video_device ˽ÓÐÊý¾Ý
+
+Äã¿ÉÒÔÓÃÒÔϺ¯ÊýÔÚ video_device ½á¹¹ÌåÖÐÉèÖÃ/»ñÈ¡Çý¶¯Ë½ÓÐÊý¾Ý£º
+
+void *video_get_drvdata(struct video_device *vdev);
+void video_set_drvdata(struct video_device *vdev, void *data);
+
+×¢Ò⣺ÔÚµ÷Óà video_register_device() Ç°Ö´ÐÐ video_set_drvdata()
+ÊÇ°²È«µÄ¡£
+
+¶øÒÔϺ¯Êý£º
+
+struct video_device *video_devdata(struct file *file);
+
+·µ»Ø file ½á¹¹ÌåÖÐÓµÓÐµÄµÄ video_device Ö¸Õë¡£
+
+video_drvdata ¸¨Öúº¯Êý½áºÏÁË video_get_drvdata ºÍ video_devdata
+µÄ¹¦ÄÜ£º
+
+void *video_drvdata(struct file *file);
+
+Äã¿ÉÒÔʹÓÃÈçÏ´úÂë´Ó video_device ½á¹¹ÌåÖлñÈ¡ v4l2_device ½á¹¹Ìå
+Ö¸Õ룺
+
+struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
+
+- É豸½ÚµãÃû
+
+video_device É豸½ÚµãÔÚÄÚºËÖеÄÃû³Æ¿ÉÒÔͨ¹ýÒÔϺ¯Êý»ñµÃ
+
+const char *video_device_node_name(struct video_device *vdev);
+
+Õâ¸öÃû×Ö±»Óû§¿Õ¼ä¹¤¾ß£¨ÀýÈç udev£©×÷ΪÌáʾÐÅϢʹÓá£Ó¦¾¡¿ÉÄÜʹÓÃ
+´Ë¹¦ÄÜ£¬¶ø·Ç·ÃÎÊ video_device::num ºÍ video_device::minor Óò¡£
+
+
+ÊÓƵ»º³å¸¨Öúº¯Êý
+---------------
+
+v4l2 ºËÐÄ API ÌṩÁËÒ»¸ö´¦ÀíÊÓƵ»º³åµÄ±ê×¼·½·¨(³ÆΪ¡°videobuf¡±)¡£
+ÕâЩ·½·¨Ê¹Çý¶¯¿ÉÒÔͨ¹ýͳһµÄ·½Ê½ÊµÏÖ read()¡¢mmap() ºÍ overlay()¡£
+Ä¿Ç°ÔÚÉ豸ÉÏÖ§³ÖÊÓƵ»º³åµÄ·½·¨ÓзÖÉ¢/¾Û¼¯ DMA(videobuf-dma-sg)¡¢
+ÏßÐÔ DMA(videobuf-dma-contig)ÒÔ¼°´ó¶àÓÃÓÚ USB É豸µÄÓà vmalloc
+·ÖÅäµÄ»º³å(videobuf-vmalloc)¡£
+
+Çë²ÎÔÄ Documentation/video4linux/videobuf£¬ÒÔ»ñµÃ¸ü¶à¹ØÓÚ videobuf
+²ãµÄʹÓÃÐÅÏ¢¡£
+
+v4l2_fh ½á¹¹Ìå
+-------------
+
+v4l2_fh ½á¹¹ÌåÌṩһ¸ö±£´æÓÃÓÚ V4L2 ¿ò¼ÜµÄÎļþ¾ä±úÌض¨Êý¾ÝµÄ¼òµ¥·½·¨¡£
+Èç¹û video_device µÄ flag ÉèÖÃÁË V4L2_FL_USE_FH_PRIO ±êÖ¾£¬ÐÂÇý¶¯
+±ØÐëʹÓà v4l2_fh ½á¹¹Ì壬ÒòΪËüÒ²ÓÃÓÚʵÏÖÓÅÏȼ¶´¦Àí£¨VIDIOC_G/S_PRIORITY£©¡£
+
+v4l2_fh µÄÓû§£¨Î»ÓÚ V4l2 ¿ò¼ÜÖУ¬²¢·ÇÇý¶¯£©¿Éͨ¹ý²âÊÔ
+video_device->flags ÖÐµÄ V4L2_FL_USES_V4L2_FH λµÃÖªÇý¶¯ÊÇ·ñʹÓÃ
+v4l2_fh ×÷ΪËûµÄ file->private_data Ö¸Õë¡£Õâ¸öλ»áÔÚµ÷Óà v4l2_fh_init()
+ʱ±»ÉèÖá£
+
+v4l2_fh ½á¹¹Ìå×÷ΪÇý¶¯×ÔÉíÎļþ¾ä±ú½á¹¹ÌåµÄÒ»²¿·Ö±»·ÖÅ䣬ÇÒÇý¶¯ÔÚ
+Æä´ò¿ªº¯ÊýÖн« file->private_data Ö¸ÏòËü¡£
+
+ÔÚÐí¶àÇé¿öÏ£¬v4l2_fh ½á¹¹Ìå»áǶÈëµ½Ò»¸ö¸ü´óµÄ½á¹¹ÌåÖС£ÕâÖÓÇé¿öÏ£¬
+Ó¦¸ÃÔÚ open() Öе÷Óà v4l2_fh_init+v4l2_fh_add£¬²¢ÔÚ release() ÖÐ
+µ÷ÓÃ v4l2_fh_del+v4l2_fh_exit¡£
+
+Çý¶¯¿ÉÒÔͨ¹ýʹÓà container_of ºêÌáÈ¡ËûÃÇ×Ô¼ºµÄÎļþ¾ä±ú½á¹¹Ìå¡£ÀýÈ磺
+
+struct my_fh {
+	int blah;
+	struct v4l2_fh fh;
+};
+
+...
+
+int my_open(struct file *file)
+{
+	struct my_fh *my_fh;
+	struct video_device *vfd;
+	int ret;
+
+	...
+
+	my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);
+
+	...
+
+	v4l2_fh_init(&my_fh->fh, vfd);
+
+	...
+
+	file->private_data = &my_fh->fh;
+	v4l2_fh_add(&my_fh->fh);
+	return 0;
+}
+
+int my_release(struct file *file)
+{
+	struct v4l2_fh *fh = file->private_data;
+	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;
+}
+
+ÒÔÏÂÊÇ v4l2_fh º¯ÊýʹÓõļò½é£º
+
+void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
+
+  ³õʼ»¯Îļþ¾ä±ú¡£Õâ*±ØÐë*ÔÚÇý¶¯µÄ v4l2_file_operations->open()
+  º¯ÊýÖÐÖ´ÐС£
+
+void v4l2_fh_add(struct v4l2_fh *fh)
+
+  Ìí¼ÓÒ»¸ö v4l2_fh µ½ video_device Îļþ¾ä±úÁÐ±í¡£Ò»µ©Îļþ¾ä±ú
+  ³õʼ»¯Íê³É¾Í±ØÐëµ÷Óá£
+
+void v4l2_fh_del(struct v4l2_fh *fh)
+
+  ´Ó video_device() Öнâ³ýÎļþ¾ä±úµÄ¹ØÁª¡£Îļþ¾ä±úµÄÍ˳öº¯ÊýÒ²
+  ½«±»µ÷Óá£
+
+void v4l2_fh_exit(struct v4l2_fh *fh)
+
+  ÇåÀíÎļþ¾ä±ú¡£ÔÚÇåÀíÍê v4l2_fh ºó£¬Ïà¹ØÄÚ´æ»á±»ÊÍ·Å¡£
+
+
+Èç¹û v4l2_fh ²»ÊÇǶÈëÔÚÆäËû½á¹¹ÌåÖеģ¬Ôò¿ÉÒÔÓÃÕâЩ¸¨Öúº¯Êý£º
+
+int v4l2_fh_open(struct file *filp)
+
+  ·ÖÅäÒ»¸ö v4l2_fh ½á¹¹Ìå¿Õ¼ä£¬³õʼ»¯²¢½«ÆäÌí¼Óµ½ file ½á¹¹ÌåÏà¹ØµÄ
+  video_device ½á¹¹ÌåÖС£
+
+int v4l2_fh_release(struct file *filp)
+
+  ´Ó file ½á¹¹ÌåÏà¹ØµÄ video_device ½á¹¹ÌåÖÐɾ³ý v4l2_fh £¬ÇåÀí
+  v4l2_fh ²¢Êͷſռ䡣
+
+ÕâÁ½¸öº¯Êý¿ÉÒÔ²åÈëµ½ v4l2_file_operation µÄ open() ºÍ release()
+²Ù×÷ÖС£
+
+
+ijЩÇý¶¯ÐèÒªÔÚµÚÒ»¸öÎļþ¾ä±ú´ò¿ªºÍ×îºóÒ»¸öÎļþ¾ä±ú¹Ø±ÕµÄʱºò×öЩ
+¹¤×÷¡£ËùÒÔ¼ÓÈëÁËÁ½¸ö¸¨Öúº¯ÊýÒÔ¼ì²é v4l2_fh ½á¹¹ÌåÊÇ·ñÊÇÏà¹ØÉ豸
+½Úµã´ò¿ªµÄΨһÎļþ¾ä±ú¡£
+
+int v4l2_fh_is_singular(struct v4l2_fh *fh)
+
+  Èç¹û´ËÎļþ¾ä±úÊÇΨһ´ò¿ªµÄÎļþ¾ä±ú£¬Ôò·µ»Ø 1 £¬·ñÔò·µ»Ø 0 ¡£
+
+int v4l2_fh_is_singular_file(struct file *filp)
+
+  ¹¦ÄÜÏàͬ£¬µ«Í¨¹ý filp->private_data µ÷Óà v4l2_fh_is_singular¡£
+
+
+V4L2 ʼþ»úÖÆ
+-----------
+
+V4L2 ʼþ»úÖÆÌṩÁËÒ»¸öͨÓõķ½·¨½«Ê¼þ´«µÝµ½Óû§¿Õ¼ä¡£Çý¶¯±ØÐëʹÓÃ
+v4l2_fh ²ÅÄÜÖ§³Ö V4L2 ʼþ»úÖÆ¡£
+
+
+ʼþͨ¹ýÒ»¸öÀàÐͺÍÑ¡Ôñ ID À´¶¨Òå¡£ID ¶ÔÓ¦Ò»¸ö V4L2 ¶ÔÏó£¬ÀýÈç
+Ò»¸ö¿ØÖÆ ID¡£Èç¹ûδʹÓã¬Ôò ID Ϊ 0¡£
+
+µ±Óû§¶©ÔÄÒ»¸öʼþ£¬Çý¶¯»áΪ´Ë·ÖÅäһЩ kevent ½á¹¹Ìå¡£ËùÒÔÿ¸ö
+ʼþ×飨ÀàÐÍ¡¢ID£©¶¼»áÓÐ×Ô¼ºµÄÒ»Ì× kevent ½á¹¹Ìå¡£Õâ±£Ö¤ÁËÈç¹û
+Ò»¸öÇý¶¯¶Ìʱ¼äÄÚ²úÉúÁËÐí¶àͬÀàʼþ£¬²»»á¸²¸ÇÆäËûÀàÐ͵Äʼþ¡£
+
+µ«Èç¹ûÄãÊÕµ½µÄʼþÊýÁ¿´óÓÚͬÀàʼþ kevent µÄ±£´æÊýÁ¿£¬Ôò×îÔçµÄ
+ʼþ½«±»¶ªÆú£¬²¢¼ÓÈëÐÂʼþ¡£
+
+´ËÍ⣬v4l2_subscribed_event ½á¹¹ÌåÄÚ²¿Óпɹ©Çý¶¯ÉèÖÃµÄ merge() ºÍ
+replace() »Øµ÷£¬ÕâЩ»Øµ÷»áÔÚÐÂʼþ²úÉúÇÒûÓжàÓà¿Õ¼äµÄʱºò±»µ÷Óá£
+replace() »Øµ÷ÈÃÄã¿ÉÒÔ½«ÔçÆÚʼþµÄ¾»ºÉÌ滻ΪÐÂʼþµÄ¾»ºÉ£¬½«ÔçÆÚ
+¾»ºÉµÄÏà¹ØÊý¾ÝºÏ²¢µ½Ìæ»»½øÀ´µÄо»ºÉÖС£µ±¸ÃÀàÐ͵Äʼþ½ö·ÖÅäÁËÒ»¸ö
+kevent ½á¹¹Ìåʱ£¬Ëü½«±»µ÷Óá£merge() »Øµ÷ÈÃÄã¿ÉÒԺϲ¢×îÔçµÄʼþ¾»ºÉ
+µ½ÔÚËüÖ®ºóµÄÄǸöʼþ¾»ºÉÖС£µ±¸ÃÀàÐ͵Äʼþ·ÖÅäÁËÁ½¸ö»ò¸ü¶à kevent
+½á¹¹Ìåʱ£¬Ëü½«±»µ÷Óá£
+
+ÕâÖÖ·½·¨²»»áÓÐ״̬ÐÅÏ¢¶ªÊ§£¬Ö»»áµ¼ÖÂÖм䲽ÖèÐÅÏ¢¶ªÊ§¡£
+
+
+¹ØÓÚ replace/merge »Øµ÷µÄÒ»¸ö²»´íµÄÀý×ÓÔÚ v4l2-event.c ÖУºÓÃÓÚ
+¿ØÖÆʼþµÄ ctrls_replace() ºÍ ctrls_merge() »Øµ÷¡£
+
+×¢Ò⣺ÕâЩ»Øµ÷¿ÉÒÔÔÚÖжÏÉÏÏÂÎÄÖе÷Óã¬ËùÒÔËüÃDZØÐ뾡¿ìÍê³É²¢Í˳ö¡£
+
+ÓÐÓõĺ¯Êý£º
+
+void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev)
+
+  ½«Ê¼þ¼ÓÈëÊÓƵÉ豸µÄ¶ÓÁС£Çý¶¯½ö¸ºÔðÌî³ä type ºÍ data Óò¡£
+  ÆäËûÓòÓÉ V4L2 Ìî³ä¡£
+
+int v4l2_event_subscribe(struct v4l2_fh *fh,
+			 struct v4l2_event_subscription *sub, unsigned elems,
+			 const struct v4l2_subscribed_event_ops *ops)
+
+  video_device->ioctl_ops->vidioc_subscribe_event ±ØÐë¼ì²âÇý¶¯ÄÜ
+  ²úÉúÌض¨ id µÄʼþ¡£È»ºóµ÷Óà v4l2_event_subscribe() À´¶©ÔĸÃʼþ¡£
+
+  elems ²ÎÊýÊǸÃʼþµÄ¶ÓÁдóС¡£ÈôΪ 0£¬V4L2 ¿ò¼Ü½«»á£¨¸ù¾ÝʼþÀàÐÍ£©
+  Ìî³äĬÈÏÖµ¡£
+
+  ops ²ÎÊýÔÊÐíÇý¶¯Ö¸¶¨Ò»ÏµÁлص÷£º
+  * add:     µ±Ìí¼ÓÒ»¸öмàÌýÕßʱµ÷Óã¨Öظ´¶©ÔÄͬһ¸öʼþ£¬´Ë»Øµ÷
+             ½ö±»Ö´ÐÐÒ»´Î£©¡£
+  * del:     µ±Ò»¸ö¼àÌýÕßÍ£Ö¹¼àÌýʱµ÷Óá£
+  * replace: Óá®Ð¡¯Ê¼þÌæ»»¡®ÔçÆÚ¡®Ê¼þ¡£
+  * merge:   ½«¡®ÔçÆÚ¡®Ê¼þºÏ²¢µ½¡®Ð¡¯Ê¼þÖС£
+  ÕâËĸöµ÷Óö¼ÊÇ¿ÉÑ¡µÄ£¬Èç¹û²»ÏëÖ¸¶¨Èκλص÷£¬Ôò ops ¿ÉΪ NULL¡£
+
+int v4l2_event_unsubscribe(struct v4l2_fh *fh,
+			   struct v4l2_event_subscription *sub)
+
+  v4l2_ioctl_ops ½á¹¹ÌåÖÐµÄ vidioc_unsubscribe_event »Øµ÷º¯Êý¡£
+  Çý¶¯³ÌÐò¿ÉÒÔÖ±½ÓʹÓà v4l2_event_unsubscribe() ʵÏÖÍ˶©Ê¼þ¹ý³Ì¡£
+
+  ÌØÊâµÄ V4L2_EVENT_ALL ÀàÐÍ£¬¿ÉÓÃÓÚÍ˶©ËùÓÐʼþ¡£Çý¶¯¿ÉÄÜÔÚÌØÊâ
+  Çé¿öÏÂÐèÒª×ö´Ë²Ù×÷¡£
+
+int v4l2_event_pending(struct v4l2_fh *fh)
+
+  ·µ»Øδ¾öʼþµÄÊýÁ¿¡£ÓÐÖúÓÚʵÏÖÂÖѯ£¨poll£©²Ù×÷¡£
+
+ʼþͨ¹ý poll ϵͳµ÷Óô«µÝµ½Óû§¿Õ¼ä¡£Çý¶¯¿ÉÓÃ
+v4l2_fh->wait (wait_queue_head_t ÀàÐÍ)×÷Ϊ²ÎÊýµ÷Óà poll_wait()¡£
+
+ʼþ·ÖΪ±ê׼ʼþºÍ˽ÓÐʼþ¡£Ðµıê׼ʼþ±ØÐëʹÓÿÉÓõÄ×îСʼþÀàÐÍ
+±àºÅ¡£Çý¶¯±ØÐë´ÓËûÃDZ¾ÀàÐ͵ıàºÅÆðʼ´¦·ÖÅäʼþ¡£ÀàÐ͵ıàºÅÆðʼΪ
+V4L2_EVENT_PRIVATE_START + n * 1000 £¬ÆäÖÐ n Ϊ¿ÉÓÃ×îС±àºÅ¡£Ã¿¸ö
+ÀàÐÍÖеĵÚÒ»¸öʼþÀàÐͱàºÅÊÇΪÒÔºóµÄʹÓñ£ÁôµÄ£¬ËùÒÔµÚÒ»¸ö¿ÉÓÃʼþ
+ÀàÐͱàºÅÊÇ¡®class base + 1¡¯¡£
+
+V4L2 ʼþ»úÖƵÄʹÓÃʵÀý¿ÉÒÔÔÚ OMAP3 ISP µÄÇý¶¯
+(drivers/media/video/omap3isp)ÖÐÕÒµ½¡£
-- 
1.7.9.5
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH]Documentation: Chinese translation of Documentation/video4linux/v4l2-framework.txt
       [not found] ` <606bebba.1234f.139870aedda.Coremail.rafaman@126.com>
@ 2012-09-02 16:18   ` harryxiyou
  0 siblings, 0 replies; 2+ messages in thread
From: harryxiyou @ 2012-09-02 16:18 UTC (permalink / raw)
  To: Rafaman
  Cc: Ninja Tekkaman, Greg-Kroah-Hartman, linux-kernel, linux-doc,
	Mauro Carvalho Chehab, kernel

On Sun, Sep 2, 2012 at 8:53 PM, Rafaman <rafaman@126.com> wrote:
> At 2012-09-02 00:51:51,"Ninja Tekkaman" <tekkamanninja@gmail.com> wrote:
>>This is a Chinese translated version of
>>Documentation/video4linux/v4l2-framework.txt
>>
>>Signed-off-by: Fu Wei <tekkamanninja@gmail.com>
>

Acked-by: Harry Wei <harryxiyou@gmail.com>


-- 
Thanks
Harry Wei

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2012-09-02 16:18 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-01 16:51 [PATCH]Documentation: Chinese translation of Documentation/video4linux/v4l2-framework.txt Ninja Tekkaman
     [not found] ` <606bebba.1234f.139870aedda.Coremail.rafaman@126.com>
2012-09-02 16:18   ` harryxiyou

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).