saa7146_video.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479
  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 (vv->ov_fb.fmt.bytesperline < vv->ov_fb.fmt.width) {
  477. vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width * fmt->depth / 8;
  478. DEB_D(("setting bytesperline to %d\n", vv->ov_fb.fmt.bytesperline));
  479. }
  480. mutex_unlock(&dev->lock);
  481. return 0;
  482. }
  483. static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
  484. {
  485. if (f->index >= NUM_FORMATS)
  486. return -EINVAL;
  487. strlcpy((char *)f->description, formats[f->index].name,
  488. sizeof(f->description));
  489. f->pixelformat = formats[f->index].pixelformat;
  490. return 0;
  491. }
  492. static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
  493. {
  494. const struct v4l2_queryctrl *ctrl;
  495. if ((c->id < V4L2_CID_BASE ||
  496. c->id >= V4L2_CID_LASTP1) &&
  497. (c->id < V4L2_CID_PRIVATE_BASE ||
  498. c->id >= V4L2_CID_PRIVATE_LASTP1))
  499. return -EINVAL;
  500. ctrl = ctrl_by_id(c->id);
  501. if (ctrl == NULL)
  502. return -EINVAL;
  503. DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n", c->id));
  504. *c = *ctrl;
  505. return 0;
  506. }
  507. static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
  508. {
  509. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  510. struct saa7146_vv *vv = dev->vv_data;
  511. const struct v4l2_queryctrl *ctrl;
  512. u32 value = 0;
  513. ctrl = ctrl_by_id(c->id);
  514. if (NULL == ctrl)
  515. return -EINVAL;
  516. switch (c->id) {
  517. case V4L2_CID_BRIGHTNESS:
  518. value = saa7146_read(dev, BCS_CTRL);
  519. c->value = 0xff & (value >> 24);
  520. DEB_D(("V4L2_CID_BRIGHTNESS: %d\n", c->value));
  521. break;
  522. case V4L2_CID_CONTRAST:
  523. value = saa7146_read(dev, BCS_CTRL);
  524. c->value = 0x7f & (value >> 16);
  525. DEB_D(("V4L2_CID_CONTRAST: %d\n", c->value));
  526. break;
  527. case V4L2_CID_SATURATION:
  528. value = saa7146_read(dev, BCS_CTRL);
  529. c->value = 0x7f & (value >> 0);
  530. DEB_D(("V4L2_CID_SATURATION: %d\n", c->value));
  531. break;
  532. case V4L2_CID_VFLIP:
  533. c->value = vv->vflip;
  534. DEB_D(("V4L2_CID_VFLIP: %d\n", c->value));
  535. break;
  536. case V4L2_CID_HFLIP:
  537. c->value = vv->hflip;
  538. DEB_D(("V4L2_CID_HFLIP: %d\n", c->value));
  539. break;
  540. default:
  541. return -EINVAL;
  542. }
  543. return 0;
  544. }
  545. static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
  546. {
  547. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  548. struct saa7146_vv *vv = dev->vv_data;
  549. const struct v4l2_queryctrl *ctrl;
  550. ctrl = ctrl_by_id(c->id);
  551. if (NULL == ctrl) {
  552. DEB_D(("unknown control %d\n", c->id));
  553. return -EINVAL;
  554. }
  555. mutex_lock(&dev->lock);
  556. switch (ctrl->type) {
  557. case V4L2_CTRL_TYPE_BOOLEAN:
  558. case V4L2_CTRL_TYPE_MENU:
  559. case V4L2_CTRL_TYPE_INTEGER:
  560. if (c->value < ctrl->minimum)
  561. c->value = ctrl->minimum;
  562. if (c->value > ctrl->maximum)
  563. c->value = ctrl->maximum;
  564. break;
  565. default:
  566. /* nothing */;
  567. }
  568. switch (c->id) {
  569. case V4L2_CID_BRIGHTNESS: {
  570. u32 value = saa7146_read(dev, BCS_CTRL);
  571. value &= 0x00ffffff;
  572. value |= (c->value << 24);
  573. saa7146_write(dev, BCS_CTRL, value);
  574. saa7146_write(dev, MC2, MASK_22 | MASK_06);
  575. break;
  576. }
  577. case V4L2_CID_CONTRAST: {
  578. u32 value = saa7146_read(dev, BCS_CTRL);
  579. value &= 0xff00ffff;
  580. value |= (c->value << 16);
  581. saa7146_write(dev, BCS_CTRL, value);
  582. saa7146_write(dev, MC2, MASK_22 | MASK_06);
  583. break;
  584. }
  585. case V4L2_CID_SATURATION: {
  586. u32 value = saa7146_read(dev, BCS_CTRL);
  587. value &= 0xffffff00;
  588. value |= (c->value << 0);
  589. saa7146_write(dev, BCS_CTRL, value);
  590. saa7146_write(dev, MC2, MASK_22 | MASK_06);
  591. break;
  592. }
  593. case V4L2_CID_HFLIP:
  594. /* fixme: we can support changing VFLIP and HFLIP here... */
  595. if (IS_CAPTURE_ACTIVE(fh) != 0) {
  596. DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
  597. mutex_unlock(&dev->lock);
  598. return -EBUSY;
  599. }
  600. vv->hflip = c->value;
  601. break;
  602. case V4L2_CID_VFLIP:
  603. if (IS_CAPTURE_ACTIVE(fh) != 0) {
  604. DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
  605. mutex_unlock(&dev->lock);
  606. return -EBUSY;
  607. }
  608. vv->vflip = c->value;
  609. break;
  610. default:
  611. mutex_unlock(&dev->lock);
  612. return -EINVAL;
  613. }
  614. mutex_unlock(&dev->lock);
  615. if (IS_OVERLAY_ACTIVE(fh) != 0) {
  616. saa7146_stop_preview(fh);
  617. saa7146_start_preview(fh);
  618. }
  619. return 0;
  620. }
  621. static int vidioc_g_parm(struct file *file, void *fh,
  622. struct v4l2_streamparm *parm)
  623. {
  624. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  625. struct saa7146_vv *vv = dev->vv_data;
  626. parm->parm.capture.readbuffers = 1;
  627. v4l2_video_std_frame_period(vv->standard->id,
  628. &parm->parm.capture.timeperframe);
  629. return 0;
  630. }
  631. static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
  632. {
  633. f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt;
  634. return 0;
  635. }
  636. static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
  637. {
  638. f->fmt.win = ((struct saa7146_fh *)fh)->ov.win;
  639. return 0;
  640. }
  641. static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f)
  642. {
  643. f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt;
  644. return 0;
  645. }
  646. static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
  647. {
  648. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  649. struct saa7146_vv *vv = dev->vv_data;
  650. struct saa7146_format *fmt;
  651. enum v4l2_field field;
  652. int maxw, maxh;
  653. int calc_bpl;
  654. DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
  655. fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat);
  656. if (NULL == fmt)
  657. return -EINVAL;
  658. field = f->fmt.pix.field;
  659. maxw = vv->standard->h_max_out;
  660. maxh = vv->standard->v_max_out;
  661. if (V4L2_FIELD_ANY == field) {
  662. field = (f->fmt.pix.height > maxh / 2)
  663. ? V4L2_FIELD_INTERLACED
  664. : V4L2_FIELD_BOTTOM;
  665. }
  666. switch (field) {
  667. case V4L2_FIELD_ALTERNATE:
  668. vv->last_field = V4L2_FIELD_TOP;
  669. maxh = maxh / 2;
  670. break;
  671. case V4L2_FIELD_TOP:
  672. case V4L2_FIELD_BOTTOM:
  673. vv->last_field = V4L2_FIELD_INTERLACED;
  674. maxh = maxh / 2;
  675. break;
  676. case V4L2_FIELD_INTERLACED:
  677. vv->last_field = V4L2_FIELD_INTERLACED;
  678. break;
  679. default:
  680. DEB_D(("no known field mode '%d'.\n", field));
  681. return -EINVAL;
  682. }
  683. f->fmt.pix.field = field;
  684. if (f->fmt.pix.width > maxw)
  685. f->fmt.pix.width = maxw;
  686. if (f->fmt.pix.height > maxh)
  687. f->fmt.pix.height = maxh;
  688. calc_bpl = (f->fmt.pix.width * fmt->depth) / 8;
  689. if (f->fmt.pix.bytesperline < calc_bpl)
  690. f->fmt.pix.bytesperline = calc_bpl;
  691. if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */
  692. f->fmt.pix.bytesperline = calc_bpl;
  693. f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
  694. DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", f->fmt.pix.width,
  695. f->fmt.pix.height, f->fmt.pix.bytesperline, f->fmt.pix.sizeimage));
  696. return 0;
  697. }
  698. static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
  699. {
  700. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  701. struct saa7146_vv *vv = dev->vv_data;
  702. struct v4l2_window *win = &f->fmt.win;
  703. enum v4l2_field field;
  704. int maxw, maxh;
  705. DEB_EE(("dev:%p\n", dev));
  706. if (NULL == vv->ov_fb.base) {
  707. DEB_D(("no fb base set.\n"));
  708. return -EINVAL;
  709. }
  710. if (NULL == vv->ov_fmt) {
  711. DEB_D(("no fb fmt set.\n"));
  712. return -EINVAL;
  713. }
  714. if (win->w.width < 48 || win->w.height < 32) {
  715. DEB_D(("min width/height. (%d,%d)\n", win->w.width, win->w.height));
  716. return -EINVAL;
  717. }
  718. if (win->clipcount > 16) {
  719. DEB_D(("clipcount too big.\n"));
  720. return -EINVAL;
  721. }
  722. field = win->field;
  723. maxw = vv->standard->h_max_out;
  724. maxh = vv->standard->v_max_out;
  725. if (V4L2_FIELD_ANY == field) {
  726. field = (win->w.height > maxh / 2)
  727. ? V4L2_FIELD_INTERLACED
  728. : V4L2_FIELD_TOP;
  729. }
  730. switch (field) {
  731. case V4L2_FIELD_TOP:
  732. case V4L2_FIELD_BOTTOM:
  733. case V4L2_FIELD_ALTERNATE:
  734. maxh = maxh / 2;
  735. break;
  736. case V4L2_FIELD_INTERLACED:
  737. break;
  738. default:
  739. DEB_D(("no known field mode '%d'.\n", field));
  740. return -EINVAL;
  741. }
  742. win->field = field;
  743. if (win->w.width > maxw)
  744. win->w.width = maxw;
  745. if (win->w.height > maxh)
  746. win->w.height = maxh;
  747. return 0;
  748. }
  749. static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f)
  750. {
  751. struct saa7146_fh *fh = __fh;
  752. struct saa7146_dev *dev = fh->dev;
  753. struct saa7146_vv *vv = dev->vv_data;
  754. int err;
  755. DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
  756. if (IS_CAPTURE_ACTIVE(fh) != 0) {
  757. DEB_EE(("streaming capture is active\n"));
  758. return -EBUSY;
  759. }
  760. err = vidioc_try_fmt_vid_cap(file, fh, f);
  761. if (0 != err)
  762. return err;
  763. fh->video_fmt = f->fmt.pix;
  764. DEB_EE(("set to pixelformat '%4.4s'\n", (char *)&fh->video_fmt.pixelformat));
  765. return 0;
  766. }
  767. static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f)
  768. {
  769. struct saa7146_fh *fh = __fh;
  770. struct saa7146_dev *dev = fh->dev;
  771. struct saa7146_vv *vv = dev->vv_data;
  772. int err;
  773. DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh));
  774. err = vidioc_try_fmt_vid_overlay(file, fh, f);
  775. if (0 != err)
  776. return err;
  777. mutex_lock(&dev->lock);
  778. fh->ov.win = f->fmt.win;
  779. fh->ov.nclips = f->fmt.win.clipcount;
  780. if (fh->ov.nclips > 16)
  781. fh->ov.nclips = 16;
  782. if (copy_from_user(fh->ov.clips, f->fmt.win.clips,
  783. sizeof(struct v4l2_clip) * fh->ov.nclips)) {
  784. mutex_unlock(&dev->lock);
  785. return -EFAULT;
  786. }
  787. /* fh->ov.fh is used to indicate that we have valid overlay informations, too */
  788. fh->ov.fh = fh;
  789. mutex_unlock(&dev->lock);
  790. /* check if our current overlay is active */
  791. if (IS_OVERLAY_ACTIVE(fh) != 0) {
  792. saa7146_stop_preview(fh);
  793. saa7146_start_preview(fh);
  794. }
  795. return 0;
  796. }
  797. static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm)
  798. {
  799. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  800. struct saa7146_vv *vv = dev->vv_data;
  801. *norm = vv->standard->id;
  802. return 0;
  803. }
  804. /* the saa7146 supfhrts (used in conjunction with the saa7111a for example)
  805. PAL / NTSC / SECAM. if your hardware does not (or does more)
  806. -- override this function in your extension */
  807. /*
  808. case VIDIOC_ENUMSTD:
  809. {
  810. struct v4l2_standard *e = arg;
  811. if (e->index < 0 )
  812. return -EINVAL;
  813. if( e->index < dev->ext_vv_data->num_stds ) {
  814. DEB_EE(("VIDIOC_ENUMSTD: index:%d\n",e->index));
  815. v4l2_video_std_construct(e, dev->ext_vv_data->stds[e->index].id, dev->ext_vv_data->stds[e->index].name);
  816. return 0;
  817. }
  818. return -EINVAL;
  819. }
  820. */
  821. static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
  822. {
  823. struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  824. struct saa7146_vv *vv = dev->vv_data;
  825. int found = 0;
  826. int err, i;
  827. DEB_EE(("VIDIOC_S_STD\n"));
  828. if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
  829. DEB_D(("cannot change video standard while streaming capture is active\n"));
  830. return -EBUSY;
  831. }
  832. if ((vv->video_status & STATUS_OVERLAY) != 0) {
  833. vv->ov_suspend = vv->video_fh;
  834. err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
  835. if (0 != err) {
  836. DEB_D(("suspending video failed. aborting\n"));
  837. return err;
  838. }
  839. }
  840. mutex_lock(&dev->lock);
  841. for (i = 0; i < dev->ext_vv_data->num_stds; i++)
  842. if (*id & dev->ext_vv_data->stds[i].id)
  843. break;
  844. if (i != dev->ext_vv_data->num_stds) {
  845. vv->standard = &dev->ext_vv_data->stds[i];
  846. if (NULL != dev->ext_vv_data->std_callback)
  847. dev->ext_vv_data->std_callback(dev, vv->standard);
  848. found = 1;
  849. }
  850. mutex_unlock(&dev->lock);
  851. if (vv->ov_suspend != NULL) {
  852. saa7146_start_preview(vv->ov_suspend);
  853. vv->ov_suspend = NULL;
  854. }
  855. if (!found) {
  856. DEB_EE(("VIDIOC_S_STD: standard not found.\n"));
  857. return -EINVAL;
  858. }
  859. DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name));
  860. return 0;
  861. }
  862. static int vidioc_overlay(struct file *file, void *fh, unsigned int on)
  863. {
  864. int err;
  865. DEB_D(("VIDIOC_OVERLAY on:%d\n", on));
  866. if (on)
  867. err = saa7146_start_preview(fh);
  868. else
  869. err = saa7146_stop_preview(fh);
  870. return err;
  871. }
  872. static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b)
  873. {
  874. struct saa7146_fh *fh = __fh;
  875. if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
  876. return videobuf_reqbufs(&fh->video_q, b);
  877. if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE)
  878. return videobuf_reqbufs(&fh->vbi_q, b);
  879. return -EINVAL;
  880. }
  881. static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
  882. {
  883. struct saa7146_fh *fh = __fh;
  884. if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
  885. return videobuf_querybuf(&fh->video_q, buf);
  886. if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
  887. return videobuf_querybuf(&fh->vbi_q, buf);
  888. return -EINVAL;
  889. }
  890. static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
  891. {
  892. struct saa7146_fh *fh = __fh;
  893. if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
  894. return videobuf_qbuf(&fh->video_q, buf);
  895. if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
  896. return videobuf_qbuf(&fh->vbi_q, buf);
  897. return -EINVAL;
  898. }
  899. static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
  900. {
  901. struct saa7146_fh *fh = __fh;
  902. if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
  903. return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK);
  904. if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
  905. return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK);
  906. return -EINVAL;
  907. }
  908. static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
  909. {
  910. struct saa7146_fh *fh = __fh;
  911. int err;
  912. DEB_D(("VIDIOC_STREAMON, type:%d\n", type));
  913. err = video_begin(fh);
  914. if (err)
  915. return err;
  916. if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
  917. return videobuf_streamon(&fh->video_q);
  918. if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
  919. return videobuf_streamon(&fh->vbi_q);
  920. return -EINVAL;
  921. }
  922. static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
  923. {
  924. struct saa7146_fh *fh = __fh;
  925. struct saa7146_dev *dev = fh->dev;
  926. struct saa7146_vv *vv = dev->vv_data;
  927. int err;
  928. DEB_D(("VIDIOC_STREAMOFF, type:%d\n", type));
  929. /* ugly: we need to copy some checks from video_end(),
  930. because videobuf_streamoff() relies on the capture running.
  931. check and fix this */
  932. if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
  933. DEB_S(("not capturing.\n"));
  934. return 0;
  935. }
  936. if (vv->video_fh != fh) {
  937. DEB_S(("capturing, but in another open.\n"));
  938. return -EBUSY;
  939. }
  940. err = -EINVAL;
  941. if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
  942. err = videobuf_streamoff(&fh->video_q);
  943. else if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
  944. err = videobuf_streamoff(&fh->vbi_q);
  945. if (0 != err) {
  946. DEB_D(("warning: videobuf_streamoff() failed.\n"));
  947. video_end(fh, file);
  948. } else {
  949. err = video_end(fh, file);
  950. }
  951. return err;
  952. }
  953. static int vidioc_g_chip_ident(struct file *file, void *__fh,
  954. struct v4l2_dbg_chip_ident *chip)
  955. {
  956. struct saa7146_fh *fh = __fh;
  957. struct saa7146_dev *dev = fh->dev;
  958. chip->ident = V4L2_IDENT_NONE;
  959. chip->revision = 0;
  960. if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) {
  961. chip->ident = V4L2_IDENT_SAA7146;
  962. return 0;
  963. }
  964. return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
  965. core, g_chip_ident, chip);
  966. }
  967. #ifdef CONFIG_VIDEO_V4L1_COMPAT
  968. static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf)
  969. {
  970. struct saa7146_fh *fh = __fh;
  971. struct videobuf_queue *q = &fh->video_q;
  972. int err, i;
  973. /* fixme: number of capture buffers and sizes for v4l apps */
  974. int gbuffers = 2;
  975. int gbufsize = 768 * 576 * 4;
  976. DEB_D(("VIDIOCGMBUF \n"));
  977. q = &fh->video_q;
  978. err = videobuf_mmap_setup(q, gbuffers, gbufsize,
  979. V4L2_MEMORY_MMAP);
  980. if (err < 0)
  981. return err;
  982. gbuffers = err;
  983. memset(mbuf, 0, sizeof(*mbuf));
  984. mbuf->frames = gbuffers;
  985. mbuf->size = gbuffers * gbufsize;
  986. for (i = 0; i < gbuffers; i++)
  987. mbuf->offsets[i] = i * gbufsize;
  988. return 0;
  989. }
  990. #endif
  991. const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
  992. .vidioc_querycap = vidioc_querycap,
  993. .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
  994. .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap,
  995. .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
  996. .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
  997. .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
  998. .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
  999. .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
  1000. .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
  1001. .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
  1002. .vidioc_g_chip_ident = vidioc_g_chip_ident,
  1003. .vidioc_overlay = vidioc_overlay,
  1004. .vidioc_g_fbuf = vidioc_g_fbuf,
  1005. .vidioc_s_fbuf = vidioc_s_fbuf,
  1006. .vidioc_reqbufs = vidioc_reqbufs,
  1007. .vidioc_querybuf = vidioc_querybuf,
  1008. .vidioc_qbuf = vidioc_qbuf,
  1009. .vidioc_dqbuf = vidioc_dqbuf,
  1010. .vidioc_g_std = vidioc_g_std,
  1011. .vidioc_s_std = vidioc_s_std,
  1012. .vidioc_queryctrl = vidioc_queryctrl,
  1013. .vidioc_g_ctrl = vidioc_g_ctrl,
  1014. .vidioc_s_ctrl = vidioc_s_ctrl,
  1015. .vidioc_streamon = vidioc_streamon,
  1016. .vidioc_streamoff = vidioc_streamoff,
  1017. .vidioc_g_parm = vidioc_g_parm,
  1018. #ifdef CONFIG_VIDEO_V4L1_COMPAT
  1019. .vidiocgmbuf = vidiocgmbuf,
  1020. #endif
  1021. };
  1022. /*********************************************************************************/
  1023. /* buffer handling functions */
  1024. static int buffer_activate (struct saa7146_dev *dev,
  1025. struct saa7146_buf *buf,
  1026. struct saa7146_buf *next)
  1027. {
  1028. struct saa7146_vv *vv = dev->vv_data;
  1029. buf->vb.state = VIDEOBUF_ACTIVE;
  1030. saa7146_set_capture(dev,buf,next);
  1031. mod_timer(&vv->video_q.timeout, jiffies+BUFFER_TIMEOUT);
  1032. return 0;
  1033. }
  1034. static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf *buf)
  1035. {
  1036. saa7146_pgtable_free(dev->pci, &buf->pt[0]);
  1037. saa7146_pgtable_free(dev->pci, &buf->pt[1]);
  1038. saa7146_pgtable_free(dev->pci, &buf->pt[2]);
  1039. }
  1040. static int buffer_prepare(struct videobuf_queue *q,
  1041. struct videobuf_buffer *vb, enum v4l2_field field)
  1042. {
  1043. struct file *file = q->priv_data;
  1044. struct saa7146_fh *fh = file->private_data;
  1045. struct saa7146_dev *dev = fh->dev;
  1046. struct saa7146_vv *vv = dev->vv_data;
  1047. struct saa7146_buf *buf = (struct saa7146_buf *)vb;
  1048. int size,err = 0;
  1049. DEB_CAP(("vbuf:%p\n",vb));
  1050. /* sanity checks */
  1051. if (fh->video_fmt.width < 48 ||
  1052. fh->video_fmt.height < 32 ||
  1053. fh->video_fmt.width > vv->standard->h_max_out ||
  1054. fh->video_fmt.height > vv->standard->v_max_out) {
  1055. DEB_D(("w (%d) / h (%d) out of bounds.\n",fh->video_fmt.width,fh->video_fmt.height));
  1056. return -EINVAL;
  1057. }
  1058. size = fh->video_fmt.sizeimage;
  1059. if (0 != buf->vb.baddr && buf->vb.bsize < size) {
  1060. DEB_D(("size mismatch.\n"));
  1061. return -EINVAL;
  1062. }
  1063. DEB_CAP(("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
  1064. fh->video_fmt.width,fh->video_fmt.height,size,v4l2_field_names[fh->video_fmt.field]));
  1065. if (buf->vb.width != fh->video_fmt.width ||
  1066. buf->vb.bytesperline != fh->video_fmt.bytesperline ||
  1067. buf->vb.height != fh->video_fmt.height ||
  1068. buf->vb.size != size ||
  1069. buf->vb.field != field ||
  1070. buf->vb.field != fh->video_fmt.field ||
  1071. buf->fmt != &fh->video_fmt) {
  1072. saa7146_dma_free(dev,q,buf);
  1073. }
  1074. if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
  1075. struct saa7146_format *sfmt;
  1076. buf->vb.bytesperline = fh->video_fmt.bytesperline;
  1077. buf->vb.width = fh->video_fmt.width;
  1078. buf->vb.height = fh->video_fmt.height;
  1079. buf->vb.size = size;
  1080. buf->vb.field = field;
  1081. buf->fmt = &fh->video_fmt;
  1082. buf->vb.field = fh->video_fmt.field;
  1083. sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
  1084. release_all_pagetables(dev, buf);
  1085. if( 0 != IS_PLANAR(sfmt->trans)) {
  1086. saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
  1087. saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
  1088. saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
  1089. } else {
  1090. saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
  1091. }
  1092. err = videobuf_iolock(q,&buf->vb, &vv->ov_fb);
  1093. if (err)
  1094. goto oops;
  1095. err = saa7146_pgtable_build(dev,buf);
  1096. if (err)
  1097. goto oops;
  1098. }
  1099. buf->vb.state = VIDEOBUF_PREPARED;
  1100. buf->activate = buffer_activate;
  1101. return 0;
  1102. oops:
  1103. DEB_D(("error out.\n"));
  1104. saa7146_dma_free(dev,q,buf);
  1105. return err;
  1106. }
  1107. static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
  1108. {
  1109. struct file *file = q->priv_data;
  1110. struct saa7146_fh *fh = file->private_data;
  1111. if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS)
  1112. *count = MAX_SAA7146_CAPTURE_BUFFERS;
  1113. *size = fh->video_fmt.sizeimage;
  1114. /* check if we exceed the "max_memory" parameter */
  1115. if( (*count * *size) > (max_memory*1048576) ) {
  1116. *count = (max_memory*1048576) / *size;
  1117. }
  1118. DEB_CAP(("%d buffers, %d bytes each.\n",*count,*size));
  1119. return 0;
  1120. }
  1121. static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
  1122. {
  1123. struct file *file = q->priv_data;
  1124. struct saa7146_fh *fh = file->private_data;
  1125. struct saa7146_dev *dev = fh->dev;
  1126. struct saa7146_vv *vv = dev->vv_data;
  1127. struct saa7146_buf *buf = (struct saa7146_buf *)vb;
  1128. DEB_CAP(("vbuf:%p\n",vb));
  1129. saa7146_buffer_queue(fh->dev,&vv->video_q,buf);
  1130. }
  1131. static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
  1132. {
  1133. struct file *file = q->priv_data;
  1134. struct saa7146_fh *fh = file->private_data;
  1135. struct saa7146_dev *dev = fh->dev;
  1136. struct saa7146_buf *buf = (struct saa7146_buf *)vb;
  1137. DEB_CAP(("vbuf:%p\n",vb));
  1138. saa7146_dma_free(dev,q,buf);
  1139. release_all_pagetables(dev, buf);
  1140. }
  1141. static struct videobuf_queue_ops video_qops = {
  1142. .buf_setup = buffer_setup,
  1143. .buf_prepare = buffer_prepare,
  1144. .buf_queue = buffer_queue,
  1145. .buf_release = buffer_release,
  1146. };
  1147. /********************************************************************************/
  1148. /* file operations */
  1149. static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
  1150. {
  1151. INIT_LIST_HEAD(&vv->video_q.queue);
  1152. init_timer(&vv->video_q.timeout);
  1153. vv->video_q.timeout.function = saa7146_buffer_timeout;
  1154. vv->video_q.timeout.data = (unsigned long)(&vv->video_q);
  1155. vv->video_q.dev = dev;
  1156. /* set some default values */
  1157. vv->standard = &dev->ext_vv_data->stds[0];
  1158. /* FIXME: what's this? */
  1159. vv->current_hps_source = SAA7146_HPS_SOURCE_PORT_A;
  1160. vv->current_hps_sync = SAA7146_HPS_SYNC_PORT_A;
  1161. }
  1162. static int video_open(struct saa7146_dev *dev, struct file *file)
  1163. {
  1164. struct saa7146_fh *fh = file->private_data;
  1165. struct saa7146_format *sfmt;
  1166. fh->video_fmt.width = 384;
  1167. fh->video_fmt.height = 288;
  1168. fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
  1169. fh->video_fmt.bytesperline = 0;
  1170. fh->video_fmt.field = V4L2_FIELD_ANY;
  1171. sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
  1172. fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
  1173. videobuf_queue_sg_init(&fh->video_q, &video_qops,
  1174. &dev->pci->dev, &dev->slock,
  1175. V4L2_BUF_TYPE_VIDEO_CAPTURE,
  1176. V4L2_FIELD_INTERLACED,
  1177. sizeof(struct saa7146_buf),
  1178. file);
  1179. return 0;
  1180. }
  1181. static void video_close(struct saa7146_dev *dev, struct file *file)
  1182. {
  1183. struct saa7146_fh *fh = file->private_data;
  1184. struct saa7146_vv *vv = dev->vv_data;
  1185. struct videobuf_queue *q = &fh->video_q;
  1186. int err;
  1187. if (IS_CAPTURE_ACTIVE(fh) != 0) {
  1188. err = video_end(fh, file);
  1189. } else if (IS_OVERLAY_ACTIVE(fh) != 0) {
  1190. err = saa7146_stop_preview(fh);
  1191. }
  1192. videobuf_stop(q);
  1193. /* hmm, why is this function declared void? */
  1194. /* return err */
  1195. }
  1196. static void video_irq_done(struct saa7146_dev *dev, unsigned long st)
  1197. {
  1198. struct saa7146_vv *vv = dev->vv_data;
  1199. struct saa7146_dmaqueue *q = &vv->video_q;
  1200. spin_lock(&dev->slock);
  1201. DEB_CAP(("called.\n"));
  1202. /* only finish the buffer if we have one... */
  1203. if( NULL != q->curr ) {
  1204. saa7146_buffer_finish(dev,q,VIDEOBUF_DONE);
  1205. }
  1206. saa7146_buffer_next(dev,q,0);
  1207. spin_unlock(&dev->slock);
  1208. }
  1209. static ssize_t video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
  1210. {
  1211. struct saa7146_fh *fh = file->private_data;
  1212. struct saa7146_dev *dev = fh->dev;
  1213. struct saa7146_vv *vv = dev->vv_data;
  1214. ssize_t ret = 0;
  1215. DEB_EE(("called.\n"));
  1216. if ((vv->video_status & STATUS_CAPTURE) != 0) {
  1217. /* fixme: should we allow read() captures while streaming capture? */
  1218. if (vv->video_fh == fh) {
  1219. DEB_S(("already capturing.\n"));
  1220. return -EBUSY;
  1221. }
  1222. DEB_S(("already capturing in another open.\n"));
  1223. return -EBUSY;
  1224. }
  1225. ret = video_begin(fh);
  1226. if( 0 != ret) {
  1227. goto out;
  1228. }
  1229. ret = videobuf_read_one(&fh->video_q , data, count, ppos,
  1230. file->f_flags & O_NONBLOCK);
  1231. if (ret != 0) {
  1232. video_end(fh, file);
  1233. } else {
  1234. ret = video_end(fh, file);
  1235. }
  1236. out:
  1237. /* restart overlay if it was active before */
  1238. if (vv->ov_suspend != NULL) {
  1239. saa7146_start_preview(vv->ov_suspend);
  1240. vv->ov_suspend = NULL;
  1241. }
  1242. return ret;
  1243. }
  1244. struct saa7146_use_ops saa7146_video_uops = {
  1245. .init = video_init,
  1246. .open = video_open,
  1247. .release = video_close,
  1248. .irq_done = video_irq_done,
  1249. .read = video_read,
  1250. };