return 0;
}
-static void get_scale(struct cx231xx *dev,
- unsigned int width, unsigned int height,
- unsigned int *hscale, unsigned int *vscale)
-{
- unsigned int maxw = norm_maxw(dev);
- unsigned int maxh = norm_maxh(dev);
-
- *hscale = (((unsigned long)maxw) << 12) / width - 4096L;
- if (*hscale >= 0x4000)
- *hscale = 0x3fff;
-
- *vscale = (((unsigned long)maxh) << 12) / height - 4096L;
- if (*vscale >= 0x4000)
- *vscale = 0x3fff;
-}
-
/* ------------------------------------------------------------------
IOCTL vidioc handling
------------------------------------------------------------------*/
struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev;
- mutex_lock(&dev->lock);
-
f->fmt.pix.width = dev->width;
f->fmt.pix.height = dev->height;
f->fmt.pix.pixelformat = dev->format->fourcc;
f->fmt.pix.field = V4L2_FIELD_INTERLACED;
- mutex_unlock(&dev->lock);
-
return 0;
}
unsigned int height = f->fmt.pix.height;
unsigned int maxw = norm_maxw(dev);
unsigned int maxh = norm_maxh(dev);
- unsigned int hscale, vscale;
struct cx231xx_fmt *fmt;
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
height must be even because of interlacing */
v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0);
- get_scale(dev, width, height, &hscale, &vscale);
-
- width = (((unsigned long)maxw) << 12) / (hscale + 4096L);
- height = (((unsigned long)maxh) << 12) / (vscale + 4096L);
-
f->fmt.pix.width = width;
f->fmt.pix.height = height;
f->fmt.pix.pixelformat = fmt->fourcc;
if (rc < 0)
return rc;
- mutex_lock(&dev->lock);
-
vidioc_try_fmt_vid_cap(file, priv, f);
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- if (!fmt) {
- rc = -EINVAL;
- goto out;
- }
+ if (!fmt)
+ return -EINVAL;
if (videobuf_queue_is_busy(&fh->vb_vidq)) {
cx231xx_errdev("%s queue busy\n", __func__);
- rc = -EBUSY;
- goto out;
+ return -EBUSY;
}
if (dev->stream_on && !fh->stream_on) {
cx231xx_errdev("%s device in use by another fh\n", __func__);
- rc = -EBUSY;
- goto out;
+ return -EBUSY;
}
/* set new image size */
dev->width = f->fmt.pix.width;
dev->height = f->fmt.pix.height;
dev->format = fmt;
- get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
call_all(dev, video, s_mbus_fmt, &mbus_fmt);
v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt);
- /* Set the correct alternate setting for this resolution */
- cx231xx_resolution_set(dev);
-
-out:
- mutex_unlock(&dev->lock);
return rc;
}
{
struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev;
+ struct v4l2_mbus_framefmt mbus_fmt;
struct v4l2_format f;
int rc;
cx231xx_info("vidioc_s_std : 0x%x\n", (unsigned int)*norm);
- mutex_lock(&dev->lock);
dev->norm = *norm;
/* Adjusts width/height, if needed */
f.fmt.pix.height = dev->height;
vidioc_try_fmt_vid_cap(file, priv, &f);
- /* set new image size */
- dev->width = f.fmt.pix.width;
- dev->height = f.fmt.pix.height;
- get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
-
call_all(dev, core, s_std, dev->norm);
- mutex_unlock(&dev->lock);
+ /* We need to reset basic properties in the decoder related to
+ resolution (since a standard change effects things like the number
+ of lines in VACT, etc) */
+ v4l2_fill_mbus_format(&mbus_fmt, &f.fmt.pix, V4L2_MBUS_FMT_FIXED);
+ call_all(dev, video, s_mbus_fmt, &mbus_fmt);
+ v4l2_fill_pix_format(&f.fmt.pix, &mbus_fmt);
- cx231xx_resolution_set(dev);
+ /* set new image size */
+ dev->width = f.fmt.pix.width;
+ dev->height = f.fmt.pix.height;
/* do mode control overrides */
cx231xx_do_mode_ctrl_overrides(dev);
struct cx231xx *dev = fh->dev;
int rc;
- if (i == 10) {
- dev->USE_ISO = 0;
- cx231xx_info("trans-mode=BULK. USE_ISO = %d\n", dev->USE_ISO);
- return 0;
- }
-
- if (i == 11) {
- dev->USE_ISO = 1;
- cx231xx_info("trans-mode=ISOC. USE_ISO = %d\n", dev->USE_ISO);
- return 0;
- }
-
dev->mode_tv = 0;
rc = check_dev(dev);
if (rc < 0)
if (0 == INPUT(i)->type)
return -EINVAL;
- mutex_lock(&dev->lock);
-
video_mux(dev, i);
- mutex_unlock(&dev->lock);
+ if (INPUT(i)->type == CX231XX_VMUX_TELEVISION ||
+ INPUT(i)->type == CX231XX_VMUX_CABLE) {
+ /* There's a tuner, so reset the standard and put it on the
+ last known frequency (since it was probably powered down
+ until now */
+ call_all(dev, core, s_std, dev->norm);
+ }
+
return 0;
}
}
*qc = cx231xx_ctls[i].v;
- mutex_lock(&dev->lock);
call_all(dev, core, queryctrl, qc);
- mutex_unlock(&dev->lock);
if (qc->type)
return 0;
if (rc < 0)
return rc;
- mutex_lock(&dev->lock);
call_all(dev, core, g_ctrl, ctrl);
- mutex_unlock(&dev->lock);
return rc;
}
if (rc < 0)
return rc;
- mutex_lock(&dev->lock);
call_all(dev, core, s_ctrl, ctrl);
- mutex_unlock(&dev->lock);
return rc;
}
if (0 != t->index)
return -EINVAL;
#if 0
- mutex_lock(&dev->lock);
call_all(dev, tuner, s_tuner, t);
- mutex_unlock(&dev->lock);
#endif
return 0;
}
struct cx231xx_fh *fh = priv;
struct cx231xx *dev = fh->dev;
- mutex_lock(&dev->lock);
f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
f->frequency = dev->ctl_freq;
call_all(dev, tuner, g_frequency, f);
- mutex_unlock(&dev->lock);
-
return 0;
}
/* set pre channel change settings in DIF first */
rc = cx231xx_tuner_pre_channel_change(dev);
- mutex_lock(&dev->lock);
-
dev->ctl_freq = f->frequency;
call_all(dev, tuner, s_frequency, f);
- mutex_unlock(&dev->lock);
-
/* set post channel change settings in DIF first */
rc = cx231xx_tuner_post_channel_change(dev);
return -EINVAL;
}
- mutex_lock(&dev->lock);
call_all(dev, core, g_register, reg);
- mutex_unlock(&dev->lock);
return ret;
}
break;
}
- mutex_lock(&dev->lock);
call_all(dev, core, s_register, reg);
- mutex_unlock(&dev->lock);
return ret;
}
if (rc < 0)
return rc;
- mutex_lock(&dev->lock);
rc = res_get(fh);
if (likely(rc >= 0))
call_all(dev, video, s_stream, 1);
- mutex_unlock(&dev->lock);
-
return rc;
}
if (type != fh->type)
return -EINVAL;
- mutex_lock(&dev->lock);
-
cx25840_call(dev, video, s_stream, 0);
videobuf_streamoff(&fh->vb_vidq);
res_free(fh);
- mutex_unlock(&dev->lock);
-
return 0;
}
if (rc < 0)
return rc;
- mutex_lock(&dev->lock);
-
f->fmt.sliced.service_set = 0;
call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced);
if (f->fmt.sliced.service_set == 0)
rc = -EINVAL;
- mutex_unlock(&dev->lock);
return rc;
}
if (rc < 0)
return rc;
- mutex_lock(&dev->lock);
call_all(dev, vbi, g_sliced_fmt, &f->fmt.sliced);
- mutex_unlock(&dev->lock);
if (f->fmt.sliced.service_set == 0)
return -EINVAL;
strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
- mutex_lock(&dev->lock);
call_all(dev, tuner, s_tuner, t);
- mutex_unlock(&dev->lock);
return 0;
}
if (0 != t->index)
return -EINVAL;
- mutex_lock(&dev->lock);
call_all(dev, tuner, s_tuner, t);
- mutex_unlock(&dev->lock);
return 0;
}
break;
}
- mutex_lock(&dev->lock);
-
cx231xx_videodbg("open dev=%s type=%s users=%d\n",
video_device_node_name(vdev), v4l2_type_names[fh_type],
dev->users);
if (errCode < 0) {
cx231xx_errdev
("Device locked on digital mode. Can't open analog\n");
- mutex_unlock(&dev->lock);
return -EBUSY;
}
#endif
fh = kzalloc(sizeof(struct cx231xx_fh), GFP_KERNEL);
if (!fh) {
cx231xx_errdev("cx231xx-video.c: Out of memory?!\n");
- mutex_unlock(&dev->lock);
return -ENOMEM;
}
fh->dev = dev;
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
dev->width = norm_maxw(dev);
dev->height = norm_maxh(dev);
- dev->hscale = 0;
- dev->vscale = 0;
/* Power up in Analog TV mode */
- if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER)
+ if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER ||
+ dev->model == CX231XX_BOARD_HAUPPAUGE_USBLIVE2)
cx231xx_set_power_mode(dev,
POLARIS_AVMODE_ENXTERNAL_AV);
else
#if 0
cx231xx_set_mode(dev, CX231XX_ANALOG_MODE);
#endif
- cx231xx_resolution_set(dev);
/* set video alternate setting */
cx231xx_set_video_alternate(dev);
NULL, &dev->video_mode.slock,
fh->type, V4L2_FIELD_INTERLACED,
sizeof(struct cx231xx_buffer),
- fh, NULL);
+ fh, &dev->lock);
if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
/* Set the required alternate setting VBI interface works in
Bulk mode only */
- if (dev->model != CX231XX_BOARD_CNXT_VIDEO_GRABBER)
+ if (dev->model != CX231XX_BOARD_CNXT_VIDEO_GRABBER &&
+ dev->model != CX231XX_BOARD_HAUPPAUGE_USBLIVE2)
cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops,
NULL, &dev->vbi_mode.slock,
fh->type, V4L2_FIELD_SEQ_TB,
sizeof(struct cx231xx_buffer),
- fh, NULL);
+ fh, &dev->lock);
}
- mutex_unlock(&dev->lock);
-
return errCode;
}
cx231xx_videodbg("users=%d\n", dev->users);
- mutex_lock(&dev->lock);
cx231xx_videodbg("users=%d\n", dev->users);
if (res_check(fh))
res_free(fh);
/*To workaround error number=-71 on EP0 for VideoGrabber,
need exclude following.*/
- if (dev->model != CX231XX_BOARD_CNXT_VIDEO_GRABBER)
+ if (dev->model != CX231XX_BOARD_CNXT_VIDEO_GRABBER &&
+ dev->model != CX231XX_BOARD_HAUPPAUGE_USBLIVE2)
if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
videobuf_stop(&fh->vb_vidq);
videobuf_mmap_free(&fh->vb_vidq);
if (dev->state & DEV_DISCONNECTED) {
if (atomic_read(&dev->devlist_count) > 0) {
cx231xx_release_resources(dev);
- mutex_unlock(&dev->lock);
kfree(dev);
dev = NULL;
return 0;
}
- mutex_unlock(&dev->lock);
return 0;
}
kfree(fh);
dev->users--;
wake_up_interruptible_nr(&dev->open, 1);
- mutex_unlock(&dev->lock);
return 0;
}
free the remaining resources */
if (dev->state & DEV_DISCONNECTED) {
cx231xx_release_resources(dev);
- mutex_unlock(&dev->lock);
kfree(dev);
dev = NULL;
return 0;
kfree(fh);
dev->users--;
wake_up_interruptible_nr(&dev->open, 1);
- mutex_unlock(&dev->lock);
return 0;
}
if ((fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
(fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)) {
- mutex_lock(&dev->lock);
rc = res_get(fh);
- mutex_unlock(&dev->lock);
if (unlikely(rc < 0))
return rc;
if (rc < 0)
return rc;
- mutex_lock(&dev->lock);
rc = res_get(fh);
- mutex_unlock(&dev->lock);
if (unlikely(rc < 0))
return POLLERR;
if (rc < 0)
return rc;
- mutex_lock(&dev->lock);
rc = res_get(fh);
- mutex_unlock(&dev->lock);
if (unlikely(rc < 0))
return rc;
.read = cx231xx_v4l2_read,
.poll = cx231xx_v4l2_poll,
.mmap = cx231xx_v4l2_mmap,
- .ioctl = video_ioctl2,
+ .unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops video_ioctl_ops = {
vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
vfd->debug = video_debug;
+ vfd->lock = &dev->lock;
snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name);
dev->width = norm_maxw(dev);
dev->height = norm_maxh(dev);
dev->interlaced = 0;
- dev->hscale = 0;
- dev->vscale = 0;
/* Analog specific initialization */
dev->format = &format[0];
- /* video_mux(dev, dev->video_input); */
+
+ /* Set the initial input */
+ video_mux(dev, dev->video_input);
/* Audio defaults */
dev->mute = 1;