Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 124428
b: refs/heads/master
c: bddcf63
h: refs/heads/master
v: v3
  • Loading branch information
Mauro Carvalho Chehab committed Dec 30, 2008
1 parent aa74939 commit d2d8ec8
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 22 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 381aaba91de9659ccb8c061d6b7248e606903374
refs/heads/master: bddcf63313c6a4a85f94db092f45e31f530da691
17 changes: 13 additions & 4 deletions trunk/drivers/media/video/em28xx/em28xx-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,10 +621,19 @@ int em28xx_capture_start(struct em28xx *dev, int start)
return rc;
}

int em28xx_outfmt_set_yuv422(struct em28xx *dev)
int em28xx_set_outfmt(struct em28xx *dev)
{
em28xx_write_reg(dev, EM28XX_R27_OUTFMT, 0x34);
em28xx_write_reg(dev, EM28XX_R10_VINMODE, 0x10);
int ret;

ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT,
dev->format->reg | 0x20, 0x3f);
if (ret < 0)
return ret;

ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, 0x10);
if (ret < 0)
return ret;

return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x11);
}

Expand Down Expand Up @@ -686,7 +695,7 @@ int em28xx_resolution_set(struct em28xx *dev)
width = norm_maxw(dev);
height = norm_maxh(dev) >> 1;

em28xx_outfmt_set_yuv422(dev);
em28xx_set_outfmt(dev);
em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
Expand Down
66 changes: 50 additions & 16 deletions trunk/drivers/media/video/em28xx/em28xx-video.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
/* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */
static unsigned long em28xx_devused;

/* supported video standards */
static struct em28xx_fmt format[] = {
{
.name = "16bpp YUY2, 4:2:2, packed",
.fourcc = V4L2_PIX_FMT_YUYV,
.depth = 16,
.reg = 0x14,
},
};

/* supported controls */
/* Common to all boards */
static struct v4l2_queryctrl em28xx_qctrl[] = {
Expand Down Expand Up @@ -386,7 +396,8 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
struct em28xx *dev = fh->dev;
struct v4l2_frequency f;

*size = 16 * fh->dev->width * fh->dev->height >> 3;
*size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3;

if (0 == *count)
*count = EM28XX_DEF_BUF;

Expand Down Expand Up @@ -439,9 +450,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
struct em28xx *dev = fh->dev;
int rc = 0, urb_init = 0;

/* FIXME: It assumes depth = 16 */
/* The only currently supported format is 16 bits/pixel */
buf->vb.size = 16 * dev->width * dev->height >> 3;
buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3;

if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
return -EINVAL;
Expand Down Expand Up @@ -536,7 +545,7 @@ static int em28xx_config(struct em28xx *dev)
dev->mute = 1; /* maybe not the right place... */
dev->volume = 0x1f;

em28xx_outfmt_set_yuv422(dev);
em28xx_set_outfmt(dev);
em28xx_colorlevels_set_default(dev);
em28xx_compression_disable(dev);

Expand Down Expand Up @@ -704,8 +713,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,

f->fmt.pix.width = dev->width;
f->fmt.pix.height = dev->height;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
f->fmt.pix.bytesperline = dev->width * 2;
f->fmt.pix.pixelformat = dev->format->fourcc;
f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3;
f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;

Expand All @@ -717,6 +726,17 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
return 0;
}

static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc)
{
unsigned int i;

for (i = 0; i < ARRAY_SIZE(format); i++)
if (format[i].fourcc == fourcc)
return &format[i];

return NULL;
}

static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
Expand All @@ -727,6 +747,14 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
unsigned int maxw = norm_maxw(dev);
unsigned int maxh = norm_maxh(dev);
unsigned int hscale, vscale;
struct em28xx_fmt *fmt;

fmt = format_by_fourcc(f->fmt.pix.pixelformat);
if (!fmt) {
em28xx_videodbg("Fourcc format (%08x) invalid.\n",
f->fmt.pix.pixelformat);
return -EINVAL;
}

/* width must even because of the YUYV format
height must be even because of interlacing */
Expand Down Expand Up @@ -765,9 +793,9 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,

f->fmt.pix.width = width;
f->fmt.pix.height = height;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
f->fmt.pix.bytesperline = width * 2;
f->fmt.pix.sizeimage = width * 2 * height;
f->fmt.pix.pixelformat = fmt->fourcc;
f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3;
f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height;
f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
f->fmt.pix.field = V4L2_FIELD_INTERLACED;

Expand All @@ -780,6 +808,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct em28xx_fh *fh = priv;
struct em28xx *dev = fh->dev;
int rc;
struct em28xx_fmt *fmt;

rc = check_dev(dev);
if (rc < 0)
Expand All @@ -789,6 +818,10 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,

vidioc_try_fmt_vid_cap(file, priv, f);

fmt = format_by_fourcc(f->fmt.pix.pixelformat);
if (!fmt)
return -EINVAL;

if (videobuf_queue_is_busy(&fh->vb_vidq)) {
em28xx_errdev("%s queue busy\n", __func__);
rc = -EBUSY;
Expand All @@ -804,6 +837,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
/* 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);

em28xx_set_alternate(dev);
Expand Down Expand Up @@ -1332,15 +1366,13 @@ static int vidioc_querycap(struct file *file, void *priv,
}

static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *fmtd)
struct v4l2_fmtdesc *f)
{
if (fmtd->index != 0)
if (unlikely(f->index >= ARRAY_SIZE(format)))
return -EINVAL;

fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
strcpy(fmtd->description, "Packed YUY2");
fmtd->pixelformat = V4L2_PIX_FMT_YUYV;
memset(fmtd->reserved, 0, sizeof(fmtd->reserved));
strlcpy(f->description, format[f->index].name, sizeof(f->description));
f->pixelformat = format[f->index].fourcc;

return 0;
}
Expand Down Expand Up @@ -2075,6 +2107,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
dev->em28xx_write_regs_req = em28xx_write_regs_req;
dev->em28xx_read_reg_req = em28xx_read_reg_req;
dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800;
dev->format = &format[0];

em28xx_pre_card_setup(dev);

Expand Down Expand Up @@ -2482,3 +2515,4 @@ static void __exit em28xx_module_exit(void)

module_init(em28xx_module_init);
module_exit(em28xx_module_exit);

7 changes: 6 additions & 1 deletion trunk/drivers/media/video/em28xx/em28xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,12 @@ struct em28xx_usb_isoc_ctl {

};

/* Struct to enumberate video formats */
struct em28xx_fmt {
char *name;
u32 fourcc; /* v4l2 format id */
int depth;
int reg;
};

/* buffer for one video frame */
Expand Down Expand Up @@ -430,6 +433,8 @@ struct em28xx {
unsigned int has_audio_class:1;
unsigned int has_alsa_audio:1;

struct em28xx_fmt *format;

struct em28xx_IR *ir;

/* Some older em28xx chips needs a waiting time after writing */
Expand Down Expand Up @@ -564,7 +569,7 @@ int em28xx_audio_setup(struct em28xx *dev);

int em28xx_colorlevels_set_default(struct em28xx *dev);
int em28xx_capture_start(struct em28xx *dev, int start);
int em28xx_outfmt_set_yuv422(struct em28xx *dev);
int em28xx_set_outfmt(struct em28xx *dev);
int em28xx_resolution_set(struct em28xx *dev);
int em28xx_set_alternate(struct em28xx *dev);
int em28xx_init_isoc(struct em28xx *dev, int max_packets,
Expand Down

0 comments on commit d2d8ec8

Please sign in to comment.