saa7146_video.c 36 KB

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