aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/video/ivtv
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ivtv')
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c19
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c3
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c28
3 files changed, 19 insertions, 31 deletions
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 9e867b5229d..908e640c274 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -892,12 +892,20 @@ int ivtv_v4l2_open(struct inode *inode, struct file *filp)
return -EBUSY;
}
+ if (!test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
+ if (atomic_read(&itv->capturing) > 0) {
+ /* switching to radio while capture is
+ in progress is not polite */
+ kfree(item);
+ return -EBUSY;
+ }
+ }
+ /* Mark that the radio is being used. */
+ set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
/* We have the radio */
ivtv_mute(itv);
/* Switch tuner to radio */
ivtv_call_i2c_clients(itv, AUDC_SET_RADIO, NULL);
- /* Mark that the radio is being used. */
- set_bit(IVTV_F_I_RADIO_USER, &itv->i_flags);
/* Select the correct audio input (i.e. radio tuner) */
ivtv_audio_set_io(itv);
if (itv->hw_flags & IVTV_HW_SAA711X)
@@ -931,13 +939,8 @@ void ivtv_mute(struct ivtv *itv)
void ivtv_unmute(struct ivtv *itv)
{
- /* initialize or refresh input */
- if (atomic_read(&itv->capturing) == 0)
- ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
-
- ivtv_msleep_timeout(100, 0);
-
if (atomic_read(&itv->capturing)) {
+ ivtv_msleep_timeout(100, 0);
ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12);
ivtv_vapi(itv, CX2341X_ENC_MUTE_AUDIO, 1, 0);
}
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index cee6c558c69..734f2d2ffa6 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -906,6 +906,9 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
IVTV_DEBUG_INFO("Input unchanged\n");
break;
}
+ if (atomic_read(&itv->capturing) > 0) {
+ return -EBUSY;
+ }
IVTV_DEBUG_INFO("Changing input from %d to %d\n",
itv->active_input, inp);
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 405e2e3fcb4..0582b9d57c5 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -554,9 +554,10 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
clear_bit(IVTV_F_I_EOS, &itv->i_flags);
/* Initialize Digitizer for Capture */
+ itv->video_dec_func(itv, VIDIOC_STREAMOFF, 0);
+ ivtv_msleep_timeout(300, 1);
ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
-
- ivtv_msleep_timeout(100, 0);
+ itv->video_dec_func(itv, VIDIOC_STREAMON, 0);
}
/* begin_capture */
@@ -713,7 +714,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
int cap_type;
unsigned long then;
int stopmode;
- u32 data[CX2341X_MBOX_MAX_DATA];
if (s->v4l2dev == NULL)
return -EINVAL;
@@ -793,27 +793,9 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
}
then = jiffies;
- /* Make sure DMA is complete */
- add_wait_queue(&s->waitq, &wait);
- do {
- /* check if DMA is pending */
- if ((s->type == IVTV_ENC_STREAM_TYPE_MPG) && /* MPG Only */
- (read_reg(IVTV_REG_DMASTATUS) & 0x02)) {
- /* Check for last DMA */
- ivtv_vapi_result(itv, data, CX2341X_ENC_GET_SEQ_END, 2, 0, 0);
-
- if (data[0] == 1) {
- IVTV_DEBUG_DMA("%s: Last DMA of size 0x%08x\n", s->name, data[1]);
- break;
- }
- } else if (read_reg(IVTV_REG_DMASTATUS) & 0x02) {
- break;
- }
- } while (!ivtv_msleep_timeout(10, 1) &&
- then + msecs_to_jiffies(2000) > jiffies);
- set_current_state(TASK_RUNNING);
- remove_wait_queue(&s->waitq, &wait);
+ /* Handle any pending interrupts */
+ ivtv_msleep_timeout(100, 1);
}
atomic_dec(&itv->capturing);