/* linux/drivers/media/video/samsung/s3c_fimc_v4l2.c
*
* V4L2 interface support file for Samsung Camera Interface (FIMC) driver
*
*
*
* 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 <linux/fs.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/videodev2.h>
#include <media/v4l2-ioctl.h>
#include "s3c_fimc.h"
static struct v4l2_input s3c_fimc_input_types[] = {
{
.index = 0,
.name = "External Camera Input",
.type = V4L2_INPUT_TYPE_CAMERA,
.audioset = 1,
.tuner = 0,
.std = V4L2_STD_PAL_BG | V4L2_STD_NTSC_M,
.status = 0,
},
{
.index = 1,
.name = "Memory Input",
.type = V4L2_INPUT_TYPE_MEMORY,
.audioset = 2,
.tuner = 0,
.std = V4L2_STD_PAL_BG | V4L2_STD_NTSC_M,
.status = 0,
}
};
static struct v4l2_output s3c_fimc_output_types[] = {
{
.index = 0,
.name = "Memory Output",
.type = V4L2_OUTPUT_TYPE_MEMORY,
.audioset = 0,
.modulator = 0,
.std = 0,
},
{
.index = 1,
.name = "LCD FIFO Output",
.type = V4L2_OUTPUT_TYPE_LCDFIFO,
.audioset = 0,
.modulator = 0,
.std = 0,
}
};
const static struct v4l2_fmtdesc s3c_fimc_capture_formats[] = {
{
.index = 0,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.flags = FORMAT_FLAGS_PLANAR,
.description = "4:2:0, planar, Y-Cb-Cr",
.pixelformat = V4L2_PIX_FMT_YUV420,
},
{
.index = 1,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.flags = FORMAT_FLAGS_PLANAR,
.description = "4:2:2, planar, Y-Cb-Cr",
.pixelformat = V4L2_PIX_FMT_YUV422P,
},
{
.index = 2,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.flags = FORMAT_FLAGS_PACKED,
.description = "4:2:2, packed, YCBYCR",
.pixelformat = V4L2_PIX_FMT_YUYV,
},
{
.index = 3,
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
.flags = FORMAT_FLAGS_PACKED,
.description = "4:2:2, packed, CBYCRY",
.pixelformat = V4L2_PIX_FMT_UYVY,
}
};
const static struct v4l2_fmtdesc s3c_fimc_overlay_formats[] = {
{
.index = 0,
.type = V4L2_BUF_TYPE_VIDEO_OVERLAY,
.flags = FORMAT_FLAGS_PACKED,
.description = "16 bpp RGB, le",
.pixelformat = V4L2_PIX_FMT_RGB565,
},
{
.index = 1,
.type = V4L2_BUF_TYPE_VIDEO_OVERLAY,
.flags = FORMAT_FLAGS_PACKED,
.description = "24 bpp RGB, le",
.pixelformat = V4L2_PIX_FMT_RGB24,
},
};
#define S3C_FIMC_MAX_INPUT_TYPES ARRAY_SIZE(s3c_fimc_input_types)
#define S3C_FIMC_MAX_OUTPUT_TYPES ARRAY_SIZE(s3c_fimc_output_types)
#define S3C_FIMC_MAX_CAPTURE_FORMATS ARRAY_SIZE(s3c_fimc_capture_formats)
#define S3C_FIMC_MAX_OVERLAY_FORMATS ARRAY_SIZE(s3c_fimc_overlay_formats)
static int s3c_fimc_v4l2_querycap(struct file *filp, void *fh,
struct v4l2_capability *cap)
{
struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
strcpy(cap->driver, "Samsung FIMC Driver");
strlcpy(cap->card, ctrl->vd->name, sizeof(cap->card));
sprintf(cap->bus_info, "FIMC AHB-bus");
cap->version = 0;
cap->capabilities = (V4L2_CAP_VIDEO_OVERLAY | \
V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING);
return 0;
}
static int s3c_fimc_v4l2_g_fbuf(struct file *filp, void *fh,
struct v4l2_framebuffer *fb)
{
struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
*fb = ctrl->v4l2.frmbuf;
fb->base = ctrl->v4l2.frmbuf.base;
fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
fb->fmt.pixelformat = ctrl->v4l2.frmbuf.fmt.pixelformat;
fb->fmt.width = ctrl->v4l2.frmbuf.fmt.width;
fb->fmt.height = ctrl->v4l2.frmbuf.fmt.height;
fb->fmt.bytesperline = ctrl->v4l2.frmbuf.fmt.bytesperline;
return 0;
}
static int s3c_fimc_v4l2_s_fbuf(struct file *filp, void *fh,
struct v4l2_framebuffer *fb)
{
struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
struct v4l2_framebuffer *frmbuf = &(ctrl->v4l2.frmbuf);
int i, bpp;
for (i = 0; i < S3C_FIMC_MAX_OVERLAY_FORMATS; i++) {
if (s3c_fimc_overlay_formats[i].pixelformat == fb->fmt.pixelformat)
break;
}
if (i == S3C_FIMC_MAX_OVERLAY_FORMATS)
return -EINVAL;
bpp = s3c_fimc_set_output_frame(ctrl, &fb->fmt);
frmbuf->base = fb->base;
frmbuf->flags = fb->flags;
frmbuf->capability = fb->capability;
frmbuf->fmt.width = fb->fmt.width;
frmbuf->fmt.height = fb->fmt.height;
frmbuf->fmt.field = fb->fmt.field;
frmbuf->fmt.pixelformat = fb->fmt.pixelformat;
frmbuf->fmt.bytesperline = fb->fmt.width * bpp / 8;
frmbuf->fmt.sizeimage = fb->fmt.width * frmbuf->fmt.bytesperline;
return 0;
}
static int s3c_fimc_v4l2_enum_fmt_vid_cap(struct file *filp, void *fh,
struct v4l2_fmtdesc *f)
{
struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
int index = f->index;
if (index >= S3C_FIMC_MAX_CAPTURE_FORMATS)
return -EINVAL;
memset(f, 0, sizeof(*f));
memcpy(f, ctrl->v4l2.fmtdesc + index, sizeof(*f));
return 0;
}
static int s3c_fimc_v4l2_g_fmt_vid_cap(struct file *filp, void *fh,
struct v4l2_format *f)
{
struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
int size = sizeof(struct v4l2_pix_format);
memset(&f->fmt.pix, 0, size);
memcpy(&f->fmt.pix, &(ctrl->v4l2.frmbuf.fmt), size);
return 0;
}
static int s3c_fimc_v4l2_s_fmt_vid_cap(struct file *filp, void *fh,
struct v4l2_format *f)
{
struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
ctrl->v4l2.frmbuf.fmt = f->fmt.pix;
if (f->fmt.pix.priv == V4L2_FMT_IN)
s3c_fimc_set_input_frame(ctrl, &f->fmt.pix);
else
s3c_fimc_set_output_frame(ctrl, &f->fmt.pix);
return 0;
}
static int s3c_fimc_v4l2_try_fmt_vid_cap(struct file *filp, void *fh,
struct v4l2_format *f)
{
return 0;
}
static int s3c_fimc_v4l2_try_fmt_overlay(struct file *filp, void *fh,
struct v4l2_format *f)
{
return 0;
}
static int s3c_fimc_v4l2_overlay(struct file *filp, void *fh, unsigned int i)
{
struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
if (i) {
if (ctrl->in_type != PATH_IN_DMA)
s3c_fimc_init_camera(ctrl);
FSET_PREVIEW(ctrl);
s3c_fimc_start_dma(ctrl);
} else {
s3c_fimc_stop_dma(ctrl);
if (ctrl->out_type != PATH_OUT_LCDFIFO) {
s3c_fimc_free_output_memory(&ctrl->out_frame);
s3c_fimc_set_output_address(ctrl);
}
}
return 0;
}
static int s3c_fimc_v4l2_g_ctrl(struct file *filp, void *fh,
struct v4l2_control *c)
{
struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
struct s3c_fimc_out_frame *frame = &ctrl->out_frame;
switch (c->id) {
case V4L2_CID_OUTPUT_ADDR:
c->value = frame->addr[c->value].phys_y;
break;
default:
err("invalid control id: %d\n", c->id);
return -EINVAL;
}
return 0;
}
static int s3c_fimc_v4l2_s_ctrl(struct file *filp, void *fh,
struct v4l2_control *c)
{
struct s3c_fimc_control *ctrl = (struct s3c_fimc_control *) fh;
struct s3c_fimc_out_frame *frame = &ctrl->out_frame;
struct s3c_fimc_window_offset *offset = &ctrl->in_cam->offset;
switch (c->id) {
case V4L2_CID_EFFECT_ORIGINAL:
frame->effect.type = EFFECT_ORIGINAL;
s3c_fimc_change_effect(ctrl);
break;
case V4L2_CID_EFFECT_NEGATIVE:
frame->effect.type = EFFECT_NEGATIVE;
s3c_fimc_change_effect(ctrl);
break;
case V4L2_CID_EFFECT_EMBOSSING:
frame->effect.type = EFFECT_EMBOSSING;
s3c_fimc_change_effect(ctrl);
break;
case V4L2_CID_EFFECT_ARTFREEZE:
frame->effect.type = EFFECT_ARTFREEZE;
s3c_fimc_change_effect(ctrl);
break;
case V4L2_CID_EFFECT_SILHOUETTE:
frame->effect.type = EFFECT_SILHOUETTE;
s3c_fimc_change_effect(ctrl);
break;
case V4L2_CID_EFFECT_ARBITRARY:
frame->effect.type = EFFECT_ARBITRARY;
frame->effect.pat_cb = PAT_CB(c->value);
frame->effect.pat_cr = PAT_CR(c->value);
s3c_fimc_change_effect(ctrl);
break;
case V4L2_CID_ROTATE_ORIGINAL:
frame->flip = FLIP_ORIGINAL;
ctrl->rot90 = 0;
s3c_fimc_change_rotate(ctrl);
break;
case V4L2_CID_HFLIP:
frame->flip = FLIP_X_AXIS;
ctrl->rot90 = 0;
s3c_fimc_change_rotate(ctrl);
break;
case V4L2
s3c_fimd_v4l2.rar_SAMSUNG camera_interface_v4l2 fimc
版权申诉
51 浏览量
2022-09-19
20:10:42
上传
评论
收藏 4KB RAR 举报
刘良运
- 粉丝: 66
- 资源: 1万+
最新资源
- 《CKA/CKAD应试指南/从docker到kubernetes 完全攻略》学习笔记 第1章docker基础(1.1-1.4)
- 基于python实现的水下压缩空气储能互补系统建模仿真与经济效益分析+源代码+论文
- 华中科技大学-自然语言处理实验,Bi-LSTM+CRF的中文分词框架,并且利用基于深度学习的方法进行中文命名实体识别++源码报告
- 基于动态罚函数的铁路车流分配与径路优化模型python源码
- 鱼群算法求解组环问题python源码+文档说明
- 基于决策优化的多波束测深测线规划模型MATLAB代码
- 课程设计-基于python实现的多目标优化算法求解带时间窗的车辆路径规划问题+源代码+文档说明+界面截图+pptx
- 基于通信信号与通信系统的MATLAB仿真源码-课程设计
- 嵌入式-信号机制(概念,发送,定时,捕捉,SIGCHLD 信号实现回收子进程)
- c语言管理系统大一大二笔记
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈