struct video_device *vdev = video_devdata(file);
struct saa7134_dev *dev = video_drvdata(file);
struct saa7134_fh *fh;
- int err;
-
- dprintk("open dev=%s\n", video_device_node_name(vdev));
- err = -EBUSY;
- if (!mutex_trylock(&dev->empress_tsq.vb_lock))
- return err;
- if (atomic_read(&dev->empress_users))
- goto done;
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- err = -ENOMEM;
if (NULL == fh)
- goto done;
+ return -ENOMEM;
v4l2_fh_init(&fh->fh, vdev);
file->private_data = fh;
saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
saa_readb(SAA7134_AUDIO_MUTE_CTRL) & ~(1 << 6));
- atomic_inc(&dev->empress_users);
- err = 0;
-
-done:
- mutex_unlock(&dev->empress_tsq.vb_lock);
- return err;
+ return 0;
}
static int ts_release(struct file *file)
struct saa7134_dev *dev = video_drvdata(file);
struct saa7134_fh *fh = file->private_data;
- videobuf_stop(&dev->empress_tsq);
- videobuf_mmap_free(&dev->empress_tsq);
+ if (res_check(fh, RESOURCE_EMPRESS)) {
+ videobuf_stop(&dev->empress_tsq);
+ videobuf_mmap_free(&dev->empress_tsq);
- /* stop the encoder */
- ts_reset_encoder(dev);
+ /* stop the encoder */
+ ts_reset_encoder(dev);
- /* Mute audio */
- saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
- saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
-
- atomic_dec(&dev->empress_users);
+ /* Mute audio */
+ saa_writeb(SAA7134_AUDIO_MUTE_CTRL,
+ saa_readb(SAA7134_AUDIO_MUTE_CTRL) | (1 << 6));
+ }
v4l2_fh_del(&fh->fh);
v4l2_fh_exit(&fh->fh);
{
struct saa7134_dev *dev = video_drvdata(file);
+ if (res_locked(dev, RESOURCE_EMPRESS))
+ return -EBUSY;
if (!dev->empress_started)
ts_init_encoder(dev);
return 0;
}
-static int empress_reqbufs(struct file *file, void *priv,
- struct v4l2_requestbuffers *p)
-{
- struct saa7134_dev *dev = video_drvdata(file);
-
- return videobuf_reqbufs(&dev->empress_tsq, p);
-}
-
-static int empress_querybuf(struct file *file, void *priv,
- struct v4l2_buffer *b)
-{
- struct saa7134_dev *dev = video_drvdata(file);
-
- return videobuf_querybuf(&dev->empress_tsq, b);
-}
-
-static int empress_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct saa7134_dev *dev = video_drvdata(file);
-
- return videobuf_qbuf(&dev->empress_tsq, b);
-}
-
-static int empress_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
-{
- struct saa7134_dev *dev = video_drvdata(file);
-
- 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)
-{
- struct saa7134_dev *dev = video_drvdata(file);
-
- return videobuf_streamon(&dev->empress_tsq);
-}
-
-static int empress_streamoff(struct file *file, void *priv,
- enum v4l2_buf_type type)
-{
- struct saa7134_dev *dev = video_drvdata(file);
-
- return videobuf_streamoff(&dev->empress_tsq);
-}
-
static const struct v4l2_file_operations ts_fops =
{
.owner = THIS_MODULE,
.vidioc_try_fmt_vid_cap = empress_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = empress_s_fmt_vid_cap,
.vidioc_g_fmt_vid_cap = empress_g_fmt_vid_cap,
- .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_reqbufs = saa7134_reqbufs,
+ .vidioc_querybuf = saa7134_querybuf,
+ .vidioc_qbuf = saa7134_qbuf,
+ .vidioc_dqbuf = saa7134_dqbuf,
+ .vidioc_streamon = saa7134_streamon,
+ .vidioc_streamoff = saa7134_streamoff,
.vidioc_g_frequency = saa7134_g_frequency,
.vidioc_s_frequency = saa7134_s_frequency,
.vidioc_g_tuner = saa7134_g_tuner,
snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name),
"%s empress (%s)", dev->name,
saa7134_boards[dev->board].name);
+ set_bit(V4L2_FL_USE_FH_PRIO, &dev->empress_dev->flags);
v4l2_ctrl_handler_init(hdl, 21);
v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, empress_ctrl_filter);
if (dev->empress_sd)
return 1;
}
-static int res_check(struct saa7134_fh *fh, unsigned int bit)
-{
- return (fh->resources & bit);
-}
-
-static int res_locked(struct saa7134_dev *dev, unsigned int bit)
-{
- return (dev->resources & bit);
-}
-
static
void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
{
{
struct video_device *vdev = video_devdata(file);
struct saa7134_dev *dev = video_drvdata(file);
+ struct saa7134_fh *fh = file->private_data;
struct videobuf_queue *q = NULL;
switch (vdev->vfl_type) {
case VFL_TYPE_GRABBER:
- q = &dev->cap;
+ q = fh->is_empress ? &dev->empress_tsq : &dev->cap;
break;
case VFL_TYPE_VBI:
q = &dev->vbi;
static int saa7134_resource(struct file *file)
{
struct video_device *vdev = video_devdata(file);
+ struct saa7134_fh *fh = file->private_data;
if (vdev->vfl_type == VFL_TYPE_GRABBER)
- return RESOURCE_VIDEO;
+ return fh->is_empress ? RESOURCE_EMPRESS : RESOURCE_VIDEO;
if (vdev->vfl_type == VFL_TYPE_VBI)
return RESOURCE_VBI;
return 0;
}
-static int saa7134_reqbufs(struct file *file, void *priv,
+int saa7134_reqbufs(struct file *file, void *priv,
struct v4l2_requestbuffers *p)
{
return videobuf_reqbufs(saa7134_queue(file), p);
}
+EXPORT_SYMBOL_GPL(saa7134_reqbufs);
-static int saa7134_querybuf(struct file *file, void *priv,
+int saa7134_querybuf(struct file *file, void *priv,
struct v4l2_buffer *b)
{
return videobuf_querybuf(saa7134_queue(file), b);
}
+EXPORT_SYMBOL_GPL(saa7134_querybuf);
-static int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{
return videobuf_qbuf(saa7134_queue(file), b);
}
+EXPORT_SYMBOL_GPL(saa7134_qbuf);
-static int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{
return videobuf_dqbuf(saa7134_queue(file), b,
file->f_flags & O_NONBLOCK);
}
+EXPORT_SYMBOL_GPL(saa7134_dqbuf);
-static int saa7134_streamon(struct file *file, void *priv,
+int saa7134_streamon(struct file *file, void *priv,
enum v4l2_buf_type type)
{
struct saa7134_dev *dev = video_drvdata(file);
* Unfortunately, I lack register-level documentation to check the
* Linux FIFO setup and confirm the perfect value.
*/
- pm_qos_add_request(&dev->qos_request,
- PM_QOS_CPU_DMA_LATENCY,
- 20);
+ if (res != RESOURCE_EMPRESS)
+ pm_qos_add_request(&dev->qos_request,
+ PM_QOS_CPU_DMA_LATENCY, 20);
return videobuf_streamon(saa7134_queue(file));
}
+EXPORT_SYMBOL_GPL(saa7134_streamon);
-static int saa7134_streamoff(struct file *file, void *priv,
+int saa7134_streamoff(struct file *file, void *priv,
enum v4l2_buf_type type)
{
struct saa7134_dev *dev = video_drvdata(file);
int err;
int res = saa7134_resource(file);
- pm_qos_remove_request(&dev->qos_request);
+ if (res != RESOURCE_EMPRESS)
+ pm_qos_remove_request(&dev->qos_request);
err = videobuf_streamoff(saa7134_queue(file));
if (err < 0)
res_free(dev, priv, res);
return 0;
}
+EXPORT_SYMBOL_GPL(saa7134_streamoff);
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int vidioc_g_register (struct file *file, void *priv,
#define RESOURCE_OVERLAY 1
#define RESOURCE_VIDEO 2
#define RESOURCE_VBI 4
+#define RESOURCE_EMPRESS 8
#define INTERLACE_AUTO 0
#define INTERLACE_ON 1
struct video_device *empress_dev;
struct v4l2_subdev *empress_sd;
struct videobuf_queue empress_tsq;
- atomic_t empress_users;
struct work_struct empress_workqueue;
int empress_started;
struct v4l2_ctrl_handler empress_ctrl_handler;
_rc; \
})
+static inline int res_check(struct saa7134_fh *fh, unsigned int bit)
+{
+ return fh->resources & bit;
+}
+
+static inline int res_locked(struct saa7134_dev *dev, unsigned int bit)
+{
+ return dev->resources & bit;
+}
+
/* ----------------------------------------------------------- */
/* saa7134-core.c */
struct v4l2_frequency *f);
int saa7134_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *f);
+int saa7134_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *p);
+int saa7134_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *b);
+int saa7134_qbuf(struct file *file, void *priv, struct v4l2_buffer *b);
+int saa7134_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b);
+int saa7134_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type type);
+int saa7134_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type type);
int saa7134_videoport_init(struct saa7134_dev *dev);
void saa7134_set_tvnorm_hw(struct saa7134_dev *dev);