summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/ivtv/ivtv-streams.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/ivtv/ivtv-streams.c')
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-streams.c63
1 files changed, 18 insertions, 45 deletions
diff --git a/linux/drivers/media/video/ivtv/ivtv-streams.c b/linux/drivers/media/video/ivtv/ivtv-streams.c
index 405e2e3fc..ebf925c54 100644
--- a/linux/drivers/media/video/ivtv/ivtv-streams.c
+++ b/linux/drivers/media/video/ivtv/ivtv-streams.c
@@ -75,7 +75,7 @@ static struct {
struct file_operations *fops;
} ivtv_stream_info[] = {
{ /* IVTV_ENC_STREAM_TYPE_MPG */
- "encoder MPEG",
+ "encoder MPG",
VFL_TYPE_GRABBER, 0,
PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE,
&ivtv_v4l2_enc_fops
@@ -93,7 +93,7 @@ static struct {
&ivtv_v4l2_enc_fops
},
{ /* IVTV_ENC_STREAM_TYPE_PCM */
- "encoder PCM audio",
+ "encoder PCM",
VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET,
PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_PRIVATE,
&ivtv_v4l2_enc_fops
@@ -105,7 +105,7 @@ static struct {
&ivtv_v4l2_enc_fops
},
{ /* IVTV_DEC_STREAM_TYPE_MPG */
- "decoder MPEG",
+ "decoder MPG",
VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET,
PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT,
&ivtv_v4l2_dec_fops
@@ -150,11 +150,11 @@ static void ivtv_stream_init(struct ivtv *itv, int type)
s->dma = ivtv_stream_info[type].dma;
s->buf_size = itv->stream_buf_size[type];
if (s->buf_size)
- s->buffers = itv->options.megabytes[type] * 1024 * 1024 / s->buf_size;
+ s->buffers = (itv->options.kilobytes[type] * 1024 + s->buf_size - 1) / s->buf_size;
spin_lock_init(&s->qlock);
init_waitqueue_head(&s->waitq);
s->id = -1;
- s->SG_handle = IVTV_DMA_UNMAPPED;
+ s->sg_handle = IVTV_DMA_UNMAPPED;
ivtv_queue_init(&s->q_free);
ivtv_queue_init(&s->q_full);
ivtv_queue_init(&s->q_dma);
@@ -192,7 +192,7 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
/* User explicitly selected 0 buffers for these streams, so don't
create them. */
if (minor >= 0 && ivtv_stream_info[type].dma != PCI_DMA_NONE &&
- itv->options.megabytes[type] == 0) {
+ itv->options.kilobytes[type] == 0) {
IVTV_INFO("Disabled %s device\n", ivtv_stream_info[type].name);
return 0;
}
@@ -238,18 +238,18 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
switch (vfl_type) {
case VFL_TYPE_GRABBER:
- IVTV_INFO("Registered device video%d for %s (%d MB)\n",
- s->v4l2dev->minor, s->name, itv->options.megabytes[type]);
+ IVTV_INFO("Registered device video%d for %s (%d kB)\n",
+ s->v4l2dev->minor, s->name, itv->options.kilobytes[type]);
break;
case VFL_TYPE_RADIO:
IVTV_INFO("Registered device radio%d for %s\n",
s->v4l2dev->minor - MINOR_VFL_TYPE_RADIO_MIN, s->name);
break;
case VFL_TYPE_VBI:
- if (itv->options.megabytes[type])
- IVTV_INFO("Registered device vbi%d for %s (%d MB)\n",
+ if (itv->options.kilobytes[type])
+ IVTV_INFO("Registered device vbi%d for %s (%d kB)\n",
s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN,
- s->name, itv->options.megabytes[type]);
+ s->name, itv->options.kilobytes[type]);
else
IVTV_INFO("Registered device vbi%d for %s\n",
s->v4l2dev->minor - MINOR_VFL_TYPE_VBI_MIN, s->name);
@@ -437,9 +437,6 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
if (s->v4l2dev == NULL)
return -EINVAL;
- /* Big serialization lock to ensure no two streams are started
- simultaneously: that can give all sorts of weird results. */
- mutex_lock(&itv->serialize_lock);
IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name);
switch (s->type) {
@@ -481,7 +478,6 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
0, sizeof(itv->vbi.sliced_mpeg_size));
break;
default:
- mutex_unlock(&itv->serialize_lock);
return -EINVAL;
}
s->subtype = subtype;
@@ -554,16 +550,16 @@ 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 */
if (ivtv_vapi(itv, CX2341X_ENC_START_CAPTURE, 2, captype, subtype))
{
IVTV_DEBUG_WARN( "Error starting capture!\n");
- mutex_unlock(&itv->serialize_lock);
return -EINVAL;
}
@@ -579,7 +575,6 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
/* you're live! sit back and await interrupts :) */
atomic_inc(&itv->capturing);
- mutex_unlock(&itv->serialize_lock);
return 0;
}
@@ -713,7 +708,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 +787,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);
@@ -821,19 +797,16 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
/* Clear capture and no-read bits */
clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
- /* ensure these global cleanup actions are done only once */
- mutex_lock(&itv->serialize_lock);
-
if (s->type == IVTV_ENC_STREAM_TYPE_VBI)
ivtv_set_irq_mask(itv, IVTV_IRQ_ENC_VBI_CAP);
if (atomic_read(&itv->capturing) > 0) {
- mutex_unlock(&itv->serialize_lock);
return 0;
}
/* Set the following Interrupt mask bits for capture */
ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
+ del_timer(&itv->dma_timer);
/* event notification (off) */
if (test_and_clear_bit(IVTV_F_I_DIG_RST, &itv->i_flags)) {
@@ -844,7 +817,6 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
}
wake_up(&s->waitq);
- mutex_unlock(&itv->serialize_lock);
return 0;
}
@@ -891,6 +863,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
ivtv_vapi(itv, CX2341X_DEC_SET_EVENT_NOTIFICATION, 4, 0, 0, IVTV_IRQ_DEC_AUD_MODE_CHG, -1);
ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_DECODE);
+ del_timer(&itv->dma_timer);
clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
clear_bit(IVTV_F_S_STREAMING, &s->s_flags);