Linux I2C总线设备驱动模型分析(ov7740)(3)

// 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;
    }
   

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/124de2ba14b952f5a166e369a62106bb.html