From: Cho KyongHo Date: Thu, 26 Mar 2015 06:04:40 +0000 (+0900) Subject: [COMMON] media: smfc: add format definitions and enumeration X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=a66982b422ee39d64da75e4d40655b6e651c947a;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git [COMMON] media: smfc: add format definitions and enumeration Change-Id: Idf188d3d4a40195abea841e535ef7352bd593d02 Signed-off-by: Cho KyongHo --- diff --git a/drivers/media/platform/exynos/smfc/smfc-regs.h b/drivers/media/platform/exynos/smfc/smfc-regs.h index 9fb9e9f1f83c..ac3af77b307f 100644 --- a/drivers/media/platform/exynos/smfc/smfc-regs.h +++ b/drivers/media/platform/exynos/smfc/smfc-regs.h @@ -12,6 +12,82 @@ #ifndef _MEDIA_EXYNOS_SMFC_REGS_H_ #define _MEDIA_EXYNOS_SMFC_REGS_H_ +#define REG_MAIN_IMAGE_FORMAT 0x040 +#define REG_SECD_IMAGE_FORMAT 0x0B8 + #define REG_IP_VERSION_NUMBER 0x064 +/* Value definitions of MAIN/SECONDARY_IMAGE_FORMAT */ +enum { + IMGSEL_GRAY, + IMGSEL_RGB, + IMGSEL_444, /* YUV */ + IMGSEL_422, /* YUV */ + IMGSEL_420, /* YUV */ + IMGSEL_422V, /* YUV */ + IMGSEL_411 /* YUV */ +}; +#define IMGFMT_RGBSHIFT 6 +enum { + RGBSEL_RGB565 = 4, + RGBSEL_ARGB32, + RGBSEL_RGB24, +}; +#define IMGFMT_444SHIFT 9 +#define IMGFMT_422SHIFT 12 +#define IMGFMT_420SHIFT 15 +#define IMGFMT_422VSHIFT 18 +#define IMGFMT_411SHIFT 21 +enum { + YUVSEL_2P = 4, + YUVSEL_3P = 5, + YUV422SEL_1P = 4, + YUV422SEL_2P = 5, + YUV422SEL_3P = 6, +}; + +#define IMGFMT_RGBSWAP (1 << 30) +#define IMGFMT_UVSWAP (1 << 27) +enum { + YUVSEL_YUYV = 0, + YUVSEL_YVYU = 1 << 28, + YUVSEL_UYVY = 2 << 28, + YUVSEL_VYUY = 3 << 28, +}; + +#define SMFC_IMGFMT_RGB565 (IMGSEL_RGB | (RGBSEL_RGB565 << IMGFMT_RGBSHIFT)) +#define SMFC_IMGFMT_BGR565 (IMGSEL_RGB | (RGBSEL_RGB565 << IMGFMT_RGBSHIFT)\ + | IMGFMT_RGBSWAP) +#define SMFC_IMGFMT_RGB24 (IMGSEL_RGB | (RGBSEL_RGB24 << IMGFMT_RGBSHIFT)) +#define SMFC_IMGFMT_BGR24 (IMGSEL_RGB | (RGBSEL_RGB24 << IMGFMT_RGBSHIFT) \ + | IMGFMT_RGBSWAP) +#define SMFC_IMGFMT_BGRA32 (IMGSEL_RGB | (RGBSEL_ARGB32 << IMGFMT_RGBSHIFT)) +#define SMFC_IMGFMT_RGBA32 (IMGSEL_RGB | (RGBSEL_ARGB32 << IMGFMT_RGBSHIFT)\ + | IMGFMT_RGBSWAP) +#define SMFC_IMGFMT_NV12 (IMGSEL_420 | (YUVSEL_2P << IMGFMT_420SHIFT)) +#define SMFC_IMGFMT_NV21 (IMGSEL_420 | (YUVSEL_2P << IMGFMT_420SHIFT) \ + | IMGFMT_UVSWAP) +#define SMFC_IMGFMT_YUV420P (IMGSEL_420 | (YUVSEL_3P << IMGFMT_420SHIFT)) +#define SMFC_IMGFMT_YVU420P (IMGSEL_420 | (YUVSEL_3P << IMGFMT_420SHIFT) \ + | IMGFMT_UVSWAP) +#define SMFC_IMGFMT_YUYV (IMGSEL_422 | (YUV422SEL_1P << IMGFMT_422SHIFT) \ + | YUVSEL_YUYV) +#define SMFC_IMGFMT_YVYU (IMGSEL_422 | (YUV422SEL_1P << IMGFMT_422SHIFT) \ + | YUVSEL_YVYU) +#define SMFC_IMGFMT_UYVY (IMGSEL_422 | (YUV422SEL_1P << IMGFMT_422SHIFT) \ + | YUVSEL_UYVY) +#define SMFC_IMGFMT_VYUY (IMGSEL_422 | (YUV422SEL_1P << IMGFMT_422SHIFT) \ + | YUVSEL_VYUY) +#define SMFC_IMGFMT_NV16 (IMGSEL_422 | (YUV422SEL_2P << IMGFMT_422SHIFT)) +#define SMFC_IMGFMT_NV61 (IMGSEL_422 | (YUV422SEL_2P << IMGFMT_422SHIFT) \ + | IMGFMT_UVSWAP) +#define SMFC_IMGFMT_YUV422 (IMGSEL_422 | (YUV422SEL_3P << IMGFMT_422SHIFT)) +#define SMFC_IMGFMT_YUV444 (IMGSEL_444 | (YUVSEL_3P << IMGFMT_444SHIFT)) + +#define SMFC_IMGFMT_JPEG444 (1 << 24) +#define SMFC_IMGFMT_JPEG422 (2 << 24) +#define SMFC_IMGFMT_JPEG420 (3 << 24) +#define SMFC_IMGFMT_JPEG422V (4 << 24) +#define SMFC_IMGFMT_JPEG411 (5 << 24) + #endif /* _MEDIA_EXYNOS_SMFC_REGS_H_ */ diff --git a/drivers/media/platform/exynos/smfc/smfc.c b/drivers/media/platform/exynos/smfc/smfc.c index 49fd0c184170..89a9c2f68eaf 100644 --- a/drivers/media/platform/exynos/smfc/smfc.c +++ b/drivers/media/platform/exynos/smfc/smfc.c @@ -29,6 +29,210 @@ #include "smfc.h" #include "smfc-regs.h" +const struct smfc_image_format smfc_image_formats[] = { + { + /* JPEG should be the first format */ + .description = "Baseline JPEG(Sequential DCT)", + .v4l2_pixfmt = V4L2_PIX_FMT_JPEG, + .regcfg = 0, /* Chagneable accroding to chroma factor */ + .bpp_buf = {0}, /* undeterministic */ + .bpp_pix = {0}, /* undeterministic */ + .num_planes = 1, + .num_buffers = 1, + .chroma_hfactor = 1, /* dummy chroma subsampling factor */ + .chroma_vfactor = 1, /* These will not affect to H/W config. */ + }, { + /* YUYV is the default format */ + .description = "YUV4:2:2 1-Plane 16BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_YUYV, + .regcfg = SMFC_IMGFMT_YUYV, + .bpp_buf = {16}, + .bpp_pix = {16}, + .num_planes = 1, + .num_buffers = 1, + .chroma_hfactor = 2, + .chroma_vfactor = 1, + }, { + .description = "YUV4:2:2 1-Plane 16BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_YVYU, + .regcfg = SMFC_IMGFMT_YVYU, + .bpp_buf = {16}, + .bpp_pix = {16}, + .num_planes = 1, + .num_buffers = 1, + .chroma_hfactor = 2, + .chroma_vfactor = 1, + }, { + .description = "YUV4:2:2 2-Plane 16BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_NV16, + .regcfg = SMFC_IMGFMT_NV16, + .bpp_buf = {16}, + .bpp_pix = {8, 8, 0}, + .num_planes = 2, + .num_buffers = 1, + .chroma_hfactor = 2, + .chroma_vfactor = 1, + }, { + .description = "YUV4:2:2 2-Plane 16BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_NV61, + .regcfg = SMFC_IMGFMT_NV61, + .bpp_buf = {16}, + .bpp_pix = {8, 8, 0}, + .num_planes = 2, + .num_buffers = 1, + .chroma_hfactor = 2, + .chroma_vfactor = 1, + }, { + .description = "YUV4:2:2 3-Plane 16BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_YUV422P, + .regcfg = SMFC_IMGFMT_YUV422, + .bpp_buf = {16}, + .bpp_pix = {8, 2, 2}, + .num_planes = 3, + .num_buffers = 1, + .chroma_hfactor = 2, + .chroma_vfactor = 1, + }, { + .description = "YUV4:2:0 2-Plane(Cb/Cr) 12BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_NV12, + .regcfg = SMFC_IMGFMT_NV12, + .bpp_buf = {12}, + .bpp_pix = {8, 4, 0}, + .num_planes = 2, + .num_buffers = 1, + .chroma_hfactor = 2, + .chroma_vfactor = 2, + }, { + .description = "YUV4:2:0 2-Plane(Cr/Cb) 12BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_NV21, + .regcfg = SMFC_IMGFMT_NV21, + .bpp_buf = {12}, + .bpp_pix = {8, 4, 0}, + .num_planes = 2, + .num_buffers = 1, + .chroma_hfactor = 2, + .chroma_vfactor = 2, + }, { + .description = "YUV4:2:0 3-Plane 12BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_YUV420, + .regcfg = SMFC_IMGFMT_YUV420P, + .bpp_buf = {12}, + .bpp_pix = {8, 2, 2}, + .num_planes = 3, + .num_buffers = 1, + .chroma_hfactor = 2, + .chroma_vfactor = 2, + }, { + .description = "YVU4:2:0 3-Plane 12BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_YVU420, + .regcfg = SMFC_IMGFMT_YVU420P, + .bpp_buf = {12}, + .bpp_pix = {8, 2, 2}, + .num_planes = 3, + .num_buffers = 1, + .chroma_hfactor = 2, + .chroma_vfactor = 2, + }, { + .description = "YUV4:4:4 3-Plane 16BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_YUV444, + .regcfg = SMFC_IMGFMT_YUV444, + .bpp_buf = {24}, + .bpp_pix = {8, 8, 8}, + .num_planes = 3, + .num_buffers = 1, + .chroma_hfactor = 1, + .chroma_vfactor = 1, + }, { + .description = "RGB565 LE 16BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_RGB565, + .regcfg = SMFC_IMGFMT_RGB565, + .bpp_buf = {16}, + .bpp_pix = {16}, + .num_planes = 1, + .num_buffers = 1, + }, { + .description = "RGB565 BE 16BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_RGB565X, + .regcfg = SMFC_IMGFMT_BGR565, + .bpp_buf = {16}, + .bpp_pix = {16}, + .num_planes = 1, + .num_buffers = 1, + }, { + .description = "RGB888 LE 24BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_RGB24, + .regcfg = SMFC_IMGFMT_RGB24, + .bpp_buf = {24}, + .bpp_pix = {24}, + .num_planes = 1, + .num_buffers = 1, + }, { + .description = "RGB888 BE 24BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_BGR24, + .regcfg = SMFC_IMGFMT_BGR24, + .bpp_buf = {24}, + .bpp_pix = {24}, + .num_planes = 1, + .num_buffers = 1, + }, { + .description = "ABGR8888 LE 32BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_RGB32, + .regcfg = SMFC_IMGFMT_RGBA32, + .bpp_pix = {32}, + .num_planes = 1, + .num_buffers = 1, + }, { + .description = "ARGB8888 BE 32BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_BGR32, + .regcfg = SMFC_IMGFMT_BGRA32, + .bpp_pix = {32}, + .num_planes = 1, + .num_buffers = 1, + }, + /* multi-planar formats must be at the last becuse of VIDOC_ENUM_FMT */ + { + .description = "YUV4:2:0 2-MPlane(Cb/Cr) 8+4BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_NV12M, + .regcfg = SMFC_IMGFMT_NV12, + .bpp_buf = {8, 4}, + .bpp_pix = {8, 4}, + .num_planes = 2, + .num_buffers = 2, + .chroma_hfactor = 2, + .chroma_vfactor = 2, + }, { + .description = "YUV4:2:0 2-MPlane(Cr/Cb) 8+4BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_NV21M, + .regcfg = SMFC_IMGFMT_NV21, + .bpp_buf = {8, 4}, + .bpp_pix = {8, 4}, + .num_planes = 2, + .num_buffers = 2, + .chroma_hfactor = 2, + .chroma_vfactor = 2, + }, { + .description = "YUV4:2:0 3-MPlane 8+2+2BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_YUV420M, + .regcfg = SMFC_IMGFMT_YUV420P, + .bpp_buf = {8, 2, 2}, + .bpp_pix = {8, 2, 2}, + .num_planes = 3, + .num_buffers = 3, + .chroma_hfactor = 2, + .chroma_vfactor = 2, + }, { + .description = "YVU4:2:0 3-MPlane 8+2+2BPP", + .v4l2_pixfmt = V4L2_PIX_FMT_YVU420M, + .regcfg = SMFC_IMGFMT_YVU420P, + .bpp_buf = {8, 2, 2}, + .bpp_pix = {8, 2, 2}, + .num_planes = 3, + .num_buffers = 3, + .chroma_hfactor = 2, + .chroma_vfactor = 2, + } +}; + static irqreturn_t exynos_smfc_irq_handler(int irq, void *priv) { return IRQ_HANDLED; @@ -209,7 +413,39 @@ static const struct v4l2_file_operations smfc_v4l2_fops = { .mmap = exynos_smfc_mmap, }; +static int smfc_v4l2_enum_fmt_mplane(struct file *filp, void *fh, + struct v4l2_fmtdesc *f) +{ + const struct smfc_image_format *fmt; + + if (f->index >= ARRAY_SIZE(smfc_image_formats)) + return -EINVAL; + + fmt = &smfc_image_formats[f->index]; + strncpy(f->description, fmt->description, sizeof(f->description)); + f->description[sizeof(f->description) - 1] = '\0'; + f->pixelformat = fmt->v4l2_pixfmt; + if (fmt->bpp_buf[0] == 0) + f->flags = V4L2_FMT_FLAG_COMPRESSED; + + return 0; +} + +static int smfc_v4l2_enum_fmt(struct file *filp, void *fh, + struct v4l2_fmtdesc *f) +{ + int ret = smfc_v4l2_enum_fmt_mplane(filp, fh, f); + if (ret < 0) + return ret; + + return smfc_image_formats[f->index].num_buffers > 1 ? -EINVAL : 0; +} + static const struct v4l2_ioctl_ops smfc_v4l2_ioctl_ops = { + .vidioc_enum_fmt_vid_cap = smfc_v4l2_enum_fmt, + .vidioc_enum_fmt_vid_out = smfc_v4l2_enum_fmt, + .vidioc_enum_fmt_vid_cap_mplane = smfc_v4l2_enum_fmt_mplane, + .vidioc_enum_fmt_vid_out_mplane = smfc_v4l2_enum_fmt_mplane, }; static void smfc_m2m_device_run(void *priv) diff --git a/drivers/media/platform/exynos/smfc/smfc.h b/drivers/media/platform/exynos/smfc/smfc.h index a7ea8fb7dfbc..cdc0df0a00e4 100644 --- a/drivers/media/platform/exynos/smfc/smfc.h +++ b/drivers/media/platform/exynos/smfc/smfc.h @@ -17,6 +17,18 @@ struct device; struct video_device; +struct smfc_image_format { + const char *description; + __u32 v4l2_pixfmt; + u32 regcfg; + unsigned char bpp_buf[3]; + unsigned char bpp_pix[3]; + unsigned char num_planes; + unsigned char num_buffers; + unsigned char chroma_hfactor; + unsigned char chroma_vfactor; +}; + struct smfc_dev { struct v4l2_device v4l2_dev; struct video_device *videodev;