From patchwork Fri Oct 30 14:01:27 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 56625 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n9UE1NIA006701 for ; Fri, 30 Oct 2009 14:01:23 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932143AbZJ3OBR (ORCPT ); Fri, 30 Oct 2009 10:01:17 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S932068AbZJ3OBQ (ORCPT ); Fri, 30 Oct 2009 10:01:16 -0400 Received: from mail.gmx.net ([213.165.64.20]:57969 "HELO mail.gmx.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S932137AbZJ3OBO (ORCPT ); Fri, 30 Oct 2009 10:01:14 -0400 Received: (qmail invoked by alias); 30 Oct 2009 14:01:16 -0000 Received: from p57BD2221.dip0.t-ipconnect.de (EHLO axis700.grange) [87.189.34.33] by mail.gmx.net (mp009) with SMTP; 30 Oct 2009 15:01:16 +0100 X-Authenticated: #20450766 X-Provags-ID: V01U2FsdGVkX1+XyTkre1aXKSEhrPDbHIQIwdVn9bT9msiLxVXyXw E7Bik/ojOj3wdJ Received: from lyakh (helo=localhost) by axis700.grange with local-esmtp (Exim 4.63) (envelope-from ) id 1N3s2h-0001f5-Ff; Fri, 30 Oct 2009 15:01:27 +0100 Date: Fri, 30 Oct 2009 15:01:27 +0100 (CET) From: Guennadi Liakhovetski To: Linux Media Mailing List cc: Hans Verkuil , Laurent Pinchart , Sakari Ailus , Muralidharan Karicheri Subject: [PATCH/RFC 7/9 v2] v4l: add an image-bus API for configuring v4l2 subdev pixel and frame formats In-Reply-To: Message-ID: References: MIME-Version: 1.0 X-Y-GMX-Trusted: 0 X-FuHaFi: 0.44 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 7a2dcc3..62d8907 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -10,7 +10,7 @@ stkwebcam-objs := stk-webcam.o stk-sensor.o omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o -videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o +videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-imagebus.o # V4L2 core modules diff --git a/drivers/media/video/v4l2-imagebus.c b/drivers/media/video/v4l2-imagebus.c new file mode 100644 index 0000000..e0a3a83 --- /dev/null +++ b/drivers/media/video/v4l2-imagebus.c @@ -0,0 +1,218 @@ +/* + * Image Bus API + * + * Copyright (C) 2009, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include + +#include +#include + +static const struct v4l2_imgbus_pixelfmt imgbus_fmt[] = { + [V4L2_IMGBUS_FMT_YUYV] = { + .fourcc = V4L2_PIX_FMT_YUYV, + .colorspace = V4L2_COLORSPACE_JPEG, + .name = "YUYV", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_2X8_PADHI, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_YVYU] = { + .fourcc = V4L2_PIX_FMT_YVYU, + .colorspace = V4L2_COLORSPACE_JPEG, + .name = "YVYU", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_2X8_PADHI, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_UYVY] = { + .fourcc = V4L2_PIX_FMT_UYVY, + .colorspace = V4L2_COLORSPACE_JPEG, + .name = "UYVY", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_2X8_PADHI, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_VYUY] = { + .fourcc = V4L2_PIX_FMT_VYUY, + .colorspace = V4L2_COLORSPACE_JPEG, + .name = "VYUY", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_2X8_PADHI, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_VYUY_SMPTE170M_8] = { + .fourcc = V4L2_PIX_FMT_VYUY, + .colorspace = V4L2_COLORSPACE_SMPTE170M, + .name = "VYUY in SMPTE170M", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_2X8_PADHI, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_VYUY_SMPTE170M_16] = { + .fourcc = V4L2_PIX_FMT_VYUY, + .colorspace = V4L2_COLORSPACE_SMPTE170M, + .name = "VYUY in SMPTE170M, 16bit", + .bits_per_sample = 16, + .packing = V4L2_IMGBUS_PACKING_NONE, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_RGB555] = { + .fourcc = V4L2_PIX_FMT_RGB555, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "RGB555", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_2X8_PADHI, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_RGB555X] = { + .fourcc = V4L2_PIX_FMT_RGB555X, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "RGB555X", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_2X8_PADHI, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_RGB565] = { + .fourcc = V4L2_PIX_FMT_RGB565, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "RGB565", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_2X8_PADHI, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_RGB565X] = { + .fourcc = V4L2_PIX_FMT_RGB565X, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "RGB565X", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_2X8_PADHI, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_SBGGR8] = { + .fourcc = V4L2_PIX_FMT_SBGGR8, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "Bayer 8 BGGR", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_NONE, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_SGBRG8] = { + .fourcc = V4L2_PIX_FMT_SGBRG8, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "Bayer 8 GBRG", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_NONE, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_SGRBG8] = { + .fourcc = V4L2_PIX_FMT_SGRBG8, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "Bayer 8 GRBG", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_NONE, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_SRGGB8] = { + .fourcc = V4L2_PIX_FMT_SRGGB8, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "Bayer 8 RGGB", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_NONE, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_SBGGR10] = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "Bayer 10 BGGR", + .bits_per_sample = 10, + .packing = V4L2_IMGBUS_PACKING_EXTEND16, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_SGBRG10] = { + .fourcc = V4L2_PIX_FMT_SGBRG10, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "Bayer 10 GBRG", + .bits_per_sample = 10, + .packing = V4L2_IMGBUS_PACKING_EXTEND16, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_SGRBG10] = { + .fourcc = V4L2_PIX_FMT_SGRBG10, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "Bayer 10 GRBG", + .bits_per_sample = 10, + .packing = V4L2_IMGBUS_PACKING_EXTEND16, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_SRGGB10] = { + .fourcc = V4L2_PIX_FMT_SRGGB10, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "Bayer 10 RGGB", + .bits_per_sample = 10, + .packing = V4L2_IMGBUS_PACKING_EXTEND16, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_GREY] = { + .fourcc = V4L2_PIX_FMT_GREY, + .colorspace = V4L2_COLORSPACE_JPEG, + .name = "Grey", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_NONE, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_Y16] = { + .fourcc = V4L2_PIX_FMT_Y16, + .colorspace = V4L2_COLORSPACE_JPEG, + .name = "Grey 16bit", + .bits_per_sample = 16, + .packing = V4L2_IMGBUS_PACKING_NONE, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_Y10] = { + .fourcc = V4L2_PIX_FMT_Y10, + .colorspace = V4L2_COLORSPACE_JPEG, + .name = "Grey 10bit", + .bits_per_sample = 10, + .packing = V4L2_IMGBUS_PACKING_EXTEND16, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_SBGGR10_2X8_PADHI_LE] = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "Bayer 10 BGGR", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_2X8_PADHI, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_SBGGR10_2X8_PADLO_LE] = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "Bayer 10 BGGR", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_2X8_PADLO, + .order = V4L2_IMGBUS_ORDER_LE, + }, [V4L2_IMGBUS_FMT_SBGGR10_2X8_PADHI_BE] = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "Bayer 10 BGGR", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_2X8_PADHI, + .order = V4L2_IMGBUS_ORDER_BE, + }, [V4L2_IMGBUS_FMT_SBGGR10_2X8_PADLO_BE] = { + .fourcc = V4L2_PIX_FMT_SBGGR10, + .colorspace = V4L2_COLORSPACE_SRGB, + .name = "Bayer 10 BGGR", + .bits_per_sample = 8, + .packing = V4L2_IMGBUS_PACKING_2X8_PADLO, + .order = V4L2_IMGBUS_ORDER_BE, + }, +}; + +const struct v4l2_imgbus_pixelfmt *v4l2_imgbus_get_fmtdesc( + enum v4l2_imgbus_pixelcode code) +{ + if ((unsigned int)code > ARRAY_SIZE(imgbus_fmt)) + return NULL; + return imgbus_fmt + code; +} +EXPORT_SYMBOL(v4l2_imgbus_get_fmtdesc); + +s32 v4l2_imgbus_bytes_per_line(u32 width, + const struct v4l2_imgbus_pixelfmt *imgf) +{ + switch (imgf->packing) { + case V4L2_IMGBUS_PACKING_NONE: + return width * imgf->bits_per_sample / 8; + case V4L2_IMGBUS_PACKING_2X8_PADHI: + case V4L2_IMGBUS_PACKING_2X8_PADLO: + case V4L2_IMGBUS_PACKING_EXTEND16: + return width * 2; + } + return -EINVAL; +} +EXPORT_SYMBOL(v4l2_imgbus_bytes_per_line); diff --git a/include/media/v4l2-imagebus.h b/include/media/v4l2-imagebus.h new file mode 100644 index 0000000..022d044 --- /dev/null +++ b/include/media/v4l2-imagebus.h @@ -0,0 +1,84 @@ +/* + * Image Bus API header + * + * Copyright (C) 2009, Guennadi Liakhovetski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef V4L2_IMGBUS_H +#define V4L2_IMGBUS_H + +enum v4l2_imgbus_packing { + V4L2_IMGBUS_PACKING_NONE, + V4L2_IMGBUS_PACKING_2X8_PADHI, + V4L2_IMGBUS_PACKING_2X8_PADLO, + V4L2_IMGBUS_PACKING_EXTEND16, +}; + +enum v4l2_imgbus_order { + V4L2_IMGBUS_ORDER_LE, + V4L2_IMGBUS_ORDER_BE, +}; + +enum v4l2_imgbus_pixelcode { + V4L2_IMGBUS_FMT_YUYV, + V4L2_IMGBUS_FMT_YVYU, + V4L2_IMGBUS_FMT_UYVY, + V4L2_IMGBUS_FMT_VYUY, + V4L2_IMGBUS_FMT_VYUY_SMPTE170M_8, + V4L2_IMGBUS_FMT_VYUY_SMPTE170M_16, + V4L2_IMGBUS_FMT_RGB555, + V4L2_IMGBUS_FMT_RGB555X, + V4L2_IMGBUS_FMT_RGB565, + V4L2_IMGBUS_FMT_RGB565X, + V4L2_IMGBUS_FMT_SBGGR8, + V4L2_IMGBUS_FMT_SGBRG8, + V4L2_IMGBUS_FMT_SGRBG8, + V4L2_IMGBUS_FMT_SRGGB8, + V4L2_IMGBUS_FMT_SBGGR10, + V4L2_IMGBUS_FMT_SGBRG10, + V4L2_IMGBUS_FMT_SGRBG10, + V4L2_IMGBUS_FMT_SRGGB10, + V4L2_IMGBUS_FMT_GREY, + V4L2_IMGBUS_FMT_Y16, + V4L2_IMGBUS_FMT_Y10, + V4L2_IMGBUS_FMT_SBGGR10_2X8_PADHI_BE, + V4L2_IMGBUS_FMT_SBGGR10_2X8_PADLO_BE, + V4L2_IMGBUS_FMT_SBGGR10_2X8_PADHI_LE, + V4L2_IMGBUS_FMT_SBGGR10_2X8_PADLO_LE, +}; + +/** + * struct v4l2_imgbus_pixelfmt - Data format on the image bus + * @fourcc: Fourcc code... + * @colorspace: and colorspace, that will be obtained if the data is + * stored in memory in the following way: + * @bits_per_sample: How many bits the bridge has to sample + * @packing: Type of sample-packing, that has to be used + * @order: Sample order when storing in memory + */ +struct v4l2_imgbus_pixelfmt { + u32 fourcc; + enum v4l2_colorspace colorspace; + const char *name; + enum v4l2_imgbus_packing packing; + enum v4l2_imgbus_order order; + u8 bits_per_sample; +}; + +struct v4l2_imgbus_framefmt { + __u32 width; + __u32 height; + enum v4l2_imgbus_pixelcode code; + enum v4l2_field field; +}; + +const struct v4l2_imgbus_pixelfmt *v4l2_imgbus_get_fmtdesc( + enum v4l2_imgbus_pixelcode code); +s32 v4l2_imgbus_bytes_per_line(u32 width, + const struct v4l2_imgbus_pixelfmt *imgf); + +#endif diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 04193eb..1e86f39 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -22,6 +22,7 @@ #define _V4L2_SUBDEV_H #include +#include struct v4l2_device; struct v4l2_subdev; @@ -196,7 +197,7 @@ struct v4l2_subdev_audio_ops { s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by video input devices. - s_crystal_freq: sets the frequency of the crystal used to generate the + s_crystal_freq: sets the frequency of the crystal used to generate the clocks in Hz. An extra flags field allows device specific configuration regarding clock frequency dividers, etc. If not used, then set flags to 0. If the frequency is not supported, then -EINVAL is returned. @@ -206,6 +207,8 @@ struct v4l2_subdev_audio_ops { s_routing: see s_routing in audio_ops, except this version is for video devices. + + enum_imgbus_fmt: enumerate pixel formats provided by a video data source */ struct v4l2_subdev_video_ops { int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); @@ -227,6 +230,11 @@ struct v4l2_subdev_video_ops { int (*s_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); + int (*enum_imgbus_fmt)(struct v4l2_subdev *sd, int index, + enum v4l2_imgbus_pixelcode *code); + int (*g_imgbus_fmt)(struct v4l2_subdev *sd, struct v4l2_imgbus_framefmt *fmt); + int (*try_imgbus_fmt)(struct v4l2_subdev *sd, struct v4l2_imgbus_framefmt *fmt); + int (*s_imgbus_fmt)(struct v4l2_subdev *sd, struct v4l2_imgbus_framefmt *fmt); }; /**