alistair23-linux/drivers/staging/media/soc_camera/soc_mediabus.c
Greg Kroah-Hartman 26855d5ace staging: media: soc_camera: add proper SPDX identifiers on files that did not have them.
There were a few files for the soc_camera drivers that did not have SPDX
identifiers on them, so fix that up.  At the same time, remove the "free
form" text that specified the license of the file, as that is impossible
for any tool to properly parse.

Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
Cc: Shawn Guo <shawnguo@kernel.org>
Cc: Sascha Hauer <s.hauer@pengutronix.de>
Cc: Fabio Estevam <festevam@gmail.com>
Cc: NXP Linux Team <linux-imx@nxp.com>
Cc: Sakari Ailus <sakari.ailus@linux.intel.com>
Cc: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Cc: linux-media@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-04-03 11:10:18 +02:00

530 lines
13 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* soc-camera media bus helper routines
*
* Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mediabus.h>
#include <media/drv-intf/soc_mediabus.h>
static const struct soc_mbus_lookup mbus_fmt[] = {
{
.code = MEDIA_BUS_FMT_YUYV8_2X8,
.fmt = {
.fourcc = V4L2_PIX_FMT_YUYV,
.name = "YUYV",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_2X8_PADHI,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_YVYU8_2X8,
.fmt = {
.fourcc = V4L2_PIX_FMT_YVYU,
.name = "YVYU",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_2X8_PADHI,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_UYVY8_2X8,
.fmt = {
.fourcc = V4L2_PIX_FMT_UYVY,
.name = "UYVY",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_2X8_PADHI,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_VYUY8_2X8,
.fmt = {
.fourcc = V4L2_PIX_FMT_VYUY,
.name = "VYUY",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_2X8_PADHI,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE,
.fmt = {
.fourcc = V4L2_PIX_FMT_RGB555,
.name = "RGB555",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_2X8_PADHI,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE,
.fmt = {
.fourcc = V4L2_PIX_FMT_RGB555X,
.name = "RGB555X",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_2X8_PADHI,
.order = SOC_MBUS_ORDER_BE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_RGB565_2X8_LE,
.fmt = {
.fourcc = V4L2_PIX_FMT_RGB565,
.name = "RGB565",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_2X8_PADHI,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_RGB565_2X8_BE,
.fmt = {
.fourcc = V4L2_PIX_FMT_RGB565X,
.name = "RGB565X",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_2X8_PADHI,
.order = SOC_MBUS_ORDER_BE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_RGB666_1X18,
.fmt = {
.fourcc = V4L2_PIX_FMT_RGB32,
.name = "RGB666/32bpp",
.bits_per_sample = 18,
.packing = SOC_MBUS_PACKING_EXTEND32,
.order = SOC_MBUS_ORDER_LE,
},
}, {
.code = MEDIA_BUS_FMT_RGB888_1X24,
.fmt = {
.fourcc = V4L2_PIX_FMT_RGB32,
.name = "RGB888/32bpp",
.bits_per_sample = 24,
.packing = SOC_MBUS_PACKING_EXTEND32,
.order = SOC_MBUS_ORDER_LE,
},
}, {
.code = MEDIA_BUS_FMT_RGB888_2X12_BE,
.fmt = {
.fourcc = V4L2_PIX_FMT_RGB32,
.name = "RGB888/32bpp",
.bits_per_sample = 12,
.packing = SOC_MBUS_PACKING_EXTEND32,
.order = SOC_MBUS_ORDER_BE,
},
}, {
.code = MEDIA_BUS_FMT_RGB888_2X12_LE,
.fmt = {
.fourcc = V4L2_PIX_FMT_RGB32,
.name = "RGB888/32bpp",
.bits_per_sample = 12,
.packing = SOC_MBUS_PACKING_EXTEND32,
.order = SOC_MBUS_ORDER_LE,
},
}, {
.code = MEDIA_BUS_FMT_SBGGR8_1X8,
.fmt = {
.fourcc = V4L2_PIX_FMT_SBGGR8,
.name = "Bayer 8 BGGR",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_NONE,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SBGGR10_1X10,
.fmt = {
.fourcc = V4L2_PIX_FMT_SBGGR10,
.name = "Bayer 10 BGGR",
.bits_per_sample = 10,
.packing = SOC_MBUS_PACKING_EXTEND16,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_Y8_1X8,
.fmt = {
.fourcc = V4L2_PIX_FMT_GREY,
.name = "Grey",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_NONE,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_Y10_1X10,
.fmt = {
.fourcc = V4L2_PIX_FMT_Y10,
.name = "Grey 10bit",
.bits_per_sample = 10,
.packing = SOC_MBUS_PACKING_EXTEND16,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE,
.fmt = {
.fourcc = V4L2_PIX_FMT_SBGGR10,
.name = "Bayer 10 BGGR",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_2X8_PADHI,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE,
.fmt = {
.fourcc = V4L2_PIX_FMT_SBGGR10,
.name = "Bayer 10 BGGR",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_2X8_PADLO,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE,
.fmt = {
.fourcc = V4L2_PIX_FMT_SBGGR10,
.name = "Bayer 10 BGGR",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_2X8_PADHI,
.order = SOC_MBUS_ORDER_BE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE,
.fmt = {
.fourcc = V4L2_PIX_FMT_SBGGR10,
.name = "Bayer 10 BGGR",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_2X8_PADLO,
.order = SOC_MBUS_ORDER_BE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_JPEG_1X8,
.fmt = {
.fourcc = V4L2_PIX_FMT_JPEG,
.name = "JPEG",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_VARIABLE,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE,
.fmt = {
.fourcc = V4L2_PIX_FMT_RGB444,
.name = "RGB444",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_2X8_PADHI,
.order = SOC_MBUS_ORDER_BE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_YUYV8_1_5X8,
.fmt = {
.fourcc = V4L2_PIX_FMT_YUV420,
.name = "YUYV 4:2:0",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_1_5X8,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_YVYU8_1_5X8,
.fmt = {
.fourcc = V4L2_PIX_FMT_YVU420,
.name = "YVYU 4:2:0",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_1_5X8,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_UYVY8_1X16,
.fmt = {
.fourcc = V4L2_PIX_FMT_UYVY,
.name = "UYVY 16bit",
.bits_per_sample = 16,
.packing = SOC_MBUS_PACKING_EXTEND16,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_VYUY8_1X16,
.fmt = {
.fourcc = V4L2_PIX_FMT_VYUY,
.name = "VYUY 16bit",
.bits_per_sample = 16,
.packing = SOC_MBUS_PACKING_EXTEND16,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_YUYV8_1X16,
.fmt = {
.fourcc = V4L2_PIX_FMT_YUYV,
.name = "YUYV 16bit",
.bits_per_sample = 16,
.packing = SOC_MBUS_PACKING_EXTEND16,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_YVYU8_1X16,
.fmt = {
.fourcc = V4L2_PIX_FMT_YVYU,
.name = "YVYU 16bit",
.bits_per_sample = 16,
.packing = SOC_MBUS_PACKING_EXTEND16,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SGRBG8_1X8,
.fmt = {
.fourcc = V4L2_PIX_FMT_SGRBG8,
.name = "Bayer 8 GRBG",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_NONE,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8,
.fmt = {
.fourcc = V4L2_PIX_FMT_SGRBG10DPCM8,
.name = "Bayer 10 BGGR DPCM 8",
.bits_per_sample = 8,
.packing = SOC_MBUS_PACKING_NONE,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SGBRG10_1X10,
.fmt = {
.fourcc = V4L2_PIX_FMT_SGBRG10,
.name = "Bayer 10 GBRG",
.bits_per_sample = 10,
.packing = SOC_MBUS_PACKING_EXTEND16,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SGRBG10_1X10,
.fmt = {
.fourcc = V4L2_PIX_FMT_SGRBG10,
.name = "Bayer 10 GRBG",
.bits_per_sample = 10,
.packing = SOC_MBUS_PACKING_EXTEND16,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SRGGB10_1X10,
.fmt = {
.fourcc = V4L2_PIX_FMT_SRGGB10,
.name = "Bayer 10 RGGB",
.bits_per_sample = 10,
.packing = SOC_MBUS_PACKING_EXTEND16,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SBGGR12_1X12,
.fmt = {
.fourcc = V4L2_PIX_FMT_SBGGR12,
.name = "Bayer 12 BGGR",
.bits_per_sample = 12,
.packing = SOC_MBUS_PACKING_EXTEND16,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SGBRG12_1X12,
.fmt = {
.fourcc = V4L2_PIX_FMT_SGBRG12,
.name = "Bayer 12 GBRG",
.bits_per_sample = 12,
.packing = SOC_MBUS_PACKING_EXTEND16,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SGRBG12_1X12,
.fmt = {
.fourcc = V4L2_PIX_FMT_SGRBG12,
.name = "Bayer 12 GRBG",
.bits_per_sample = 12,
.packing = SOC_MBUS_PACKING_EXTEND16,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
}, {
.code = MEDIA_BUS_FMT_SRGGB12_1X12,
.fmt = {
.fourcc = V4L2_PIX_FMT_SRGGB12,
.name = "Bayer 12 RGGB",
.bits_per_sample = 12,
.packing = SOC_MBUS_PACKING_EXTEND16,
.order = SOC_MBUS_ORDER_LE,
.layout = SOC_MBUS_LAYOUT_PACKED,
},
},
};
int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
unsigned int *numerator, unsigned int *denominator)
{
switch (mf->packing) {
case SOC_MBUS_PACKING_NONE:
case SOC_MBUS_PACKING_EXTEND16:
*numerator = 1;
*denominator = 1;
return 0;
case SOC_MBUS_PACKING_EXTEND32:
*numerator = 1;
*denominator = 1;
return 0;
case SOC_MBUS_PACKING_2X8_PADHI:
case SOC_MBUS_PACKING_2X8_PADLO:
*numerator = 2;
*denominator = 1;
return 0;
case SOC_MBUS_PACKING_1_5X8:
*numerator = 3;
*denominator = 2;
return 0;
case SOC_MBUS_PACKING_VARIABLE:
*numerator = 0;
*denominator = 1;
return 0;
}
return -EINVAL;
}
EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
{
if (mf->layout != SOC_MBUS_LAYOUT_PACKED)
return width * mf->bits_per_sample / 8;
switch (mf->packing) {
case SOC_MBUS_PACKING_NONE:
return width * mf->bits_per_sample / 8;
case SOC_MBUS_PACKING_2X8_PADHI:
case SOC_MBUS_PACKING_2X8_PADLO:
case SOC_MBUS_PACKING_EXTEND16:
return width * 2;
case SOC_MBUS_PACKING_1_5X8:
return width * 3 / 2;
case SOC_MBUS_PACKING_VARIABLE:
return 0;
case SOC_MBUS_PACKING_EXTEND32:
return width * 4;
}
return -EINVAL;
}
EXPORT_SYMBOL(soc_mbus_bytes_per_line);
s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf,
u32 bytes_per_line, u32 height)
{
if (mf->layout == SOC_MBUS_LAYOUT_PACKED)
return bytes_per_line * height;
switch (mf->packing) {
case SOC_MBUS_PACKING_2X8_PADHI:
case SOC_MBUS_PACKING_2X8_PADLO:
return bytes_per_line * height * 2;
case SOC_MBUS_PACKING_1_5X8:
return bytes_per_line * height * 3 / 2;
default:
return -EINVAL;
}
}
EXPORT_SYMBOL(soc_mbus_image_size);
const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc(
u32 code,
const struct soc_mbus_lookup *lookup,
int n)
{
int i;
for (i = 0; i < n; i++)
if (lookup[i].code == code)
return &lookup[i].fmt;
return NULL;
}
EXPORT_SYMBOL(soc_mbus_find_fmtdesc);
const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
u32 code)
{
return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
}
EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
unsigned int flags)
{
unsigned long common_flags;
bool hsync = true, vsync = true, pclk, data, mode;
bool mipi_lanes, mipi_clock;
common_flags = cfg->flags & flags;
switch (cfg->type) {
case V4L2_MBUS_PARALLEL:
hsync = common_flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH |
V4L2_MBUS_HSYNC_ACTIVE_LOW);
vsync = common_flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH |
V4L2_MBUS_VSYNC_ACTIVE_LOW);
/* fall through */
case V4L2_MBUS_BT656:
pclk = common_flags & (V4L2_MBUS_PCLK_SAMPLE_RISING |
V4L2_MBUS_PCLK_SAMPLE_FALLING);
data = common_flags & (V4L2_MBUS_DATA_ACTIVE_HIGH |
V4L2_MBUS_DATA_ACTIVE_LOW);
mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE);
return (!hsync || !vsync || !pclk || !data || !mode) ?
0 : common_flags;
case V4L2_MBUS_CSI2_DPHY:
mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES;
mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK |
V4L2_MBUS_CSI2_CONTINUOUS_CLOCK);
return (!mipi_lanes || !mipi_clock) ? 0 : common_flags;
default:
WARN_ON(1);
return -EINVAL;
}
return 0;
}
EXPORT_SYMBOL(soc_mbus_config_compatible);
static int __init soc_mbus_init(void)
{
return 0;
}
static void __exit soc_mbus_exit(void)
{
}
module_init(soc_mbus_init);
module_exit(soc_mbus_exit);
MODULE_DESCRIPTION("soc-camera media bus interface");
MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
MODULE_LICENSE("GPL v2");