Skip to content

Commit

Permalink
V4L/DVB (9927): em28xx: use a more standard way to specify video formats
Browse files Browse the repository at this point in the history
This patch uses the same code for enumberating video formats that are
present on cx88, bttv and saa7134 drivers.

Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Mauro Carvalho Chehab committed Dec 30, 2008
1 parent 381aaba commit bddcf63
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 21 deletions.
17 changes: 13 additions & 4 deletions 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 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 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 bddcf63

Please sign in to comment.