saa7146_video.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471
  1. #include <media/saa7146_vv.h>
  2. #include <media/v4l2-chip-ident.h>
  3. static int max_memory = 32;
  4. module_param(max_memory, int, 0644);
  5. MODULE_PARM_DESC(max_memory, "maximum memory usage for capture buffers (default: 32Mb)");
  6. #define IS_CAPTURE_ACTIVE(fh) \
  7. (((vv->video_status & STATUS_CAPTURE) != 0) && (vv->video_fh == fh))
  8. #define IS_OVERLAY_ACTIVE(fh) \
  9. (((vv->video_status & STATUS_OVERLAY) != 0) && (vv->video_fh == fh))
  10. /* format descriptions for capture and preview */
  11. static struct saa7146_format formats[] = {
  12. {
  13. .name = "RGB-8 (3-3-2)",
  14. .pixelformat = V4L2_PIX_FMT_RGB332,
  15. .trans = RGB08_COMPOSED,
  16. .depth = 8,
  17. .flags = 0,
  18. }, {
  19. .name = "RGB-16 (5/B-6/G-5/R)",
  20. .pixelformat = V4L2_PIX_FMT_RGB565,
  21. .trans = RGB16_COMPOSED,
  22. .depth = 16,
  23. .flags = 0,
  24. }, {
  25. .name = "RGB-24 (B-G-R)",
  26. .pixelformat = V4L2_PIX_FMT_BGR24,
  27. .trans = RGB24_COMPOSED,
  28. .depth = 24,
  29. .flags = 0,
  30. }, {
  31. .name = "RGB-32 (B-G-R)",
  32. .pixelformat = V4L2_PIX_FMT_BGR32,
  33. .trans = RGB32_COMPOSED,
  34. .depth = 32,
  35. .flags = 0,
  36. }, {
  37. .name = "RGB-32 (R-G-B)",
  38. .pixelformat = V4L2_PIX_FMT_RGB32,
  39. .trans = RGB32_COMPOSED,
  40. .depth = 32,
  41. .flags = 0,
  42. .swap = 0x2,
  43. }, {
  44. .name = "Greyscale-8",
  45. .pixelformat = V4L2_PIX_FMT_GREY,
  46. .trans = Y8,
  47. .depth = 8,
  48. .flags = 0,
  49. }, {
  50. .name = "YUV 4:2:2 planar (Y-Cb-Cr)",
  51. .pixelformat = V4L2_PIX_FMT_YUV422P,
  52. .trans = YUV422_DECOMPOSED,
  53. .depth = 16,
  54. .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR,
  55. }, {
  56. .name = "YVU 4:2:0 planar (Y-Cb-Cr)",
  57. .pixelformat = V4L2_PIX_FMT_YVU420,
  58. .trans = YUV420_DECOMPOSED,
  59. .depth = 12,
  60. .flags = FORMAT_BYTE_SWAP|FORMAT_IS_PLANAR,
  61. }, {
  62. .name = "YUV 4:2:0 planar (Y-Cb-Cr)",
  63. .pixelformat = V4L2_PIX_FMT_YUV420,
  64. .trans = YUV420_DECOMPOSED,
  65. .depth = 12,
  66. .flags = FORMAT_IS_PLANAR,
  67. }, {
  68. .name = "YUV 4:2:2 (U-Y-V-Y)",
  69. .pixelformat = V4L2_PIX_FMT_UYVY,
  70. .trans = YUV422_COMPOSED,
  71. .depth = 16,
  72. .flags = 0,
  73. }
  74. };
  75. /* unfortunately, the saa7146 contains a bug which prevents it from doing on-the-fly byte swaps.
  76. due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped
  77. (like V4L2_PIX_FMT_YUYV) ... 8-( */
  78. static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
  79. struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc)
  80. {
  81. int i, j = NUM_FORMATS;
  82. for (i = 0; i < j; i++) {
  83. if (formats[i].pixelformat == fourcc) {
  84. return formats+i;
  85. }
  86. }
  87. DEB_D(("unknown pixelformat:'%4.4s'\n",(char *)&fourcc));
  88. return NULL;
  89. }
  90. static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f);
  91. int saa7146_start_preview(struct saa7146_fh *fh)
  92. {
  93. struct saa7146_dev *dev = fh->dev;
  94. struct saa7146_vv *vv = dev->vv_data;
  95. struct v4l2_format fmt;
  96. int ret = 0, err = 0;
  97. DEB_EE(("dev:%p, fh:%p\n",dev,fh));
  98. /* check if we have overlay informations */
  99. if( NULL == fh->ov.fh ) {
  100. DEB_D(("no overlay data available. try S_FMT first.\n"));
  101. return -EAGAIN;
  102. }
  103. /* check if streaming capture is running */
  104. if (IS_CAPTURE_ACTIVE(fh) != 0) {
  105. DEB_D(("streaming capture is active.\n"));
  106. return -EBUSY;
  107. }
  108. /* check if overlay is running */
  109. if (IS_OVERLAY_ACTIVE(fh) != 0) {
  110. if (vv->video_fh == fh) {
  111. DEB_D(("overlay is already active.\n"));
  112. return 0;
  113. }
  114. DEB_D(("overlay is already active in another open.\n"));
  115. return -EBUSY;
  116. }
  117. if (0 == saa7146_res_get(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP)) {
  118. DEB_D(("cannot get necessary overlay resources\n"));
  119. return -EBUSY;
  120. }
  121. fmt.fmt.win = fh->ov.win;
  122. err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt);
  123. if (0 != err) {
  124. saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
  125. return -EBUSY;
  126. }
  127. fh->ov.win = fmt.fmt.win;
  128. vv->ov_data = &fh->ov;
  129. DEB_D(("%dx%d+%d+%d %s field=%s\n",
  130. fh->ov.win.w.width,fh->ov.win.w.height,
  131. fh->ov.win.w.left,fh->ov.win.w.top,
  132. vv->ov_fmt->name,v4l2_field_names[fh->ov.win.field]));
  133. if (0 != (ret = saa7146_enable_overlay(fh))) {
  134. DEB_D(("enabling overlay failed: %d\n",ret));
  135. saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
  136. return ret;
  137. }
  138. vv->video_status = STATUS_OVERLAY;
  139. vv->video_fh = fh;
  140. return 0;
  141. }
  142. EXPORT_SYMBOL_GPL(saa7146_start_preview);
  143. int saa7146_stop_preview(struct saa7146_fh *fh)
  144. {
  145. struct saa7146_dev *dev = fh->dev;
  146. struct saa7146_vv *vv = dev->vv_data;
  147. DEB_EE(("dev:%p, fh:%p\n",dev,fh));
  148. /* check if streaming capture is running */
  149. if (IS_CAPTURE_ACTIVE(fh) != 0) {
  150. DEB_D(("streaming capture is active.\n"));
  151. return -EBUSY;
  152. }
  153. /* check if overlay is running at all */
  154. if ((vv->video_status & STATUS_OVERLAY) == 0) {
  155. DEB_D(("no active overlay.\n"));
  156. return 0;
  157. }
  158. if (vv->video_fh != fh) {
  159. DEB_D(("overlay is active, but in another open.\n"));
  160. return -EBUSY;
  161. }
  162. vv->video_status = 0;
  163. vv->video_fh = NULL;
  164. saa7146_disable_overlay(fh);
  165. saa7146_res_free(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
  166. return 0;
  167. }
  168. EXPORT_SYMBOL_GPL(saa7146_stop_preview);
  169. /********************************************************************************/
  170. /* device controls */
  171. static struct v4l2_queryctrl controls[] = {
  172. {
  173. .id = V4L2_CID_BRIGHTNESS,
  174. .name = "Brightness",
  175. .minimum = 0,
  176. .maximum = 255,
  177. .step = 1,
  178. .default_value = 128,
  179. .type = V4L2_CTRL_TYPE_INTEGER,
  180. .flags = V4L2_CTRL_FLAG_SLIDER,
  181. },{
  182. .id = V4L2_CID_CONTRAST,
  183. .name = "Contrast",
  184. .minimum = 0,
  185. .maximum = 127,
  186. .step = 1,
  187. .default_value = 64,
  188. .type = V4L2_CTRL_TYPE_INTEGER,
  189. .flags = V4L2_CTRL_FLAG_SLIDER,
  190. },{
  191. .id = V4L2_CID_SATURATION,
  192. .name = "Saturation",
  193. .minimum = 0,
  194. .maximum = 127,
  195. .step = 1,
  196. .default_value = 64,
  197. .type = V4L2_CTRL_TYPE_INTEGER,
  198. .flags = V4L2_CTRL_FLAG_SLIDER,
  199. },{
  200. .id = V4L2_CID_VFLIP,
  201. .name = "Vertical Flip",
  202. .minimum = 0,
  203. .maximum = 1,
  204. .type = V4L2_CTRL_TYPE_BOOLEAN,
  205. },{
  206. .id = V4L2_CID_HFLIP,
  207. .name = "Horizontal Flip",
  208. .minimum = 0,
  209. .maximum = 1,
  210. .type = V4L2_CTRL_TYPE_BOOLEAN,
  211. },
  212. };
  213. static int NUM_CONTROLS = sizeof(controls)/sizeof(struct v4l2_queryctrl);
  214. #define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 0)
  215. static struct v4l2_queryctrl* ctrl_by_id(int id)
  216. {
  217. int i;
  218. for (i = 0; i < NUM_CONTROLS; i++)
  219. if (controls[i].id == id)
  220. return controls+i;
  221. return NULL;
  222. }
  223. /********************************************************************************/
  224. /* common pagetable functions */
  225. static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf)
  226. {
  227. struct pci_dev *pci = dev->pci;
  228. struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
  229. struct scatterlist *list = dma->sglist;
  230. int length = dma->sglen;
  231. struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
  232. DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length));
  233. if( 0 != IS_PLANAR(sfmt->trans)) {
  234. struct saa7146_pgtable *pt1 = &buf->pt[0];
  235. struct saa7146_pgtable *pt2 = &buf->pt[1];
  236. struct saa7146_pgtable *pt3 = &buf->pt[2];
  237. __le32 *ptr1, *ptr2, *ptr3;
  238. __le32 fill;
  239. int size = buf->fmt->width*buf->fmt->height;
  240. int i,p,m1,m2,m3,o1,o2;
  241. switch( sfmt->depth ) {
  242. case 12: {
  243. /* create some offsets inside the page table */
  244. m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1;
  245. m2 = ((size+(size/4)+PAGE_SIZE)/PAGE_SIZE)-1;
  246. m3 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
  247. o1 = size%PAGE_SIZE;
  248. o2 = (size+(size/4))%PAGE_SIZE;
  249. DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2));
  250. break;
  251. }
  252. case 16: {
  253. /* create some offsets inside the page table */
  254. m1 = ((size+PAGE_SIZE)/PAGE_SIZE)-1;
  255. m2 = ((size+(size/2)+PAGE_SIZE)/PAGE_SIZE)-1;
  256. m3 = ((2*size+PAGE_SIZE)/PAGE_SIZE)-1;
  257. o1 = size%PAGE_SIZE;
  258. o2 = (size+(size/2))%PAGE_SIZE;
  259. DEB_CAP(("size:%d, m1:%d, m2:%d, m3:%d, o1:%d, o2:%d\n",size,m1,m2,m3,o1,o2));
  260. break;
  261. }
  262. default: {
  263. return -1;
  264. }
  265. }
  266. ptr1 = pt1->cpu;
  267. ptr2 = pt2->cpu;
  268. ptr3 = pt3->cpu;
  269. /* walk all pages, copy all page addresses to ptr1 */
  270. for (i = 0; i < length; i++, list++) {
  271. for (p = 0; p * 4096 < list->length; p++, ptr1++) {
  272. *ptr1 = cpu_to_le32(sg_dma_address(list) - list->offset);
  273. }
  274. }
  275. /*
  276. ptr1 = pt1->cpu;
  277. for(j=0;j<40;j++) {
  278. printk("ptr1 %d: 0x%08x\n",j,ptr1[j]);
  279. }
  280. */
  281. /* if we have a user buffer, the first page may not be
  282. aligned to a page boundary. */
  283. pt1->offset = dma->sglist->offset;
  284. pt2->offset = pt1->offset+o1;
  285. pt3->offset = pt1->offset+o2;
  286. /* create video-dma2 page table */
  287. ptr1 = pt1->cpu;
  288. for(i = m1; i <= m2 ; i++, ptr2++) {
  289. *ptr2 = ptr1[i];
  290. }
  291. fill = *(ptr2-1);
  292. for(;i<1024;i++,ptr2++) {
  293. *ptr2 = fill;
  294. }
  295. /* create video-dma3 page table */
  296. ptr1 = pt1->cpu;
  297. for(i = m2; i <= m3; i++,ptr3++) {
  298. *ptr3 = ptr1[i];
  299. }
  300. fill = *(ptr3-1);
  301. for(;i<1024;i++,ptr3++) {
  302. *ptr3 = fill;
  303. }
  304. /* finally: finish up video-dma1 page table */
  305. ptr1 = pt1->cpu+m1;
  306. fill = pt1->cpu[m1];
  307. for(i=m1;i<1024;i++,ptr1++) {
  308. *ptr1 = fill;
  309. }
  310. /*
  311. ptr1 = pt1->cpu;
  312. ptr2 = pt2->cpu;
  313. ptr3 = pt3->cpu;
  314. for(j=0;j<40;j++) {
  315. printk("ptr1 %d: 0x%08x\n",j,ptr1[j]);
  316. }
  317. for(j=0;j<40;j++) {
  318. printk("ptr2 %d: 0x%08x\n",j,ptr2[j]);
  319. }
  320. for(j=0;j<40;j++) {
  321. printk("ptr3 %d: 0x%08x\n",j,ptr3[j]);
  322. }
  323. */
  324. } else {
  325. struct saa7146_pgtable *pt = &buf->pt[0];
  326. return saa7146_pgtable_build_single(pci, pt, list, length);
  327. }
  328. return 0;
  329. }
  330. /********************************************************************************/
  331. /* file operations */
  332. static int video_begin(struct saa7146_fh *fh)
  333. {
  334. struct saa7146_dev *dev = fh->dev;
  335. struct saa7146_vv *vv = dev->vv_data;
  336. struct saa7146_format *fmt = NULL;
  337. unsigned int resource;
  338. int ret = 0, err = 0;
  339. DEB_EE(("dev:%p, fh:%p\n",dev,fh));
  340. if ((vv->video_status & STATUS_CAPTURE) != 0) {
  341. if (vv->video_fh == fh) {
  342. DEB_S(("already capturing.\n"));
  343. return 0;
  344. }
  345. DEB_S(("already capturing in another open.\n"));
  346. return -EBUSY;
  347. }
  348. if ((vv->video_status & STATUS_OVERLAY) != 0) {
  349. DEB_S(("warning: suspending overlay video for streaming capture.\n"));
  350. vv->ov_suspend = vv->video_fh;
  351. err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
  352. if (0 != err) {
  353. DEB_D(("suspending video failed. aborting\n"));
  354. return err;
  355. }
  356. }
  357. fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
  358. /* we need to have a valid format set here */
  359. BUG_ON(NULL == fmt);
  360. if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
  361. resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
  362. } else {
  363. resource = RESOURCE_DMA1_HPS;
  364. }
  365. ret = saa7146_res_get(fh, resource);
  366. if (0 == ret) {
  367. DEB_S(("cannot get capture resource %d\n",resource));
  368. if (vv->ov_suspend != NULL) {
  369. saa7146_start_preview(vv->ov_suspend);
  370. vv->ov_suspend = NULL;
  371. }
  372. return -EBUSY;
  373. }
  374. /* clear out beginning of streaming bit (rps register 0)*/
  375. saa7146_write(dev, MC2, MASK_27 );
  376. /* enable rps0 irqs */
  377. SAA7146_IER_ENABLE(dev, MASK_27);
  378. vv->video_fh = fh;
  379. vv->video_status = STATUS_CAPTURE;
  380. return 0;
  381. }
  382. static int video_end(struct saa7146_fh *fh, struct file *file)
  383. {
  384. struct saa7146_dev *dev = fh->dev;
  385. struct saa7146_vv *vv = dev->vv_data;
  386. struct saa7146_format *fmt = NULL;
  387. unsigned long flags;
  388. unsigned int resource;
  389. u32 dmas = 0;
  390. DEB_EE(("dev:%p, fh:%p\n",dev,fh));
  391. if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
  392. DEB_S(("not capturing.\n"));
  393. return 0;
  394. }
  395. if (vv->video_fh != fh) {
  396. DEB_S(("capturing, but in another open.\n"));
  397. return -EBUSY;
  398. }
  399. fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
  400. /* we need to have a valid format set here */
  401. BUG_ON(NULL == fmt);
  402. if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
  403. resource = RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP|RESOURCE_DMA3_BRS;
  404. dmas = MASK_22 | MASK_21 | MASK_20;
  405. } else {
  406. resource = RESOURCE_DMA1_HPS;
  407. dmas = MASK_22;
  408. }
  409. spin_lock_irqsave(&dev->slock,flags);
  410. /* disable rps0 */
  411. saa7146_write(dev, MC1, MASK_28);
  412. /* disable rps0 irqs */
  413. SAA7146_IER_DISABLE(dev, MASK_27);
  414. /* shut down all used video dma transfers */
  415. saa7146_write(dev, MC1, dmas);
  416. spin_unlock_irqrestore(&dev->slock, flags);
  417. vv->video_fh = NULL;
  418. vv->video_status = 0;
  419. saa7146_res_free(fh, resource);
  420. if (vv->ov_suspend != NULL) {
  421. saa7146_start_preview(vv->ov_suspend);
  422. vv->ov_suspend = NULL;
  423. }
  424. return 0;
  425. }
  426. static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
  427. {
  428. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  429. strcpy((char *)cap->driver, "saa7146 v4l2");
  430. strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
  431. sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
  432. cap->version = SAA7146_VERSION_CODE;
  433. cap->capabilities =
  434. V4L2_CAP_VIDEO_CAPTURE |
  435. V4L2_CAP_VIDEO_OVERLAY |
  436. V4L2_CAP_READWRITE |
  437. V4L2_CAP_STREAMING;
  438. cap->capabilities |= dev->ext_vv_data->capabilities;
  439. return 0;
  440. }
  441. static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
  442. {
  443. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  444. struct saa7146_vv *vv = dev->vv_data;
  445. *fb = vv->ov_fb;
  446. fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
  447. return 0;
  448. }
  449. static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
  450. {
  451. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  452. struct saa7146_vv *vv = dev->vv_data;
  453. struct saa7146_format *fmt;
  454. DEB_EE(("VIDIOC_S_FBUF\n"));
  455. if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
  456. return -EPERM;
  457. /* check args */
  458. fmt = format_by_fourcc(dev, fb->fmt.pixelformat);
  459. if (NULL == fmt)
  460. return -EINVAL;
  461. /* planar formats are not allowed for overlay video, clipping and video dma would clash */
  462. if (fmt->flags & FORMAT_IS_PLANAR)
  463. DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",
  464. (char *)&fmt->pixelformat));
  465. /* check if overlay is running */
  466. if (IS_OVERLAY_ACTIVE(fh) != 0) {
  467. if (vv->video_fh != fh) {
  468. DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n"));
  469. return -EBUSY;
  470. }
  471. }
  472. mutex_lock(&dev->lock);
  473. /* ok, accept it */
  474. vv->ov_fb = *fb;
  475. vv->ov_fmt = fmt;
  476. if (0 == vv->ov_fb.fmt.bytesperline)
  477. vv->ov_fb.fmt.bytesperline =
  478. vv->ov_fb.fmt.width * fmt->depth / 8;
  479. mutex_unlock(&dev->lock);
  480. return 0;
  481. }
  482. static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
  483. {
  484. if (f->index >= NUM_FORMATS)
  485. return -EINVAL;
  486. strlcpy((char *)f->description, formats[f->index].name,
  487. sizeof(f->description));
  488. f->pixelformat = formats[f->index].pixelformat;
  489. return 0;
  490. }
  491. static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
  492. {
  493. const struct v4l2_queryctrl *ctrl;
  494. if ((c->id < V4L2_CID_BASE ||
  495. c->id >= V4L2_CID_LASTP1) &&
  496. (c->id < V4L2_CID_PRIVATE_BASE ||
  497. c->id >= V4L2_CID_PRIVATE_LASTP1))
  498. return -EINVAL;
  499. ctrl = ctrl_by_id(c->id);
  500. if (ctrl == NULL)
  501. return -EINVAL;
  502. DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n", c->id));
  503. *c = *ctrl;
  504. return 0;
  505. }
  506. static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
  507. {
  508. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  509. struct saa7146_vv *vv = dev->vv_data;
  510. const struct v4l2_queryctrl *ctrl;
  511. u32 value = 0;
  512. ctrl = ctrl_by_id(c->id);
  513. if (NULL == ctrl)
  514. return -EINVAL;
  515. switch (c->id) {
  516. case V4L2_CID_BRIGHTNESS:
  517. value = saa7146_read(dev, BCS_CTRL);
  518. c->value = 0xff & (value >> 24);
  519. DEB_D(("V4L2_CID_BRIGHTNESS: %d\n", c->value));
  520. break;
  521. case V4L2_CID_CONTRAST:
  522. value = saa7146_read(dev, BCS_CTRL);
  523. c->value = 0x7f & (value >> 16);
  524. DEB_D(("V4L2_CID_CONTRAST: %d\n", c->value));
  525. break;
  526. case V4L2_CID_SATURATION:
  527. value = saa7146_read(dev, BCS_CTRL);
  528. c->value = 0x7f & (value >> 0);
  529. DEB_D(("V4L2_CID_SATURATION: %d\n", c->value));
  530. break;
  531. case V4L2_CID_VFLIP:
  532. c->value = vv->vflip;
  533. DEB_D(("V4L2_CID_VFLIP: %d\n", c->value));
  534. break;
  535. case V4L2_CID_HFLIP:
  536. c->value = vv->hflip;
  537. DEB_D(("V4L2_CID_HFLIP: %d\n", c->value));
  538. break;
  539. default:
  540. return -EINVAL;
  541. }
  542. return 0;
  543. }
  544. static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
  545. {
  546. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  547. struct saa7146_vv *vv = dev->vv_data;
  548. const struct v4l2_queryctrl *ctrl;
  549. ctrl = ctrl_by_id(c->id);
  550. if (NULL == ctrl) {
  551. DEB_D(("unknown control %d\n", c->id));
  552. return -EINVAL;
  553. }
  554. mutex_lock(&dev->lock);
  555. switch (ctrl->type) {
  556. case V4L2_CTRL_TYPE_BOOLEAN:
  557. case V4L2_CTRL_TYPE_MENU:
  558. case V4L2_CTRL_TYPE_INTEGER:
  559. if (c->value < ctrl->minimum)
  560. c->value = ctrl->minimum;
  561. if (c->value > ctrl->maximum)
  562. c->value = ctrl->maximum;
  563. break;
  564. default:
  565. /* nothing */;
  566. }
  567. switch (c->id) {
  568. case V4L2_CID_BRIGHTNESS: {
  569. u32 value = saa7146_read(dev, BCS_CTRL);
  570. value &= 0x00ffffff;
  571. value |= (c->value << 24);
  572. saa7146_write(dev, BCS_CTRL, value);
  573. saa7146_write(dev, MC2, MASK_22 | MASK_06);
  574. break;
  575. }
  576. case V4L2_CID_CONTRAST: {
  577. u32 value = saa7146_read(dev, BCS_CTRL);
  578. value &= 0xff00ffff;
  579. value |= (c->value << 16);
  580. saa7146_write(dev, BCS_CTRL, value);
  581. saa7146_write(dev, MC2, MASK_22 | MASK_06);
  582. break;
  583. }
  584. case V4L2_CID_SATURATION: {
  585. u32 value = saa7146_read(dev, BCS_CTRL);
  586. value &= 0xffffff00;
  587. value |= (c->value << 0);
  588. saa7146_write(dev, BCS_CTRL, value);
  589. saa7146_write(dev, MC2, MASK_22 | MASK_06);
  590. break;
  591. }
  592. case V4L2_CID_HFLIP:
  593. /* fixme: we can support changing VFLIP and HFLIP here... */
  594. if (IS_CAPTURE_ACTIVE(fh) != 0) {
  595. DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
  596. mutex_unlock(&dev->lock);
  597. return -EBUSY;
  598. }
  599. vv->hflip = c->value;
  600. break;
  601. case V4L2_CID_VFLIP:
  602. if (IS_CAPTURE_ACTIVE(fh) != 0) {
  603. DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
  604. mutex_unlock(&dev->lock);
  605. return -EBUSY;
  606. }
  607. vv->vflip = c->value;
  608. break;
  609. default:
  610. mutex_unlock(&dev->lock);
  611. return -EINVAL;
  612. }
  613. mutex_unlock(&dev->lock);
  614. if (IS_OVERLAY_ACTIVE(fh) != 0) {
  615. saa7146_stop_preview(fh);
  616. saa7146_start_preview(fh);
  617. }
  618. return 0;
  619. }
  620. static int vidioc_g_parm(struct file *file, void *fh,
  621. struct v4l2_streamparm *parm)
  622. {
  623. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  624. struct saa7146_vv *vv = dev->vv_data;
  625. parm->parm.capture.readbuffers = 1;
  626. v4l2_video_std_frame_period(vv->standard->id,
  627. &parm->parm.capture.timeperframe);
  628. return 0;
  629. }
  630. static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
  631. {
  632. f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt;
  633. return 0;
  634. }
  635. static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
  636. {
  637. f->fmt.win = ((struct saa7146_fh *)fh)->ov.win;
  638. return 0;
  639. }
  640. static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f)
  641. {
  642. f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt;
  643. return 0;
  644. }
  645. static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
  646. {
  647. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  648. struct saa7146_vv *vv = dev->vv_data;
  649. struct saa7146_format *fmt;
  650. enum v4l2_field field;
  651. int maxw, maxh;
  652. int calc_bpl;
  653. DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
  654. fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat);
  655. if (NULL == fmt)
  656. return -EINVAL;
  657. field = f->fmt.pix.field;
  658. maxw = vv->standard->h_max_out;
  659. maxh = vv->standard->v_max_out;
  660. if (V4L2_FIELD_ANY == field) {
  661. field = (f->fmt.pix.height > maxh / 2)
  662. ? V4L2_FIELD_INTERLACED
  663. : V4L2_FIELD_BOTTOM;
  664. }
  665. switch (field) {
  666. case V4L2_FIELD_ALTERNATE:
  667. vv->last_field = V4L2_FIELD_TOP;
  668. maxh = maxh / 2;
  669. break;
  670. case V4L2_FIELD_TOP:
  671. case V4L2_FIELD_BOTTOM:
  672. vv->last_field = V4L2_FIELD_INTERLACED;
  673. maxh = maxh / 2;
  674. break;
  675. case V4L2_FIELD_INTERLACED:
  676. vv->last_field = V4L2_FIELD_INTERLACED;
  677. break;
  678. default:
  679. DEB_D(("no known field mode '%d'.\n", field));
  680. return -EINVAL;
  681. }
  682. f->fmt.pix.field = field;
  683. if (f->fmt.pix.width > maxw)
  684. f->fmt.pix.width = maxw;
  685. if (f->fmt.pix.height > maxh)
  686. f->fmt.pix.height = maxh;
  687. calc_bpl = (f->fmt.pix.width * fmt->depth) / 8;
  688. if (f->fmt.pix.bytesperline < calc_bpl)
  689. f->fmt.pix.bytesperline = calc_bpl;
  690. if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */
  691. f->fmt.pix.bytesperline = calc_bpl;
  692. f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
  693. DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", f->fmt.pix.width,
  694. f->fmt.pix.height, f->fmt.pix.bytesperline, f->fmt.pix.sizeimage));
  695. return 0;
  696. }
  697. static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
  698. {
  699. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  700. struct saa7146_vv *vv = dev->vv_data;
  701. struct v4l2_window *win = &f->fmt.win;
  702. enum v4l2_field field;
  703. int maxw, maxh;
  704. DEB_EE(("dev:%p\n", dev));
  705. if (NULL == vv->ov_fb.base) {
  706. DEB_D(("no fb base set.\n"));
  707. return -EINVAL;
  708. }
  709. if (NULL == vv->ov_fmt) {
  710. DEB_D(("no fb fmt set.\n"));
  711. return -EINVAL;
  712. }
  713. if (win->w.width < 48 || win->w.height < 32) {
  714. DEB_D(("min width/height. (%d,%d)\n", win->w.width, win->w.height));
  715. return -EINVAL;
  716. }
  717. if (win->clipcount > 16) {
  718. DEB_D(("clipcount too big.\n"));
  719. return -EINVAL;
  720. }
  721. field = win->field;
  722. maxw = vv->standard->h_max_out;
  723. maxh = vv->standard->v_max_out;
  724. if (V4L2_FIELD_ANY == field) {
  725. field = (win->w.height > maxh / 2)
  726. ? V4L2_FIELD_INTERLACED
  727. : V4L2_FIELD_TOP;
  728. }
  729. switch (field) {
  730. case V4L2_FIELD_TOP:
  731. case V4L2_FIELD_BOTTOM:
  732. case V4L2_FIELD_ALTERNATE:
  733. maxh = maxh / 2;
  734. break;
  735. case V4L2_FIELD_INTERLACED:
  736. break;
  737. default:
  738. DEB_D(("no known field mode '%d'.\n", field));
  739. return -EINVAL;
  740. }
  741. win->field = field;
  742. if (win->w.width > maxw)
  743. win->w.width = maxw;
  744. if (win->w.height > maxh)
  745. win->w.height = maxh;
  746. return 0;
  747. }
  748. static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f)
  749. {
  750. struct saa7146_fh *fh = __fh;
  751. struct saa7146_dev *dev = fh->dev;
  752. struct saa7146_vv *vv = dev->vv_data;
  753. int err;
  754. DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
  755. if (IS_CAPTURE_ACTIVE(fh) != 0) {
  756. DEB_EE(("streaming capture is active\n"));
  757. return -EBUSY;
  758. }
  759. err = vidioc_try_fmt_vid_cap(file, fh, f);
  760. if (0 != err)
  761. return err;
  762. fh->video_fmt = f->fmt.pix;
  763. DEB_EE(("set to pixelformat '%4.4s'\n", (char *)&fh->video_fmt.pixelformat));
  764. return 0;
  765. }
  766. static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f)
  767. {
  768. struct saa7146_fh *fh = __fh;
  769. struct saa7146_dev *dev = fh->dev;
  770. struct saa7146_vv *vv = dev->vv_data;
  771. int err;
  772. DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh));
  773. err = vidioc_try_fmt_vid_overlay(file, fh, f);
  774. if (0 != err)
  775. return err;
  776. mutex_lock(&dev->lock);
  777. fh->ov.win = f->fmt.win;
  778. fh->ov.nclips = f->fmt.win.clipcount;
  779. if (fh->ov.nclips > 16)
  780. fh->ov.nclips = 16;
  781. if (copy_from_user(fh->ov.clips, f->fmt.win.clips,
  782. sizeof(struct v4l2_clip) * fh->ov.nclips)) {
  783. mutex_unlock(&dev->lock);
  784. return -EFAULT;
  785. }
  786. /* fh->ov.fh is used to indicate that we have valid overlay informations, too */
  787. fh->ov.fh = fh;
  788. mutex_unlock(&dev->lock);
  789. /* check if our current overlay is active */
  790. if (IS_OVERLAY_ACTIVE(fh) != 0) {
  791. saa7146_stop_preview(fh);
  792. saa7146_start_preview(fh);
  793. }
  794. return 0;
  795. }
  796. static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm)
  797. {
  798. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  799. struct saa7146_vv *vv = dev->vv_data;
  800. *norm = vv->standard->id;
  801. return 0;
  802. }
  803. /* the saa7146 supfhrts (used in conjunction with the saa7111a for example)
  804. PAL / NTSC / SECAM. if your hardware does not (or does more)
  805. -- override this function in your extension */
  806. /*
  807. case VIDIOC_ENUMSTD:
  808. {
  809. struct v4l2_standard *e = arg;
  810. if (e->index < 0 )
  811. return -EINVAL;
  812. if( e->index < dev->ext_vv_data->num_stds ) {
  813. DEB_EE(("VIDIOC_ENUMSTD: index:%d\n",e->index));
  814. v4l2_video_std_construct(e, dev->ext_vv_data->stds[e->index].id, dev->ext_vv_data->stds[e->index].name);
  815. return 0;
  816. }
  817. return -EINVAL;
  818. }
  819. */
  820. static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
  821. {
  822. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  823. struct saa7146_vv *vv = dev->vv_data;
  824. int found = 0;
  825. int err, i;
  826. DEB_EE(("VIDIOC_S_STD\n"));
  827. if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
  828. DEB_D(("cannot change video standard while streaming capture is active\n"));
  829. return -EBUSY;
  830. }
  831. if ((vv->video_status & STATUS_OVERLAY) != 0) {
  832. vv->ov_suspend = vv->video_fh;
  833. err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
  834. if (0 != err) {
  835. DEB_D(("suspending video failed. aborting\n"));
  836. return err;
  837. }
  838. }
  839. mutex_lock(&dev->lock);
  840. for (i = 0; i < dev->ext_vv_data->num_stds; i++)
  841. if (*id & dev->ext_vv_data->stds[i].id)
  842. break;
  843. if (i != dev->ext_vv_data->num_stds) {
  844. vv->standard = &dev->ext_vv_data->stds[i];
  845. if (NULL != dev->ext_vv_data->std_callback)
  846. dev->ext_vv_data->std_callback(dev, vv->standard);
  847. found = 1;
  848. }
  849. mutex_unlock(&dev->lock);
  850. if (vv->ov_suspend != NULL) {
  851. saa7146_start_preview(vv->ov_suspend);
  852. vv->ov_suspend = NULL;
  853. }
  854. if (!found) {
  855. DEB_EE(("VIDIOC_S_STD: standard not found.\n"));
  856. return -EINVAL;
  857. }
  858. DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name));
  859. return 0;
  860. }
  861. static int vidioc_overlay(struct file *file, void *fh, unsigned int on)
  862. {
  863. int err;
  864. DEB_D(("VIDIOC_OVERLAY on:%d\n", on));
  865. if (on)
  866. err = saa7146_start_preview(fh);
  867. else
  868. err = saa7146_stop_preview(fh);
  869. return err;
  870. }
  871. static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b)
  872. {
  873. struct saa7146_fh *fh = __fh;
  874. if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
  875. return videobuf_reqbufs(&fh->video_q, b);
  876. if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE)
  877. return videobuf_reqbufs(&fh->vbi_q, b);
  878. return -EINVAL;
  879. }
  880. static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
  881. {
  882. struct saa7146_fh *fh = __fh;
  883. if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
  884. return videobuf_querybuf(&fh->video_q, buf);
  885. if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
  886. return videobuf_querybuf(&fh->vbi_q, buf);
  887. return -EINVAL;
  888. }
  889. static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
  890. {
  891. struct saa7146_fh *fh = __fh;
  892. if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
  893. return videobuf_qbuf(&fh->video_q, buf);
  894. if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
  895. return videobuf_qbuf(&fh->vbi_q, buf);
  896. return -EINVAL;
  897. }
  898. static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
  899. {
  900. struct saa7146_fh *fh = __fh;
  901. if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
  902. return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK);
  903. if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
  904. return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK);
  905. return -EINVAL;
  906. }
  907. static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
  908. {
  909. struct saa7146_fh *fh = __fh;
  910. int err;
  911. DEB_D(("VIDIOC_STREAMON, type:%d\n", type));
  912. err = video_begin(fh);
  913. if (err)
  914. return err;
  915. if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
  916. return videobuf_streamon(&fh->video_q);
  917. if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
  918. return videobuf_streamon(&fh->vbi_q);
  919. return -EINVAL;
  920. }
  921. static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
  922. {
  923. struct saa7146_fh *fh = __fh;
  924. struct saa7146_dev *dev = fh->dev;
  925. struct saa7146_vv *vv = dev->vv_data;
  926. int err;
  927. DEB_D(("VIDIOC_STREAMOFF, type:%d\n", type));
  928. /* ugly: we need to copy some checks from video_end(),
  929. because videobuf_streamoff() relies on the capture running.
  930. check and fix this */
  931. if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
  932. DEB_S(("not capturing.\n"));
  933. return 0;
  934. }
  935. if (vv->video_fh != fh) {
  936. DEB_S(("capturing, but in another open.\n"));
  937. return -EBUSY;
  938. }
  939. err = -EINVAL;
  940. if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
  941. err = videobuf_streamoff(&fh->video_q);
  942. else if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
  943. err = videobuf_streamoff(&fh->vbi_q);
  944. if (0 != err) {
  945. DEB_D(("warning: videobuf_streamoff() failed.\n"));
  946. video_end(fh, file);
  947. } else {
  948. err = video_end(fh, file);
  949. }
  950. return err;
  951. }
  952. static int vidioc_g_chip_ident(struct file *file, void *__fh,
  953. struct v4l2_dbg_chip_ident *chip)
  954. {
  955. struct saa7146_fh *fh = __fh;
  956. struct saa7146_dev *dev = fh->dev;
  957. chip->ident = V4L2_IDENT_NONE;
  958. chip->revision = 0;
  959. if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) {
  960. chip->ident = V4L2_IDENT_SAA7146;
  961. return 0;
  962. }
  963. return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
  964. core, g_chip_ident, chip);
  965. }
  966. #ifdef CONFIG_VIDEO_V4L1_COMPAT
  967. static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf)
  968. {
  969. struct saa7146_fh *fh = __fh;
  970. struct videobuf_queue *q = &fh->video_q;
  971. int err, i;
  972. /* fixme: number of capture buffers and sizes for v4l apps */
  973. int gbuffers = 2;
  974. int gbufsize = 768 * 576 * 4;
  975. DEB_D(("VIDIOCGMBUF \n"));
  976. q = &fh->video_q;
  977. err = videobuf_mmap_setup(q, gbuffers, gbufsize,
  978. V4L2_MEMORY_MMAP);
  979. if (err < 0)
  980. return err;
  981. gbuffers = err;
  982. memset(mbuf, 0, sizeof(*mbuf));
  983. mbuf->frames = gbuffers;
  984. mbuf->size = gbuffers * gbufsize;
  985. for (i = 0; i < gbuffers; i++)
  986. mbuf->offsets[i] = i * gbufsize;
  987. return 0;
  988. }
  989. #endif
  990. const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
  991. .vidioc_querycap = vidioc_querycap,
  992. .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
  993. .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap,
  994. .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
  995. .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
  996. .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
  997. .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
  998. .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
  999. .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
  1000. .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
  1001. .vidioc_g_chip_ident = vidioc_g_chip_ident,
  1002. .vidioc_overlay = vidioc_overlay,
  1003. .vidioc_g_fbuf = vidioc_g_fbuf,
  1004. .vidioc_s_fbuf = vidioc_s_fbuf,
  1005. .vidioc_reqbufs = vidioc_reqbufs,
  1006. .vidioc_querybuf = vidioc_querybuf,
  1007. .vidioc_qbuf = vidioc_qbuf,
  1008. .vidioc_dqbuf = vidioc_dqbuf,
  1009. .vidioc_g_std = vidioc_g_std,
  1010. .vidioc_s_std = vidioc_s_std,
  1011. .vidioc_queryctrl = vidioc_queryctrl,
  1012. .vidioc_g_ctrl = vidioc_g_ctrl,
  1013. .vidioc_s_ctrl = vidioc_s_ctrl,
  1014. .vidioc_streamon = vidioc_streamon,
  1015. .vidioc_streamoff = vidioc_streamoff,
  1016. .vidioc_g_parm = vidioc_g_parm,
  1017. #ifdef CONFIG_VIDEO_V4L1_COMPAT
  1018. .vidiocgmbuf = vidiocgmbuf,
  1019. #endif
  1020. };
  1021. /*********************************************************************************/
  1022. /* buffer handling functions */
  1023. static int buffer_activate (struct saa7146_dev *dev,
  1024. struct saa7146_buf *buf,
  1025. struct saa7146_buf *next)
  1026. {
  1027. struct saa7146_vv *vv = dev->vv_data;
  1028. buf->vb.state = VIDEOBUF_ACTIVE;
  1029. saa7146_set_capture(dev,buf,next);
  1030. mod_timer(&vv->video_q.timeout, jiffies+BUFFER_TIMEOUT);
  1031. return 0;
  1032. }
  1033. static int buffer_prepare(struct videobuf_queue *q,
  1034. struct videobuf_buffer *vb, enum v4l2_field field)
  1035. {
  1036. struct file *file = q->priv_data;
  1037. struct saa7146_fh *fh = file->private_data;
  1038. struct saa7146_dev *dev = fh->dev;
  1039. struct saa7146_vv *vv = dev->vv_data;
  1040. struct saa7146_buf *buf = (struct saa7146_buf *)vb;
  1041. int size,err = 0;
  1042. DEB_CAP(("vbuf:%p\n",vb));
  1043. /* sanity checks */
  1044. if (fh->video_fmt.width < 48 ||
  1045. fh->video_fmt.height < 32 ||
  1046. fh->video_fmt.width > vv->standard->h_max_out ||
  1047. fh->video_fmt.height > vv->standard->v_max_out) {
  1048. DEB_D(("w (%d) / h (%d) out of bounds.\n",fh->video_fmt.width,fh->video_fmt.height));
  1049. return -EINVAL;
  1050. }
  1051. size = fh->video_fmt.sizeimage;
  1052. if (0 != buf->vb.baddr && buf->vb.bsize < size) {
  1053. DEB_D(("size mismatch.\n"));
  1054. return -EINVAL;
  1055. }
  1056. DEB_CAP(("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
  1057. fh->video_fmt.width,fh->video_fmt.height,size,v4l2_field_names[fh->video_fmt.field]));
  1058. if (buf->vb.width != fh->video_fmt.width ||
  1059. buf->vb.bytesperline != fh->video_fmt.bytesperline ||
  1060. buf->vb.height != fh->video_fmt.height ||
  1061. buf->vb.size != size ||
  1062. buf->vb.field != field ||
  1063. buf->vb.field != fh->video_fmt.field ||
  1064. buf->fmt != &fh->video_fmt) {
  1065. saa7146_dma_free(dev,q,buf);
  1066. }
  1067. if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
  1068. struct saa7146_format *sfmt;
  1069. buf->vb.bytesperline = fh->video_fmt.bytesperline;
  1070. buf->vb.width = fh->video_fmt.width;
  1071. buf->vb.height = fh->video_fmt.height;
  1072. buf->vb.size = size;
  1073. buf->vb.field = field;
  1074. buf->fmt = &fh->video_fmt;
  1075. buf->vb.field = fh->video_fmt.field;
  1076. sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
  1077. if( 0 != IS_PLANAR(sfmt->trans)) {
  1078. saa7146_pgtable_free(dev->pci, &buf->pt[0]);
  1079. saa7146_pgtable_free(dev->pci, &buf->pt[1]);
  1080. saa7146_pgtable_free(dev->pci, &buf->pt[2]);
  1081. saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
  1082. saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
  1083. saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
  1084. } else {
  1085. saa7146_pgtable_free(dev->pci, &buf->pt[0]);
  1086. saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
  1087. }
  1088. err = videobuf_iolock(q,&buf->vb, &vv->ov_fb);
  1089. if (err)
  1090. goto oops;
  1091. err = saa7146_pgtable_build(dev,buf);
  1092. if (err)
  1093. goto oops;
  1094. }
  1095. buf->vb.state = VIDEOBUF_PREPARED;
  1096. buf->activate = buffer_activate;
  1097. return 0;
  1098. oops:
  1099. DEB_D(("error out.\n"));
  1100. saa7146_dma_free(dev,q,buf);
  1101. return err;
  1102. }
  1103. static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
  1104. {
  1105. struct file *file = q->priv_data;
  1106. struct saa7146_fh *fh = file->private_data;
  1107. if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS)
  1108. *count = MAX_SAA7146_CAPTURE_BUFFERS;
  1109. *size = fh->video_fmt.sizeimage;
  1110. /* check if we exceed the "max_memory" parameter */
  1111. if( (*count * *size) > (max_memory*1048576) ) {
  1112. *count = (max_memory*1048576) / *size;
  1113. }
  1114. DEB_CAP(("%d buffers, %d bytes each.\n",*count,*size));
  1115. return 0;
  1116. }
  1117. static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
  1118. {
  1119. struct file *file = q->priv_data;
  1120. struct saa7146_fh *fh = file->private_data;
  1121. struct saa7146_dev *dev = fh->dev;
  1122. struct saa7146_vv *vv = dev->vv_data;
  1123. struct saa7146_buf *buf = (struct saa7146_buf *)vb;
  1124. DEB_CAP(("vbuf:%p\n",vb));
  1125. saa7146_buffer_queue(fh->dev,&vv->video_q,buf);
  1126. }
  1127. static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
  1128. {
  1129. struct file *file = q->priv_data;
  1130. struct saa7146_fh *fh = file->private_data;
  1131. struct saa7146_dev *dev = fh->dev;
  1132. struct saa7146_buf *buf = (struct saa7146_buf *)vb;
  1133. DEB_CAP(("vbuf:%p\n",vb));
  1134. saa7146_dma_free(dev,q,buf);
  1135. }
  1136. static struct videobuf_queue_ops video_qops = {
  1137. .buf_setup = buffer_setup,
  1138. .buf_prepare = buffer_prepare,
  1139. .buf_queue = buffer_queue,
  1140. .buf_release = buffer_release,
  1141. };
  1142. /********************************************************************************/
  1143. /* file operations */
  1144. static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
  1145. {
  1146. INIT_LIST_HEAD(&vv->video_q.queue);
  1147. init_timer(&vv->video_q.timeout);
  1148. vv->video_q.timeout.function = saa7146_buffer_timeout;
  1149. vv->video_q.timeout.data = (unsigned long)(&vv->video_q);
  1150. vv->video_q.dev = dev;
  1151. /* set some default values */
  1152. vv->standard = &dev->ext_vv_data->stds[0];
  1153. /* FIXME: what's this? */
  1154. vv->current_hps_source = SAA7146_HPS_SOURCE_PORT_A;
  1155. vv->current_hps_sync = SAA7146_HPS_SYNC_PORT_A;
  1156. }
  1157. static int video_open(struct saa7146_dev *dev, struct file *file)
  1158. {
  1159. struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
  1160. struct saa7146_format *sfmt;
  1161. fh->video_fmt.width = 384;
  1162. fh->video_fmt.height = 288;
  1163. fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
  1164. fh->video_fmt.bytesperline = 0;
  1165. fh->video_fmt.field = V4L2_FIELD_ANY;
  1166. sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
  1167. fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
  1168. videobuf_queue_sg_init(&fh->video_q, &video_qops,
  1169. &dev->pci->dev, &dev->slock,
  1170. V4L2_BUF_TYPE_VIDEO_CAPTURE,
  1171. V4L2_FIELD_INTERLACED,
  1172. sizeof(struct saa7146_buf),
  1173. file);
  1174. return 0;
  1175. }
  1176. static void video_close(struct saa7146_dev *dev, struct file *file)
  1177. {
  1178. struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
  1179. struct saa7146_vv *vv = dev->vv_data;
  1180. struct videobuf_queue *q = &fh->video_q;
  1181. int err;
  1182. if (IS_CAPTURE_ACTIVE(fh) != 0) {
  1183. err = video_end(fh, file);
  1184. } else if (IS_OVERLAY_ACTIVE(fh) != 0) {
  1185. err = saa7146_stop_preview(fh);
  1186. }
  1187. videobuf_stop(q);
  1188. /* hmm, why is this function declared void? */
  1189. /* return err */
  1190. }
  1191. static void video_irq_done(struct saa7146_dev *dev, unsigned long st)
  1192. {
  1193. struct saa7146_vv *vv = dev->vv_data;
  1194. struct saa7146_dmaqueue *q = &vv->video_q;
  1195. spin_lock(&dev->slock);
  1196. DEB_CAP(("called.\n"));
  1197. /* only finish the buffer if we have one... */
  1198. if( NULL != q->curr ) {
  1199. saa7146_buffer_finish(dev,q,VIDEOBUF_DONE);
  1200. }
  1201. saa7146_buffer_next(dev,q,0);
  1202. spin_unlock(&dev->slock);
  1203. }
  1204. static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
  1205. {
  1206. struct saa7146_fh *fh = file->private_data;
  1207. struct saa7146_dev *dev = fh->dev;
  1208. struct saa7146_vv *vv = dev->vv_data;
  1209. ssize_t ret = 0;
  1210. DEB_EE(("called.\n"));
  1211. if ((vv->video_status & STATUS_CAPTURE) != 0) {
  1212. /* fixme: should we allow read() captures while streaming capture? */
  1213. if (vv->video_fh == fh) {
  1214. DEB_S(("already capturing.\n"));
  1215. return -EBUSY;
  1216. }
  1217. DEB_S(("already capturing in another open.\n"));
  1218. return -EBUSY;
  1219. }
  1220. ret = video_begin(fh);
  1221. if( 0 != ret) {
  1222. goto out;
  1223. }
  1224. ret = videobuf_read_one(&fh->video_q , data, count, ppos,
  1225. file->f_flags & O_NONBLOCK);
  1226. if (ret != 0) {
  1227. video_end(fh, file);
  1228. } else {
  1229. ret = video_end(fh, file);
  1230. }
  1231. out:
  1232. /* restart overlay if it was active before */
  1233. if (vv->ov_suspend != NULL) {
  1234. saa7146_start_preview(vv->ov_suspend);
  1235. vv->ov_suspend = NULL;
  1236. }
  1237. return ret;
  1238. }
  1239. struct saa7146_use_ops saa7146_video_uops = {
  1240. .init = video_init,
  1241. .open = video_open,
  1242. .release = video_close,
  1243. .irq_done = video_irq_done,
  1244. .read = video_read,
  1245. };