2005-04-16 15:20:36 -07:00
/*
*
* ( c ) 2004 Gerd Knorr < kraxel @ bytesex . org > [ SuSE Labs ]
*
* 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 .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include <linux/init.h>
# include <linux/list.h>
# include <linux/module.h>
# include <linux/kernel.h>
2009-07-11 22:08:37 +04:00
# include <linux/smp_lock.h>
2005-04-16 15:20:36 -07:00
# include <linux/delay.h>
# include "saa7134-reg.h"
# include "saa7134.h"
# include <media/saa6752hs.h>
2006-01-09 15:32:31 -02:00
# include <media/v4l2-common.h>
2008-08-08 12:43:59 -03:00
# include <media/v4l2-chip-ident.h>
2005-04-16 15:20:36 -07:00
/* ------------------------------------------------------------------ */
MODULE_AUTHOR ( " Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] " ) ;
MODULE_LICENSE ( " GPL " ) ;
static unsigned int empress_nr [ ] = { [ 0 . . . ( SAA7134_MAXBOARDS - 1 ) ] = UNSET } ;
2005-12-12 00:37:28 -08:00
2005-04-16 15:20:36 -07:00
module_param_array ( empress_nr , int , NULL , 0444 ) ;
MODULE_PARM_DESC ( empress_nr , " ts device number " ) ;
2008-04-22 14:41:48 -03:00
static unsigned int debug ;
2005-04-16 15:20:36 -07:00
module_param ( debug , int , 0644 ) ;
MODULE_PARM_DESC ( debug , " enable debug messages " ) ;
# define dprintk(fmt, arg...) if (debug) \
printk ( KERN_DEBUG " %s/empress: " fmt , dev - > name , # # arg )
/* ------------------------------------------------------------------ */
static void ts_reset_encoder ( struct saa7134_dev * dev )
{
if ( ! dev - > empress_started )
return ;
saa_writeb ( SAA7134_SPECIAL_MODE , 0x00 ) ;
msleep ( 10 ) ;
2005-11-08 21:37:43 -08:00
saa_writeb ( SAA7134_SPECIAL_MODE , 0x01 ) ;
2005-04-16 15:20:36 -07:00
msleep ( 100 ) ;
dev - > empress_started = 0 ;
}
static int ts_init_encoder ( struct saa7134_dev * dev )
{
2008-08-26 13:44:40 -03:00
u32 leading_null_bytes = 0 ;
2006-06-18 16:40:10 -03:00
2008-08-26 13:44:40 -03:00
/* If more cards start to need this, then this
should probably be added to the card definitions . */
switch ( dev - > board ) {
case SAA7134_BOARD_BEHOLD_M6 :
case SAA7134_BOARD_BEHOLD_M63 :
case SAA7134_BOARD_BEHOLD_M6_EXTRA :
leading_null_bytes = 1 ;
break ;
}
2005-04-16 15:20:36 -07:00
ts_reset_encoder ( dev ) ;
2009-01-17 12:17:14 -03:00
saa_call_all ( dev , core , init , leading_null_bytes ) ;
2005-04-16 15:20:36 -07:00
dev - > empress_started = 1 ;
2005-11-08 21:37:43 -08:00
return 0 ;
2005-04-16 15:20:36 -07:00
}
/* ------------------------------------------------------------------ */
2008-12-30 06:58:20 -03:00
static int ts_open ( struct file * file )
2005-04-16 15:20:36 -07:00
{
2009-12-10 11:47:13 -02:00
struct video_device * vdev = video_devdata ( file ) ;
2009-12-10 11:44:04 -02:00
struct saa7134_dev * dev = video_drvdata ( file ) ;
2005-04-16 15:20:36 -07:00
int err ;
2009-12-10 11:47:13 -02:00
dprintk ( " open dev=%s \n " , video_device_node_name ( vdev ) ) ;
2005-04-16 15:20:36 -07:00
err = - EBUSY ;
2008-01-31 13:57:53 -03:00
if ( ! mutex_trylock ( & dev - > empress_tsq . vb_lock ) )
2010-01-29 06:51:08 -03:00
return err ;
2008-07-26 09:01:24 -03:00
if ( atomic_read ( & dev - > empress_users ) )
2010-01-29 06:51:08 -03:00
goto done ;
2005-04-16 15:20:36 -07:00
2007-06-20 05:37:27 -03:00
/* Unmute audio */
saa_writeb ( SAA7134_AUDIO_MUTE_CTRL ,
saa_readb ( SAA7134_AUDIO_MUTE_CTRL ) & ~ ( 1 < < 6 ) ) ;
2008-07-26 09:01:24 -03:00
atomic_inc ( & dev - > empress_users ) ;
2005-04-16 15:20:36 -07:00
file - > private_data = dev ;
err = 0 ;
done :
2010-01-29 06:51:08 -03:00
mutex_unlock ( & dev - > empress_tsq . vb_lock ) ;
2005-04-16 15:20:36 -07:00
return err ;
}
2008-12-30 06:58:20 -03:00
static int ts_release ( struct file * file )
2005-04-16 15:20:36 -07:00
{
struct saa7134_dev * dev = file - > private_data ;
2007-11-13 20:11:26 -03:00
videobuf_stop ( & dev - > empress_tsq ) ;
2005-04-16 15:20:36 -07:00
videobuf_mmap_free ( & dev - > empress_tsq ) ;
/* stop the encoder */
ts_reset_encoder ( dev ) ;
2007-06-20 05:37:27 -03:00
/* Mute audio */
saa_writeb ( SAA7134_AUDIO_MUTE_CTRL ,
saa_readb ( SAA7134_AUDIO_MUTE_CTRL ) | ( 1 < < 6 ) ) ;
2008-07-26 09:01:24 -03:00
atomic_dec ( & dev - > empress_users ) ;
2008-06-22 17:03:02 -03:00
2005-04-16 15:20:36 -07:00
return 0 ;
}
static ssize_t
ts_read ( struct file * file , char __user * data , size_t count , loff_t * ppos )
{
struct saa7134_dev * dev = file - > private_data ;
if ( ! dev - > empress_started )
ts_init_encoder ( dev ) ;
return videobuf_read_stream ( & dev - > empress_tsq ,
data , count , ppos , 0 ,
file - > f_flags & O_NONBLOCK ) ;
}
static unsigned int
ts_poll ( struct file * file , struct poll_table_struct * wait )
{
struct saa7134_dev * dev = file - > private_data ;
return videobuf_poll_stream ( file , & dev - > empress_tsq , wait ) ;
}
static int
ts_mmap ( struct file * file , struct vm_area_struct * vma )
{
struct saa7134_dev * dev = file - > private_data ;
return videobuf_mmap_mapper ( & dev - > empress_tsq , vma ) ;
}
/*
* This function is _not_ called directly , but from
* video_generic_ioctl ( and maybe others ) . userspace
* copying is done already , arg is a kernel pointer .
*/
2007-12-11 12:56:23 -03:00
static int empress_querycap ( struct file * file , void * priv ,
struct v4l2_capability * cap )
2005-04-16 15:20:36 -07:00
{
2008-05-21 01:20:34 -03:00
struct saa7134_dev * dev = file - > private_data ;
2007-12-11 12:56:23 -03:00
strcpy ( cap - > driver , " saa7134 " ) ;
strlcpy ( cap - > card , saa7134_boards [ dev - > board ] . name ,
sizeof ( cap - > card ) ) ;
sprintf ( cap - > bus_info , " PCI:%s " , pci_name ( dev - > pci ) ) ;
cap - > version = SAA7134_VERSION_CODE ;
cap - > capabilities =
V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING ;
return 0 ;
}
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
static int empress_enum_input ( struct file * file , void * priv ,
struct v4l2_input * i )
{
if ( i - > index ! = 0 )
return - EINVAL ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
i - > type = V4L2_INPUT_TYPE_CAMERA ;
strcpy ( i - > name , " CCIR656 " ) ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
return 0 ;
}
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
static int empress_g_input ( struct file * file , void * priv , unsigned int * i )
{
* i = 0 ;
return 0 ;
}
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
static int empress_s_input ( struct file * file , void * priv , unsigned int i )
{
if ( i ! = 0 )
return - EINVAL ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
return 0 ;
}
2005-04-16 15:20:36 -07:00
2008-05-28 12:16:41 -03:00
static int empress_enum_fmt_vid_cap ( struct file * file , void * priv ,
2007-12-11 12:56:23 -03:00
struct v4l2_fmtdesc * f )
{
if ( f - > index ! = 0 )
return - EINVAL ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
strlcpy ( f - > description , " MPEG TS " , sizeof ( f - > description ) ) ;
f - > pixelformat = V4L2_PIX_FMT_MPEG ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
return 0 ;
}
2005-04-16 15:20:36 -07:00
2008-05-28 12:16:41 -03:00
static int empress_g_fmt_vid_cap ( struct file * file , void * priv ,
2007-12-11 12:56:23 -03:00
struct v4l2_format * f )
{
2008-06-10 14:19:31 -03:00
struct saa7134_dev * dev = file - > private_data ;
2005-04-16 15:20:36 -07:00
2009-01-17 12:17:14 -03:00
saa_call_all ( dev , video , g_fmt , f ) ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
f - > fmt . pix . pixelformat = V4L2_PIX_FMT_MPEG ;
f - > fmt . pix . sizeimage = TS_PACKET_SIZE * dev - > ts . nr_packets ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
return 0 ;
}
2005-04-16 15:20:36 -07:00
2008-05-28 12:16:41 -03:00
static int empress_s_fmt_vid_cap ( struct file * file , void * priv ,
2007-12-11 12:56:23 -03:00
struct v4l2_format * f )
{
2008-06-10 14:19:31 -03:00
struct saa7134_dev * dev = file - > private_data ;
2005-04-16 15:20:36 -07:00
2009-01-17 12:17:14 -03:00
saa_call_all ( dev , video , s_fmt , f ) ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
f - > fmt . pix . pixelformat = V4L2_PIX_FMT_MPEG ;
f - > fmt . pix . sizeimage = TS_PACKET_SIZE * dev - > ts . nr_packets ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
return 0 ;
}
2009-05-28 01:58:57 -03:00
static int empress_try_fmt_vid_cap ( struct file * file , void * priv ,
struct v4l2_format * f )
{
struct saa7134_dev * dev = file - > private_data ;
f - > fmt . pix . pixelformat = V4L2_PIX_FMT_MPEG ;
f - > fmt . pix . sizeimage = TS_PACKET_SIZE * dev - > ts . nr_packets ;
return 0 ;
}
2007-12-11 12:56:23 -03:00
static int empress_reqbufs ( struct file * file , void * priv ,
struct v4l2_requestbuffers * p )
{
2008-06-10 14:19:31 -03:00
struct saa7134_dev * dev = file - > private_data ;
2007-12-11 12:56:23 -03:00
return videobuf_reqbufs ( & dev - > empress_tsq , p ) ;
}
static int empress_querybuf ( struct file * file , void * priv ,
struct v4l2_buffer * b )
{
2008-06-10 14:19:31 -03:00
struct saa7134_dev * dev = file - > private_data ;
2007-12-11 12:56:23 -03:00
return videobuf_querybuf ( & dev - > empress_tsq , b ) ;
}
static int empress_qbuf ( struct file * file , void * priv , struct v4l2_buffer * b )
{
2008-06-10 14:19:31 -03:00
struct saa7134_dev * dev = file - > private_data ;
2007-12-11 12:56:23 -03:00
return videobuf_qbuf ( & dev - > empress_tsq , b ) ;
}
static int empress_dqbuf ( struct file * file , void * priv , struct v4l2_buffer * b )
{
2008-06-10 14:19:31 -03:00
struct saa7134_dev * dev = file - > private_data ;
2007-12-11 12:56:23 -03:00
return videobuf_dqbuf ( & dev - > empress_tsq , b ,
file - > f_flags & O_NONBLOCK ) ;
}
static int empress_streamon ( struct file * file , void * priv ,
enum v4l2_buf_type type )
{
2008-06-10 14:19:31 -03:00
struct saa7134_dev * dev = file - > private_data ;
2007-12-11 12:56:23 -03:00
return videobuf_streamon ( & dev - > empress_tsq ) ;
}
static int empress_streamoff ( struct file * file , void * priv ,
enum v4l2_buf_type type )
{
2008-06-10 14:19:31 -03:00
struct saa7134_dev * dev = file - > private_data ;
2007-12-11 12:56:23 -03:00
return videobuf_streamoff ( & dev - > empress_tsq ) ;
}
static int empress_s_ext_ctrls ( struct file * file , void * priv ,
struct v4l2_ext_controls * ctrls )
{
2008-06-10 14:19:31 -03:00
struct saa7134_dev * dev = file - > private_data ;
2008-06-27 21:18:15 -03:00
int err ;
2007-12-11 12:56:23 -03:00
/* count == 0 is abused in saa6752hs.c, so that special
case is handled here explicitly . */
if ( ctrls - > count = = 0 )
2006-06-18 16:40:10 -03:00
return 0 ;
2005-04-16 15:20:36 -07:00
2007-12-11 12:56:23 -03:00
if ( ctrls - > ctrl_class ! = V4L2_CTRL_CLASS_MPEG )
return - EINVAL ;
2009-01-17 12:17:14 -03:00
err = saa_call_empress ( dev , core , s_ext_ctrls , ctrls ) ;
2007-12-11 12:56:23 -03:00
ts_init_encoder ( dev ) ;
2008-06-27 21:18:15 -03:00
return err ;
2005-04-16 15:20:36 -07:00
}
2007-12-11 12:56:23 -03:00
static int empress_g_ext_ctrls ( struct file * file , void * priv ,
struct v4l2_ext_controls * ctrls )
2005-04-16 15:20:36 -07:00
{
2008-06-10 14:19:31 -03:00
struct saa7134_dev * dev = file - > private_data ;
2007-12-11 12:56:23 -03:00
if ( ctrls - > ctrl_class ! = V4L2_CTRL_CLASS_MPEG )
return - EINVAL ;
2009-01-17 12:17:14 -03:00
return saa_call_empress ( dev , core , g_ext_ctrls , ctrls ) ;
2008-06-27 21:18:15 -03:00
}
2007-12-11 12:56:23 -03:00
2008-07-26 09:04:06 -03:00
static int empress_g_ctrl ( struct file * file , void * priv ,
struct v4l2_control * c )
{
struct saa7134_dev * dev = file - > private_data ;
return saa7134_g_ctrl_internal ( dev , NULL , c ) ;
}
static int empress_s_ctrl ( struct file * file , void * priv ,
struct v4l2_control * c )
{
struct saa7134_dev * dev = file - > private_data ;
return saa7134_s_ctrl_internal ( dev , NULL , c ) ;
}
2008-06-27 21:18:15 -03:00
static int empress_queryctrl ( struct file * file , void * priv ,
struct v4l2_queryctrl * c )
{
2009-02-13 10:57:48 -03:00
/* Must be sorted from low to high control ID! */
2008-06-27 21:18:15 -03:00
static const u32 user_ctrls [ ] = {
V4L2_CID_USER_CLASS ,
V4L2_CID_BRIGHTNESS ,
V4L2_CID_CONTRAST ,
V4L2_CID_SATURATION ,
V4L2_CID_HUE ,
V4L2_CID_AUDIO_VOLUME ,
V4L2_CID_AUDIO_MUTE ,
V4L2_CID_HFLIP ,
0
} ;
2009-02-13 10:57:48 -03:00
/* Must be sorted from low to high control ID! */
2008-06-27 21:18:15 -03:00
static const u32 mpeg_ctrls [ ] = {
V4L2_CID_MPEG_CLASS ,
V4L2_CID_MPEG_STREAM_TYPE ,
V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ ,
V4L2_CID_MPEG_AUDIO_ENCODING ,
V4L2_CID_MPEG_AUDIO_L2_BITRATE ,
V4L2_CID_MPEG_VIDEO_ENCODING ,
V4L2_CID_MPEG_VIDEO_ASPECT ,
V4L2_CID_MPEG_VIDEO_BITRATE_MODE ,
V4L2_CID_MPEG_VIDEO_BITRATE ,
V4L2_CID_MPEG_VIDEO_BITRATE_PEAK ,
0
} ;
static const u32 * ctrl_classes [ ] = {
user_ctrls ,
mpeg_ctrls ,
NULL
} ;
struct saa7134_dev * dev = file - > private_data ;
c - > id = v4l2_ctrl_next ( ctrl_classes , c - > id ) ;
if ( c - > id = = 0 )
return - EINVAL ;
if ( c - > id = = V4L2_CID_USER_CLASS | | c - > id = = V4L2_CID_MPEG_CLASS )
2009-02-21 18:47:24 -03:00
return v4l2_ctrl_query_fill ( c , 0 , 0 , 0 , 0 ) ;
2008-06-27 21:18:15 -03:00
if ( V4L2_CTRL_ID2CLASS ( c - > id ) ! = V4L2_CTRL_CLASS_MPEG )
return saa7134_queryctrl ( file , priv , c ) ;
2009-01-17 12:17:14 -03:00
return saa_call_empress ( dev , core , queryctrl , c ) ;
2008-06-27 21:18:15 -03:00
}
static int empress_querymenu ( struct file * file , void * priv ,
struct v4l2_querymenu * c )
{
struct saa7134_dev * dev = file - > private_data ;
if ( V4L2_CTRL_ID2CLASS ( c - > id ) ! = V4L2_CTRL_CLASS_MPEG )
return - EINVAL ;
2009-01-17 12:17:14 -03:00
return saa_call_empress ( dev , core , querymenu , c ) ;
2005-04-16 15:20:36 -07:00
}
2008-08-08 12:43:59 -03:00
static int empress_g_chip_ident ( struct file * file , void * fh ,
2008-12-30 07:14:19 -03:00
struct v4l2_dbg_chip_ident * chip )
2008-08-08 12:43:59 -03:00
{
struct saa7134_dev * dev = file - > private_data ;
chip - > ident = V4L2_IDENT_NONE ;
chip - > revision = 0 ;
2008-12-30 07:14:19 -03:00
if ( chip - > match . type = = V4L2_CHIP_MATCH_I2C_DRIVER & &
! strcmp ( chip - > match . name , " saa6752hs " ) )
2009-01-17 12:17:14 -03:00
return saa_call_empress ( dev , core , g_chip_ident , chip ) ;
2009-03-28 09:27:02 -03:00
if ( chip - > match . type = = V4L2_CHIP_MATCH_I2C_ADDR )
2009-01-17 12:17:14 -03:00
return saa_call_empress ( dev , core , g_chip_ident , chip ) ;
2008-08-08 12:43:59 -03:00
return - EINVAL ;
}
2008-09-06 06:34:44 -03:00
static int empress_s_std ( struct file * file , void * priv , v4l2_std_id * id )
{
struct saa7134_dev * dev = file - > private_data ;
return saa7134_s_std_internal ( dev , NULL , id ) ;
}
static int empress_g_std ( struct file * file , void * priv , v4l2_std_id * id )
{
struct saa7134_dev * dev = file - > private_data ;
* id = dev - > tvnorm - > id ;
return 0 ;
}
2008-08-08 12:43:59 -03:00
2008-12-30 06:58:20 -03:00
static const struct v4l2_file_operations ts_fops =
2005-04-16 15:20:36 -07:00
{
. owner = THIS_MODULE ,
. open = ts_open ,
. release = ts_release ,
. read = ts_read ,
. poll = ts_poll ,
. mmap = ts_mmap ,
2007-12-11 12:56:23 -03:00
. ioctl = video_ioctl2 ,
2005-04-16 15:20:36 -07:00
} ;
2008-07-21 02:57:38 -03:00
static const struct v4l2_ioctl_ops ts_ioctl_ops = {
2007-12-11 12:56:23 -03:00
. vidioc_querycap = empress_querycap ,
2008-05-28 12:16:41 -03:00
. vidioc_enum_fmt_vid_cap = empress_enum_fmt_vid_cap ,
2009-05-28 01:58:57 -03:00
. vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap ,
2008-05-28 12:16:41 -03:00
. vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap ,
. vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap ,
2007-12-11 12:56:23 -03:00
. vidioc_reqbufs = empress_reqbufs ,
. vidioc_querybuf = empress_querybuf ,
. vidioc_qbuf = empress_qbuf ,
. vidioc_dqbuf = empress_dqbuf ,
. vidioc_streamon = empress_streamon ,
. vidioc_streamoff = empress_streamoff ,
. vidioc_s_ext_ctrls = empress_s_ext_ctrls ,
. vidioc_g_ext_ctrls = empress_g_ext_ctrls ,
. vidioc_enum_input = empress_enum_input ,
. vidioc_g_input = empress_g_input ,
. vidioc_s_input = empress_s_input ,
2008-06-27 21:18:15 -03:00
. vidioc_queryctrl = empress_queryctrl ,
. vidioc_querymenu = empress_querymenu ,
2008-07-26 09:04:06 -03:00
. vidioc_g_ctrl = empress_g_ctrl ,
. vidioc_s_ctrl = empress_s_ctrl ,
2008-08-08 12:43:59 -03:00
. vidioc_g_chip_ident = empress_g_chip_ident ,
2008-09-06 06:34:44 -03:00
. vidioc_s_std = empress_s_std ,
. vidioc_g_std = empress_g_std ,
2008-07-21 02:57:38 -03:00
} ;
/* ----------------------------------------------------------- */
static struct video_device saa7134_empress_template = {
. name = " saa7134-empress " ,
. fops = & ts_fops ,
. ioctl_ops = & ts_ioctl_ops ,
2007-12-11 12:56:23 -03:00
. tvnorms = SAA7134_NORMS ,
. current_norm = V4L2_STD_PAL ,
2005-04-16 15:20:36 -07:00
} ;
2006-11-22 14:57:56 +00:00
static void empress_signal_update ( struct work_struct * work )
2005-04-16 15:20:36 -07:00
{
2006-11-22 14:57:56 +00:00
struct saa7134_dev * dev =
container_of ( work , struct saa7134_dev , empress_workqueue ) ;
2005-04-16 15:20:36 -07:00
if ( dev - > nosignal ) {
dprintk ( " no video signal \n " ) ;
} else {
dprintk ( " video signal acquired \n " ) ;
}
}
static void empress_signal_change ( struct saa7134_dev * dev )
{
schedule_work ( & dev - > empress_workqueue ) ;
}
static int empress_init ( struct saa7134_dev * dev )
{
int err ;
2008-04-08 23:20:00 -03:00
dprintk ( " %s: %s \n " , dev - > name , __func__ ) ;
2005-04-16 15:20:36 -07:00
dev - > empress_dev = video_device_alloc ( ) ;
if ( NULL = = dev - > empress_dev )
return - ENOMEM ;
* ( dev - > empress_dev ) = saa7134_empress_template ;
2008-07-20 06:31:39 -03:00
dev - > empress_dev - > parent = & dev - > pci - > dev ;
2005-04-16 15:20:36 -07:00
dev - > empress_dev - > release = video_device_release ;
snprintf ( dev - > empress_dev - > name , sizeof ( dev - > empress_dev - > name ) ,
" %s empress (%s) " , dev - > name ,
saa7134_boards [ dev - > board ] . name ) ;
2006-11-22 14:57:56 +00:00
INIT_WORK ( & dev - > empress_workqueue , empress_signal_update ) ;
2005-04-16 15:20:36 -07:00
2009-12-10 11:44:04 -02:00
video_set_drvdata ( dev - > empress_dev , dev ) ;
2005-04-16 15:20:36 -07:00
err = video_register_device ( dev - > empress_dev , VFL_TYPE_GRABBER ,
empress_nr [ dev - > nr ] ) ;
if ( err < 0 ) {
printk ( KERN_INFO " %s: can't register video device \n " ,
dev - > name ) ;
video_device_release ( dev - > empress_dev ) ;
dev - > empress_dev = NULL ;
return err ;
}
2009-11-27 13:57:15 -03:00
printk ( KERN_INFO " %s: registered device %s [mpeg] \n " ,
dev - > name , video_device_node_name ( dev - > empress_dev ) ) ;
2005-04-16 15:20:36 -07:00
2008-04-22 14:42:13 -03:00
videobuf_queue_sg_init ( & dev - > empress_tsq , & saa7134_ts_qops ,
& dev - > pci - > dev , & dev - > slock ,
2005-04-16 15:20:36 -07:00
V4L2_BUF_TYPE_VIDEO_CAPTURE ,
V4L2_FIELD_ALTERNATE ,
sizeof ( struct saa7134_buf ) ,
dev ) ;
2006-11-22 14:57:56 +00:00
empress_signal_update ( & dev - > empress_workqueue ) ;
2005-04-16 15:20:36 -07:00
return 0 ;
}
static int empress_fini ( struct saa7134_dev * dev )
{
2008-04-08 23:20:00 -03:00
dprintk ( " %s: %s \n " , dev - > name , __func__ ) ;
2005-04-16 15:20:36 -07:00
if ( NULL = = dev - > empress_dev )
return 0 ;
flush_scheduled_work ( ) ;
video_unregister_device ( dev - > empress_dev ) ;
dev - > empress_dev = NULL ;
return 0 ;
}
static struct saa7134_mpeg_ops empress_ops = {
. type = SAA7134_MPEG_EMPRESS ,
. init = empress_init ,
. fini = empress_fini ,
. signal_change = empress_signal_change ,
} ;
static int __init empress_register ( void )
{
return saa7134_ts_register ( & empress_ops ) ;
}
static void __exit empress_unregister ( void )
{
saa7134_ts_unregister ( & empress_ops ) ;
}
module_init ( empress_register ) ;
module_exit ( empress_unregister ) ;
/* ----------------------------------------------------------- */
/*
* Local variables :
* c - basic - offset : 8
* End :
*/