2005-04-17 02:20:36 +04:00
/*
2005-06-24 09:05:09 +04:00
*
2005-04-17 02:20:36 +04:00
* Video for Linux Two
* Backward Compatibility Layer
*
* Support subroutines for providing V4L2 drivers with backward
* compatibility with applications using the old API .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*
2007-01-09 17:20:59 +03:00
* Author : Bill Dirks < bill @ thedirks . org >
2005-04-17 02:20:36 +04:00
* et al .
*
*/
# include <linux/init.h>
# include <linux/module.h>
# include <linux/types.h>
# include <linux/kernel.h>
# include <linux/sched.h>
# include <linux/mm.h>
# include <linux/fs.h>
# include <linux/file.h>
# include <linux/string.h>
# include <linux/errno.h>
# include <linux/slab.h>
# include <linux/videodev.h>
2006-06-05 17:26:32 +04:00
# include <media/v4l2-common.h>
2008-07-20 15:12:02 +04:00
# include <media/v4l2-ioctl.h>
2005-04-17 02:20:36 +04:00
# include <asm/uaccess.h>
# include <asm/system.h>
# include <asm/pgtable.h>
2008-04-22 21:41:48 +04:00
static unsigned int debug ;
2005-04-17 02:20:36 +04:00
module_param ( debug , int , 0644 ) ;
2008-04-22 21:45:57 +04:00
MODULE_PARM_DESC ( debug , " enable debug messages " ) ;
2005-04-17 02:20:36 +04:00
MODULE_AUTHOR ( " Bill Dirks " ) ;
MODULE_DESCRIPTION ( " v4l(1) compatibility layer for v4l2 drivers. " ) ;
MODULE_LICENSE ( " GPL " ) ;
2008-04-22 21:45:57 +04:00
# define dprintk(fmt, arg...) \
do { \
if ( debug ) \
printk ( KERN_DEBUG " v4l1-compat: " fmt , # # arg ) ; \
} while ( 0 )
2005-04-17 02:20:36 +04:00
/*
* I O C T L T R A N S L A T I O N
*
* From here on down is the code for translating the numerous
* ioctl commands from the old API to the new API .
*/
static int
2008-10-21 18:27:20 +04:00
get_v4l_control ( struct file * file ,
2005-04-17 02:20:36 +04:00
int cid ,
v4l2_kioctl drv )
{
struct v4l2_queryctrl qctrl2 ;
struct v4l2_control ctrl2 ;
int err ;
qctrl2 . id = cid ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_QUERYCTRL , & qctrl2 ) ;
2005-04-17 02:20:36 +04:00
if ( err < 0 )
2008-04-22 21:45:57 +04:00
dprintk ( " VIDIOC_QUERYCTRL: %d \n " , err ) ;
if ( err = = 0 & & ! ( qctrl2 . flags & V4L2_CTRL_FLAG_DISABLED ) ) {
2005-04-17 02:20:36 +04:00
ctrl2 . id = qctrl2 . id ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_CTRL , & ctrl2 ) ;
2005-04-17 02:20:36 +04:00
if ( err < 0 ) {
2008-04-22 21:45:57 +04:00
dprintk ( " VIDIOC_G_CTRL: %d \n " , err ) ;
2005-04-17 02:20:36 +04:00
return 0 ;
}
2009-08-01 23:48:41 +04:00
return DIV_ROUND_CLOSEST ( ( ctrl2 . value - qctrl2 . minimum ) * 65535 ,
qctrl2 . maximum - qctrl2 . minimum ) ;
2005-04-17 02:20:36 +04:00
}
return 0 ;
}
static int
2008-10-21 18:27:20 +04:00
set_v4l_control ( struct file * file ,
2005-04-17 02:20:36 +04:00
int cid ,
int value ,
v4l2_kioctl drv )
{
struct v4l2_queryctrl qctrl2 ;
struct v4l2_control ctrl2 ;
int err ;
qctrl2 . id = cid ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_QUERYCTRL , & qctrl2 ) ;
2005-04-17 02:20:36 +04:00
if ( err < 0 )
2008-04-22 21:45:57 +04:00
dprintk ( " VIDIOC_QUERYCTRL: %d \n " , err ) ;
2005-04-17 02:20:36 +04:00
if ( err = = 0 & &
! ( qctrl2 . flags & V4L2_CTRL_FLAG_DISABLED ) & &
2008-04-22 21:45:57 +04:00
! ( qctrl2 . flags & V4L2_CTRL_FLAG_GRABBED ) ) {
2005-04-17 02:20:36 +04:00
if ( value < 0 )
value = 0 ;
if ( value > 65535 )
value = 65535 ;
if ( value & & qctrl2 . type = = V4L2_CTRL_TYPE_BOOLEAN )
value = 65535 ;
ctrl2 . id = qctrl2 . id ;
ctrl2 . value =
( value * ( qctrl2 . maximum - qctrl2 . minimum )
+ 32767 )
/ 65535 ;
ctrl2 . value + = qctrl2 . minimum ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_S_CTRL , & ctrl2 ) ;
2005-04-17 02:20:36 +04:00
if ( err < 0 )
2008-04-22 21:45:57 +04:00
dprintk ( " VIDIOC_S_CTRL: %d \n " , err ) ;
2005-04-17 02:20:36 +04:00
}
return 0 ;
}
/* ----------------------------------------------------------------- */
2008-04-22 02:30:21 +04:00
static const unsigned int palette2pixelformat [ ] = {
2005-04-17 02:20:36 +04:00
[ VIDEO_PALETTE_GREY ] = V4L2_PIX_FMT_GREY ,
[ VIDEO_PALETTE_RGB555 ] = V4L2_PIX_FMT_RGB555 ,
[ VIDEO_PALETTE_RGB565 ] = V4L2_PIX_FMT_RGB565 ,
[ VIDEO_PALETTE_RGB24 ] = V4L2_PIX_FMT_BGR24 ,
[ VIDEO_PALETTE_RGB32 ] = V4L2_PIX_FMT_BGR32 ,
/* yuv packed pixel */
[ VIDEO_PALETTE_YUYV ] = V4L2_PIX_FMT_YUYV ,
[ VIDEO_PALETTE_YUV422 ] = V4L2_PIX_FMT_YUYV ,
[ VIDEO_PALETTE_UYVY ] = V4L2_PIX_FMT_UYVY ,
/* yuv planar */
[ VIDEO_PALETTE_YUV410P ] = V4L2_PIX_FMT_YUV410 ,
[ VIDEO_PALETTE_YUV420 ] = V4L2_PIX_FMT_YUV420 ,
[ VIDEO_PALETTE_YUV420P ] = V4L2_PIX_FMT_YUV420 ,
[ VIDEO_PALETTE_YUV411P ] = V4L2_PIX_FMT_YUV411P ,
[ VIDEO_PALETTE_YUV422P ] = V4L2_PIX_FMT_YUV422P ,
} ;
2007-10-18 14:07:07 +04:00
static unsigned int __pure
2005-04-17 02:20:36 +04:00
palette_to_pixelformat ( unsigned int palette )
{
if ( palette < ARRAY_SIZE ( palette2pixelformat ) )
return palette2pixelformat [ palette ] ;
else
return 0 ;
}
2007-04-28 05:56:28 +04:00
static unsigned int __attribute_const__
pixelformat_to_palette ( unsigned int pixelformat )
2005-04-17 02:20:36 +04:00
{
int palette = 0 ;
2008-04-22 21:45:57 +04:00
switch ( pixelformat ) {
2005-04-17 02:20:36 +04:00
case V4L2_PIX_FMT_GREY :
palette = VIDEO_PALETTE_GREY ;
break ;
case V4L2_PIX_FMT_RGB555 :
palette = VIDEO_PALETTE_RGB555 ;
break ;
case V4L2_PIX_FMT_RGB565 :
palette = VIDEO_PALETTE_RGB565 ;
break ;
case V4L2_PIX_FMT_BGR24 :
palette = VIDEO_PALETTE_RGB24 ;
break ;
case V4L2_PIX_FMT_BGR32 :
palette = VIDEO_PALETTE_RGB32 ;
break ;
/* yuv packed pixel */
case V4L2_PIX_FMT_YUYV :
palette = VIDEO_PALETTE_YUYV ;
break ;
case V4L2_PIX_FMT_UYVY :
palette = VIDEO_PALETTE_UYVY ;
break ;
/* yuv planar */
case V4L2_PIX_FMT_YUV410 :
palette = VIDEO_PALETTE_YUV420 ;
break ;
case V4L2_PIX_FMT_YUV420 :
palette = VIDEO_PALETTE_YUV420 ;
break ;
case V4L2_PIX_FMT_YUV411P :
palette = VIDEO_PALETTE_YUV411P ;
break ;
case V4L2_PIX_FMT_YUV422P :
palette = VIDEO_PALETTE_YUV422P ;
break ;
}
return palette ;
}
/* ----------------------------------------------------------------- */
2008-04-22 21:45:57 +04:00
static int poll_one ( struct file * file , struct poll_wqueues * pwq )
2005-04-17 02:20:36 +04:00
{
int retval = 1 ;
poll_table * table ;
2008-04-22 21:45:57 +04:00
poll_initwait ( pwq ) ;
table = & pwq - > pt ;
2005-04-17 02:20:36 +04:00
for ( ; ; ) {
int mask ;
mask = file - > f_op - > poll ( file , table ) ;
if ( mask & POLLIN )
break ;
table = NULL ;
if ( signal_pending ( current ) ) {
retval = - ERESTARTSYS ;
break ;
}
2009-01-07 01:40:59 +03:00
poll_schedule ( pwq , TASK_INTERRUPTIBLE ) ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
poll_freewait ( pwq ) ;
2005-04-17 02:20:36 +04:00
return retval ;
}
2008-04-22 21:45:57 +04:00
static int count_inputs (
struct file * file ,
v4l2_kioctl drv )
2005-04-17 02:20:36 +04:00
{
struct v4l2_input input2 ;
int i ;
for ( i = 0 ; ; i + + ) {
2008-04-22 21:45:57 +04:00
memset ( & input2 , 0 , sizeof ( input2 ) ) ;
2005-04-17 02:20:36 +04:00
input2 . index = i ;
2008-10-21 18:27:20 +04:00
if ( 0 ! = drv ( file , VIDIOC_ENUMINPUT , & input2 ) )
2005-04-17 02:20:36 +04:00
break ;
}
return i ;
}
2008-04-22 21:45:57 +04:00
static int check_size (
struct file * file ,
v4l2_kioctl drv ,
int * maxw ,
int * maxh )
2005-04-17 02:20:36 +04:00
{
struct v4l2_fmtdesc desc2 ;
struct v4l2_format fmt2 ;
2008-04-22 21:45:57 +04:00
memset ( & desc2 , 0 , sizeof ( desc2 ) ) ;
memset ( & fmt2 , 0 , sizeof ( fmt2 ) ) ;
2005-04-17 02:20:36 +04:00
desc2 . type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
2008-10-21 18:27:20 +04:00
if ( 0 ! = drv ( file , VIDIOC_ENUM_FMT , & desc2 ) )
2005-04-17 02:20:36 +04:00
goto done ;
fmt2 . type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
fmt2 . fmt . pix . width = 10000 ;
fmt2 . fmt . pix . height = 10000 ;
fmt2 . fmt . pix . pixelformat = desc2 . pixelformat ;
2008-10-21 18:27:20 +04:00
if ( 0 ! = drv ( file , VIDIOC_TRY_FMT , & fmt2 ) )
2005-04-17 02:20:36 +04:00
goto done ;
* maxw = fmt2 . fmt . pix . width ;
* maxh = fmt2 . fmt . pix . height ;
2008-04-22 21:45:57 +04:00
done :
2005-04-17 02:20:36 +04:00
return 0 ;
}
/* ----------------------------------------------------------------- */
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_get_capabilities (
2008-04-22 21:45:57 +04:00
struct video_capability * cap ,
struct file * file ,
v4l2_kioctl drv )
2005-04-17 02:20:36 +04:00
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
struct v4l2_framebuffer fbuf ;
struct v4l2_capability * cap2 ;
cap2 = kzalloc ( sizeof ( * cap2 ) , GFP_KERNEL ) ;
if ( ! cap2 ) {
err = - ENOMEM ;
return err ;
}
memset ( cap , 0 , sizeof ( * cap ) ) ;
memset ( & fbuf , 0 , sizeof ( fbuf ) ) ;
2005-04-17 02:20:36 +04:00
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_QUERYCAP , cap2 ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCGCAP / VIDIOC_QUERYCAP: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
if ( cap2 - > capabilities & V4L2_CAP_VIDEO_OVERLAY ) {
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_FBUF , & fbuf ) ;
2005-04-17 02:20:36 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCGCAP / VIDIOC_G_FBUF: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
memset ( & fbuf , 0 , sizeof ( fbuf ) ) ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
err = 0 ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
memcpy ( cap - > name , cap2 - > card ,
min ( sizeof ( cap - > name ) , sizeof ( cap2 - > card ) ) ) ;
cap - > name [ sizeof ( cap - > name ) - 1 ] = 0 ;
if ( cap2 - > capabilities & V4L2_CAP_VIDEO_CAPTURE )
cap - > type | = VID_TYPE_CAPTURE ;
if ( cap2 - > capabilities & V4L2_CAP_TUNER )
cap - > type | = VID_TYPE_TUNER ;
if ( cap2 - > capabilities & V4L2_CAP_VBI_CAPTURE )
cap - > type | = VID_TYPE_TELETEXT ;
if ( cap2 - > capabilities & V4L2_CAP_VIDEO_OVERLAY )
cap - > type | = VID_TYPE_OVERLAY ;
if ( fbuf . capability & V4L2_FBUF_CAP_LIST_CLIPPING )
cap - > type | = VID_TYPE_CLIPPING ;
2008-10-21 18:27:20 +04:00
cap - > channels = count_inputs ( file , drv ) ;
check_size ( file , drv ,
2008-04-22 21:45:57 +04:00
& cap - > maxwidth , & cap - > maxheight ) ;
cap - > audios = 0 ; /* FIXME */
cap - > minwidth = 48 ; /* FIXME */
cap - > minheight = 32 ; /* FIXME */
done :
kfree ( cap2 ) ;
return err ;
}
2006-08-06 16:10:06 +04:00
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_get_frame_buffer (
2008-04-22 21:45:57 +04:00
struct video_buffer * buffer ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
struct v4l2_framebuffer fbuf ;
2005-04-17 02:20:36 +04:00
2008-04-22 21:45:57 +04:00
memset ( buffer , 0 , sizeof ( * buffer ) ) ;
memset ( & fbuf , 0 , sizeof ( fbuf ) ) ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_FBUF , & fbuf ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCGFBUF / VIDIOC_G_FBUF: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
buffer - > base = fbuf . base ;
buffer - > height = fbuf . fmt . height ;
buffer - > width = fbuf . fmt . width ;
switch ( fbuf . fmt . pixelformat ) {
case V4L2_PIX_FMT_RGB332 :
buffer - > depth = 8 ;
2005-04-17 02:20:36 +04:00
break ;
2008-04-22 21:45:57 +04:00
case V4L2_PIX_FMT_RGB555 :
buffer - > depth = 15 ;
break ;
case V4L2_PIX_FMT_RGB565 :
buffer - > depth = 16 ;
break ;
case V4L2_PIX_FMT_BGR24 :
buffer - > depth = 24 ;
break ;
case V4L2_PIX_FMT_BGR32 :
buffer - > depth = 32 ;
break ;
default :
buffer - > depth = 0 ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
if ( fbuf . fmt . bytesperline ) {
buffer - > bytesperline = fbuf . fmt . bytesperline ;
if ( ! buffer - > depth & & buffer - > width )
buffer - > depth = ( ( fbuf . fmt . bytesperline < < 3 )
+ ( buffer - > width - 1 ) )
/ buffer - > width ;
} else {
buffer - > bytesperline =
( buffer - > width * buffer - > depth + 7 ) & 7 ;
buffer - > bytesperline > > = 3 ;
}
done :
return err ;
}
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_set_frame_buffer (
2008-04-22 21:45:57 +04:00
struct video_buffer * buffer ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
struct v4l2_framebuffer fbuf ;
memset ( & fbuf , 0 , sizeof ( fbuf ) ) ;
fbuf . base = buffer - > base ;
fbuf . fmt . height = buffer - > height ;
fbuf . fmt . width = buffer - > width ;
switch ( buffer - > depth ) {
case 8 :
fbuf . fmt . pixelformat = V4L2_PIX_FMT_RGB332 ;
break ;
case 15 :
fbuf . fmt . pixelformat = V4L2_PIX_FMT_RGB555 ;
break ;
case 16 :
fbuf . fmt . pixelformat = V4L2_PIX_FMT_RGB565 ;
break ;
case 24 :
fbuf . fmt . pixelformat = V4L2_PIX_FMT_BGR24 ;
break ;
case 32 :
fbuf . fmt . pixelformat = V4L2_PIX_FMT_BGR32 ;
2005-04-17 02:20:36 +04:00
break ;
}
2008-04-22 21:45:57 +04:00
fbuf . fmt . bytesperline = buffer - > bytesperline ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_S_FBUF , & fbuf ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSFBUF / VIDIOC_S_FBUF: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
return err ;
}
2005-04-17 02:20:36 +04:00
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_get_win_cap_dimensions (
2008-04-22 21:45:57 +04:00
struct video_window * win ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
struct v4l2_format * fmt ;
2005-04-17 02:20:36 +04:00
2008-04-22 21:45:57 +04:00
fmt = kzalloc ( sizeof ( * fmt ) , GFP_KERNEL ) ;
if ( ! fmt ) {
err = - ENOMEM ;
return err ;
}
memset ( win , 0 , sizeof ( * win ) ) ;
2005-04-17 02:20:36 +04:00
2008-04-22 21:45:57 +04:00
fmt - > type = V4L2_BUF_TYPE_VIDEO_OVERLAY ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_FMT , fmt ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCGWIN / VIDIOC_G_WIN: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
if ( err = = 0 ) {
win - > x = fmt - > fmt . win . w . left ;
win - > y = fmt - > fmt . win . w . top ;
win - > width = fmt - > fmt . win . w . width ;
win - > height = fmt - > fmt . win . w . height ;
win - > chromakey = fmt - > fmt . win . chromakey ;
2005-04-17 02:20:36 +04:00
win - > clips = NULL ;
win - > clipcount = 0 ;
2008-04-22 21:45:57 +04:00
goto done ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
fmt - > type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_FMT , fmt ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCGWIN / VIDIOC_G_FMT: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
win - > x = 0 ;
win - > y = 0 ;
win - > width = fmt - > fmt . pix . width ;
win - > height = fmt - > fmt . pix . height ;
win - > chromakey = 0 ;
win - > clips = NULL ;
win - > clipcount = 0 ;
done :
kfree ( fmt ) ;
return err ;
}
2005-04-17 02:20:36 +04:00
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_set_win_cap_dimensions (
2008-04-22 21:45:57 +04:00
struct video_window * win ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err , err1 , err2 ;
2008-04-22 21:45:57 +04:00
struct v4l2_format * fmt ;
fmt = kzalloc ( sizeof ( * fmt ) , GFP_KERNEL ) ;
if ( ! fmt ) {
err = - ENOMEM ;
return err ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
fmt - > type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
2008-10-21 18:27:20 +04:00
drv ( file , VIDIOC_STREAMOFF , & fmt - > type ) ;
err1 = drv ( file , VIDIOC_G_FMT , fmt ) ;
2008-04-22 21:45:57 +04:00
if ( err1 < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSWIN / VIDIOC_G_FMT: %ld \n " , err1 ) ;
2008-04-22 21:45:57 +04:00
if ( err1 = = 0 ) {
fmt - > fmt . pix . width = win - > width ;
fmt - > fmt . pix . height = win - > height ;
fmt - > fmt . pix . field = V4L2_FIELD_ANY ;
fmt - > fmt . pix . bytesperline = 0 ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_S_FMT , fmt ) ;
2005-04-17 02:20:36 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSWIN / VIDIOC_S_FMT #1: %ld \n " ,
2008-04-22 21:45:57 +04:00
err ) ;
win - > width = fmt - > fmt . pix . width ;
win - > height = fmt - > fmt . pix . height ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
memset ( fmt , 0 , sizeof ( * fmt ) ) ;
fmt - > type = V4L2_BUF_TYPE_VIDEO_OVERLAY ;
fmt - > fmt . win . w . left = win - > x ;
fmt - > fmt . win . w . top = win - > y ;
fmt - > fmt . win . w . width = win - > width ;
fmt - > fmt . win . w . height = win - > height ;
fmt - > fmt . win . chromakey = win - > chromakey ;
fmt - > fmt . win . clips = ( void __user * ) win - > clips ;
fmt - > fmt . win . clipcount = win - > clipcount ;
2008-10-21 18:27:20 +04:00
err2 = drv ( file , VIDIOC_S_FMT , fmt ) ;
2008-04-22 21:45:57 +04:00
if ( err2 < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSWIN / VIDIOC_S_FMT #2: %ld \n " , err2 ) ;
2008-04-22 21:45:57 +04:00
if ( err1 ! = 0 & & err2 ! = 0 )
err = err1 ;
else
err = 0 ;
kfree ( fmt ) ;
return err ;
}
2005-04-17 02:20:36 +04:00
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_turn_preview_on_off (
2008-04-22 21:45:57 +04:00
int * on ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
if ( 0 = = * on ) {
/* dirty hack time. But v4l1 has no STREAMOFF
* equivalent in the API , and this one at
* least comes close . . . */
2008-10-21 18:27:20 +04:00
drv ( file , VIDIOC_STREAMOFF , & captype ) ;
2005-04-17 02:20:36 +04:00
}
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_OVERLAY , on ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCCAPTURE / VIDIOC_PREVIEW: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
return err ;
}
2008-03-06 02:24:43 +03:00
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_get_input_info (
2008-04-22 21:45:57 +04:00
struct video_channel * chan ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
struct v4l2_input input2 ;
v4l2_std_id sid ;
2006-08-08 16:10:16 +04:00
2008-04-22 21:45:57 +04:00
memset ( & input2 , 0 , sizeof ( input2 ) ) ;
input2 . index = chan - > channel ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_ENUMINPUT , & input2 ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
dprintk ( " VIDIOCGCHAN / VIDIOC_ENUMINPUT: "
2008-12-30 13:04:34 +03:00
" channel=%d err=%ld \n " , chan - > channel , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
chan - > channel = input2 . index ;
memcpy ( chan - > name , input2 . name ,
min ( sizeof ( chan - > name ) , sizeof ( input2 . name ) ) ) ;
chan - > name [ sizeof ( chan - > name ) - 1 ] = 0 ;
chan - > tuners = ( input2 . type = = V4L2_INPUT_TYPE_TUNER ) ? 1 : 0 ;
chan - > flags = ( chan - > tuners ) ? VIDEO_VC_TUNER : 0 ;
switch ( input2 . type ) {
case V4L2_INPUT_TYPE_TUNER :
chan - > type = VIDEO_TYPE_TV ;
break ;
default :
case V4L2_INPUT_TYPE_CAMERA :
chan - > type = VIDEO_TYPE_CAMERA ;
2005-04-17 02:20:36 +04:00
break ;
}
2008-04-22 21:45:57 +04:00
chan - > norm = 0 ;
2009-09-15 15:08:20 +04:00
/* Note: G_STD might not be present for radio receivers,
* so we should ignore any errors . */
if ( drv ( file , VIDIOC_G_STD , & sid ) = = 0 ) {
2008-04-22 21:45:57 +04:00
if ( sid & V4L2_STD_PAL )
chan - > norm = VIDEO_MODE_PAL ;
if ( sid & V4L2_STD_NTSC )
chan - > norm = VIDEO_MODE_NTSC ;
if ( sid & V4L2_STD_SECAM )
chan - > norm = VIDEO_MODE_SECAM ;
2009-03-29 15:12:27 +04:00
if ( sid = = V4L2_STD_ALL )
chan - > norm = VIDEO_MODE_AUTO ;
2008-04-22 21:45:57 +04:00
}
done :
return err ;
}
2007-04-28 05:56:29 +04:00
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_set_input (
2008-04-22 21:45:57 +04:00
struct video_channel * chan ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
v4l2_std_id sid = 0 ;
2005-04-17 02:20:36 +04:00
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_S_INPUT , & chan - > channel ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSCHAN / VIDIOC_S_INPUT: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
switch ( chan - > norm ) {
case VIDEO_MODE_PAL :
sid = V4L2_STD_PAL ;
break ;
case VIDEO_MODE_NTSC :
sid = V4L2_STD_NTSC ;
break ;
case VIDEO_MODE_SECAM :
sid = V4L2_STD_SECAM ;
2005-04-17 02:20:36 +04:00
break ;
2009-03-29 15:12:27 +04:00
case VIDEO_MODE_AUTO :
sid = V4L2_STD_ALL ;
break ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
if ( 0 ! = sid ) {
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_S_STD , & sid ) ;
2005-04-17 02:20:36 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSCHAN / VIDIOC_S_STD: %ld \n " , err ) ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
return err ;
}
2006-11-20 18:10:04 +03:00
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_get_picture (
2008-04-22 21:45:57 +04:00
struct video_picture * pict ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
struct v4l2_format * fmt ;
2006-11-20 18:10:04 +03:00
2008-04-22 21:45:57 +04:00
fmt = kzalloc ( sizeof ( * fmt ) , GFP_KERNEL ) ;
if ( ! fmt ) {
err = - ENOMEM ;
return err ;
2005-04-17 02:20:36 +04:00
}
2008-10-21 18:27:20 +04:00
pict - > brightness = get_v4l_control ( file ,
2008-04-22 21:45:57 +04:00
V4L2_CID_BRIGHTNESS , drv ) ;
2008-10-21 18:27:20 +04:00
pict - > hue = get_v4l_control ( file ,
2008-04-22 21:45:57 +04:00
V4L2_CID_HUE , drv ) ;
2008-10-21 18:27:20 +04:00
pict - > contrast = get_v4l_control ( file ,
2008-04-22 21:45:57 +04:00
V4L2_CID_CONTRAST , drv ) ;
2008-10-21 18:27:20 +04:00
pict - > colour = get_v4l_control ( file ,
2008-04-22 21:45:57 +04:00
V4L2_CID_SATURATION , drv ) ;
2008-10-21 18:27:20 +04:00
pict - > whiteness = get_v4l_control ( file ,
2008-04-22 21:45:57 +04:00
V4L2_CID_WHITENESS , drv ) ;
fmt - > type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_FMT , fmt ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCGPICT / VIDIOC_G_FMT: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
2005-04-17 02:20:36 +04:00
}
2010-10-24 20:33:09 +04:00
if ( fmt - > fmt . pix . width )
{
pict - > depth = ( ( fmt - > fmt . pix . bytesperline < < 3 )
+ ( fmt - > fmt . pix . width - 1 ) )
/ fmt - > fmt . pix . width ;
} else {
err = - EINVAL ;
goto done ;
}
2008-04-22 21:45:57 +04:00
pict - > palette = pixelformat_to_palette (
fmt - > fmt . pix . pixelformat ) ;
done :
kfree ( fmt ) ;
return err ;
}
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_set_picture (
2008-04-22 21:45:57 +04:00
struct video_picture * pict ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
struct v4l2_framebuffer fbuf ;
int mem_err = 0 , ovl_err = 0 ;
struct v4l2_format * fmt ;
fmt = kzalloc ( sizeof ( * fmt ) , GFP_KERNEL ) ;
if ( ! fmt ) {
err = - ENOMEM ;
return err ;
}
memset ( & fbuf , 0 , sizeof ( fbuf ) ) ;
2008-10-21 18:27:20 +04:00
set_v4l_control ( file ,
2008-04-22 21:45:57 +04:00
V4L2_CID_BRIGHTNESS , pict - > brightness , drv ) ;
2008-10-21 18:27:20 +04:00
set_v4l_control ( file ,
2008-04-22 21:45:57 +04:00
V4L2_CID_HUE , pict - > hue , drv ) ;
2008-10-21 18:27:20 +04:00
set_v4l_control ( file ,
2008-04-22 21:45:57 +04:00
V4L2_CID_CONTRAST , pict - > contrast , drv ) ;
2008-10-21 18:27:20 +04:00
set_v4l_control ( file ,
2008-04-22 21:45:57 +04:00
V4L2_CID_SATURATION , pict - > colour , drv ) ;
2008-10-21 18:27:20 +04:00
set_v4l_control ( file ,
2008-04-22 21:45:57 +04:00
V4L2_CID_WHITENESS , pict - > whiteness , drv ) ;
/*
* V4L1 uses this ioctl to set both memory capture and overlay
* pixel format , while V4L2 has two different ioctls for this .
* Some cards may not support one or the other , and may support
* different pixel formats for memory vs overlay .
*/
fmt - > type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_FMT , fmt ) ;
2008-04-22 21:45:57 +04:00
/* If VIDIOC_G_FMT failed, then the driver likely doesn't
support memory capture . Trying to set the memory capture
parameters would be pointless . */
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSPICT / VIDIOC_G_FMT: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
mem_err = - 1000 ; /* didn't even try */
} else if ( fmt - > fmt . pix . pixelformat ! =
palette_to_pixelformat ( pict - > palette ) ) {
fmt - > fmt . pix . pixelformat = palette_to_pixelformat (
pict - > palette ) ;
2008-10-21 18:27:20 +04:00
mem_err = drv ( file , VIDIOC_S_FMT , fmt ) ;
2008-04-22 21:45:57 +04:00
if ( mem_err < 0 )
dprintk ( " VIDIOCSPICT / VIDIOC_S_FMT: %d \n " ,
mem_err ) ;
2005-04-17 02:20:36 +04:00
}
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_FBUF , & fbuf ) ;
2008-04-22 21:45:57 +04:00
/* If VIDIOC_G_FBUF failed, then the driver likely doesn't
support overlay . Trying to set the overlay parameters
would be quite pointless . */
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSPICT / VIDIOC_G_FBUF: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
ovl_err = - 1000 ; /* didn't even try */
} else if ( fbuf . fmt . pixelformat ! =
palette_to_pixelformat ( pict - > palette ) ) {
fbuf . fmt . pixelformat = palette_to_pixelformat (
pict - > palette ) ;
2008-10-21 18:27:20 +04:00
ovl_err = drv ( file , VIDIOC_S_FBUF , & fbuf ) ;
2008-04-22 21:45:57 +04:00
if ( ovl_err < 0 )
dprintk ( " VIDIOCSPICT / VIDIOC_S_FBUF: %d \n " ,
ovl_err ) ;
}
if ( ovl_err < 0 & & mem_err < 0 ) {
/* ioctl failed, couldn't set either parameter */
if ( mem_err ! = - 1000 )
err = mem_err ;
else if ( ovl_err = = - EPERM )
2005-04-17 02:20:36 +04:00
err = 0 ;
2008-04-22 21:45:57 +04:00
else
err = ovl_err ;
} else
err = 0 ;
kfree ( fmt ) ;
return err ;
}
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_get_tuner (
2008-04-22 21:45:57 +04:00
struct video_tuner * tun ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
int i ;
2008-04-22 21:45:57 +04:00
struct v4l2_tuner tun2 ;
struct v4l2_standard std2 ;
v4l2_std_id sid ;
memset ( & tun2 , 0 , sizeof ( tun2 ) ) ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_TUNER , & tun2 ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCGTUNER / VIDIOC_G_TUNER: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
memcpy ( tun - > name , tun2 . name ,
min ( sizeof ( tun - > name ) , sizeof ( tun2 . name ) ) ) ;
tun - > name [ sizeof ( tun - > name ) - 1 ] = 0 ;
tun - > rangelow = tun2 . rangelow ;
tun - > rangehigh = tun2 . rangehigh ;
tun - > flags = 0 ;
tun - > mode = VIDEO_MODE_AUTO ;
for ( i = 0 ; i < 64 ; i + + ) {
memset ( & std2 , 0 , sizeof ( std2 ) ) ;
std2 . index = i ;
2008-10-21 18:27:20 +04:00
if ( 0 ! = drv ( file , VIDIOC_ENUMSTD , & std2 ) )
2005-04-17 02:20:36 +04:00
break ;
2008-04-22 21:45:57 +04:00
if ( std2 . id & V4L2_STD_PAL )
tun - > flags | = VIDEO_TUNER_PAL ;
if ( std2 . id & V4L2_STD_NTSC )
tun - > flags | = VIDEO_TUNER_NTSC ;
if ( std2 . id & V4L2_STD_SECAM )
tun - > flags | = VIDEO_TUNER_SECAM ;
}
2005-06-24 09:05:09 +04:00
2009-09-15 15:08:20 +04:00
/* Note: G_STD might not be present for radio receivers,
* so we should ignore any errors . */
if ( drv ( file , VIDIOC_G_STD , & sid ) = = 0 ) {
2008-04-22 21:45:57 +04:00
if ( sid & V4L2_STD_PAL )
tun - > mode = VIDEO_MODE_PAL ;
if ( sid & V4L2_STD_NTSC )
tun - > mode = VIDEO_MODE_NTSC ;
if ( sid & V4L2_STD_SECAM )
tun - > mode = VIDEO_MODE_SECAM ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
if ( tun2 . capability & V4L2_TUNER_CAP_LOW )
tun - > flags | = VIDEO_TUNER_LOW ;
if ( tun2 . rxsubchans & V4L2_TUNER_SUB_STEREO )
tun - > flags | = VIDEO_TUNER_STEREO_ON ;
tun - > signal = tun2 . signal ;
done :
return err ;
}
2005-04-17 02:20:36 +04:00
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_select_tuner (
2008-04-22 21:45:57 +04:00
struct video_tuner * tun ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
struct v4l2_tuner t ; /*84 bytes on x86_64*/
memset ( & t , 0 , sizeof ( t ) ) ;
2005-04-17 02:20:36 +04:00
2008-04-22 21:45:57 +04:00
t . index = tun - > tuner ;
2009-03-29 15:12:27 +04:00
err = drv ( file , VIDIOC_S_TUNER , & t ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 )
2009-03-29 15:12:27 +04:00
dprintk ( " VIDIOCSTUNER / VIDIOC_S_TUNER: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
return err ;
}
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_get_frequency (
2008-04-22 21:45:57 +04:00
unsigned long * freq ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
struct v4l2_frequency freq2 ;
memset ( & freq2 , 0 , sizeof ( freq2 ) ) ;
freq2 . tuner = 0 ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_FREQUENCY , & freq2 ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCGFREQ / VIDIOC_G_FREQUENCY: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
if ( 0 = = err )
* freq = freq2 . frequency ;
return err ;
}
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_set_frequency (
2008-04-22 21:45:57 +04:00
unsigned long * freq ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
struct v4l2_frequency freq2 ;
memset ( & freq2 , 0 , sizeof ( freq2 ) ) ;
2008-10-21 18:27:20 +04:00
drv ( file , VIDIOC_G_FREQUENCY , & freq2 ) ;
2008-04-22 21:45:57 +04:00
freq2 . frequency = * freq ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_S_FREQUENCY , & freq2 ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSFREQ / VIDIOC_S_FREQUENCY: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
return err ;
}
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_get_audio (
2008-04-22 21:45:57 +04:00
struct video_audio * aud ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
int i ;
2008-04-22 21:45:57 +04:00
struct v4l2_queryctrl qctrl2 ;
struct v4l2_audio aud2 ;
struct v4l2_tuner tun2 ;
memset ( & aud2 , 0 , sizeof ( aud2 ) ) ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_AUDIO , & aud2 ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCGAUDIO / VIDIOC_G_AUDIO: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
memcpy ( aud - > name , aud2 . name ,
min ( sizeof ( aud - > name ) , sizeof ( aud2 . name ) ) ) ;
aud - > name [ sizeof ( aud - > name ) - 1 ] = 0 ;
aud - > audio = aud2 . index ;
aud - > flags = 0 ;
2008-10-21 18:27:20 +04:00
i = get_v4l_control ( file , V4L2_CID_AUDIO_VOLUME , drv ) ;
2008-04-22 21:45:57 +04:00
if ( i > = 0 ) {
aud - > volume = i ;
aud - > flags | = VIDEO_AUDIO_VOLUME ;
}
2008-10-21 18:27:20 +04:00
i = get_v4l_control ( file , V4L2_CID_AUDIO_BASS , drv ) ;
2008-04-22 21:45:57 +04:00
if ( i > = 0 ) {
aud - > bass = i ;
aud - > flags | = VIDEO_AUDIO_BASS ;
}
2008-10-21 18:27:20 +04:00
i = get_v4l_control ( file , V4L2_CID_AUDIO_TREBLE , drv ) ;
2008-04-22 21:45:57 +04:00
if ( i > = 0 ) {
aud - > treble = i ;
aud - > flags | = VIDEO_AUDIO_TREBLE ;
}
2008-10-21 18:27:20 +04:00
i = get_v4l_control ( file , V4L2_CID_AUDIO_BALANCE , drv ) ;
2008-04-22 21:45:57 +04:00
if ( i > = 0 ) {
aud - > balance = i ;
aud - > flags | = VIDEO_AUDIO_BALANCE ;
}
2008-10-21 18:27:20 +04:00
i = get_v4l_control ( file , V4L2_CID_AUDIO_MUTE , drv ) ;
2008-04-22 21:45:57 +04:00
if ( i > = 0 ) {
if ( i )
aud - > flags | = VIDEO_AUDIO_MUTE ;
aud - > flags | = VIDEO_AUDIO_MUTABLE ;
}
aud - > step = 1 ;
qctrl2 . id = V4L2_CID_AUDIO_VOLUME ;
2008-10-21 18:27:20 +04:00
if ( drv ( file , VIDIOC_QUERYCTRL , & qctrl2 ) = = 0 & &
2008-04-22 21:45:57 +04:00
! ( qctrl2 . flags & V4L2_CTRL_FLAG_DISABLED ) )
aud - > step = qctrl2 . step ;
aud - > mode = 0 ;
memset ( & tun2 , 0 , sizeof ( tun2 ) ) ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_TUNER , & tun2 ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCGAUDIO / VIDIOC_G_TUNER: %ld \n " , err ) ;
2005-04-17 02:20:36 +04:00
err = 0 ;
2008-04-22 21:45:57 +04:00
goto done ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
if ( tun2 . rxsubchans & V4L2_TUNER_SUB_LANG2 )
aud - > mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2 ;
else if ( tun2 . rxsubchans & V4L2_TUNER_SUB_STEREO )
aud - > mode = VIDEO_SOUND_STEREO ;
else if ( tun2 . rxsubchans & V4L2_TUNER_SUB_MONO )
aud - > mode = VIDEO_SOUND_MONO ;
done :
return err ;
}
2005-04-17 02:20:36 +04:00
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_set_audio (
2008-04-22 21:45:57 +04:00
struct video_audio * aud ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
struct v4l2_audio aud2 ;
struct v4l2_tuner tun2 ;
memset ( & aud2 , 0 , sizeof ( aud2 ) ) ;
memset ( & tun2 , 0 , sizeof ( tun2 ) ) ;
aud2 . index = aud - > audio ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_S_AUDIO , & aud2 ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSAUDIO / VIDIOC_S_AUDIO: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
2008-10-21 18:27:20 +04:00
set_v4l_control ( file , V4L2_CID_AUDIO_VOLUME ,
2008-04-22 21:45:57 +04:00
aud - > volume , drv ) ;
2008-10-21 18:27:20 +04:00
set_v4l_control ( file , V4L2_CID_AUDIO_BASS ,
2008-04-22 21:45:57 +04:00
aud - > bass , drv ) ;
2008-10-21 18:27:20 +04:00
set_v4l_control ( file , V4L2_CID_AUDIO_TREBLE ,
2008-04-22 21:45:57 +04:00
aud - > treble , drv ) ;
2008-10-21 18:27:20 +04:00
set_v4l_control ( file , V4L2_CID_AUDIO_BALANCE ,
2008-04-22 21:45:57 +04:00
aud - > balance , drv ) ;
2008-10-21 18:27:20 +04:00
set_v4l_control ( file , V4L2_CID_AUDIO_MUTE ,
2008-04-22 21:45:57 +04:00
! ! ( aud - > flags & VIDEO_AUDIO_MUTE ) , drv ) ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_TUNER , & tun2 ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSAUDIO / VIDIOC_G_TUNER: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
if ( err = = 0 ) {
switch ( aud - > mode ) {
default :
case VIDEO_SOUND_MONO :
case VIDEO_SOUND_LANG1 :
tun2 . audmode = V4L2_TUNER_MODE_MONO ;
2005-04-17 02:20:36 +04:00
break ;
2008-04-22 21:45:57 +04:00
case VIDEO_SOUND_STEREO :
tun2 . audmode = V4L2_TUNER_MODE_STEREO ;
2005-04-17 02:20:36 +04:00
break ;
2008-04-22 21:45:57 +04:00
case VIDEO_SOUND_LANG2 :
tun2 . audmode = V4L2_TUNER_MODE_LANG2 ;
2005-04-17 02:20:36 +04:00
break ;
}
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_S_TUNER , & tun2 ) ;
2005-04-17 02:20:36 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSAUDIO / VIDIOC_S_TUNER: %ld \n " , err ) ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
err = 0 ;
done :
return err ;
}
2005-04-17 02:20:36 +04:00
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_capture_frame (
2008-04-22 21:45:57 +04:00
struct video_mmap * mm ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
struct v4l2_buffer buf ;
struct v4l2_format * fmt ;
2005-04-17 02:20:36 +04:00
2008-04-22 21:45:57 +04:00
fmt = kzalloc ( sizeof ( * fmt ) , GFP_KERNEL ) ;
if ( ! fmt ) {
err = - ENOMEM ;
return err ;
}
memset ( & buf , 0 , sizeof ( buf ) ) ;
fmt - > type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_FMT , fmt ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCMCAPTURE / VIDIOC_G_FMT: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
if ( mm - > width ! = fmt - > fmt . pix . width | |
mm - > height ! = fmt - > fmt . pix . height | |
palette_to_pixelformat ( mm - > format ) ! =
fmt - > fmt . pix . pixelformat ) {
/* New capture format... */
fmt - > fmt . pix . width = mm - > width ;
fmt - > fmt . pix . height = mm - > height ;
fmt - > fmt . pix . pixelformat =
palette_to_pixelformat ( mm - > format ) ;
fmt - > fmt . pix . field = V4L2_FIELD_ANY ;
fmt - > fmt . pix . bytesperline = 0 ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_S_FMT , fmt ) ;
2005-04-17 02:20:36 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCMCAPTURE / VIDIOC_S_FMT: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
}
buf . index = mm - > frame ;
buf . type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_QUERYBUF , & buf ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCMCAPTURE / VIDIOC_QUERYBUF: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_QBUF , & buf ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCMCAPTURE / VIDIOC_QBUF: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_STREAMON , & captype ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCMCAPTURE / VIDIOC_STREAMON: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
done :
kfree ( fmt ) ;
return err ;
}
2005-04-17 02:20:36 +04:00
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_sync (
2008-04-22 21:45:57 +04:00
int * i ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
enum v4l2_buf_type captype = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
struct v4l2_buffer buf ;
2008-04-22 21:45:57 +04:00
struct poll_wqueues * pwq ;
2008-04-22 21:45:57 +04:00
memset ( & buf , 0 , sizeof ( buf ) ) ;
buf . index = * i ;
buf . type = V4L2_BUF_TYPE_VIDEO_CAPTURE ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_QUERYBUF , & buf ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
/* No such buffer */
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSYNC / VIDIOC_QUERYBUF: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
if ( ! ( buf . flags & V4L2_BUF_FLAG_MAPPED ) ) {
/* Buffer is not mapped */
err = - EINVAL ;
goto done ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
/* make sure capture actually runs so we don't block forever */
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_STREAMON , & captype ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSYNC / VIDIOC_STREAMON: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
2005-04-17 02:20:36 +04:00
2008-04-22 21:45:57 +04:00
pwq = kmalloc ( sizeof ( * pwq ) , GFP_KERNEL ) ;
2008-04-22 21:45:57 +04:00
/* Loop as long as the buffer is queued, but not done */
while ( ( buf . flags & ( V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_DONE ) )
= = V4L2_BUF_FLAG_QUEUED ) {
2008-04-22 21:45:57 +04:00
err = poll_one ( file , pwq ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 | | /* error or sleep was interrupted */
err = = 0 ) /* timeout? Shouldn't occur. */
2008-03-06 02:24:43 +03:00
break ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_QUERYBUF , & buf ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSYNC / VIDIOC_QUERYBUF: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
}
2008-04-22 21:45:57 +04:00
kfree ( pwq ) ;
2008-04-22 21:45:57 +04:00
if ( ! ( buf . flags & V4L2_BUF_FLAG_DONE ) ) /* not done */
goto done ;
do {
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_DQBUF , & buf ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSYNC / VIDIOC_DQBUF: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
} while ( err = = 0 & & buf . index ! = * i ) ;
done :
return err ;
}
2005-04-17 02:20:36 +04:00
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_get_vbi_format (
2008-04-22 21:45:57 +04:00
struct vbi_format * fmt ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
struct v4l2_format * fmt2 ;
fmt2 = kzalloc ( sizeof ( * fmt2 ) , GFP_KERNEL ) ;
if ( ! fmt2 ) {
err = - ENOMEM ;
return err ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
fmt2 - > type = V4L2_BUF_TYPE_VBI_CAPTURE ;
2005-04-17 02:20:36 +04:00
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_G_FMT , fmt2 ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCGVBIFMT / VIDIOC_G_FMT: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
if ( fmt2 - > fmt . vbi . sample_format ! = V4L2_PIX_FMT_GREY ) {
err = - EINVAL ;
goto done ;
}
memset ( fmt , 0 , sizeof ( * fmt ) ) ;
fmt - > samples_per_line = fmt2 - > fmt . vbi . samples_per_line ;
fmt - > sampling_rate = fmt2 - > fmt . vbi . sampling_rate ;
fmt - > sample_format = VIDEO_PALETTE_RAW ;
fmt - > start [ 0 ] = fmt2 - > fmt . vbi . start [ 0 ] ;
fmt - > count [ 0 ] = fmt2 - > fmt . vbi . count [ 0 ] ;
fmt - > start [ 1 ] = fmt2 - > fmt . vbi . start [ 1 ] ;
fmt - > count [ 1 ] = fmt2 - > fmt . vbi . count [ 1 ] ;
fmt - > flags = fmt2 - > fmt . vbi . flags & 0x03 ;
done :
kfree ( fmt2 ) ;
return err ;
}
2006-01-09 20:25:27 +03:00
2008-12-30 13:04:34 +03:00
static noinline long v4l1_compat_set_vbi_format (
2008-04-22 21:45:57 +04:00
struct vbi_format * fmt ,
struct file * file ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2008-04-22 21:45:57 +04:00
struct v4l2_format * fmt2 = NULL ;
2005-04-17 02:20:36 +04:00
2008-04-22 21:45:57 +04:00
if ( VIDEO_PALETTE_RAW ! = fmt - > sample_format ) {
err = - EINVAL ;
return err ;
}
fmt2 = kzalloc ( sizeof ( * fmt2 ) , GFP_KERNEL ) ;
if ( ! fmt2 ) {
err = - ENOMEM ;
return err ;
2005-04-17 02:20:36 +04:00
}
2008-04-22 21:45:57 +04:00
fmt2 - > type = V4L2_BUF_TYPE_VBI_CAPTURE ;
fmt2 - > fmt . vbi . samples_per_line = fmt - > samples_per_line ;
fmt2 - > fmt . vbi . sampling_rate = fmt - > sampling_rate ;
fmt2 - > fmt . vbi . sample_format = V4L2_PIX_FMT_GREY ;
fmt2 - > fmt . vbi . start [ 0 ] = fmt - > start [ 0 ] ;
fmt2 - > fmt . vbi . count [ 0 ] = fmt - > count [ 0 ] ;
fmt2 - > fmt . vbi . start [ 1 ] = fmt - > start [ 1 ] ;
fmt2 - > fmt . vbi . count [ 1 ] = fmt - > count [ 1 ] ;
fmt2 - > fmt . vbi . flags = fmt - > flags ;
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_TRY_FMT , fmt2 ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 ) {
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSVBIFMT / VIDIOC_TRY_FMT: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
goto done ;
}
if ( fmt2 - > fmt . vbi . samples_per_line ! = fmt - > samples_per_line | |
fmt2 - > fmt . vbi . sampling_rate ! = fmt - > sampling_rate | |
fmt2 - > fmt . vbi . sample_format ! = V4L2_PIX_FMT_GREY | |
fmt2 - > fmt . vbi . start [ 0 ] ! = fmt - > start [ 0 ] | |
fmt2 - > fmt . vbi . count [ 0 ] ! = fmt - > count [ 0 ] | |
fmt2 - > fmt . vbi . start [ 1 ] ! = fmt - > start [ 1 ] | |
fmt2 - > fmt . vbi . count [ 1 ] ! = fmt - > count [ 1 ] | |
fmt2 - > fmt . vbi . flags ! = fmt - > flags ) {
err = - EINVAL ;
goto done ;
}
2008-10-21 18:27:20 +04:00
err = drv ( file , VIDIOC_S_FMT , fmt2 ) ;
2008-04-22 21:45:57 +04:00
if ( err < 0 )
2008-12-30 13:04:34 +03:00
dprintk ( " VIDIOCSVBIFMT / VIDIOC_S_FMT: %ld \n " , err ) ;
2008-04-22 21:45:57 +04:00
done :
kfree ( fmt2 ) ;
return err ;
}
/*
* This function is exported .
*/
2008-12-30 13:04:34 +03:00
long
2008-10-21 18:27:20 +04:00
v4l_compat_translate_ioctl ( struct file * file ,
2008-04-22 21:45:57 +04:00
int cmd ,
void * arg ,
v4l2_kioctl drv )
{
2008-12-30 13:04:34 +03:00
long err ;
2005-04-17 02:20:36 +04:00
2008-04-22 21:45:57 +04:00
switch ( cmd ) {
case VIDIOCGCAP : /* capability */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_get_capabilities ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCGFBUF : /* get frame buffer */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_get_frame_buffer ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCSFBUF : /* set frame buffer */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_set_frame_buffer ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCGWIN : /* get window or capture dimensions */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_get_win_cap_dimensions ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCSWIN : /* set window and/or capture dimensions */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_set_win_cap_dimensions ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCCAPTURE : /* turn on/off preview */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_turn_preview_on_off ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCGCHAN : /* get input information */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_get_input_info ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCSCHAN : /* set input */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_set_input ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCGPICT : /* get tone controls & partial capture format */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_get_picture ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCSPICT : /* set tone controls & partial capture format */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_set_picture ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCGTUNER : /* get tuner information */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_get_tuner ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCSTUNER : /* select a tuner input */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_select_tuner ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCGFREQ : /* get frequency */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_get_frequency ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCSFREQ : /* set frequency */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_set_frequency ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCGAUDIO : /* get audio properties/controls */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_get_audio ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCSAUDIO : /* set audio controls */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_set_audio ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCMCAPTURE : /* capture a frame */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_capture_frame ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCSYNC : /* wait for a frame */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_sync ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCGVBIFMT : /* query VBI data capture format */
2008-10-21 18:27:20 +04:00
err = v4l1_compat_get_vbi_format ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
case VIDIOCSVBIFMT :
2008-10-21 18:27:20 +04:00
err = v4l1_compat_set_vbi_format ( arg , file , drv ) ;
2008-04-22 21:45:57 +04:00
break ;
2005-04-17 02:20:36 +04:00
default :
err = - ENOIOCTLCMD ;
break ;
}
return err ;
}
EXPORT_SYMBOL ( v4l_compat_translate_ioctl ) ;
/*
* Local variables :
* c - basic - offset : 8
* End :
*/