frame->v4l2_buf.bytesused = frame->data_end - frame->data;
frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
- atomic_inc(&gspca_dev->nevent);
wake_up_interruptible(&gspca_dev->wq); /* event = new frame */
i = (gspca_dev->fr_i + 1) % gspca_dev->nframes;
gspca_dev->fr_i = i;
gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
gspca_dev->last_packet_type = DISCARD_PACKET;
gspca_dev->sequence = 0;
- atomic_set(&gspca_dev->nevent, 0);
return 0;
}
goto out;
}
gspca_dev->streaming = 1;
- atomic_set(&gspca_dev->nevent, 0);
/* some bulk transfers are started by the subdriver */
if (gspca_dev->alt == 0 && gspca_dev->cam.bulk_nurbs == 0)
"usb_submit_urb [%d] err %d", n, ret);
gspca_dev->streaming = 0;
destroy_urbs(gspca_dev);
- if (ret == -ENOSPC)
+ if (ret == -ENOSPC) {
+ msleep(20); /* wait for kill
+ * complete */
break; /* try the previous alt */
+ }
goto out;
}
}
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0);
if (ret < 0)
- PDEBUG(D_ERR|D_STREAM, "set interface 0 err %d", ret);
+ PDEBUG(D_ERR|D_STREAM, "set alt 0 err %d", ret);
return ret;
}
static void gspca_stream_off(struct gspca_dev *gspca_dev)
{
gspca_dev->streaming = 0;
- atomic_set(&gspca_dev->nevent, 0);
if (gspca_dev->present
&& gspca_dev->sd_desc->stopN)
gspca_dev->sd_desc->stopN(gspca_dev);
return -EINVAL;
}
+/*fixme: have an audio flag in gspca_dev?*/
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *audio)
+{
+ if (audio->index != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *audio)
+{
+ memset(audio, 0, sizeof *audio);
+ strcpy(audio->name, "Microphone");
+ return 0;
+}
+
+static int vidioc_enumaudio(struct file *file, void *priv,
+ struct v4l2_audio *audio)
+{
+ if (audio->index != 0)
+ return -EINVAL;
+
+ strcpy(audio->name, "Microphone");
+ audio->capability = 0;
+ audio->mode = 0;
+ return 0;
+}
+
static int vidioc_querymenu(struct file *file, void *priv,
struct v4l2_querymenu *qmenu)
{
gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
gspca_dev->last_packet_type = DISCARD_PACKET;
gspca_dev->sequence = 0;
- atomic_set(&gspca_dev->nevent, 0);
ret = 0;
out:
mutex_unlock(&gspca_dev->queue_lock);
i = gspca_dev->fr_o;
j = gspca_dev->fr_queue[i];
frame = &gspca_dev->frame[j];
- if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) {
- atomic_dec(&gspca_dev->nevent);
- goto ok;
- }
- if (nonblock_ing) /* no frame yet */
- return -EAGAIN;
- /* wait till a frame is ready */
- for (;;) {
+ if (!(frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE)) {
+ if (nonblock_ing)
+ return -EAGAIN;
+
+ /* wait till a frame is ready */
ret = wait_event_interruptible_timeout(gspca_dev->wq,
- atomic_read(&gspca_dev->nevent) > 0,
- msecs_to_jiffies(3000));
- if (ret <= 0) {
- if (ret < 0)
- return ret; /* interrupt */
- return -EIO; /* timeout */
- }
- atomic_dec(&gspca_dev->nevent);
- if (!gspca_dev->streaming || !gspca_dev->present)
+ (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) ||
+ !gspca_dev->streaming || !gspca_dev->present,
+ msecs_to_jiffies(3000));
+ if (ret < 0)
+ return ret;
+ if (ret == 0 || !gspca_dev->streaming || !gspca_dev->present)
return -EIO;
- i = gspca_dev->fr_o;
- j = gspca_dev->fr_queue[i];
- frame = &gspca_dev->frame[j];
- if (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE)
- break;
}
-ok:
+
gspca_dev->fr_o = (i + 1) % gspca_dev->nframes;
PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d",
gspca_dev->fr_q,
.vidioc_queryctrl = vidioc_queryctrl,
.vidioc_g_ctrl = vidioc_g_ctrl,
.vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_enumaudio = vidioc_enumaudio,
.vidioc_querymenu = vidioc_querymenu,
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
gspca_dev->empty_packet = -1; /* don't check the empty packets */
/* configure the subdriver and initialize the USB device */
- ret = gspca_dev->sd_desc->config(gspca_dev, id);
+ ret = sd_desc->config(gspca_dev, id);
if (ret < 0)
goto out;
- ret = gspca_dev->sd_desc->init(gspca_dev);
+ ret = sd_desc->init(gspca_dev);
if (ret < 0)
goto out;
ret = gspca_set_alt0(gspca_dev);
init_waitqueue_head(&gspca_dev->wq);
/* init video stuff */
- gspca_dev->vdev = video_device_alloc();
- memcpy(gspca_dev->vdev, &gspca_template, sizeof gspca_template);
- gspca_dev->vdev->parent = &dev->dev;
+ memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
+ gspca_dev->vdev.parent = &dev->dev;
gspca_dev->module = module;
gspca_dev->present = 1;
ret = video_register_device(&gspca_dev->vdev,