v4l1-compat.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297
  1. /*
  2. *
  3. * Video for Linux Two
  4. * Backward Compatibility Layer
  5. *
  6. * Support subroutines for providing V4L2 drivers with backward
  7. * compatibility with applications using the old API.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version
  12. * 2 of the License, or (at your option) any later version.
  13. *
  14. * Author: Bill Dirks <bill@thedirks.org>
  15. * et al.
  16. *
  17. */
  18. #include <linux/init.h>
  19. #include <linux/module.h>
  20. #include <linux/types.h>
  21. #include <linux/kernel.h>
  22. #include <linux/sched.h>
  23. #include <linux/mm.h>
  24. #include <linux/fs.h>
  25. #include <linux/file.h>
  26. #include <linux/string.h>
  27. #include <linux/errno.h>
  28. #include <linux/slab.h>
  29. #include <linux/videodev.h>
  30. #include <media/v4l2-common.h>
  31. #include <media/v4l2-ioctl.h>
  32. #include <asm/uaccess.h>
  33. #include <asm/system.h>
  34. #include <asm/pgtable.h>
  35. #ifdef CONFIG_KMOD
  36. #include <linux/kmod.h>
  37. #endif
  38. static unsigned int debug;
  39. module_param(debug, int, 0644);
  40. MODULE_PARM_DESC(debug, "enable debug messages");
  41. MODULE_AUTHOR("Bill Dirks");
  42. MODULE_DESCRIPTION("v4l(1) compatibility layer for v4l2 drivers.");
  43. MODULE_LICENSE("GPL");
  44. #define dprintk(fmt, arg...) \
  45. do { \
  46. if (debug) \
  47. printk(KERN_DEBUG "v4l1-compat: " fmt , ## arg);\
  48. } while (0)
  49. /*
  50. * I O C T L T R A N S L A T I O N
  51. *
  52. * From here on down is the code for translating the numerous
  53. * ioctl commands from the old API to the new API.
  54. */
  55. static int
  56. get_v4l_control(struct inode *inode,
  57. struct file *file,
  58. int cid,
  59. v4l2_kioctl drv)
  60. {
  61. struct v4l2_queryctrl qctrl2;
  62. struct v4l2_control ctrl2;
  63. int err;
  64. qctrl2.id = cid;
  65. err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
  66. if (err < 0)
  67. dprintk("VIDIOC_QUERYCTRL: %d\n", err);
  68. if (err == 0 && !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED)) {
  69. ctrl2.id = qctrl2.id;
  70. err = drv(inode, file, VIDIOC_G_CTRL, &ctrl2);
  71. if (err < 0) {
  72. dprintk("VIDIOC_G_CTRL: %d\n", err);
  73. return 0;
  74. }
  75. return ((ctrl2.value - qctrl2.minimum) * 65535
  76. + (qctrl2.maximum - qctrl2.minimum) / 2)
  77. / (qctrl2.maximum - qctrl2.minimum);
  78. }
  79. return 0;
  80. }
  81. static int
  82. set_v4l_control(struct inode *inode,
  83. struct file *file,
  84. int cid,
  85. int value,
  86. v4l2_kioctl drv)
  87. {
  88. struct v4l2_queryctrl qctrl2;
  89. struct v4l2_control ctrl2;
  90. int err;
  91. qctrl2.id = cid;
  92. err = drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2);
  93. if (err < 0)
  94. dprintk("VIDIOC_QUERYCTRL: %d\n", err);
  95. if (err == 0 &&
  96. !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED) &&
  97. !(qctrl2.flags & V4L2_CTRL_FLAG_GRABBED)) {
  98. if (value < 0)
  99. value = 0;
  100. if (value > 65535)
  101. value = 65535;
  102. if (value && qctrl2.type == V4L2_CTRL_TYPE_BOOLEAN)
  103. value = 65535;
  104. ctrl2.id = qctrl2.id;
  105. ctrl2.value =
  106. (value * (qctrl2.maximum - qctrl2.minimum)
  107. + 32767)
  108. / 65535;
  109. ctrl2.value += qctrl2.minimum;
  110. err = drv(inode, file, VIDIOC_S_CTRL, &ctrl2);
  111. if (err < 0)
  112. dprintk("VIDIOC_S_CTRL: %d\n", err);
  113. }
  114. return 0;
  115. }
  116. /* ----------------------------------------------------------------- */
  117. static const unsigned int palette2pixelformat[] = {
  118. [VIDEO_PALETTE_GREY] = V4L2_PIX_FMT_GREY,
  119. [VIDEO_PALETTE_RGB555] = V4L2_PIX_FMT_RGB555,
  120. [VIDEO_PALETTE_RGB565] = V4L2_PIX_FMT_RGB565,
  121. [VIDEO_PALETTE_RGB24] = V4L2_PIX_FMT_BGR24,
  122. [VIDEO_PALETTE_RGB32] = V4L2_PIX_FMT_BGR32,
  123. /* yuv packed pixel */
  124. [VIDEO_PALETTE_YUYV] = V4L2_PIX_FMT_YUYV,
  125. [VIDEO_PALETTE_YUV422] = V4L2_PIX_FMT_YUYV,
  126. [VIDEO_PALETTE_UYVY] = V4L2_PIX_FMT_UYVY,
  127. /* yuv planar */
  128. [VIDEO_PALETTE_YUV410P] = V4L2_PIX_FMT_YUV410,
  129. [VIDEO_PALETTE_YUV420] = V4L2_PIX_FMT_YUV420,
  130. [VIDEO_PALETTE_YUV420P] = V4L2_PIX_FMT_YUV420,
  131. [VIDEO_PALETTE_YUV411P] = V4L2_PIX_FMT_YUV411P,
  132. [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P,
  133. };
  134. static unsigned int __pure
  135. palette_to_pixelformat(unsigned int palette)
  136. {
  137. if (palette < ARRAY_SIZE(palette2pixelformat))
  138. return palette2pixelformat[palette];
  139. else
  140. return 0;
  141. }
  142. static unsigned int __attribute_const__
  143. pixelformat_to_palette(unsigned int pixelformat)
  144. {
  145. int palette = 0;
  146. switch (pixelformat) {
  147. case V4L2_PIX_FMT_GREY:
  148. palette = VIDEO_PALETTE_GREY;
  149. break;
  150. case V4L2_PIX_FMT_RGB555:
  151. palette = VIDEO_PALETTE_RGB555;
  152. break;
  153. case V4L2_PIX_FMT_RGB565:
  154. palette = VIDEO_PALETTE_RGB565;
  155. break;
  156. case V4L2_PIX_FMT_BGR24:
  157. palette = VIDEO_PALETTE_RGB24;
  158. break;
  159. case V4L2_PIX_FMT_BGR32:
  160. palette = VIDEO_PALETTE_RGB32;
  161. break;
  162. /* yuv packed pixel */
  163. case V4L2_PIX_FMT_YUYV:
  164. palette = VIDEO_PALETTE_YUYV;
  165. break;
  166. case V4L2_PIX_FMT_UYVY:
  167. palette = VIDEO_PALETTE_UYVY;
  168. break;
  169. /* yuv planar */
  170. case V4L2_PIX_FMT_YUV410:
  171. palette = VIDEO_PALETTE_YUV420;
  172. break;
  173. case V4L2_PIX_FMT_YUV420:
  174. palette = VIDEO_PALETTE_YUV420;
  175. break;
  176. case V4L2_PIX_FMT_YUV411P:
  177. palette = VIDEO_PALETTE_YUV411P;
  178. break;
  179. case V4L2_PIX_FMT_YUV422P:
  180. palette = VIDEO_PALETTE_YUV422P;
  181. break;
  182. }
  183. return palette;
  184. }
  185. /* ----------------------------------------------------------------- */
  186. static int poll_one(struct file *file, struct poll_wqueues *pwq)
  187. {
  188. int retval = 1;
  189. poll_table *table;
  190. poll_initwait(pwq);
  191. table = &pwq->pt;
  192. for (;;) {
  193. int mask;
  194. set_current_state(TASK_INTERRUPTIBLE);
  195. mask = file->f_op->poll(file, table);
  196. if (mask & POLLIN)
  197. break;
  198. table = NULL;
  199. if (signal_pending(current)) {
  200. retval = -ERESTARTSYS;
  201. break;
  202. }
  203. schedule();
  204. }
  205. set_current_state(TASK_RUNNING);
  206. poll_freewait(pwq);
  207. return retval;
  208. }
  209. static int count_inputs(
  210. struct inode *inode,
  211. struct file *file,
  212. v4l2_kioctl drv)
  213. {
  214. struct v4l2_input input2;
  215. int i;
  216. for (i = 0;; i++) {
  217. memset(&input2, 0, sizeof(input2));
  218. input2.index = i;
  219. if (0 != drv(inode, file, VIDIOC_ENUMINPUT, &input2))
  220. break;
  221. }
  222. return i;
  223. }
  224. static int check_size(
  225. struct inode *inode,
  226. struct file *file,
  227. v4l2_kioctl drv,
  228. int *maxw,
  229. int *maxh)
  230. {
  231. struct v4l2_fmtdesc desc2;
  232. struct v4l2_format fmt2;
  233. memset(&desc2, 0, sizeof(desc2));
  234. memset(&fmt2, 0, sizeof(fmt2));
  235. desc2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  236. if (0 != drv(inode, file, VIDIOC_ENUM_FMT, &desc2))
  237. goto done;
  238. fmt2.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  239. fmt2.fmt.pix.width = 10000;
  240. fmt2.fmt.pix.height = 10000;
  241. fmt2.fmt.pix.pixelformat = desc2.pixelformat;
  242. if (0 != drv(inode, file, VIDIOC_TRY_FMT, &fmt2))
  243. goto done;
  244. *maxw = fmt2.fmt.pix.width;
  245. *maxh = fmt2.fmt.pix.height;
  246. done:
  247. return 0;
  248. }
  249. /* ----------------------------------------------------------------- */
  250. static noinline int v4l1_compat_get_capabilities(
  251. struct video_capability *cap,
  252. struct inode *inode,
  253. struct file *file,
  254. v4l2_kioctl drv)
  255. {
  256. int err;
  257. struct v4l2_framebuffer fbuf;
  258. struct v4l2_capability *cap2;
  259. cap2 = kzalloc(sizeof(*cap2), GFP_KERNEL);
  260. if (!cap2) {
  261. err = -ENOMEM;
  262. return err;
  263. }
  264. memset(cap, 0, sizeof(*cap));
  265. memset(&fbuf, 0, sizeof(fbuf));
  266. err = drv(inode, file, VIDIOC_QUERYCAP, cap2);
  267. if (err < 0) {
  268. dprintk("VIDIOCGCAP / VIDIOC_QUERYCAP: %d\n", err);
  269. goto done;
  270. }
  271. if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY) {
  272. err = drv(inode, file, VIDIOC_G_FBUF, &fbuf);
  273. if (err < 0) {
  274. dprintk("VIDIOCGCAP / VIDIOC_G_FBUF: %d\n", err);
  275. memset(&fbuf, 0, sizeof(fbuf));
  276. }
  277. err = 0;
  278. }
  279. memcpy(cap->name, cap2->card,
  280. min(sizeof(cap->name), sizeof(cap2->card)));
  281. cap->name[sizeof(cap->name) - 1] = 0;
  282. if (cap2->capabilities & V4L2_CAP_VIDEO_CAPTURE)
  283. cap->type |= VID_TYPE_CAPTURE;
  284. if (cap2->capabilities & V4L2_CAP_TUNER)
  285. cap->type |= VID_TYPE_TUNER;
  286. if (cap2->capabilities & V4L2_CAP_VBI_CAPTURE)
  287. cap->type |= VID_TYPE_TELETEXT;
  288. if (cap2->capabilities & V4L2_CAP_VIDEO_OVERLAY)
  289. cap->type |= VID_TYPE_OVERLAY;
  290. if (fbuf.capability & V4L2_FBUF_CAP_LIST_CLIPPING)
  291. cap->type |= VID_TYPE_CLIPPING;
  292. cap->channels = count_inputs(inode, file, drv);
  293. check_size(inode, file, drv,
  294. &cap->maxwidth, &cap->maxheight);
  295. cap->audios = 0; /* FIXME */
  296. cap->minwidth = 48; /* FIXME */
  297. cap->minheight = 32; /* FIXME */
  298. done:
  299. kfree(cap2);
  300. return err;
  301. }
  302. static noinline int v4l1_compat_get_frame_buffer(
  303. struct video_buffer *buffer,
  304. struct inode *inode,
  305. struct file *file,
  306. v4l2_kioctl drv)
  307. {
  308. int err;
  309. struct v4l2_framebuffer fbuf;
  310. memset(buffer, 0, sizeof(*buffer));
  311. memset(&fbuf, 0, sizeof(fbuf));
  312. err = drv(inode, file, VIDIOC_G_FBUF, &fbuf);
  313. if (err < 0) {
  314. dprintk("VIDIOCGFBUF / VIDIOC_G_FBUF: %d\n", err);
  315. goto done;
  316. }
  317. buffer->base = fbuf.base;
  318. buffer->height = fbuf.fmt.height;
  319. buffer->width = fbuf.fmt.width;
  320. switch (fbuf.fmt.pixelformat) {
  321. case V4L2_PIX_FMT_RGB332:
  322. buffer->depth = 8;
  323. break;
  324. case V4L2_PIX_FMT_RGB555:
  325. buffer->depth = 15;
  326. break;
  327. case V4L2_PIX_FMT_RGB565:
  328. buffer->depth = 16;
  329. break;
  330. case V4L2_PIX_FMT_BGR24:
  331. buffer->depth = 24;
  332. break;
  333. case V4L2_PIX_FMT_BGR32:
  334. buffer->depth = 32;
  335. break;
  336. default:
  337. buffer->depth = 0;
  338. }
  339. if (fbuf.fmt.bytesperline) {
  340. buffer->bytesperline = fbuf.fmt.bytesperline;
  341. if (!buffer->depth && buffer->width)
  342. buffer->depth = ((fbuf.fmt.bytesperline<<3)
  343. + (buffer->width-1))
  344. / buffer->width;
  345. } else {
  346. buffer->bytesperline =
  347. (buffer->width * buffer->depth + 7) & 7;
  348. buffer->bytesperline >>= 3;
  349. }
  350. done:
  351. return err;
  352. }
  353. static noinline int v4l1_compat_set_frame_buffer(
  354. struct video_buffer *buffer,
  355. struct inode *inode,
  356. struct file *file,
  357. v4l2_kioctl drv)
  358. {
  359. int err;
  360. struct v4l2_framebuffer fbuf;
  361. memset(&fbuf, 0, sizeof(fbuf));
  362. fbuf.base = buffer->base;
  363. fbuf.fmt.height = buffer->height;
  364. fbuf.fmt.width = buffer->width;
  365. switch (buffer->depth) {
  366. case 8:
  367. fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB332;
  368. break;
  369. case 15:
  370. fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB555;
  371. break;
  372. case 16:
  373. fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB565;
  374. break;
  375. case 24:
  376. fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR24;
  377. break;
  378. case 32:
  379. fbuf.fmt.pixelformat = V4L2_PIX_FMT_BGR32;
  380. break;
  381. }
  382. fbuf.fmt.bytesperline = buffer->bytesperline;
  383. err = drv(inode, file, VIDIOC_S_FBUF, &fbuf);
  384. if (err < 0)
  385. dprintk("VIDIOCSFBUF / VIDIOC_S_FBUF: %d\n", err);
  386. return err;
  387. }
  388. static noinline int v4l1_compat_get_win_cap_dimensions(
  389. struct video_window *win,
  390. struct inode *inode,
  391. struct file *file,
  392. v4l2_kioctl drv)
  393. {
  394. int err;
  395. struct v4l2_format *fmt;
  396. fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
  397. if (!fmt) {
  398. err = -ENOMEM;
  399. return err;
  400. }
  401. memset(win, 0, sizeof(*win));
  402. fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
  403. err = drv(inode, file, VIDIOC_G_FMT, fmt);
  404. if (err < 0)
  405. dprintk("VIDIOCGWIN / VIDIOC_G_WIN: %d\n", err);
  406. if (err == 0) {
  407. win->x = fmt->fmt.win.w.left;
  408. win->y = fmt->fmt.win.w.top;
  409. win->width = fmt->fmt.win.w.width;
  410. win->height = fmt->fmt.win.w.height;
  411. win->chromakey = fmt->fmt.win.chromakey;
  412. win->clips = NULL;
  413. win->clipcount = 0;
  414. goto done;
  415. }
  416. fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  417. err = drv(inode, file, VIDIOC_G_FMT, fmt);
  418. if (err < 0) {
  419. dprintk("VIDIOCGWIN / VIDIOC_G_FMT: %d\n", err);
  420. goto done;
  421. }
  422. win->x = 0;
  423. win->y = 0;
  424. win->width = fmt->fmt.pix.width;
  425. win->height = fmt->fmt.pix.height;
  426. win->chromakey = 0;
  427. win->clips = NULL;
  428. win->clipcount = 0;
  429. done:
  430. kfree(fmt);
  431. return err;
  432. }
  433. static noinline int v4l1_compat_set_win_cap_dimensions(
  434. struct video_window *win,
  435. struct inode *inode,
  436. struct file *file,
  437. v4l2_kioctl drv)
  438. {
  439. int err, err1, err2;
  440. struct v4l2_format *fmt;
  441. fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
  442. if (!fmt) {
  443. err = -ENOMEM;
  444. return err;
  445. }
  446. fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  447. drv(inode, file, VIDIOC_STREAMOFF, &fmt->type);
  448. err1 = drv(inode, file, VIDIOC_G_FMT, fmt);
  449. if (err1 < 0)
  450. dprintk("VIDIOCSWIN / VIDIOC_G_FMT: %d\n", err1);
  451. if (err1 == 0) {
  452. fmt->fmt.pix.width = win->width;
  453. fmt->fmt.pix.height = win->height;
  454. fmt->fmt.pix.field = V4L2_FIELD_ANY;
  455. fmt->fmt.pix.bytesperline = 0;
  456. err = drv(inode, file, VIDIOC_S_FMT, fmt);
  457. if (err < 0)
  458. dprintk("VIDIOCSWIN / VIDIOC_S_FMT #1: %d\n",
  459. err);
  460. win->width = fmt->fmt.pix.width;
  461. win->height = fmt->fmt.pix.height;
  462. }
  463. memset(fmt, 0, sizeof(*fmt));
  464. fmt->type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
  465. fmt->fmt.win.w.left = win->x;
  466. fmt->fmt.win.w.top = win->y;
  467. fmt->fmt.win.w.width = win->width;
  468. fmt->fmt.win.w.height = win->height;
  469. fmt->fmt.win.chromakey = win->chromakey;
  470. fmt->fmt.win.clips = (void __user *)win->clips;
  471. fmt->fmt.win.clipcount = win->clipcount;
  472. err2 = drv(inode, file, VIDIOC_S_FMT, fmt);
  473. if (err2 < 0)
  474. dprintk("VIDIOCSWIN / VIDIOC_S_FMT #2: %d\n", err2);
  475. if (err1 != 0 && err2 != 0)
  476. err = err1;
  477. else
  478. err = 0;
  479. kfree(fmt);
  480. return err;
  481. }
  482. static noinline int v4l1_compat_turn_preview_on_off(
  483. int *on,
  484. struct inode *inode,
  485. struct file *file,
  486. v4l2_kioctl drv)
  487. {
  488. int err;
  489. enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  490. if (0 == *on) {
  491. /* dirty hack time. But v4l1 has no STREAMOFF
  492. * equivalent in the API, and this one at
  493. * least comes close ... */
  494. drv(inode, file, VIDIOC_STREAMOFF, &captype);
  495. }
  496. err = drv(inode, file, VIDIOC_OVERLAY, on);
  497. if (err < 0)
  498. dprintk("VIDIOCCAPTURE / VIDIOC_PREVIEW: %d\n", err);
  499. return err;
  500. }
  501. static noinline int v4l1_compat_get_input_info(
  502. struct video_channel *chan,
  503. struct inode *inode,
  504. struct file *file,
  505. v4l2_kioctl drv)
  506. {
  507. int err;
  508. struct v4l2_input input2;
  509. v4l2_std_id sid;
  510. memset(&input2, 0, sizeof(input2));
  511. input2.index = chan->channel;
  512. err = drv(inode, file, VIDIOC_ENUMINPUT, &input2);
  513. if (err < 0) {
  514. dprintk("VIDIOCGCHAN / VIDIOC_ENUMINPUT: "
  515. "channel=%d err=%d\n", chan->channel, err);
  516. goto done;
  517. }
  518. chan->channel = input2.index;
  519. memcpy(chan->name, input2.name,
  520. min(sizeof(chan->name), sizeof(input2.name)));
  521. chan->name[sizeof(chan->name) - 1] = 0;
  522. chan->tuners = (input2.type == V4L2_INPUT_TYPE_TUNER) ? 1 : 0;
  523. chan->flags = (chan->tuners) ? VIDEO_VC_TUNER : 0;
  524. switch (input2.type) {
  525. case V4L2_INPUT_TYPE_TUNER:
  526. chan->type = VIDEO_TYPE_TV;
  527. break;
  528. default:
  529. case V4L2_INPUT_TYPE_CAMERA:
  530. chan->type = VIDEO_TYPE_CAMERA;
  531. break;
  532. }
  533. chan->norm = 0;
  534. err = drv(inode, file, VIDIOC_G_STD, &sid);
  535. if (err < 0)
  536. dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %d\n", err);
  537. if (err == 0) {
  538. if (sid & V4L2_STD_PAL)
  539. chan->norm = VIDEO_MODE_PAL;
  540. if (sid & V4L2_STD_NTSC)
  541. chan->norm = VIDEO_MODE_NTSC;
  542. if (sid & V4L2_STD_SECAM)
  543. chan->norm = VIDEO_MODE_SECAM;
  544. }
  545. done:
  546. return err;
  547. }
  548. static noinline int v4l1_compat_set_input(
  549. struct video_channel *chan,
  550. struct inode *inode,
  551. struct file *file,
  552. v4l2_kioctl drv)
  553. {
  554. int err;
  555. v4l2_std_id sid = 0;
  556. err = drv(inode, file, VIDIOC_S_INPUT, &chan->channel);
  557. if (err < 0)
  558. dprintk("VIDIOCSCHAN / VIDIOC_S_INPUT: %d\n", err);
  559. switch (chan->norm) {
  560. case VIDEO_MODE_PAL:
  561. sid = V4L2_STD_PAL;
  562. break;
  563. case VIDEO_MODE_NTSC:
  564. sid = V4L2_STD_NTSC;
  565. break;
  566. case VIDEO_MODE_SECAM:
  567. sid = V4L2_STD_SECAM;
  568. break;
  569. }
  570. if (0 != sid) {
  571. err = drv(inode, file, VIDIOC_S_STD, &sid);
  572. if (err < 0)
  573. dprintk("VIDIOCSCHAN / VIDIOC_S_STD: %d\n", err);
  574. }
  575. return err;
  576. }
  577. static noinline int v4l1_compat_get_picture(
  578. struct video_picture *pict,
  579. struct inode *inode,
  580. struct file *file,
  581. v4l2_kioctl drv)
  582. {
  583. int err;
  584. struct v4l2_format *fmt;
  585. fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
  586. if (!fmt) {
  587. err = -ENOMEM;
  588. return err;
  589. }
  590. pict->brightness = get_v4l_control(inode, file,
  591. V4L2_CID_BRIGHTNESS, drv);
  592. pict->hue = get_v4l_control(inode, file,
  593. V4L2_CID_HUE, drv);
  594. pict->contrast = get_v4l_control(inode, file,
  595. V4L2_CID_CONTRAST, drv);
  596. pict->colour = get_v4l_control(inode, file,
  597. V4L2_CID_SATURATION, drv);
  598. pict->whiteness = get_v4l_control(inode, file,
  599. V4L2_CID_WHITENESS, drv);
  600. fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  601. err = drv(inode, file, VIDIOC_G_FMT, fmt);
  602. if (err < 0) {
  603. dprintk("VIDIOCGPICT / VIDIOC_G_FMT: %d\n", err);
  604. goto done;
  605. }
  606. pict->depth = ((fmt->fmt.pix.bytesperline << 3)
  607. + (fmt->fmt.pix.width - 1))
  608. / fmt->fmt.pix.width;
  609. pict->palette = pixelformat_to_palette(
  610. fmt->fmt.pix.pixelformat);
  611. done:
  612. kfree(fmt);
  613. return err;
  614. }
  615. static noinline int v4l1_compat_set_picture(
  616. struct video_picture *pict,
  617. struct inode *inode,
  618. struct file *file,
  619. v4l2_kioctl drv)
  620. {
  621. int err;
  622. struct v4l2_framebuffer fbuf;
  623. int mem_err = 0, ovl_err = 0;
  624. struct v4l2_format *fmt;
  625. fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
  626. if (!fmt) {
  627. err = -ENOMEM;
  628. return err;
  629. }
  630. memset(&fbuf, 0, sizeof(fbuf));
  631. set_v4l_control(inode, file,
  632. V4L2_CID_BRIGHTNESS, pict->brightness, drv);
  633. set_v4l_control(inode, file,
  634. V4L2_CID_HUE, pict->hue, drv);
  635. set_v4l_control(inode, file,
  636. V4L2_CID_CONTRAST, pict->contrast, drv);
  637. set_v4l_control(inode, file,
  638. V4L2_CID_SATURATION, pict->colour, drv);
  639. set_v4l_control(inode, file,
  640. V4L2_CID_WHITENESS, pict->whiteness, drv);
  641. /*
  642. * V4L1 uses this ioctl to set both memory capture and overlay
  643. * pixel format, while V4L2 has two different ioctls for this.
  644. * Some cards may not support one or the other, and may support
  645. * different pixel formats for memory vs overlay.
  646. */
  647. fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  648. err = drv(inode, file, VIDIOC_G_FMT, fmt);
  649. /* If VIDIOC_G_FMT failed, then the driver likely doesn't
  650. support memory capture. Trying to set the memory capture
  651. parameters would be pointless. */
  652. if (err < 0) {
  653. dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n", err);
  654. mem_err = -1000; /* didn't even try */
  655. } else if (fmt->fmt.pix.pixelformat !=
  656. palette_to_pixelformat(pict->palette)) {
  657. fmt->fmt.pix.pixelformat = palette_to_pixelformat(
  658. pict->palette);
  659. mem_err = drv(inode, file, VIDIOC_S_FMT, fmt);
  660. if (mem_err < 0)
  661. dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",
  662. mem_err);
  663. }
  664. err = drv(inode, file, VIDIOC_G_FBUF, &fbuf);
  665. /* If VIDIOC_G_FBUF failed, then the driver likely doesn't
  666. support overlay. Trying to set the overlay parameters
  667. would be quite pointless. */
  668. if (err < 0) {
  669. dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n", err);
  670. ovl_err = -1000; /* didn't even try */
  671. } else if (fbuf.fmt.pixelformat !=
  672. palette_to_pixelformat(pict->palette)) {
  673. fbuf.fmt.pixelformat = palette_to_pixelformat(
  674. pict->palette);
  675. ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf);
  676. if (ovl_err < 0)
  677. dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",
  678. ovl_err);
  679. }
  680. if (ovl_err < 0 && mem_err < 0) {
  681. /* ioctl failed, couldn't set either parameter */
  682. if (mem_err != -1000)
  683. err = mem_err;
  684. else if (ovl_err == -EPERM)
  685. err = 0;
  686. else
  687. err = ovl_err;
  688. } else
  689. err = 0;
  690. kfree(fmt);
  691. return err;
  692. }
  693. static noinline int v4l1_compat_get_tuner(
  694. struct video_tuner *tun,
  695. struct inode *inode,
  696. struct file *file,
  697. v4l2_kioctl drv)
  698. {
  699. int err, i;
  700. struct v4l2_tuner tun2;
  701. struct v4l2_standard std2;
  702. v4l2_std_id sid;
  703. memset(&tun2, 0, sizeof(tun2));
  704. err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
  705. if (err < 0) {
  706. dprintk("VIDIOCGTUNER / VIDIOC_G_TUNER: %d\n", err);
  707. goto done;
  708. }
  709. memcpy(tun->name, tun2.name,
  710. min(sizeof(tun->name), sizeof(tun2.name)));
  711. tun->name[sizeof(tun->name) - 1] = 0;
  712. tun->rangelow = tun2.rangelow;
  713. tun->rangehigh = tun2.rangehigh;
  714. tun->flags = 0;
  715. tun->mode = VIDEO_MODE_AUTO;
  716. for (i = 0; i < 64; i++) {
  717. memset(&std2, 0, sizeof(std2));
  718. std2.index = i;
  719. if (0 != drv(inode, file, VIDIOC_ENUMSTD, &std2))
  720. break;
  721. if (std2.id & V4L2_STD_PAL)
  722. tun->flags |= VIDEO_TUNER_PAL;
  723. if (std2.id & V4L2_STD_NTSC)
  724. tun->flags |= VIDEO_TUNER_NTSC;
  725. if (std2.id & V4L2_STD_SECAM)
  726. tun->flags |= VIDEO_TUNER_SECAM;
  727. }
  728. err = drv(inode, file, VIDIOC_G_STD, &sid);
  729. if (err < 0)
  730. dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %d\n", err);
  731. if (err == 0) {
  732. if (sid & V4L2_STD_PAL)
  733. tun->mode = VIDEO_MODE_PAL;
  734. if (sid & V4L2_STD_NTSC)
  735. tun->mode = VIDEO_MODE_NTSC;
  736. if (sid & V4L2_STD_SECAM)
  737. tun->mode = VIDEO_MODE_SECAM;
  738. }
  739. if (tun2.capability & V4L2_TUNER_CAP_LOW)
  740. tun->flags |= VIDEO_TUNER_LOW;
  741. if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
  742. tun->flags |= VIDEO_TUNER_STEREO_ON;
  743. tun->signal = tun2.signal;
  744. done:
  745. return err;
  746. }
  747. static noinline int v4l1_compat_select_tuner(
  748. struct video_tuner *tun,
  749. struct inode *inode,
  750. struct file *file,
  751. v4l2_kioctl drv)
  752. {
  753. int err;
  754. struct v4l2_tuner t;/*84 bytes on x86_64*/
  755. memset(&t, 0, sizeof(t));
  756. t.index = tun->tuner;
  757. err = drv(inode, file, VIDIOC_S_INPUT, &t);
  758. if (err < 0)
  759. dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %d\n", err);
  760. return err;
  761. }
  762. static noinline int v4l1_compat_get_frequency(
  763. unsigned long *freq,
  764. struct inode *inode,
  765. struct file *file,
  766. v4l2_kioctl drv)
  767. {
  768. int err;
  769. struct v4l2_frequency freq2;
  770. memset(&freq2, 0, sizeof(freq2));
  771. freq2.tuner = 0;
  772. err = drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
  773. if (err < 0)
  774. dprintk("VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %d\n", err);
  775. if (0 == err)
  776. *freq = freq2.frequency;
  777. return err;
  778. }
  779. static noinline int v4l1_compat_set_frequency(
  780. unsigned long *freq,
  781. struct inode *inode,
  782. struct file *file,
  783. v4l2_kioctl drv)
  784. {
  785. int err;
  786. struct v4l2_frequency freq2;
  787. memset(&freq2, 0, sizeof(freq2));
  788. drv(inode, file, VIDIOC_G_FREQUENCY, &freq2);
  789. freq2.frequency = *freq;
  790. err = drv(inode, file, VIDIOC_S_FREQUENCY, &freq2);
  791. if (err < 0)
  792. dprintk("VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %d\n", err);
  793. return err;
  794. }
  795. static noinline int v4l1_compat_get_audio(
  796. struct video_audio *aud,
  797. struct inode *inode,
  798. struct file *file,
  799. v4l2_kioctl drv)
  800. {
  801. int err, i;
  802. struct v4l2_queryctrl qctrl2;
  803. struct v4l2_audio aud2;
  804. struct v4l2_tuner tun2;
  805. memset(&aud2, 0, sizeof(aud2));
  806. err = drv(inode, file, VIDIOC_G_AUDIO, &aud2);
  807. if (err < 0) {
  808. dprintk("VIDIOCGAUDIO / VIDIOC_G_AUDIO: %d\n", err);
  809. goto done;
  810. }
  811. memcpy(aud->name, aud2.name,
  812. min(sizeof(aud->name), sizeof(aud2.name)));
  813. aud->name[sizeof(aud->name) - 1] = 0;
  814. aud->audio = aud2.index;
  815. aud->flags = 0;
  816. i = get_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME, drv);
  817. if (i >= 0) {
  818. aud->volume = i;
  819. aud->flags |= VIDEO_AUDIO_VOLUME;
  820. }
  821. i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BASS, drv);
  822. if (i >= 0) {
  823. aud->bass = i;
  824. aud->flags |= VIDEO_AUDIO_BASS;
  825. }
  826. i = get_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE, drv);
  827. if (i >= 0) {
  828. aud->treble = i;
  829. aud->flags |= VIDEO_AUDIO_TREBLE;
  830. }
  831. i = get_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE, drv);
  832. if (i >= 0) {
  833. aud->balance = i;
  834. aud->flags |= VIDEO_AUDIO_BALANCE;
  835. }
  836. i = get_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE, drv);
  837. if (i >= 0) {
  838. if (i)
  839. aud->flags |= VIDEO_AUDIO_MUTE;
  840. aud->flags |= VIDEO_AUDIO_MUTABLE;
  841. }
  842. aud->step = 1;
  843. qctrl2.id = V4L2_CID_AUDIO_VOLUME;
  844. if (drv(inode, file, VIDIOC_QUERYCTRL, &qctrl2) == 0 &&
  845. !(qctrl2.flags & V4L2_CTRL_FLAG_DISABLED))
  846. aud->step = qctrl2.step;
  847. aud->mode = 0;
  848. memset(&tun2, 0, sizeof(tun2));
  849. err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
  850. if (err < 0) {
  851. dprintk("VIDIOCGAUDIO / VIDIOC_G_TUNER: %d\n", err);
  852. err = 0;
  853. goto done;
  854. }
  855. if (tun2.rxsubchans & V4L2_TUNER_SUB_LANG2)
  856. aud->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
  857. else if (tun2.rxsubchans & V4L2_TUNER_SUB_STEREO)
  858. aud->mode = VIDEO_SOUND_STEREO;
  859. else if (tun2.rxsubchans & V4L2_TUNER_SUB_MONO)
  860. aud->mode = VIDEO_SOUND_MONO;
  861. done:
  862. return err;
  863. }
  864. static noinline int v4l1_compat_set_audio(
  865. struct video_audio *aud,
  866. struct inode *inode,
  867. struct file *file,
  868. v4l2_kioctl drv)
  869. {
  870. int err;
  871. struct v4l2_audio aud2;
  872. struct v4l2_tuner tun2;
  873. memset(&aud2, 0, sizeof(aud2));
  874. memset(&tun2, 0, sizeof(tun2));
  875. aud2.index = aud->audio;
  876. err = drv(inode, file, VIDIOC_S_AUDIO, &aud2);
  877. if (err < 0) {
  878. dprintk("VIDIOCSAUDIO / VIDIOC_S_AUDIO: %d\n", err);
  879. goto done;
  880. }
  881. set_v4l_control(inode, file, V4L2_CID_AUDIO_VOLUME,
  882. aud->volume, drv);
  883. set_v4l_control(inode, file, V4L2_CID_AUDIO_BASS,
  884. aud->bass, drv);
  885. set_v4l_control(inode, file, V4L2_CID_AUDIO_TREBLE,
  886. aud->treble, drv);
  887. set_v4l_control(inode, file, V4L2_CID_AUDIO_BALANCE,
  888. aud->balance, drv);
  889. set_v4l_control(inode, file, V4L2_CID_AUDIO_MUTE,
  890. !!(aud->flags & VIDEO_AUDIO_MUTE), drv);
  891. err = drv(inode, file, VIDIOC_G_TUNER, &tun2);
  892. if (err < 0)
  893. dprintk("VIDIOCSAUDIO / VIDIOC_G_TUNER: %d\n", err);
  894. if (err == 0) {
  895. switch (aud->mode) {
  896. default:
  897. case VIDEO_SOUND_MONO:
  898. case VIDEO_SOUND_LANG1:
  899. tun2.audmode = V4L2_TUNER_MODE_MONO;
  900. break;
  901. case VIDEO_SOUND_STEREO:
  902. tun2.audmode = V4L2_TUNER_MODE_STEREO;
  903. break;
  904. case VIDEO_SOUND_LANG2:
  905. tun2.audmode = V4L2_TUNER_MODE_LANG2;
  906. break;
  907. }
  908. err = drv(inode, file, VIDIOC_S_TUNER, &tun2);
  909. if (err < 0)
  910. dprintk("VIDIOCSAUDIO / VIDIOC_S_TUNER: %d\n", err);
  911. }
  912. err = 0;
  913. done:
  914. return err;
  915. }
  916. static noinline int v4l1_compat_capture_frame(
  917. struct video_mmap *mm,
  918. struct inode *inode,
  919. struct file *file,
  920. v4l2_kioctl drv)
  921. {
  922. int err;
  923. enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  924. struct v4l2_buffer buf;
  925. struct v4l2_format *fmt;
  926. fmt = kzalloc(sizeof(*fmt), GFP_KERNEL);
  927. if (!fmt) {
  928. err = -ENOMEM;
  929. return err;
  930. }
  931. memset(&buf, 0, sizeof(buf));
  932. fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  933. err = drv(inode, file, VIDIOC_G_FMT, fmt);
  934. if (err < 0) {
  935. dprintk("VIDIOCMCAPTURE / VIDIOC_G_FMT: %d\n", err);
  936. goto done;
  937. }
  938. if (mm->width != fmt->fmt.pix.width ||
  939. mm->height != fmt->fmt.pix.height ||
  940. palette_to_pixelformat(mm->format) !=
  941. fmt->fmt.pix.pixelformat) {
  942. /* New capture format... */
  943. fmt->fmt.pix.width = mm->width;
  944. fmt->fmt.pix.height = mm->height;
  945. fmt->fmt.pix.pixelformat =
  946. palette_to_pixelformat(mm->format);
  947. fmt->fmt.pix.field = V4L2_FIELD_ANY;
  948. fmt->fmt.pix.bytesperline = 0;
  949. err = drv(inode, file, VIDIOC_S_FMT, fmt);
  950. if (err < 0) {
  951. dprintk("VIDIOCMCAPTURE / VIDIOC_S_FMT: %d\n", err);
  952. goto done;
  953. }
  954. }
  955. buf.index = mm->frame;
  956. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  957. err = drv(inode, file, VIDIOC_QUERYBUF, &buf);
  958. if (err < 0) {
  959. dprintk("VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %d\n", err);
  960. goto done;
  961. }
  962. err = drv(inode, file, VIDIOC_QBUF, &buf);
  963. if (err < 0) {
  964. dprintk("VIDIOCMCAPTURE / VIDIOC_QBUF: %d\n", err);
  965. goto done;
  966. }
  967. err = drv(inode, file, VIDIOC_STREAMON, &captype);
  968. if (err < 0)
  969. dprintk("VIDIOCMCAPTURE / VIDIOC_STREAMON: %d\n", err);
  970. done:
  971. kfree(fmt);
  972. return err;
  973. }
  974. static noinline int v4l1_compat_sync(
  975. int *i,
  976. struct inode *inode,
  977. struct file *file,
  978. v4l2_kioctl drv)
  979. {
  980. int err;
  981. enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  982. struct v4l2_buffer buf;
  983. struct poll_wqueues *pwq;
  984. memset(&buf, 0, sizeof(buf));
  985. buf.index = *i;
  986. buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
  987. err = drv(inode, file, VIDIOC_QUERYBUF, &buf);
  988. if (err < 0) {
  989. /* No such buffer */
  990. dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err);
  991. goto done;
  992. }
  993. if (!(buf.flags & V4L2_BUF_FLAG_MAPPED)) {
  994. /* Buffer is not mapped */
  995. err = -EINVAL;
  996. goto done;
  997. }
  998. /* make sure capture actually runs so we don't block forever */
  999. err = drv(inode, file, VIDIOC_STREAMON, &captype);
  1000. if (err < 0) {
  1001. dprintk("VIDIOCSYNC / VIDIOC_STREAMON: %d\n", err);
  1002. goto done;
  1003. }
  1004. pwq = kmalloc(sizeof(*pwq), GFP_KERNEL);
  1005. /* Loop as long as the buffer is queued, but not done */
  1006. while ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE))
  1007. == V4L2_BUF_FLAG_QUEUED) {
  1008. err = poll_one(file, pwq);
  1009. if (err < 0 || /* error or sleep was interrupted */
  1010. err == 0) /* timeout? Shouldn't occur. */
  1011. break;
  1012. err = drv(inode, file, VIDIOC_QUERYBUF, &buf);
  1013. if (err < 0)
  1014. dprintk("VIDIOCSYNC / VIDIOC_QUERYBUF: %d\n", err);
  1015. }
  1016. kfree(pwq);
  1017. if (!(buf.flags & V4L2_BUF_FLAG_DONE)) /* not done */
  1018. goto done;
  1019. do {
  1020. err = drv(inode, file, VIDIOC_DQBUF, &buf);
  1021. if (err < 0)
  1022. dprintk("VIDIOCSYNC / VIDIOC_DQBUF: %d\n", err);
  1023. } while (err == 0 && buf.index != *i);
  1024. done:
  1025. return err;
  1026. }
  1027. static noinline int v4l1_compat_get_vbi_format(
  1028. struct vbi_format *fmt,
  1029. struct inode *inode,
  1030. struct file *file,
  1031. v4l2_kioctl drv)
  1032. {
  1033. int err;
  1034. struct v4l2_format *fmt2;
  1035. fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
  1036. if (!fmt2) {
  1037. err = -ENOMEM;
  1038. return err;
  1039. }
  1040. fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
  1041. err = drv(inode, file, VIDIOC_G_FMT, fmt2);
  1042. if (err < 0) {
  1043. dprintk("VIDIOCGVBIFMT / VIDIOC_G_FMT: %d\n", err);
  1044. goto done;
  1045. }
  1046. if (fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY) {
  1047. err = -EINVAL;
  1048. goto done;
  1049. }
  1050. memset(fmt, 0, sizeof(*fmt));
  1051. fmt->samples_per_line = fmt2->fmt.vbi.samples_per_line;
  1052. fmt->sampling_rate = fmt2->fmt.vbi.sampling_rate;
  1053. fmt->sample_format = VIDEO_PALETTE_RAW;
  1054. fmt->start[0] = fmt2->fmt.vbi.start[0];
  1055. fmt->count[0] = fmt2->fmt.vbi.count[0];
  1056. fmt->start[1] = fmt2->fmt.vbi.start[1];
  1057. fmt->count[1] = fmt2->fmt.vbi.count[1];
  1058. fmt->flags = fmt2->fmt.vbi.flags & 0x03;
  1059. done:
  1060. kfree(fmt2);
  1061. return err;
  1062. }
  1063. static noinline int v4l1_compat_set_vbi_format(
  1064. struct vbi_format *fmt,
  1065. struct inode *inode,
  1066. struct file *file,
  1067. v4l2_kioctl drv)
  1068. {
  1069. int err;
  1070. struct v4l2_format *fmt2 = NULL;
  1071. if (VIDEO_PALETTE_RAW != fmt->sample_format) {
  1072. err = -EINVAL;
  1073. return err;
  1074. }
  1075. fmt2 = kzalloc(sizeof(*fmt2), GFP_KERNEL);
  1076. if (!fmt2) {
  1077. err = -ENOMEM;
  1078. return err;
  1079. }
  1080. fmt2->type = V4L2_BUF_TYPE_VBI_CAPTURE;
  1081. fmt2->fmt.vbi.samples_per_line = fmt->samples_per_line;
  1082. fmt2->fmt.vbi.sampling_rate = fmt->sampling_rate;
  1083. fmt2->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
  1084. fmt2->fmt.vbi.start[0] = fmt->start[0];
  1085. fmt2->fmt.vbi.count[0] = fmt->count[0];
  1086. fmt2->fmt.vbi.start[1] = fmt->start[1];
  1087. fmt2->fmt.vbi.count[1] = fmt->count[1];
  1088. fmt2->fmt.vbi.flags = fmt->flags;
  1089. err = drv(inode, file, VIDIOC_TRY_FMT, fmt2);
  1090. if (err < 0) {
  1091. dprintk("VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %d\n", err);
  1092. goto done;
  1093. }
  1094. if (fmt2->fmt.vbi.samples_per_line != fmt->samples_per_line ||
  1095. fmt2->fmt.vbi.sampling_rate != fmt->sampling_rate ||
  1096. fmt2->fmt.vbi.sample_format != V4L2_PIX_FMT_GREY ||
  1097. fmt2->fmt.vbi.start[0] != fmt->start[0] ||
  1098. fmt2->fmt.vbi.count[0] != fmt->count[0] ||
  1099. fmt2->fmt.vbi.start[1] != fmt->start[1] ||
  1100. fmt2->fmt.vbi.count[1] != fmt->count[1] ||
  1101. fmt2->fmt.vbi.flags != fmt->flags) {
  1102. err = -EINVAL;
  1103. goto done;
  1104. }
  1105. err = drv(inode, file, VIDIOC_S_FMT, fmt2);
  1106. if (err < 0)
  1107. dprintk("VIDIOCSVBIFMT / VIDIOC_S_FMT: %d\n", err);
  1108. done:
  1109. kfree(fmt2);
  1110. return err;
  1111. }
  1112. /*
  1113. * This function is exported.
  1114. */
  1115. int
  1116. v4l_compat_translate_ioctl(struct inode *inode,
  1117. struct file *file,
  1118. int cmd,
  1119. void *arg,
  1120. v4l2_kioctl drv)
  1121. {
  1122. int err;
  1123. switch (cmd) {
  1124. case VIDIOCGCAP: /* capability */
  1125. err = v4l1_compat_get_capabilities(arg, inode, file, drv);
  1126. break;
  1127. case VIDIOCGFBUF: /* get frame buffer */
  1128. err = v4l1_compat_get_frame_buffer(arg, inode, file, drv);
  1129. break;
  1130. case VIDIOCSFBUF: /* set frame buffer */
  1131. err = v4l1_compat_set_frame_buffer(arg, inode, file, drv);
  1132. break;
  1133. case VIDIOCGWIN: /* get window or capture dimensions */
  1134. err = v4l1_compat_get_win_cap_dimensions(arg, inode, file, drv);
  1135. break;
  1136. case VIDIOCSWIN: /* set window and/or capture dimensions */
  1137. err = v4l1_compat_set_win_cap_dimensions(arg, inode, file, drv);
  1138. break;
  1139. case VIDIOCCAPTURE: /* turn on/off preview */
  1140. err = v4l1_compat_turn_preview_on_off(arg, inode, file, drv);
  1141. break;
  1142. case VIDIOCGCHAN: /* get input information */
  1143. err = v4l1_compat_get_input_info(arg, inode, file, drv);
  1144. break;
  1145. case VIDIOCSCHAN: /* set input */
  1146. err = v4l1_compat_set_input(arg, inode, file, drv);
  1147. break;
  1148. case VIDIOCGPICT: /* get tone controls & partial capture format */
  1149. err = v4l1_compat_get_picture(arg, inode, file, drv);
  1150. break;
  1151. case VIDIOCSPICT: /* set tone controls & partial capture format */
  1152. err = v4l1_compat_set_picture(arg, inode, file, drv);
  1153. break;
  1154. case VIDIOCGTUNER: /* get tuner information */
  1155. err = v4l1_compat_get_tuner(arg, inode, file, drv);
  1156. break;
  1157. case VIDIOCSTUNER: /* select a tuner input */
  1158. err = v4l1_compat_select_tuner(arg, inode, file, drv);
  1159. break;
  1160. case VIDIOCGFREQ: /* get frequency */
  1161. err = v4l1_compat_get_frequency(arg, inode, file, drv);
  1162. break;
  1163. case VIDIOCSFREQ: /* set frequency */
  1164. err = v4l1_compat_set_frequency(arg, inode, file, drv);
  1165. break;
  1166. case VIDIOCGAUDIO: /* get audio properties/controls */
  1167. err = v4l1_compat_get_audio(arg, inode, file, drv);
  1168. break;
  1169. case VIDIOCSAUDIO: /* set audio controls */
  1170. err = v4l1_compat_set_audio(arg, inode, file, drv);
  1171. break;
  1172. case VIDIOCMCAPTURE: /* capture a frame */
  1173. err = v4l1_compat_capture_frame(arg, inode, file, drv);
  1174. break;
  1175. case VIDIOCSYNC: /* wait for a frame */
  1176. err = v4l1_compat_sync(arg, inode, file, drv);
  1177. break;
  1178. case VIDIOCGVBIFMT: /* query VBI data capture format */
  1179. err = v4l1_compat_get_vbi_format(arg, inode, file, drv);
  1180. break;
  1181. case VIDIOCSVBIFMT:
  1182. err = v4l1_compat_set_vbi_format(arg, inode, file, drv);
  1183. break;
  1184. default:
  1185. err = -ENOIOCTLCMD;
  1186. break;
  1187. }
  1188. return err;
  1189. }
  1190. EXPORT_SYMBOL(v4l_compat_translate_ioctl);
  1191. /*
  1192. * Local variables:
  1193. * c-basic-offset: 8
  1194. * End:
  1195. */