/* unfortunately, the saa7146 contains a bug which prevents it from doing on-the-fly byte swaps.
due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped
(like V4L2_PIX_FMT_YUYV) ... 8-( */
/* unfortunately, the saa7146 contains a bug which prevents it from doing on-the-fly byte swaps.
due to this, it's impossible to provide additional *packed* formats, which are simply byte swapped
(like V4L2_PIX_FMT_YUYV) ... 8-( */
static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc)
{
int i, j = NUM_FORMATS;
static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format);
struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc)
{
int i, j = NUM_FORMATS;
- field = (win->w.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_TOP;
- }
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- case V4L2_FIELD_ALTERNATE:
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- break;
- default: {
+ field = (win->w.height > maxh/2)
+ ? V4L2_FIELD_INTERLACED
+ : V4L2_FIELD_TOP;
+ }
+ switch (field) {
+ case V4L2_FIELD_TOP:
+ case V4L2_FIELD_BOTTOM:
+ case V4L2_FIELD_ALTERNATE:
+ maxh = maxh / 2;
+ break;
+ case V4L2_FIELD_INTERLACED:
+ break;
+ default: {
field = f->fmt.pix.field;
maxw = vv->standard->h_max_out;
maxh = vv->standard->v_max_out;
field = f->fmt.pix.field;
maxw = vv->standard->h_max_out;
maxh = vv->standard->v_max_out;
if (f->fmt.pix.bytesperline > (2*PAGE_SIZE * fmt->depth)/8) /* arbitrary constraint */
f->fmt.pix.bytesperline = calc_bpl;
if (f->fmt.pix.bytesperline > (2*PAGE_SIZE * fmt->depth)/8) /* arbitrary constraint */
f->fmt.pix.bytesperline = calc_bpl;
f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n",f->fmt.pix.width,f->fmt.pix.height,f->fmt.pix.bytesperline,f->fmt.pix.sizeimage));
f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n",f->fmt.pix.width,f->fmt.pix.height,f->fmt.pix.bytesperline,f->fmt.pix.sizeimage));
if (0 == saa7146_res_get(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP)) {
DEB_D(("cannot get necessary overlay resources\n"));
return -EBUSY;
if (0 == saa7146_res_get(fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP)) {
DEB_D(("cannot get necessary overlay resources\n"));
return -EBUSY;
err = try_win(dev,&fh->ov.win);
if (0 != err) {
saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
return -EBUSY;
}
err = try_win(dev,&fh->ov.win);
if (0 != err) {
saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
return -EBUSY;
}
vv->ov_data = &fh->ov;
DEB_D(("%dx%d+%d+%d %s field=%s\n",
fh->ov.win.w.width,fh->ov.win.w.height,
fh->ov.win.w.left,fh->ov.win.w.top,
vv->ov_fmt->name,v4l2_field_names[fh->ov.win.field]));
vv->ov_data = &fh->ov;
DEB_D(("%dx%d+%d+%d %s field=%s\n",
fh->ov.win.w.width,fh->ov.win.w.height,
fh->ov.win.w.left,fh->ov.win.w.top,
vv->ov_fmt->name,v4l2_field_names[fh->ov.win.field]));
if (0 != (ret = saa7146_enable_overlay(fh))) {
DEB_D(("enabling overlay failed: %d\n",ret));
saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
if (0 != (ret = saa7146_enable_overlay(fh))) {
DEB_D(("enabling overlay failed: %d\n",ret));
saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
fh->ov.win = f->fmt.win;
fh->ov.nclips = f->fmt.win.clipcount;
if (fh->ov.nclips > 16)
fh->ov.nclips = 16;
if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) {
fh->ov.win = f->fmt.win;
fh->ov.nclips = f->fmt.win.clipcount;
if (fh->ov.nclips > 16)
fh->ov.nclips = 16;
if (copy_from_user(fh->ov.clips,f->fmt.win.clips,sizeof(struct v4l2_clip)*fh->ov.nclips)) {
/* fixme: we can support changing VFLIP and HFLIP here... */
if (IS_CAPTURE_ACTIVE(fh) != 0) {
DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
/* fixme: we can support changing VFLIP and HFLIP here... */
if (IS_CAPTURE_ACTIVE(fh) != 0) {
DEB_D(("V4L2_CID_HFLIP while active capture.\n"));
/* if we have a user buffer, the first page may not be
aligned to a page boundary. */
pt1->offset = buf->vb.dma.sglist->offset;
pt2->offset = pt1->offset+o1;
pt3->offset = pt1->offset+o2;
/* if we have a user buffer, the first page may not be
aligned to a page boundary. */
pt1->offset = buf->vb.dma.sglist->offset;
pt2->offset = pt1->offset+o1;
pt3->offset = pt1->offset+o2;
/* create video-dma2 page table */
ptr1 = pt1->cpu;
for(i = m1; i <= m2 ; i++, ptr2++) {
/* create video-dma2 page table */
ptr1 = pt1->cpu;
for(i = m1; i <= m2 ; i++, ptr2++) {
} else {
struct saa7146_pgtable *pt = &buf->pt[0];
return saa7146_pgtable_build_single(pci, pt, list, length);
} else {
struct saa7146_pgtable *pt = &buf->pt[0];
return saa7146_pgtable_build_single(pci, pt, list, length);
fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
/* we need to have a valid format set here */
BUG_ON(NULL == fmt);
fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat);
/* we need to have a valid format set here */
BUG_ON(NULL == fmt);
saa7146_write(dev, MC1, dmas);
spin_unlock_irqrestore(&dev->slock, flags);
saa7146_write(dev, MC1, dmas);
spin_unlock_irqrestore(&dev->slock, flags);
if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) {
DEB_D(("extension handles ioctl exclusive.\n"));
result = dev->ext_vv_data->ioctl(fh, cmd, arg);
if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) {
DEB_D(("extension handles ioctl exclusive.\n"));
result = dev->ext_vv_data->ioctl(fh, cmd, arg);
{
struct v4l2_capability *cap = arg;
memset(cap,0,sizeof(*cap));
DEB_EE(("VIDIOC_QUERYCAP\n"));
{
struct v4l2_capability *cap = arg;
memset(cap,0,sizeof(*cap));
DEB_EE(("VIDIOC_QUERYCAP\n"));
/* planar formats are not allowed for overlay video, clipping and video dma would clash */
if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",(char *)&fmt->pixelformat));
}
/* check if overlay is running */
/* planar formats are not allowed for overlay video, clipping and video dma would clash */
if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",(char *)&fmt->pixelformat));
}
/* check if overlay is running */
if (vv->video_fh != fh) {
DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n"));
return -EBUSY;
if (vv->video_fh != fh) {
DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n"));
return -EBUSY;
}
DEB_EE(("VIDIOC_ENUM_FMT: type:%d, index:%d\n",f->type,f->index));
}
DEB_EE(("VIDIOC_ENUM_FMT: type:%d, index:%d\n",f->type,f->index));
{
DEB_EE(("VIDIOC_S_CTRL\n"));
err = set_control(fh,arg);
return err;
}
{
DEB_EE(("VIDIOC_S_CTRL\n"));
err = set_control(fh,arg);
return err;
}
parm->parm.capture.readbuffers = 1;
// fixme: only for PAL!
parm->parm.capture.timeperframe.numerator = 1;
parm->parm.capture.timeperframe.denominator = 25;
parm->parm.capture.readbuffers = 1;
// fixme: only for PAL!
parm->parm.capture.timeperframe.numerator = 1;
parm->parm.capture.timeperframe.denominator = 25;
err = videobuf_mmap_setup(q,gbuffers,gbufsize,
V4L2_MEMORY_MMAP);
if (err < 0) {
err = videobuf_mmap_setup(q,gbuffers,gbufsize,
V4L2_MEMORY_MMAP);
if (err < 0) {
mbuf->size = gbuffers * gbufsize;
for (i = 0; i < gbuffers; i++)
mbuf->offsets[i] = i * gbufsize;
mbuf->size = gbuffers * gbufsize;
for (i = 0; i < gbuffers; i++)
mbuf->offsets[i] = i * gbufsize;
buf->vb.state = STATE_ACTIVE;
saa7146_set_capture(dev,buf,next);
buf->vb.state = STATE_ACTIVE;
saa7146_set_capture(dev,buf,next);
DEB_CAP(("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
fh->video_fmt.width,fh->video_fmt.height,size,v4l2_field_names[fh->video_fmt.field]));
if (buf->vb.width != fh->video_fmt.width ||
DEB_CAP(("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
fh->video_fmt.width,fh->video_fmt.height,size,v4l2_field_names[fh->video_fmt.field]));
if (buf->vb.width != fh->video_fmt.width ||
buf->vb.field != field ||
buf->vb.field != fh->video_fmt.field ||
buf->fmt != &fh->video_fmt) {
buf->vb.field != field ||
buf->vb.field != fh->video_fmt.field ||
buf->fmt != &fh->video_fmt) {
buf->vb.bytesperline = fh->video_fmt.bytesperline;
buf->vb.width = fh->video_fmt.width;
buf->vb.height = fh->video_fmt.height;
buf->vb.bytesperline = fh->video_fmt.bytesperline;
buf->vb.width = fh->video_fmt.width;
buf->vb.height = fh->video_fmt.height;
if( 0 != IS_PLANAR(sfmt->trans)) {
saa7146_pgtable_free(dev->pci, &buf->pt[0]);
saa7146_pgtable_free(dev->pci, &buf->pt[1]);
if( 0 != IS_PLANAR(sfmt->trans)) {
saa7146_pgtable_free(dev->pci, &buf->pt[0]);
saa7146_pgtable_free(dev->pci, &buf->pt[1]);
saa7146_pgtable_free(dev->pci, &buf->pt[0]);
saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
}
saa7146_pgtable_free(dev->pci, &buf->pt[0]);
saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
}
DEB_CAP(("%d buffers, %d bytes each.\n",*count,*size));
return 0;
DEB_CAP(("%d buffers, %d bytes each.\n",*count,*size));
return 0;
struct saa7146_dev *dev = fh->dev;
struct saa7146_vv *vv = dev->vv_data;
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
struct saa7146_dev *dev = fh->dev;
struct saa7146_vv *vv = dev->vv_data;
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
DEB_CAP(("vbuf:%p\n",vb));
saa7146_buffer_queue(fh->dev,&vv->video_q,buf);
}
DEB_CAP(("vbuf:%p\n",vb));
saa7146_buffer_queue(fh->dev,&vv->video_q,buf);
}
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
{
struct file *file = q->priv_data;
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
{
struct file *file = q->priv_data;
struct saa7146_fh *fh = file->private_data;
struct saa7146_dev *dev = fh->dev;
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
struct saa7146_vv *vv = dev->vv_data;
int err;
struct saa7146_fh *fh = (struct saa7146_fh *)file->private_data;
struct saa7146_vv *vv = dev->vv_data;
int err;
- ret = videobuf_read_one(&fh->video_q, data, count, ppos,
+ ret = videobuf_read_one(&fh->video_q , data, count, ppos,