Based on kernel version 3.9. Page generated on 2013-05-02 23:17 EST.
1 Chinese translated version of Documentation/video4linux/v4l2-framework.txt 2 3 If you have any comment or update to the content, please contact the 4 original document maintainer directly. However, if you have a problem 5 communicating in English you can also ask the Chinese maintainer for 6 help. Contact the Chinese maintainer if this translation is outdated 7 or if there is a problem with the translation. 8 9 Maintainer: Mauro Carvalho Chehab <mchehab@infradead.org> 10 Chinese maintainer: Fu Wei <tekkamanninja@gmail.com> 11 --------------------------------------------------------------------- 12 Documentation/video4linux/v4l2-framework.txt çä¸æç¿»è¯ 13 14 妿æ³è¯è®ºææ´æ°æ¬æçå 容ï¼è¯·ç´æ¥èç³»åææ¡£çç»´æ¤è ãå¦æä½ ä½¿ç¨è±æ 15 äº¤æµæå°é¾çè¯ï¼ä¹å¯ä»¥å䏿çç»´æ¤è æ±å©ã妿æ¬ç¿»è¯æ´æ°ä¸åæ¶æè ç¿» 16 è¯åå¨é®é¢ï¼è¯·èç³»ä¸æçç»´æ¤è ã 17 è±æçç»´æ¤è ï¼ Mauro Carvalho Chehab <mchehab@infradead.org> 18 䏿çç»´æ¤è ï¼ å ç Fu Wei <tekkamanninja@gmail.com> 19 䏿çç¿»è¯è ï¼ å ç Fu Wei <tekkamanninja@gmail.com> 20 ä¸æçæ ¡è¯è ï¼ å ç Fu Wei <tekkamanninja@gmail.com> 21 22 23 以ä¸ä¸ºæ£æ 24 --------------------------------------------------------------------- 25 V4L2 驱卿¡æ¶æ¦è§ 26 ============== 27 28 æ¬ææ¡£æè¿° V4L2 æ¡æ¶ææä¾çåç§ç»æåå®ä»¬ä¹é´çå ³ç³»ã 29 30 31 ä»ç» 32 ---- 33 34 大é¨åç°ä»£ V4L2 设å¤ç±å¤ä¸ª IC ç»æï¼å¨ /dev ä¸å¯¼åºå¤ä¸ªè®¾å¤èç¹ï¼ 35 å¹¶åæ¶å建é V4L2 设å¤ï¼å¦ DVBãALSAãFBãI2C å红å¤è¾å ¥è®¾å¤ï¼ã 36 ç±äºè¿ç§ç¡¬ä»¶ç夿æ§ï¼V4L2 驱å¨ä¹åå¾é叏夿ã 37 38 å°¤å ¶æ¯ V4L2 å¿ é¡»æ¯æ IC å®ç°é³è§é¢çå¤è·¯å¤ç¨åç¼è§£ç ï¼è¿å°±æ´å¢å äºå ¶ 39 夿æ§ãé常è¿äº IC éè¿ä¸ä¸ªæå¤ä¸ª I2C æ»çº¿è¿æ¥å°ä¸»æ¡¥é©±å¨å¨ï¼ä½ä¹å¯ 40 使ç¨å ¶ä»æ»çº¿ãè¿äºè®¾å¤ç§°ä¸ºâå设å¤âã 41 42 é¿æä»¥æ¥ï¼è¿ä¸ªæ¡æ¶ä» éäºéè¿ video_device ç»æä½å建 V4L 设å¤èç¹ï¼ 43 å¹¶ä½¿ç¨ video_buf å¤çè§é¢ç¼å²ï¼æ³¨ï¼æ¬æä¸è®¨è®º video_buf æ¡æ¶ï¼ã 44 45 è¿æå³çææé©±å¨å¿ é¡»èªå·±è®¾ç½®è®¾å¤å®ä¾å¹¶è¿æ¥å°å设å¤ãå ¶ä¸ä¸é¨åè¦æ£ç¡®å° 46 å®ææ¯æ¯è¾å¤æçï¼ä½¿å¾è®¸å¤é©±å¨é½æ²¡ææ£ç¡®å°å®ç°ã 47 48 ç±äºæ¡æ¶çç¼ºå¤±ï¼æå¾å¤éç¨ä»£ç é½ä¸å¯éå¤å©ç¨ã 49 50 å æ¤ï¼è¿ä¸ªæ¡æ¶æå»ºææé©±å¨é½éè¦çåºæ¬ç»æåï¼èç»ä¸çæ¡æ¶å°ä½¿éç¨ä»£ç 51 å建æå®ç¨å½æ°å¹¶å¨ææé©±å¨ä¸å ±äº«å徿´å 容æã 52 53 54 驱å¨ç»æ 55 ------- 56 57 ææ V4L2 驱å¨é½æå¦ä¸ç»æï¼ 58 59 1) æ¯ä¸ªè®¾å¤å®ä¾çç»æä½--å å«å ¶è®¾å¤ç¶æã 60 61 2) åå§ååæ§å¶å设å¤çæ¹æ³ï¼å¦ææï¼ã 62 63 3) å建 V4L2 设å¤èç¹ (/dev/videoXã/dev/vbiX å /dev/radioX) 64 å¹¶è·è¸ªè®¾å¤èç¹çç¹å®æ°æ®ã 65 66 4) ç¹å®æä»¶å¥æç»æä½--å 嫿¯ä¸ªæä»¶å¥æçæ°æ®ã 67 68 5) è§é¢ç¼å²å¤çã 69 70 以䏿¯å®ä»¬çåç¥å ³ç³»å¾ï¼ 71 72 device instancesï¼è®¾å¤å®ä¾ï¼ 73 | 74 +-sub-device instancesï¼å设å¤å®ä¾ï¼ 75 | 76 \-V4L2 device nodesï¼V4L2 设å¤èç¹ï¼ 77 | 78 \-filehandle instancesï¼æä»¶å¥æå®ä¾ï¼ 79 80 81 æ¡æ¶ç»æ 82 ------- 83 84 è¯¥æ¡æ¶é常类似驱å¨ç»æï¼å®æä¸ä¸ª v4l2_device ç»æç¨äºä¿åè®¾å¤ 85 å®ä¾çæ°æ®ï¼ä¸ä¸ª v4l2_subdev ç»æä½ä»£è¡¨å设å¤å®ä¾ï¼video_device 86 ç»æä½ä¿å V4L2 设å¤èç¹çæ°æ®ï¼å°æ¥ v4l2_fh ç»æä½å°è·è¸ªæä»¶å¥æ 87 å®ä¾ï¼ææªå°æªå®ç°ï¼ã 88 89 V4L2 æ¡æ¶ä¹å¯ä¸åªä½æ¡æ¶æ´åï¼å¯éçï¼ã妿驱å¨è®¾ç½®äº v4l2_device 90 ç»æä½ç mdev åï¼å设å¤åè§é¢èç¹çå ¥å£å°èªå¨åºç°å¨åªä½æ¡æ¶ä¸ã 91 92 93 v4l2_device ç»æä½ 94 ---------------- 95 96 æ¯ä¸ªè®¾å¤å®ä¾é½éè¿ v4l2_device (v4l2-device.h)ç»æä½æ¥è¡¨ç¤ºã 97 ç®å设å¤å¯ä»¥ä» åé è¿ä¸ªç»æä½ï¼ä½å¨å¤§å¤æ°æ åµä¸ï¼é½ä¼å°è¿ä¸ªç»æä½ 98 åµå ¥å°ä¸ä¸ªæ´å¤§çç»æä½ä¸ã 99 100 ä½ å¿ é¡»æ³¨åè¿ä¸ªè®¾å¤å®ä¾ï¼ 101 102 v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); 103 104 注åæä½å°ä¼åå§å v4l2_device ç»æä½ã妿 dev->driver_data å 105 为 NULLï¼å°±å°å ¶æå v4l2_devã 106 107 éè¦ä¸åªä½æ¡æ¶æ´åç驱å¨å¿ é¡»æå¨è®¾ç½® dev->driver_dataï¼æåå å« 108 v4l2_device ç»æä½å®ä¾ç驱å¨ç¹å®è®¾å¤ç»æä½ãè¿å¯ä»¥å¨æ³¨å V4L2 è®¾å¤ 109 å®ä¾åéè¿ dev_set_drvdata() 彿°å®æãåæ¶å¿ é¡»è®¾ç½® v4l2_device 110 ç»æä½ç mdev åï¼æåéå½çåå§å并注åè¿ç media_device å®ä¾ã 111 112 妿 v4l2_dev->name 为空ï¼åå®å°è¢«è®¾ç½®ä¸ºä» dev ä¸è¡çåºçå¼ï¼ä¸ºäº 113 æ´å 精确ï¼å½¢å¼ä¸ºé©±å¨ååè· bus_idï¼ãå¦æä½ å¨è°ç¨ v4l2_device_register 114 åå·²ç»è®¾ç½®å¥½äºï¼åä¸ä¼è¢«ä¿®æ¹ã妿 dev 为 NULLï¼åä½ *å¿ é¡»*å¨è°ç¨ 115 v4l2_device_register å设置 v4l2_dev->nameã 116 117 ä½ å¯ä»¥åºäºé©±å¨åå驱å¨çå ¨å± atomic_t ç±»åçå®ä¾ç¼å·ï¼éè¿ 118 v4l2_device_set_name() 设置 nameãè¿æ ·ä¼çæç±»ä¼¼ ivtv0ãivtv1 ç 119 ååãè¥é©±å¨å以æ°åç»å°¾ï¼åä¼å¨ç¼å·å驱å¨åé´æå ¥ä¸ä¸ªç ´æå·ï¼å¦ï¼ 120 cx18-0ãcx18-1 çãæ¤å½æ°è¿åå®ä¾ç¼å·ã 121 122 第ä¸ä¸ª âdevâ åæ°é常æ¯ä¸ä¸ªæå pci_devãusb_interface æ 123 platform_device çæéãå¾å°ä½¿å ¶ä¸º NULLï¼é¤éæ¯ä¸ä¸ªISAè®¾å¤æè 124 å½ä¸ä¸ªè®¾å¤å建äºå¤ä¸ª PCI 设å¤ï¼ä½¿å¾ v4l2_dev æ æ³ä¸ä¸ä¸ªç¹å®çç¶è®¾å¤ 125 å ³èã 126 127 ä½ ä¹å¯ä»¥æä¾ä¸ä¸ª notify() åè°ï¼ä½¿å设å¤å¯ä»¥è°ç¨å®å®ç°äºä»¶éç¥ã 128 ä½è¿ä¸ªè®¾ç½®ä¸å设å¤ç¸å ³ãåè®¾å¤æ¯æçä»»ä½éç¥å¿ é¡»å¨ 129 include/media/<subdevice>.h ä¸å®ä¹ä¸ä¸ªæ¶æ¯å¤´ã 130 131 注é v4l2_device 使ç¨å¦ä¸å½æ°ï¼ 132 133 v4l2_device_unregister(struct v4l2_device *v4l2_dev); 134 135 妿 dev->driver_data åæå v4l2_devï¼å°ä¼è¢«é置为 NULLãæ³¨éåæ¶ 136 ä¼èªå¨ä»è®¾å¤ä¸æ³¨éææå设å¤ã 137 138 å¦æä½ æä¸ä¸ªçææè®¾å¤ï¼å¦USB设å¤ï¼ï¼å彿å¼åçæ¶ï¼ç¶è®¾å¤å°æ æã 139 ç±äº v4l2_device æä¸ä¸ªæåç¶è®¾å¤çæéå¿ é¡»è¢«æ¸ é¤ï¼åæ¶æ å¿ç¶è®¾å¤ 140 å·²æ¶å¤±ï¼æä»¥å¿ é¡»è°ç¨ä»¥ä¸å½æ°ï¼ 141 142 v4l2_device_disconnect(struct v4l2_device *v4l2_dev); 143 144 è¿ä¸ªå½æ°å¹¶*ä¸*注éå设å¤ï¼å æ¤ä½ ä¾ç¶è¦è°ç¨ v4l2_device_unregister() 145 彿°ãå¦æä½ ç驱å¨å¨å¹¶éçææçï¼å°±æ²¡æå¿ è¦è°ç¨ v4l2_device_disconnect()ã 146 147 ææ¶ä½ éè¦éåææè¢«ç¹å®é©±å¨æ³¨åç设å¤ãè¿é常åçå¨å¤ä¸ªè®¾å¤é©±å¨ä½¿ç¨ 148 åä¸ä¸ªç¡¬ä»¶çæ åµä¸ãå¦ï¼ivtvfb 驱卿¯ä¸ä¸ªä½¿ç¨ ivtv 硬件ç帧ç¼å²é©±å¨ï¼ 149 åæ¶ alsa 驱å¨ä¹ä½¿ç¨æ¤ç¡¬ä»¶ã 150 151 ä½ å¯ä»¥ä½¿ç¨å¦ä¸ä¾ç¨éåæææ³¨åç设å¤ï¼ 152 153 static int callback(struct device *dev, void *p) 154 { 155 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev); 156 157 /* æµè¯è¿ä¸ªè®¾å¤æ¯å¦å·²ç»åå§å */ 158 if (v4l2_dev == NULL) 159 return 0; 160 ... 161 return 0; 162 } 163 164 int iterate(void *p) 165 { 166 struct device_driver *drv; 167 int err; 168 169 /* å¨PCI æ»çº¿ä¸æ¥æ¾ivtv驱å¨ã 170 pci_bus_typeæ¯å ¨å±ç. 对äºUSBæ»çº¿ä½¿ç¨usb_bus_typeã */ 171 drv = driver_find("ivtv", &pci_bus_type); 172 /* éåææçivtv设å¤å®ä¾ */ 173 err = driver_for_each_device(drv, NULL, p, callback); 174 put_driver(drv); 175 return err; 176 } 177 178 ææ¶ä½ éè¦ä¸ä¸ªè®¾å¤å®ä¾çè¿è¡è®¡æ°ãè¿ä¸ªé常ç¨äºæ å°ä¸ä¸ªè®¾å¤å®ä¾å°ä¸ä¸ª 179 模åéæ©æ°ç»çç´¢å¼ã 180 181 æ¨èæ¹æ³å¦ä¸ï¼ 182 183 static atomic_t drv_instance = ATOMIC_INIT(0); 184 185 static int drv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) 186 { 187 ... 188 state->instance = atomic_inc_return(&drv_instance) - 1; 189 } 190 191 å¦æä½ æå¤ä¸ªè®¾å¤èç¹ï¼å¯¹äºçææè®¾å¤ï¼ç¥é使¶æ³¨é v4l2_device ç»æä½ 192 å°±æ¯è¾å°é¾ãä¸ºæ¤ v4l2_device æå¼ç¨è®¡æ°æ¯æãå½è°ç¨ video_register_device 193 æ¶å¢å å¼ç¨è®¡æ°ï¼è设å¤èç¹éæ¾æ¶åå°å¼ç¨è®¡æ°ãå½å¼ç¨è®¡æ°ä¸ºé¶ï¼å 194 v4l2_device çrelease() åè°å°è¢«æ§è¡ãä½ å°±å¯ä»¥å¨æ¤æ¶åæåçæ¸ çå·¥ä½ã 195 196 妿å建äºå ¶ä»è®¾å¤èç¹ï¼æ¯å¦ ALSAï¼ï¼åä½ å¯ä»¥éè¿ä»¥ä¸å½æ°æå¨å¢å 197 å¼ç¨è®¡æ°ï¼ 198 199 void v4l2_device_get(struct v4l2_device *v4l2_dev); 200 201 æ: 202 203 int v4l2_device_put(struct v4l2_device *v4l2_dev); 204 205 ç±äºå¼ç¨ææ¯åå§å为 1 ï¼ä½ ä¹éè¦å¨ disconnect() åè°ï¼å¯¹äº USB 设å¤ï¼ä¸ 206 è°ç¨ v4l2_device_putï¼æè remove() åè°ï¼ä¾å¦å¯¹äº PCI 设å¤ï¼ï¼å¦å 207 å¼ç¨è®¡æ°å°æ°¸è¿ä¸ä¼ä¸º 0 ã 208 209 v4l2_subdevç»æä½ 210 ------------------ 211 212 许å¤é©±å¨éè¦ä¸å设å¤éä¿¡ãè¿äºè®¾å¤å¯ä»¥å®æåç§ä»»å¡ï¼ä½é常ä»ä»¬è´è´£ 213 é³è§é¢å¤ç¨åç¼è§£ç ãå¦ç½ç»æå头çå设å¤é常æ¯ä¼ æå¨åæå头æ§å¶å¨ã 214 215 è¿äºä¸è¬ä¸º I2C æ¥å£è®¾å¤ï¼ä½å¹¶ä¸ä¸å®é½æ¯ã为äºç»é©±å¨æä¾è°ç¨å设å¤ç 216 ç»ä¸æ¥å£ï¼v4l2_subdev ç»æä½ï¼v4l2-subdev.hï¼äº§çäºã 217 218 æ¯ä¸ªå设å¤é©±å¨é½å¿ é¡»æä¸ä¸ª v4l2_subdev ç»æä½ãè¿ä¸ªç»æä½å¯ä»¥åç¬ 219 代表ä¸ä¸ªç®åçå设å¤ï¼ä¹å¯ä»¥åµå ¥å°ä¸ä¸ªæ´å¤§çç»æä½ä¸ï¼ä¸æ´å¤è®¾å¤ç¶æ 220 ä¿¡æ¯ä¿åå¨ä¸èµ·ãé常æä¸ä¸ªä¸çº§è®¾å¤ç»æä½ï¼æ¯å¦ï¼i2c_clientï¼å å«äº 221 å æ ¸å建çè®¾å¤æ°æ®ãå»ºè®®ä½¿ç¨ v4l2_set_subdevdata() å°è¿ä¸ªç»æä½ç 222 æéä¿åå¨ v4l2_subdev çç§ææ°æ®å(dev_priv)ä¸ãè¿ä½¿å¾éè¿ v4l2_subdev 223 æ¾å°å®é çä½å±æ»çº¿ç¹å®è®¾å¤æ°æ®åå¾å®¹æã 224 225 ä½ åæ¶éè¦ä¸ä¸ªä»ä½å±ç»æä½è·å v4l2_subdev æéçæ¹æ³ã对äºå¸¸ç¨ç 226 i2c_client ç»æä½ï¼i2c_set_clientdata() 彿°å¯ç¨äºä¿åä¸ä¸ª v4l2_subdev 227 æéï¼å¯¹äºå ¶ä»æ»çº¿ä½ å¯è½éè¦ä½¿ç¨å ¶ä»ç¸å ³å½æ°ã 228 229 桥驱å¨ä¸ä¹åºä¿åæ¯ä¸ªå设å¤çç§ææ°æ®ï¼æ¯å¦ä¸ä¸ªæåç¹å®æ¡¥çå设å¤ç§æ 230 æ°æ®çæéãä¸ºæ¤ v4l2_subdev ç»æä½æä¾ä¸»æºç§ææ°æ®å(host_priv)ï¼ 231 å¹¶å¯éè¿ v4l2_get_subdev_hostdata() å v4l2_set_subdev_hostdata() 232 访é®ã 233 234 仿»çº¿æ¡¥é©±å¨çè§è§ï¼é©±å¨å è½½åè®¾å¤æ¨¡å并以æç§æ¹å¼è·å¾ v4l2_subdev 235 ç»æä½æéãå¯¹äº i2c æ»çº¿è®¾å¤ç¸å¯¹ç®åï¼è°ç¨ i2c_get_clientdata()ã 236 对äºå ¶ä»æ»çº¿ä¹éè¦å类似çæä½ãé对 I2C æ»çº¿ä¸çå设å¤è¾ å©å½æ°å¸®ä½ 237 宿äºå¤§é¨å夿çå·¥ä½ã 238 239 æ¯ä¸ª v4l2_subdev é½å å«å设å¤é©±å¨éè¦å®ç°ç彿°æéï¼å¦æå¯¹æ¤è®¾å¤ 240 ä¸éç¨ï¼å¯ä¸ºNULLï¼ãç±äºå设å¤å¯å®æè®¸å¤ä¸åçå·¥ä½ï¼èå¨ä¸ä¸ªåºå¤§ç 241 彿°æéç»æä½ä¸éå¸¸ä» æå°æ°æç¨ç彿°å®ç°å ¶åè½è¯å®ä¸åéãæä»¥ï¼ 242 彿°æéæ ¹æ®å ¶å®ç°çåè½è¢«åç±»ï¼æ¯ä¸ç±»é½æèªå·±ç彿°æéç»æä½ã 243 244 é¡¶å±å½æ°æéç»æä½å å«äºæååç±»å½æ°æéç»æä½çæéï¼å¦æå设å¤é©±å¨ 245 䏿¯æè¯¥ç±»å½æ°ä¸çä»»ä½ä¸ä¸ªåè½ï¼åæåè¯¥ç±»ç»æä½çæé为NULLã 246 247 è¿äºç»æä½å®ä¹å¦ä¸ï¼ 248 249 struct v4l2_subdev_core_ops { 250 int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip); 251 int (*log_status)(struct v4l2_subdev *sd); 252 int (*init)(struct v4l2_subdev *sd, u32 val); 253 ... 254 }; 255 256 struct v4l2_subdev_tuner_ops { 257 ... 258 }; 259 260 struct v4l2_subdev_audio_ops { 261 ... 262 }; 263 264 struct v4l2_subdev_video_ops { 265 ... 266 }; 267 268 struct v4l2_subdev_pad_ops { 269 ... 270 }; 271 272 struct v4l2_subdev_ops { 273 const struct v4l2_subdev_core_ops *core; 274 const struct v4l2_subdev_tuner_ops *tuner; 275 const struct v4l2_subdev_audio_ops *audio; 276 const struct v4l2_subdev_video_ops *video; 277 const struct v4l2_subdev_pad_ops *video; 278 }; 279 280 å ¶ä¸ coreï¼æ ¸å¿ï¼å½æ°éé常å¯ç¨äºææå设å¤ï¼å ¶ä»ç±»å«çå®ç°ä¾èµäº 281 å设å¤ãå¦è§é¢è®¾å¤å¯è½ä¸æ¯æé³é¢æä½å½æ°ï¼åä¹äº¦ç¶ã 282 283 è¿æ ·ç设置å¨éå¶äºå½æ°æéæ°éçåæ¶ï¼è¿ä½¿å¢å æ°çæä½å½æ°ååç±» 284 åå¾è¾ä¸ºå®¹æã 285 286 å设å¤é©±å¨å¯ä½¿ç¨å¦ä¸å½æ°åå§å v4l2_subdev ç»æä½ï¼ 287 288 v4l2_subdev_init(sd, &ops); 289 290 ç¶åï¼ä½ å¿ é¡»ç¨ä¸ä¸ªå¯ä¸çåååå§å subdev->nameï¼å¹¶åå§å模åç 291 owner åãè¥ä½¿ç¨ i2c è¾ å©å½æ°ï¼è¿äºé½ä¼å¸®ä½ å¤ç好ã 292 293 è¥éååªä½æ¡æ¶æ´åï¼ä½ å¿ é¡»è°ç¨ media_entity_init() åå§å v4l2_subdev 294 ç»æä½ä¸ç media_entity ç»æä½ï¼entity åï¼ï¼ 295 296 struct media_pad *pads = &my_sd->pads; 297 int err; 298 299 err = media_entity_init(&sd->entity, npads, pads, 0); 300 301 pads æ°ç»å¿ é¡»é¢å åå§åãæ é¡»æå¨è®¾ç½® media_entity ç type å 302 name åï¼ä½å¦æå¿ è¦ï¼revision åå¿ é¡»åå§åã 303 304 å½ï¼ä»»ä½ï¼å设å¤èç¹è¢«æå¼/å ³éï¼å¯¹ entity çå¼ç¨å°è¢«èªå¨è·å/éæ¾ã 305 306 å¨å设å¤è¢«æ³¨éä¹åï¼ä¸è¦å¿è®°æ¸ ç media_entity ç»æä½ï¼ 307 308 media_entity_cleanup(&sd->entity); 309 310 妿å设å¤é©±å¨è¶åäºå¤çè§é¢å¹¶æ´åè¿äºåªä½æ¡æ¶ï¼å¿ é¡»ä½¿ç¨ v4l2_subdev_pad_ops 311 æ¿ä»£ v4l2_subdev_video_ops å®ç°æ ¼å¼ç¸å ³çåè½ã 312 313 è¿ç§æ åµä¸ï¼å设å¤é©±å¨åºè¯¥è®¾ç½® link_validate åï¼ä»¥æä¾å®èªèº«ç龿¥ 314 éªè¯å½æ°ã龿¥éªè¯å½æ°åºå¯¹ç®¡éï¼ä¸¤ç«¯é¾æ¥ç齿¯ V4L2 å设å¤ï¼ä¸çæ¯ä¸ª 315 龿¥è°ç¨ã驱å¨è¿è¦è´è´£éªè¯å设å¤åè§é¢èç¹é´æ ¼å¼é ç½®çæ£ç¡®æ§ã 316 317 妿 link_validate æä½æ²¡æè®¾ç½®ï¼é»è®¤ç v4l2_subdev_link_validate_default() 318 彿°å°ä¼è¢«è°ç¨ãè¿ä¸ªå½æ°ä¿è¯å®½ãé«ååªä½æ»çº¿åç´ æ ¼å¼å¨é¾æ¥çæ¶å两端 319 é½ä¸è´ãå设å¤é©±å¨é¤äºå®ä»¬èªå·±çæ£æµå¤ï¼ä¹å¯ä»¥èªç±ä½¿ç¨è¿ä¸ªå½æ°ä»¥æ§è¡ 320 ä¸é¢æå°çæ£æ¥ã 321 322 设å¤ï¼æ¡¥ï¼é©±å¨ç¨åºå¿ é¡»å v4l2_device 注å v4l2_subdevï¼ 323 324 int err = v4l2_device_register_subdev(v4l2_dev, sd); 325 326 妿åè®¾å¤æ¨¡åå¨å®æ³¨å忶失ï¼è¿ä¸ªæä½å¯è½å¤±è´¥ãå¨è¿ä¸ªå½æ°æåè¿ååï¼ 327 subdev->dev åå°±æåäº v4l2_deviceã 328 329 妿 v4l2_device ç¶è®¾å¤ç mdev å为é NULL å¼ï¼åå设å¤å®ä½å°è¢«èªå¨ 330 注å为åªä½è®¾å¤ã 331 332 注éå设å¤åå¯ç¨å¦ä¸å½æ°ï¼ 333 334 v4l2_device_unregister_subdev(sd); 335 336 æ¤åï¼åè®¾å¤æ¨¡åå°±å¯å¸è½½ï¼ä¸ sd->dev == NULLã 337 338 注åä¹è®¾å¤åï¼å¯éè¿ä»¥ä¸æ¹å¼ç´æ¥è°ç¨å ¶æä½å½æ°ï¼ 339 340 err = sd->ops->core->g_chip_ident(sd, &chip); 341 342 ä½ä½¿ç¨å¦ä¸å®ä¼æ¯è¾å®¹æä¸åéï¼ 343 344 err = v4l2_subdev_call(sd, core, g_chip_ident, &chip); 345 346 è¿ä¸ªå®å°ä¼å NULL æéæ£æ¥ï¼å¦æ subdev 为 NULLï¼åè¿å-ENODEVï¼å¦æ 347 subdev->core æ subdev->core->g_chip_ident 为 NULLï¼åè¿å -ENOIOCTLCMDï¼ 348 å¦åå°è¿å subdev->ops->core->g_chip_ident ops è°ç¨çå®é ç»æã 349 350 ææ¶ä¹å¯è½åæ¶è°ç¨æææä¸ç³»åå设å¤çæä¸ªæä½å½æ°ï¼ 351 352 v4l2_device_call_all(v4l2_dev, 0, core, g_chip_ident, &chip); 353 354 ä»»ä½ä¸æ¯ææ¤æä½çå设å¤é½ä¼è¢«è·³è¿ï¼å¹¶å¿½ç¥é误è¿åå¼ãä½å¦æä½ éè¦ 355 æ£æ¥åºéç ï¼åå¯ä½¿ç¨å¦ä¸å½æ°ï¼ 356 357 err = v4l2_device_call_until_err(v4l2_dev, 0, core, g_chip_ident, &chip); 358 359 é¤ -ENOIOCTLCMD å¤çä»»ä½é误é½ä¼è·³åºå¾ªç¯å¹¶è¿åé误å¼ã妿ï¼é¤ -ENOIOCTLCMD 360 å¤ï¼æ²¡æé误åçï¼åè¿å 0ã 361 362 对äºä»¥ä¸ä¸¤ä¸ªå½æ°ç第äºä¸ªåæ°ä¸ºç» IDãå¦æä¸º 0ï¼åææå设å¤é½ä¼æ§è¡ 363 è¿ä¸ªæä½ãå¦æä¸ºé 0 å¼ï¼ååªæé£äºç» ID å¹é çåè®¾å¤æä¼æ§è¡æ¤æä½ã 364 卿¡¥é©±å¨æ³¨åä¸ä¸ªå设å¤åï¼å¯ä»¥è®¾ç½® sd->grp_id ä¸ºä»»ä½ææå¼ï¼é»è®¤å¼ä¸º 365 0ï¼ãè¿ä¸ªå¼å±äºæ¡¥é©±å¨ï¼ä¸å设å¤é©±å¨å°ä¸ä¼ä¿®æ¹å使ç¨å®ã 366 367 ç» ID èµäºäºæ¡¥é©±å¨æ´å¤å¯¹äºå¦ä½è°ç¨åè°çæ§å¶ãä¾å¦ï¼çµè·¯æ¿ä¸æå¤ä¸ª 368 é³é¢è¯çï¼æ¯ä¸ªé½ææ¹åé³éçè½åãä½å½ç¨æ·æ³è¦æ¹åé³éçæ¶åï¼é常 369 åªæä¸ä¸ªä¼è¢«å®é 使ç¨ãä½ å¯ä»¥å¯¹è¿æ ·çå设å¤è®¾ç½®ç» ID 为ï¼ä¾å¦ AUDIO_CONTROLLERï¼ 370 å¹¶å¨è°ç¨ v4l2_device_call_all() æ¶æå®å®ä¸ºç» ID å¼ãè¿å°±ä¿è¯äºåªæ 371 éè¦çåè®¾å¤æä¼æ§è¡è¿ä¸ªåè°ã 372 373 妿å设å¤éè¦éç¥å®ç v4l2_device ç¶è®¾å¤ä¸ä¸ªäºä»¶ï¼å¯ä»¥è°ç¨ 374 v4l2_subdev_notify(sd, notification, arg)ãè¿ä¸ªå®æ£æ¥æ¯å¦æä¸ä¸ª 375 notify() åè°è¢«æ³¨åï¼å¦ææ²¡æï¼è¿å -ENODEVãå¦åè¿å notify() è°ç¨ 376 ç»æã 377 378 ä½¿ç¨ v4l2_subdev ç好å¤å¨äºå®æ¯ä¸ä¸ªéç¨ç»æä½ï¼ä¸ä¸å å«ä»»ä½åºå±ç¡¬ä»¶ 379 ä¿¡æ¯ãææé©±å¨å¯ä»¥å å«å¤ä¸ª I2C æ»çº¿çå设å¤ï¼ä½ä¹æåè®¾å¤æ¯éè¿ GPIO 380 æ§å¶ãè¿ä¸ªåºå«ä» å¨é ç½®è®¾å¤æ¶æå ³ç³»ï¼ä¸æ¦åè®¾å¤æ³¨å宿ï¼å¯¹äº v4l2 381 åç³»ç»æ¥è¯´å°±å®å ¨éæäºã 382 383 384 V4L2 å设å¤ç¨æ·ç©ºé´API 385 -------------------- 386 387 é¤äºéè¿ v4l2_subdev_ops ç»æå¯¼åºçå æ ¸ APIï¼V4L2 å设å¤ä¹å¯ä»¥ç´æ¥ 388 éè¿ç¨æ·ç©ºé´åºç¨ç¨åºæ¥æ§å¶ã 389 390 å¯ä»¥å¨ /dev ä¸å建å为 v4l-subdevX 设å¤èç¹ï¼ä»¥éè¿å ¶ç´æ¥è®¿é®å设å¤ã 391 妿åè®¾å¤æ¯æç¨æ·ç©ºé´ç´æ¥é ç½®ï¼å¿ 须卿³¨åå设置 V4L2_SUBDEV_FL_HAS_DEVNODE 392 æ å¿ã 393 394 注åå设å¤ä¹åï¼ v4l2_device 驱å¨ä¼éè¿è°ç¨ v4l2_device_register_subdev_nodes() 395 彿°ä¸ºææå·²æ³¨åå¹¶è®¾ç½®äº V4L2_SUBDEV_FL_HAS_DEVNODE çå设å¤å建 396 设å¤èç¹ãè¿äºè®¾å¤èç¹ä¼å¨åè®¾å¤æ³¨éæ¶èªå¨å é¤ã 397 398 è¿äºè®¾å¤èç¹å¤ç V4L2 API çä¸ä¸ªåéã 399 400 VIDIOC_QUERYCTRL 401 VIDIOC_QUERYMENU 402 VIDIOC_G_CTRL 403 VIDIOC_S_CTRL 404 VIDIOC_G_EXT_CTRLS 405 VIDIOC_S_EXT_CTRLS 406 VIDIOC_TRY_EXT_CTRLS 407 408 è¿äº ioctls æ§å¶ä¸ V4L2 ä¸å®ä¹çä¸è´ãä»ä»¬è¡ä¸ºç¸åï¼å¯ä¸ç 409 ä¸åæ¯ä»ä»¬åªå¤çå设å¤çæ§å¶å®ç°ãæ ¹æ®é©±å¨ç¨åºï¼è¿äºæ§å¶ä¹ 410 å¯ä»¥éè¿ä¸ä¸ªï¼æå¤ä¸ªï¼ V4L2 设å¤èç¹è®¿é®ã 411 412 VIDIOC_DQEVENT 413 VIDIOC_SUBSCRIBE_EVENT 414 VIDIOC_UNSUBSCRIBE_EVENT 415 416 è¿äº ioctls äºä»¶ä¸ V4L2 ä¸å®ä¹çä¸è´ãä»ä»¬è¡ä¸ºç¸åï¼å¯ä¸ç 417 ä¸åæ¯ä»ä»¬åªå¤çå设å¤äº§ççäºä»¶ãæ ¹æ®é©±å¨ç¨åºï¼è¿äºäºä»¶ä¹ 418 å¯ä»¥éè¿ä¸ä¸ªï¼æå¤ä¸ªï¼ V4L2 设å¤èç¹ä¸æ¥ã 419 420 è¦ä½¿ç¨äºä»¶éç¥çå设å¤é©±å¨ï¼å¨æ³¨åå设å¤åå¿ é¡»å¨ v4l2_subdev::flags 421 ä¸è®¾ç½® V4L2_SUBDEV_USES_EVENTS å¹¶å¨ v4l2_subdev::nevents 422 ä¸åå§åäºä»¶éåæ·±åº¦ã注å宿åï¼äºä»¶ä¼å¨ v4l2_subdev::devnode 423 设å¤èç¹ä¸åé叏䏿 ·è¢«æéã 424 425 为æ£ç¡®æ¯æäºä»¶æºå¶ï¼poll() æä»¶æä½ä¹åºè¢«å®ç°ã 426 427 ç§æ ioctls 428 429 ä¸å¨ä»¥ä¸å表ä¸çææ ioctls ä¼éè¿ core::ioctl æä½ç´æ¥ä¼ é 430 ç»å设å¤é©±å¨ã 431 432 433 I2C å设å¤é©±å¨ 434 ------------- 435 436 ç±äºè¿äºé©±å¨å¾å¸¸è§ï¼æä»¥å ç¹æä¾äºç¹å®çè¾ å©å½æ°(v4l2-common.h)让è¿äº 437 设å¤çä½¿ç¨æ´å 容æã 438 439 æ·»å v4l2_subdev æ¯æçæ¨èæ¹æ³æ¯è®© I2C 驱å¨å° v4l2_subdev ç»æä½ 440 åµå ¥å°ä¸ºæ¯ä¸ª I2C 设å¤å®ä¾å建çç¶æç»æä½ä¸ãèæç®åçè®¾å¤æ²¡æç¶æ 441 ç»æä½ï¼æ¤æ¶å¯ä»¥ç´æ¥å建ä¸ä¸ª v4l2_subdev ç»æä½ã 442 443 ä¸ä¸ªå ¸åçç¶æç»æä½å¦ä¸æç¤ºï¼âchipnameâç¨è¯çå代æ¿ï¼ï¼ 444 445 struct chipname_state { 446 struct v4l2_subdev sd; 447 ... /* éå çç¶æå*/ 448 }; 449 450 åå§å v4l2_subdev ç»æä½çæ¹æ³å¦ä¸ï¼ 451 452 v4l2_i2c_subdev_init(&state->sd, client, subdev_ops); 453 454 è¿ä¸ªå½æ°å°å¡«å v4l2_subdev ç»æä½ä¸çææåï¼å¹¶ä¿è¯ v4l2_subdev å 455 i2c_client 齿åå½¼æ¤ã 456 457 åæ¶ï¼ä½ ä¹åºè¯¥ä¸ºä» v4l2_subdev æéæ¾å° chipname_state ç»æä½æé 458 æ·»å ä¸ä¸ªè¾ å©å è彿°ã 459 460 static inline struct chipname_state *to_state(struct v4l2_subdev *sd) 461 { 462 return container_of(sd, struct chipname_state, sd); 463 } 464 465 使ç¨ä»¥ä¸å½æ°å¯ä»¥éè¿ v4l2_subdev ç»æä½æéè·å¾ i2c_client ç»æä½ 466 æéï¼ 467 468 struct i2c_client *client = v4l2_get_subdevdata(sd); 469 470 è以ä¸å½æ°åç¸åï¼éè¿ i2c_client ç»æä½æéè·å¾ v4l2_subdev ç»æä½ 471 æéï¼ 472 473 struct v4l2_subdev *sd = i2c_get_clientdata(client); 474 475 å½ remove()彿°è¢«è°ç¨åï¼å¿ é¡»ä¿è¯å è°ç¨ v4l2_device_unregister_subdev(sd)ã 476 æ¤æä½å°ä¼ä»æ¡¥é©±å¨ä¸æ³¨éå设å¤ãå³ä½¿åè®¾å¤æ²¡ææ³¨åï¼è°ç¨æ¤å½æ°ä¹æ¯ 477 å®å ¨çã 478 479 å¿ é¡»è¿æ ·åçåå æ¯ï¼å½æ¡¥é©±å¨æ³¨é i2c éé 卿¶ï¼remove()åè°å½æ° 480 ä¼è¢«é£ä¸ªéé å¨ä¸ç i2c 设å¤è°ç¨ãæ¤åï¼ç¸åºç v4l2_subdev ç»æä½ 481 å°±ä¸åå¨äºï¼ææå®ä»¬å¿ é¡»å 被注éãå¨ remove()åè°å½æ°ä¸è°ç¨ 482 v4l2_device_unregister_subdev(sd)ï¼å¯ä»¥ä¿è¯æ§è¡æ»æ¯æ£ç¡®çã 483 484 485 桥驱å¨ä¹æä¸äºè¾ ç»å½æ°å¯ç¨ï¼ 486 487 struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter, 488 "module_foo", "chipid", 0x36, NULL); 489 490 è¿ä¸ªå½æ°ä¼å è½½ç»å®ç模åï¼å¦ææ²¡ææ¨¡åéè¦å è½½ï¼å¯ä»¥ä¸º NULLï¼ï¼ 491 å¹¶ç¨ç»å®ç i2c éé å¨ç»æä½æéï¼i2c_adapterï¼å å¨ä»¶å°åï¼chip/addressï¼ 492 ä½ä¸ºåæ°è°ç¨ i2c_new_device()ã妿ä¸å顺å©ï¼åå°±å¨ v4l2_device 493 䏿³¨åäºå设å¤ã 494 495 ä½ ä¹å¯ä»¥å©ç¨ v4l2_i2c_new_subdev()çæåä¸ä¸ªåæ°ï¼ä¼ éä¸ä¸ªå¯è½ç 496 I2C å°åæ°ç»ï¼è®©å½æ°èªå¨æ¢æµãè¿äºæ¢æµå°ååªæå¨åä¸ä¸ªåæ°ä¸º 0 ç 497 æ åµä¸ä½¿ç¨ãéé¶åæ°æå³çä½ ç¥éåç¡®ç i2c å°åï¼æä»¥æ¤æ¶æ é¡»è¿è¡ 498 æ¢æµã 499 500 妿åºéï¼ä¸¤ä¸ªå½æ°é½è¿å NULLã 501 502 注æï¼ä¼ éç» v4l2_i2c_new_subdev()ç chipid é叏䏿¨¡ååä¸è´ã 503 å®å è®¸ä½ æå®ä¸ä¸ªè¯ççåä½ï¼æ¯å¦âsaa7114âæâsaa7115âãä¸è¬éè¿ 504 i2c 驱å¨èªå¨æ¢æµãchipid çä½¿ç¨æ¯å¨ä»åéè¦æ·±å ¥äºè§£çäºæ ãè¿ä¸ªä¸ 505 i2c 驱å¨ä¸åï¼è¾å®¹ææ··æ·ãè¦ç¥éæ¯æåªäºè¯çåä½ï¼ä½ å¯ä»¥æ¥é i2c 506 驱å¨ä»£ç ç i2c_device_id 表ï¼ä¸é¢ååºäºææå¯è½æ¯æçè¯çã 507 508 è¿æä¸¤ä¸ªè¾ å©å½æ°ï¼ 509 510 v4l2_i2c_new_subdev_cfgï¼è¿ä¸ªå½æ°æ·»å æ°ç irq å platform_data 511 åæ°ï¼å¹¶æâaddrâåâprobed_addrsâåæ°ï¼å¦æ addr éé¶ï¼åè¢«ä½¿ç¨ 512 ï¼ä¸æ¢æµåä½ï¼ï¼å¦å probed_addrs ä¸çå°åå°ç¨äºèªå¨æ¢æµã 513 514 ä¾å¦ï¼ä»¥ä¸ä»£ç å°ä¼æ¢æµå°åï¼0x10ï¼ï¼ 515 516 struct v4l2_subdev *sd = v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, 517 "module_foo", "chipid", 0, NULL, 0, I2C_ADDRS(0x10)); 518 519 v4l2_i2c_new_subdev_board 使ç¨ä¸ä¸ª i2c_board_info ç»æä½ï¼å°å ¶ 520 æ¿ä»£ irqãplatform_data å add råæ°ä¼ éç» i2c 驱å¨ã 521 522 妿åè®¾å¤æ¯æ s_config æ ¸å¿æä½ï¼è¿ä¸ªæä½ä¼å¨å设å¤é 置好ä¹å以 irq å 523 platform_data ä¸ºåæ°è°ç¨ãæ©æç v4l2_i2c_new_(probed_)subdev 彿° 524 åæ ·ä¹ä¼è°ç¨ s_configï¼ä½ä» å¨ irq 为 0 ä¸ platform_data 为 NULL æ¶ã 525 526 video_deviceç»æä½ 527 ----------------- 528 529 å¨ /dev ç®å½ä¸çå®é 设å¤èç¹æ ¹æ® video_device ç»æä½(v4l2-dev.h) 530 åå»ºãæ¤ç»æä½æ¢å¯ä»¥å¨æåé ä¹å¯ä»¥åµå ¥å°ä¸ä¸ªæ´å¤§çç»æä½ä¸ã 531 532 卿åé æ¹æ³å¦ä¸ï¼ 533 534 struct video_device *vdev = video_device_alloc(); 535 536 if (vdev == NULL) 537 return -ENOMEM; 538 539 vdev->release = video_device_release; 540 541 妿å°å ¶åµå ¥å°ä¸ä¸ªå¤§ç»æä½ä¸ï¼åå¿ é¡»èªå·±å®ç° release()åè°ã 542 543 struct video_device *vdev = &my_vdev->vdev; 544 545 vdev->release = my_vdev_release; 546 547 release()åè°å¿ 须被设置ï¼ä¸å¨æåä¸ä¸ª video_device ç¨æ·éåºä¹å 548 被è°ç¨ã 549 550 é»è®¤ç video_device_release()åè°åªæ¯è°ç¨ kfree æ¥éæ¾ä¹ååé ç 551 å åã 552 553 ä½ åºè¯¥è®¾ç½®è¿äºåï¼ 554 555 - v4l2_dev: 设置为 v4l2_device ç¶è®¾å¤ã 556 557 - name: 设置为å¯ä¸çæè¿°æ§è®¾å¤åã 558 559 - fops: 设置为已æç v4l2_file_operations ç»æä½ã 560 561 - ioctl_ops: å¦æä½ ä½¿ç¨v4l2_ioctl_ops æ¥ç®å ioctl çç»´æ¤ 562 (强ç建议使ç¨ï¼ä¸å°æ¥å¯è½åä¸ºå¼ºå¶æ§ç!)ï¼ç¶åè®¾ç½®ä½ èªå·±ç 563 v4l2_ioctl_ops ç»æä½. 564 565 - lock: å¦æä½ è¦å¨é©±å¨ä¸å®ç°ææçéæä½ï¼å设为 NULL ãå¦å 566 å°±è¦è®¾ç½®ä¸ä¸ªæå struct mutex_lock ç»æä½çæéï¼è¿ä¸ªéå° 567 å¨ unlocked_ioctl æä»¶æä½è¢«è°ç¨åç±å æ ¸è·å¾ï¼å¹¶å¨è°ç¨è¿åå 568 éæ¾ã详è§ä¸ä¸èã 569 570 - prio: ä¿æå¯¹ä¼å 级çè·è¸ªãç¨äºå®ç° VIDIOC_G/S_PRIORITYã妿 571 设置为 NULLï¼åä¼ä½¿ç¨ v4l2_device ä¸ç v4l2_prio_state ç»æä½ã 572 妿è¦å¯¹æ¯ä¸ªè®¾å¤èç¹ï¼ç»ï¼å®ç°ç¬ç«çä¼å 级ï¼å¯ä»¥å°å ¶æåèªå·± 573 å®ç°ç v4l2_prio_state ç»æä½ã 574 575 - parent: ä» å¨ä½¿ç¨ NULL ä½ä¸ºç¶è®¾å¤ç»æä½åæ°æ³¨å v4l2_device æ¶ 576 设置æ¤åæ°ãåªæå¨ä¸ä¸ªç¡¬ä»¶è®¾å¤å å«å¤ä¸ä¸ª PCI 设å¤ï¼å ±äº«åä¸ä¸ª 577 v4l2_device æ ¸å¿æ¶æä¼åçã 578 579 cx88 驱å¨å°±æ¯ä¸ä¸ªä¾åï¼ä¸ä¸ª v4l2_device ç»æä½æ ¸å¿ï¼è¢«ä¸ä¸ªè£¸ç 580 è§é¢ PCI 设å¤(cx8800)åä¸ä¸ª MPEG PCI 设å¤(cx8802)å ±ç¨ãç±äº 581 v4l2_device æ æ³ä¸ç¹å®ç PCI 设å¤å ³èï¼æææ²¡æè®¾ç½®ç¶è®¾å¤ãä½å½ 582 video_device é ç½®åï¼å°±ç¥é使ç¨åªä¸ªç¶ PCI 设å¤äºã 583 584 - flagsï¼å¯éãå¦æä½ è¦è®©æ¡æ¶å¤ç设置 VIDIOC_G/S_PRIORITY ioctlsï¼ 585 请设置 V4L2_FL_USE_FH_PRIOãè¿è¦æ±ä½ ä½¿ç¨ v4l2_fh ç»æä½ã 586 䏿¦ææé©±å¨ä½¿ç¨äºæ ¸å¿çä¼å 级å¤çï¼æç»è¿ä¸ªæ å¿å°æ¶å¤±ãä½ç°å¨å® 587 å¿ é¡»è¢«æ¾å¼è®¾ç½®ã 588 589 å¦æä½ ä½¿ç¨ v4l2_ioctl_opsï¼ååºè¯¥å¨ v4l2_file_operations ç»æä½ä¸ 590 设置 .unlocked_ioctl æå video_ioctl2ã 591 592 请å¿ä½¿ç¨ .ioctlï¼å®å·²è¢«åºå¼ï¼ä»åå°æ¶å¤±ã 593 594 æäºæ åµä¸ä½ è¦åè¯æ ¸å¿ï¼ä½ å¨ v4l2_ioctl_ops æå®çæä¸ªå½æ°åºè¢«å¿½ç¥ã 595 ä½ å¯ä»¥å¨ video_device_register 被è°ç¨åéè¿ä»¥ä¸å½æ°æ è®°è¿ä¸ª ioctlsã 596 597 void v4l2_disable_ioctl(struct video_device *vdev, unsigned int cmd); 598 599 åºäºå¤é¨å ç´ ï¼ä¾å¦æä¸ªæ¿å¡å·²è¢«ä½¿ç¨ï¼ï¼å¨ä¸å建æ°ç»æä½çæ åµä¸ï¼ä½ æ³ 600 è¦å ³é v4l2_ioctl_ops ä¸æä¸ªç¹æ§å¾å¾éè¦è¿ä¸ªæºå¶ã 601 602 v4l2_file_operations ç»æä½æ¯ file_operations çä¸ä¸ªåéãå ¶ä¸»è¦ 603 åºå«å¨äºï¼å inode 忰仿ªè¢«ä½¿ç¨ï¼å®å°è¢«å¿½ç¥ã 604 605 妿éè¦ä¸åªä½æ¡æ¶æ´åï¼ä½ å¿ é¡»éè¿è°ç¨ media_entity_init() åå§å 606 åµå ¥å¨ video_device ç»æä½ä¸ç media_entityï¼entity åï¼ç»æä½ï¼ 607 608 struct media_pad *pad = &my_vdev->pad; 609 int err; 610 611 err = media_entity_init(&vdev->entity, 1, pad, 0); 612 613 pads æ°ç»å¿ é¡»é¢å åå§åãæ²¡æå¿ è¦æå¨è®¾ç½® media_entity ç type å 614 name åã 615 616 å½ï¼ä»»ä½ï¼å设å¤èç¹è¢«æå¼/å ³éï¼å¯¹ entity çå¼ç¨å°è¢«èªå¨è·å/éæ¾ã 617 618 v4l2_file_operations ä¸é 619 -------------------------- 620 621 ä½ å¯ä»¥å¨ video_device ç»æä½ä¸è®¾ç½®ä¸ä¸ªæå mutex_lock çæéãé常 622 è¿æ¢å¯æ¯ä¸ä¸ªé¡¶å±äºæ¥éä¹å¯ä¸ºè®¾å¤èç¹èªèº«çäºæ¥éãé»è®¤æ åµä¸ï¼æ¤é 623 ç¨äº unlocked_ioctlï¼ä½ä¸ºäºä½¿ç¨ ioctls ä½ éè¿ä»¥ä¸å½æ°å¯ç¦ç¨éå®ï¼ 624 625 void v4l2_disable_ioctl_locking(struct video_device *vdev, unsigned int cmd); 626 627 ä¾å¦: v4l2_disable_ioctl_locking(vdev, VIDIOC_DQBUF); 628 629 ä½ å¿ é¡»å¨æ³¨å video_device åè°ç¨è¿ä¸ªå½æ°ã 630 631 ç¹å«æ¯å¯¹äº USB 驱å¨ç¨åºï¼æäºå½ä»¤ï¼å¦è®¾ç½®æ§å¶ï¼éè¦å¾é¿çæ¶é´ï¼å¯è½ 632 éè¦èªè¡ä¸ºç¼å²åºéåç ioctls å®ç°éå®ã 633 634 å¦æä½ éè¦æ´ç»ç²åº¦çéï¼ä½ å¿ é¡»è®¾ç½® mutex_lock 为 NULLï¼å¹¶å®å ¨èªå·±å®ç° 635 éæºå¶ã 636 637 è¿å®å ¨ç±é©±å¨å¼åè å³å®ä½¿ç¨ä½ç§æ¹æ³ãç¶èï¼å¦æä½ ç驱å¨åå¨é¿å»¶æ¶æä½ 638 ï¼ä¾å¦ï¼æ¹å USB æå头çæå æ¶é´å¯è½éè¦è¾é¿æ¶é´ï¼ï¼èä½ åæ³è®©ç¨æ· 639 å¨çå¾ é¿å»¶æ¶æä½å®ææé´åå ¶ä»çäºï¼åä½ æå¥½èªå·±å®ç°éæºå¶ã 640 641 妿æå®ä¸ä¸ªéï¼åææ ioctl æä½å°å¨è¿ä¸ªéçä½ç¨ä¸ä¸²è¡æ§è¡ãå¦æä½ 642 ä½¿ç¨ videobufï¼åå¿ é¡»å°åä¸ä¸ªéä¼ éç» videobuf éååå§å彿°ï¼å¦ 643 videobuf å¿ é¡»çå¾ ä¸å¸§çå°è¾¾ï¼åå¯ä¸´æ¶è§£éå¹¶å¨è¿ä¹åéæ°ä¸éãå¦æé©±å¨ 644 ä¹å¨ä»£ç æ§è¡æé´çå¾ ï¼åå¯ååæ ·çå·¥ä½ï¼ä¸´æ¶è§£éï¼åä¸éï¼è®©å ¶ä»è¿ç¨ 645 å¯ä»¥å¨ç¬¬ä¸ä¸ªè¿ç¨é»å¡æ¶è®¿é®è®¾å¤èç¹ã 646 647 å¨ä½¿ç¨ videobuf2 çæ åµä¸ï¼å¿ é¡»å®ç° wait_prepare å wait_finish åè° 648 å¨éå½çæ¶åè§£é/å éãè¿ä¸æ¥æ¥è¯´ï¼å¦æä½ å¨ video_device ç»æä½ä¸ä½¿ç¨ 649 éï¼åå¿ é¡»å¨ wait_prepare å wait_finish ä¸å¯¹è¿ä¸ªäºæ¥éè¿è¡è§£é/å éã 650 651 çææçæå¼å®ç°ä¹å¿ é¡»å¨è°ç¨ v4l2_device_disconnect åè·å¾éã 652 653 video_device注å 654 --------------- 655 656 æ¥ä¸æ¥ä½ éè¦æ³¨åè§é¢è®¾å¤ï¼è¿ä¼ä¸ºä½ å建ä¸ä¸ªå符设å¤ã 657 658 err = video_register_device(vdev, VFL_TYPE_GRABBER, -1); 659 if (err) { 660 video_device_release(vdev); /* or kfree(my_vdev); */ 661 return err; 662 } 663 664 妿 v4l2_device ç¶è®¾å¤ç mdev å为é NULL å¼ï¼è§é¢è®¾å¤å®ä½å°èªå¨ 665 注å为åªä½è®¾å¤ã 666 667 注ååªç§è®¾å¤æ¯æ ¹æ®ç±»åï¼typeï¼åæ°ãåå¨ä»¥ä¸ç±»åï¼ 668 669 VFL_TYPE_GRABBER: ç¨äºè§é¢è¾å ¥/è¾åºè®¾å¤ç videoX 670 VFL_TYPE_VBI: ç¨äºåç´æ¶éæ°æ®ç vbiX (ä¾å¦ï¼éèå¼åå¹ï¼å¾æçµè§) 671 VFL_TYPE_RADIO: ç¨äºå¹¿æè°è°å¨ç radioX 672 673 æåä¸ä¸ªåæ°è®©ä½ ç¡®å®ä¸ä¸ªææ§å¶è®¾å¤ç设å¤èç¹å·æ°é(ä¾å¦ videoX ä¸ç X)ã 674 éå¸¸ä½ å¯ä»¥ä¼ å ¥-1ï¼è®© v4l2 æ¡æ¶èªå·±éæ©ç¬¬ä¸ä¸ªç©ºé²çç¼å·ã使¯ææ¶ç¨æ· 675 éè¦éæ©ä¸ä¸ªç¹å®çèç¹å·ã驱å¨å è®¸ç¨æ·éè¿é©±å¨æ¨¡ååæ°éæ©ä¸ä¸ªç¹å®ç 676 设å¤èç¹å·æ¯å¾æ®éçãè¿ä¸ªç¼å·å°ä¼ä¼ éç»è¿ä¸ªå½æ°ï¼ä¸ video_register_device 677 å°ä¼è¯å¾éæ©è¿ä¸ªè®¾å¤èç¹å·ã妿è¿ä¸ªç¼å·è¢«å ç¨ï¼ä¸ä¸ä¸ªç©ºé²ç设å¤èç¹ 678 ç¼å·å°è¢«éä¸ï¼å¹¶åå æ ¸æ¥å¿ä¸åéä¸ä¸ªè¦åä¿¡æ¯ã 679 680 å¦ä¸ä¸ªä½¿ç¨åºæ¯æ¯å½é©±å¨å建å¤ä¸ªè®¾å¤æ¶ãè¿ç§æ åµä¸ï¼å¯¹ä¸åçè§é¢è®¾å¤å¨ 681 ç¼å·ä¸ä½¿ç¨ä¸åçèå´æ¯å¾æç¨çãä¾å¦ï¼è§é¢æè·è®¾å¤ä» 0 å¼å§ï¼è§é¢ 682 è¾åºè®¾å¤ä» 16 å¼å§ãæä»¥ä½ å¯ä»¥ä½¿ç¨æåä¸ä¸ªåæ°æ¥æå®è®¾å¤èç¹å·æå°å¼ï¼ 683 è v4l2 æ¡æ¶ä¼è¯å¾éæ©ç¬¬ä¸ä¸ªç空é²ç¼å·ï¼çäºæå¤§äºä½ æä¾çç¼å·ï¼ã 684 å¦æå¤±è´¥ï¼åå®ä¼å°±éæ©ç¬¬ä¸ä¸ªç©ºé²çç¼å·ã 685 686 ç±äºè¿ç§æ åµä¸ï¼ä½ ä¼å¿½ç¥æ æ³éæ©ç¹å®è®¾å¤èç¹å·çè¦åï¼åå¯è°ç¨ 687 video_register_device_no_warn() 彿°é¿å è¦åä¿¡æ¯ç产çã 688 689 åªè¦è®¾å¤èç¹è¢«å建ï¼ä¸äºå±æ§ä¹ä¼åæ¶å建ãå¨ /sys/class/video4linux 690 ç®å½ä¸ä½ 伿¾å°è¿äºè®¾å¤ãä¾å¦è¿å ¥å ¶ä¸ç video0 ç®å½ï¼ä½ ä¼çå°ânameâå 691 âindexâ屿§ãânameâ屿§å¼å°±æ¯ video_device ç»æä½ä¸çânameâåã 692 693 âindexâ屿§å¼å°±æ¯è®¾å¤èç¹çç´¢å¼å¼ï¼æ¯æ¬¡è°ç¨ video_register_device()ï¼ 694 ç´¢å¼å¼é½éå¢ 1 ã第ä¸ä¸ªè§é¢è®¾å¤èç¹æ»æ¯ä»ç´¢å¼å¼ 0 å¼å§ã 695 696 ç¨æ·å¯ä»¥è®¾ç½® udev è§åï¼å©ç¨ç´¢å¼å±æ§çæè±å¨ç设å¤åï¼ä¾å¦ï¼ç¨âmpegXâ 697 代表 MPEG è§é¢æè·è®¾å¤èç¹ï¼ã 698 699 å¨è®¾å¤æå注ååï¼å°±å¯ä»¥ä½¿ç¨è¿äºåï¼ 700 701 - vfl_type: ä¼ éç» video_register_device ç设å¤ç±»åã 702 - minor: å·²ææ´¾ç次设å¤å·ã 703 - num: 设å¤èç¹ç¼å· (ä¾å¦ videoX ä¸ç X)ã 704 - index: 设å¤ç´¢å¼å·ã 705 706 å¦ææ³¨å失败ï¼ä½ å¿ é¡»è°ç¨ video_device_release() æ¥éæ¾å·²åé ç 707 video_device ç»æä½ï¼å¦æ video_device æ¯åµå ¥å¨èªå·±å建çç»æä½ä¸ï¼ 708 ä½ ä¹å¿ 须鿾å®ãvdev->release() åè°ä¸ä¼å¨æ³¨å失败ä¹å被è°ç¨ï¼ 709 ä½ ä¹ä¸åºè¯å¾å¨æ³¨åå¤±è´¥åæ³¨é设å¤ã 710 711 712 video_device 注é 713 ---------------- 714 715 å½è§é¢è®¾å¤èç¹å·²è¢«ç§»é¤ï¼ä¸è®ºæ¯å¸è½½é©±å¨è¿æ¯USBè®¾å¤æå¼ï¼ä½ é½åºæ³¨é 716 å®ä»¬ï¼ 717 718 video_unregister_device(vdev); 719 720 è¿ä¸ªæä½å°ä» sysfs ä¸ç§»é¤è®¾å¤èç¹ï¼å¯¼è´ udev å°å ¶ä» /dev ä¸ç§»é¤ï¼ã 721 722 video_unregister_device() è¿åä¹åï¼å°±æ æ³å®ææå¼æä½ãå°½ç®¡å¦æ¤ï¼ 723 USB 设å¤çæ åµåä¸åï¼æäºåºç¨ç¨åºå¯è½ä¾ç¶æå¼çå ¶ä¸ä¸ä¸ªå·²æ³¨éè®¾å¤ 724 èç¹ãæä»¥å¨æ³¨éä¹åï¼æææä»¶æä½ï¼å½ç¶é¤äº release ï¼ä¹åºè¿åé误å¼ã 725 726 彿åä¸ä¸ªè§é¢è®¾å¤èç¹çç¨æ·éåºï¼å vdev->release() åè°ä¼è¢«è°ç¨ï¼ 727 å¹¶ä¸ä½ å¯ä»¥åæåçæ¸ çæä½ã 728 729 ä¸è¦å¿è®°æ¸ çä¸è§é¢è®¾å¤ç¸å ³çåªä½å ¥å£ï¼å¦æè¢«åå§åè¿ï¼ï¼ 730 731 media_entity_cleanup(&vdev->entity); 732 733 è¿å¯ä»¥å¨ release åè°ä¸å®æã 734 735 736 video_device è¾ å©å½æ° 737 --------------------- 738 739 ä¸äºæç¨çè¾ å©å½æ°å¦ä¸ï¼ 740 741 - file/video_device ç§ææ°æ® 742 743 ä½ å¯ä»¥ç¨ä»¥ä¸å½æ°å¨ video_device ç»æä½ä¸è®¾ç½®/è·å驱å¨ç§ææ°æ®ï¼ 744 745 void *video_get_drvdata(struct video_device *vdev); 746 void video_set_drvdata(struct video_device *vdev, void *data); 747 748 注æï¼å¨è°ç¨ video_register_device() åæ§è¡ video_set_drvdata() 749 æ¯å®å ¨çã 750 751 è以ä¸å½æ°ï¼ 752 753 struct video_device *video_devdata(struct file *file); 754 755 è¿å file ç»æä½ä¸æ¥æçç video_device æéã 756 757 video_drvdata è¾ å©å½æ°ç»åäº video_get_drvdata å video_devdata 758 çåè½ï¼ 759 760 void *video_drvdata(struct file *file); 761 762 ä½ å¯ä»¥ä½¿ç¨å¦ä¸ä»£ç ä» video_device ç»æä½ä¸è·å v4l2_device ç»æä½ 763 æéï¼ 764 765 struct v4l2_device *v4l2_dev = vdev->v4l2_dev; 766 767 - 设å¤èç¹å 768 769 video_device 设å¤èç¹å¨å æ ¸ä¸çåç§°å¯ä»¥éè¿ä»¥ä¸å½æ°è·å¾ 770 771 const char *video_device_node_name(struct video_device *vdev); 772 773 è¿ä¸ªååè¢«ç¨æ·ç©ºé´å·¥å ·ï¼ä¾å¦ udevï¼ä½ä¸ºæç¤ºä¿¡æ¯ä½¿ç¨ãåºå°½å¯è½ä½¿ç¨ 774 æ¤åè½ï¼èéè®¿é® video_device::num å video_device::minor åã 775 776 777 è§é¢ç¼å²è¾ å©å½æ° 778 --------------- 779 780 v4l2 æ ¸å¿ API æä¾äºä¸ä¸ªå¤çè§é¢ç¼å²çæ åæ¹æ³(称为âvideobufâ)ã 781 è¿äºæ¹æ³ä½¿é©±å¨å¯ä»¥éè¿ç»ä¸çæ¹å¼å®ç° read()ãmmap() å overlay()ã 782 ç®åå¨è®¾å¤ä¸æ¯æè§é¢ç¼å²çæ¹æ³æåæ£/èé DMA(videobuf-dma-sg)ã 783 çº¿æ§ DMA(videobuf-dma-contig)以å大å¤ç¨äº USB 设å¤çç¨ vmalloc 784 åé çç¼å²(videobuf-vmalloc)ã 785 786 请åé Documentation/video4linux/videobufï¼ä»¥è·å¾æ´å¤å ³äº videobuf 787 å±ç使ç¨ä¿¡æ¯ã 788 789 v4l2_fh ç»æä½ 790 ------------- 791 792 v4l2_fh ç»æä½æä¾ä¸ä¸ªä¿åç¨äº V4L2 æ¡æ¶çæä»¶å¥æç¹å®æ°æ®çç®åæ¹æ³ã 793 妿 video_device ç flag è®¾ç½®äº V4L2_FL_USE_FH_PRIO æ å¿ï¼æ°é©±å¨ 794 å¿ é¡»ä½¿ç¨ v4l2_fh ç»æä½ï¼å 为å®ä¹ç¨äºå®ç°ä¼å 级å¤çï¼VIDIOC_G/S_PRIORITYï¼ã 795 796 v4l2_fh çç¨æ·ï¼ä½äº V4l2 æ¡æ¶ä¸ï¼å¹¶é驱å¨ï¼å¯éè¿æµè¯ 797 video_device->flags ä¸ç V4L2_FL_USES_V4L2_FH ä½å¾ç¥é©±å¨æ¯å¦ä½¿ç¨ 798 v4l2_fh ä½ä¸ºä»ç file->private_data æéãè¿ä¸ªä½ä¼å¨è°ç¨ v4l2_fh_init() 799 æ¶è¢«è®¾ç½®ã 800 801 v4l2_fh ç»æä½ä½ä¸ºé©±å¨èªèº«æä»¶å¥æç»æä½çä¸é¨å被åé ï¼ä¸é©±å¨å¨ 802 å ¶æå¼å½æ°ä¸å° file->private_data æåå®ã 803 804 å¨è®¸å¤æ åµä¸ï¼v4l2_fh ç»æä½ä¼åµå ¥å°ä¸ä¸ªæ´å¤§çç»æä½ä¸ãè¿éæ åµä¸ï¼ 805 åºè¯¥å¨ open() ä¸è°ç¨ v4l2_fh_init+v4l2_fh_addï¼å¹¶å¨ release() ä¸ 806 è°ç¨ v4l2_fh_del+v4l2_fh_exitã 807 808 驱å¨å¯ä»¥éè¿ä½¿ç¨ container_of 宿åä»ä»¬èªå·±çæä»¶å¥æç»æä½ãä¾å¦ï¼ 809 810 struct my_fh { 811 int blah; 812 struct v4l2_fh fh; 813 }; 814 815 ... 816 817 int my_open(struct file *file) 818 { 819 struct my_fh *my_fh; 820 struct video_device *vfd; 821 int ret; 822 823 ... 824 825 my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL); 826 827 ... 828 829 v4l2_fh_init(&my_fh->fh, vfd); 830 831 ... 832 833 file->private_data = &my_fh->fh; 834 v4l2_fh_add(&my_fh->fh); 835 return 0; 836 } 837 838 int my_release(struct file *file) 839 { 840 struct v4l2_fh *fh = file->private_data; 841 struct my_fh *my_fh = container_of(fh, struct my_fh, fh); 842 843 ... 844 v4l2_fh_del(&my_fh->fh); 845 v4l2_fh_exit(&my_fh->fh); 846 kfree(my_fh); 847 return 0; 848 } 849 850 以䏿¯ v4l2_fh 彿°ä½¿ç¨çç®ä»ï¼ 851 852 void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev) 853 854 åå§åæä»¶å¥æãè¿*å¿ é¡»*å¨é©±å¨ç v4l2_file_operations->open() 855 彿°ä¸æ§è¡ã 856 857 void v4l2_fh_add(struct v4l2_fh *fh) 858 859 æ·»å ä¸ä¸ª v4l2_fh å° video_device æä»¶å¥æå表ã䏿¦æä»¶å¥æ 860 åå§åå®æå°±å¿ é¡»è°ç¨ã 861 862 void v4l2_fh_del(struct v4l2_fh *fh) 863 864 ä» video_device() ä¸è§£é¤æä»¶å¥æçå ³èãæä»¶å¥æçéåºå½æ°ä¹ 865 å°è¢«è°ç¨ã 866 867 void v4l2_fh_exit(struct v4l2_fh *fh) 868 869 æ¸ çæä»¶å¥æã卿¸ çå® v4l2_fh åï¼ç¸å ³å åä¼è¢«éæ¾ã 870 871 872 妿 v4l2_fh 䏿¯åµå ¥å¨å ¶ä»ç»æä½ä¸çï¼åå¯ä»¥ç¨è¿äºè¾ å©å½æ°ï¼ 873 874 int v4l2_fh_open(struct file *filp) 875 876 åé ä¸ä¸ª v4l2_fh ç»æä½ç©ºé´ï¼åå§åå¹¶å°å ¶æ·»å å° file ç»æä½ç¸å ³ç 877 video_device ç»æä½ä¸ã 878 879 int v4l2_fh_release(struct file *filp) 880 881 ä» file ç»æä½ç¸å ³ç video_device ç»æä½ä¸å é¤ v4l2_fh ï¼æ¸ ç 882 v4l2_fh å¹¶éæ¾ç©ºé´ã 883 884 è¿ä¸¤ä¸ªå½æ°å¯ä»¥æå ¥å° v4l2_file_operation ç open() å release() 885 æä½ä¸ã 886 887 888 æäºé©±å¨éè¦å¨ç¬¬ä¸ä¸ªæä»¶å¥ææå¼åæåä¸ä¸ªæä»¶å¥æå ³éçæ¶ååäº 889 å·¥ä½ãæä»¥å å ¥äºä¸¤ä¸ªè¾ å©å½æ°ä»¥æ£æ¥ v4l2_fh ç»æä½æ¯å¦æ¯ç¸å ³è®¾å¤ 890 èç¹æå¼çå¯ä¸æä»¶å¥æã 891 892 int v4l2_fh_is_singular(struct v4l2_fh *fh) 893 894 å¦ææ¤æä»¶å¥ææ¯å¯ä¸æå¼çæä»¶å¥æï¼åè¿å 1 ï¼å¦åè¿å 0 ã 895 896 int v4l2_fh_is_singular_file(struct file *filp) 897 898 åè½ç¸åï¼ä½éè¿ filp->private_data è°ç¨ v4l2_fh_is_singularã 899 900 901 V4L2 äºä»¶æºå¶ 902 ----------- 903 904 V4L2 äºä»¶æºå¶æä¾äºä¸ä¸ªéç¨çæ¹æ³å°äºä»¶ä¼ éå°ç¨æ·ç©ºé´ã驱å¨å¿ é¡»ä½¿ç¨ 905 v4l2_fh æè½æ¯æ V4L2 äºä»¶æºå¶ã 906 907 908 äºä»¶éè¿ä¸ä¸ªç±»ååéæ© ID æ¥å®ä¹ãID 对åºä¸ä¸ª V4L2 对象ï¼ä¾å¦ 909 ä¸ä¸ªæ§å¶ IDã妿æªä½¿ç¨ï¼å ID 为 0ã 910 911 å½ç¨æ·è®¢é ä¸ä¸ªäºä»¶ï¼é©±å¨ä¼ä¸ºæ¤åé ä¸äº kevent ç»æä½ãæä»¥æ¯ä¸ª 912 äºä»¶ç»ï¼ç±»åãIDï¼é½ä¼æèªå·±çä¸å¥ kevent ç»æä½ãè¿ä¿è¯äºå¦æ 913 ä¸ä¸ªé©±å¨çæ¶é´å 产çäºè®¸å¤åç±»äºä»¶ï¼ä¸ä¼è¦çå ¶ä»ç±»åçäºä»¶ã 914 915 ä½å¦æä½ æ¶å°çäºä»¶æ°é大äºåç±»äºä»¶ kevent çä¿åæ°éï¼åææ©ç 916 äºä»¶å°è¢«ä¸¢å¼ï¼å¹¶å å ¥æ°äºä»¶ã 917 918 æ¤å¤ï¼v4l2_subscribed_event ç»æä½å 鍿å¯ä¾é©±å¨è®¾ç½®ç merge() å 919 replace() åè°ï¼è¿äºåè°ä¼å¨æ°äºä»¶äº§ç䏿²¡æå¤ä½ç©ºé´çæ¶å被è°ç¨ã 920 replace() åè°è®©ä½ å¯ä»¥å°æ©æäºä»¶çåè·æ¿æ¢ä¸ºæ°äºä»¶çåè·ï¼å°æ©æ 921 åè·çç¸å ³æ°æ®åå¹¶å°æ¿æ¢è¿æ¥çæ°åè·ä¸ãå½è¯¥ç±»åçäºä»¶ä» åé äºä¸ä¸ª 922 kevent ç»æä½æ¶ï¼å®å°è¢«è°ç¨ãmerge() åè°è®©ä½ å¯ä»¥åå¹¶ææ©çäºä»¶åè· 923 å°å¨å®ä¹åçé£ä¸ªäºä»¶åè·ä¸ãå½è¯¥ç±»åçäºä»¶åé äºä¸¤ä¸ªææ´å¤ kevent 924 ç»æä½æ¶ï¼å®å°è¢«è°ç¨ã 925 926 è¿ç§æ¹æ³ä¸ä¼æç¶æä¿¡æ¯ä¸¢å¤±ï¼åªä¼å¯¼è´ä¸é´æ¥éª¤ä¿¡æ¯ä¸¢å¤±ã 927 928 929 å ³äº replace/merge åè°çä¸ä¸ªä¸éçä¾åå¨ v4l2-event.c ä¸ï¼ç¨äº 930 æ§å¶äºä»¶ç ctrls_replace() å ctrls_merge() åè°ã 931 932 注æï¼è¿äºåè°å¯ä»¥å¨ä¸æä¸ä¸æä¸è°ç¨ï¼æä»¥å®ä»¬å¿ é¡»å°½å¿«å®æå¹¶éåºã 933 934 æç¨ç彿°ï¼ 935 936 void v4l2_event_queue(struct video_device *vdev, const struct v4l2_event *ev) 937 938 å°äºä»¶å å ¥è§é¢è®¾å¤çéåã驱å¨ä» è´è´£å¡«å type å data åã 939 å ¶ä»åç± V4L2 å¡«å ã 940 941 int v4l2_event_subscribe(struct v4l2_fh *fh, 942 struct v4l2_event_subscription *sub, unsigned elems, 943 const struct v4l2_subscribed_event_ops *ops) 944 945 video_device->ioctl_ops->vidioc_subscribe_event å¿ é¡»æ£æµé©±å¨è½ 946 产çç¹å® id çäºä»¶ãç¶åè°ç¨ v4l2_event_subscribe() æ¥è®¢é 该äºä»¶ã 947 948 elems åæ°æ¯è¯¥äºä»¶çéå大å°ãè¥ä¸º 0ï¼V4L2 æ¡æ¶å°ä¼ï¼æ ¹æ®äºä»¶ç±»åï¼ 949 å¡«å é»è®¤å¼ã 950 951 ops åæ°å è®¸é©±å¨æå®ä¸ç³»ååè°ï¼ 952 * add: 彿·»å ä¸ä¸ªæ°çå¬è æ¶è°ç¨ï¼éå¤è®¢é åä¸ä¸ªäºä»¶ï¼æ¤åè° 953 ä» è¢«æ§è¡ä¸æ¬¡ï¼ã 954 * del: å½ä¸ä¸ªçå¬è 忢ç嬿¶è°ç¨ã 955 * replace: ç¨âæ°âäºä»¶æ¿æ¢âæ©æâäºä»¶ã 956 * merge: å°âæ©æâäºä»¶åå¹¶å°âæ°âäºä»¶ä¸ã 957 è¿å个è°ç¨é½æ¯å¯éçï¼å¦æä¸æ³æå®ä»»ä½åè°ï¼å ops å¯ä¸º NULLã 958 959 int v4l2_event_unsubscribe(struct v4l2_fh *fh, 960 struct v4l2_event_subscription *sub) 961 962 v4l2_ioctl_ops ç»æä½ä¸ç vidioc_unsubscribe_event åè°å½æ°ã 963 驱å¨ç¨åºå¯ä»¥ç´æ¥ä½¿ç¨ v4l2_event_unsubscribe() å®ç°é订äºä»¶è¿ç¨ã 964 965 ç¹æ®ç V4L2_EVENT_ALL ç±»åï¼å¯ç¨äºé订ææäºä»¶ã驱å¨å¯è½å¨ç¹æ® 966 æ åµä¸éè¦åæ¤æä½ã 967 968 int v4l2_event_pending(struct v4l2_fh *fh) 969 970 è¿åæªå³äºä»¶çæ°éãæå©äºå®ç°è½®è¯¢ï¼pollï¼æä½ã 971 972 äºä»¶éè¿ poll ç³»ç»è°ç¨ä¼ éå°ç¨æ·ç©ºé´ã驱å¨å¯ç¨ 973 v4l2_fh->wait (wait_queue_head_t ç±»å)ä½ä¸ºåæ°è°ç¨ poll_wait()ã 974 975 äºä»¶å为æ åäºä»¶åç§æäºä»¶ãæ°çæ åäºä»¶å¿ 须使ç¨å¯ç¨çæå°äºä»¶ç±»å 976 ç¼å·ã驱å¨å¿ é¡»ä»ä»ä»¬æ¬ç±»åçç¼å·èµ·å§å¤åé äºä»¶ãç±»åçç¼å·èµ·å§ä¸º 977 V4L2_EVENT_PRIVATE_START + n * 1000 ï¼å ¶ä¸ n 为å¯ç¨æå°ç¼å·ãæ¯ä¸ª 978 ç±»åä¸ç第ä¸ä¸ªäºä»¶ç±»åç¼å·æ¯ä¸ºä»¥åç使ç¨ä¿ççï¼æä»¥ç¬¬ä¸ä¸ªå¯ç¨äºä»¶ 979 ç±»åç¼å·æ¯âclass base + 1âã 980 981 V4L2 äºä»¶æºå¶ç使ç¨å®ä¾å¯ä»¥å¨ OMAP3 ISP çé©±å¨ 982 (drivers/media/video/omap3isp)䏿¾å°ã