// CAMIF
static unsigned long *CISRCFMT;
static unsigned long *CIWDOFST;
static unsigned long *CIGCTRL;
static unsigned long *CIPRCLRSA1;
static unsigned long *CIPRCLRSA2;
static unsigned long *CIPRCLRSA3;
static unsigned long *CIPRCLRSA4;
static unsigned long *CIPRTRGFMT;
static unsigned long *CIPRCTRL;
static unsigned long *CIPRSCPRERATIO;
static unsigned long *CIPRSCPREDST;
static unsigned long *CIPRSCCTRL;
static unsigned long *CIPRTAREA;
static unsigned long *CIIMGCPT;
// IRQ
static unsigned long *SRCPND;
static unsigned long *INTPND;
static unsigned long *SUBSRCPND;
static unsigned int SRC_Width, SRC_Height;
static unsigned int TargetHsize_Pr, TargetVsize_Pr;
static unsigned long buf_size;
static unsigned int bytesperline;
static DECLARE_WAIT_QUEUE_HEAD(cam_wait_queue);
/* 中断标志 */
static volatile int ev_cam = 0;
static irqreturn_t cmos_ov7740_camif_irq_c(int irq, void *dev_id)
{
return IRQ_HANDLED;
}
static irqreturn_t cmos_ov7740_camif_irq_p(int irq, void *dev_id)
{
/* 清中断 */
*SRCPND = 1<<6;
*INTPND = 1<<6;
*SUBSRCPND = 1<<12;
ev_cam = 1;
wake_up_interruptible(&cam_wait_queue);
return IRQ_HANDLED;
}
/* A2 参考 uvc_v4l2_do_ioctl */
static int cmos_ov7740_vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
memset(cap, 0, sizeof *cap);
strcpy(cap->driver, "cmos_ov7740");
strcpy(cap->card, "cmos_ov7740");
cap->version = 2;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
return 0;
}
/* A3 列举支持哪种格式
* 参考: uvc_fmts 数组
*/
static int cmos_ov7740_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
struct cmos_ov7740_fmt *fmt;
if (f->index >= ARRAY_SIZE(formats))
return -EINVAL;
fmt = &formats[f->index];
strlcpy(f->description, fmt->name, sizeof(f->description));
f->pixelformat = fmt->fourcc;
return 0;
}
/* A4 返回当前所使用的格式 */
static int cmos_ov7740_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
return 0;
}
/* A5 测试驱动程序是否支持某种格式, 强制设置该格式
* 参考: uvc_v4l2_try_format
* myvivi_vidioc_try_fmt_vid_cap
*/
static int cmos_ov7740_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
{
return -EINVAL;
}
if ((f->fmt.pix.pixelformat != V4L2_PIX_FMT_RGB565) && (f->fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24))
return -EINVAL;
return 0;
}
/* A6 参考 myvivi_vidioc_s_fmt_vid_cap */
static int cmos_ov7740_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
int ret = cmos_ov7740_vidioc_try_fmt_vid_cap(file, NULL, f);
if (ret < 0)
return ret;
TargetHsize_Pr = f->fmt.pix.width;
TargetVsize_Pr = f->fmt.pix.height;
if(f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565)
{
*CIPRSCCTRL &= ~(1<<30);
f->fmt.pix.bytesperline = (f->fmt.pix.width * 16) >> 3;
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
buf_size = f->fmt.pix.sizeimage;
bytesperline = f->fmt.pix.bytesperline;
}
else if(f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
{
*CIPRSCCTRL |= (1<<30);
f->fmt.pix.bytesperline = (f->fmt.pix.width * 32) >> 3;
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
buf_size = f->fmt.pix.sizeimage;
bytesperline = f->fmt.pix.bytesperline;
}