saa7146_video.c 37 KB

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