摄像头(Ov965x)驱动分析

来源:互联网 发布:好看的戒指知乎 编辑:程序博客网 时间:2024/05/17 19:22
摄像头(Ov965x)驱动分析

本人喜欢用代码+伪代码的方式写笔记。文中的花括号可能是方便记录而已。

如:

hw_get_module(LED_HARDWARE_MODULE_ID, (const hw_module_t**)&module)
{
    问:怎么获得模块信息的?
    答:hardware\libhardware\Hardware.c

    ...........

}

原创分析, 转载请注明出处:http://www.cnblogs.com/langlang/

作者email: dayhappyhappy@163.com

 

module_init(s3c_fimc_register)    platform_driver_register(&s3c_fimc_driver)  //.name    = "s3c-fimc",    {        //1  控制器        s3c_fimc_register_controller(pdev)        {            struct s3c_fimc_control *ctrl;            ctrl->vd = &s3c_fimc_video_device[id];    //s3c_fimc_video_device中包含了操作函数               s3c_fimc_video_device[id]                {                    .fops = &s3c_fimc_fops,//fops对应的是针对v4l2设备的基本操作                        {                            .read = s3c_fimc_read                            {                                struct s3c_fimc_control *ctrl = filp->private_data;                                end = min_t(size_t, ctrl->out_frame.buf_size, count);                                copy_to_user(buf, s3c_fimc_get_current_frame(ctrl), end)                                 {                                               struct s3c_fimc_out_frame *frame = &ctrl->out_frame;                                    return frame->addr[frame->cfn].virt_y;                                }                            }                            .open = s3c_fimc_open                            {                                struct s3c_fimc_control *ctrl;                                ctrl = &s3c_fimc.ctrl[id];                                s3c_fimc_reset(ctrl); //底层寄存器操作                                filp->private_data = ctrl;                            }                        }                    .ioctl_ops = &s3c_fimc_v4l2_ops,//是对v4l2的所有ioctl操作集合的描述               }        }        /*2  时钟设置 fimc source clock */        //3  DMA初始化        s3c_fimc_init_global(pdev)        {            //DMA设置            s3c_fimc.dma_start = s3c_get_media_memory(S3C_MDEV_FIMC);            s3c_fimc.dma_total = s3c_get_media_memsize(S3C_MDEV_FIMC);            s3c_fimc.dma_current = s3c_fimc.dma_start;            /* test pattern */            s3c_fimc.camera[test_pattern.id] = &test_pattern;             {                问:  这个参数在什么时候用到?                s3c_fimc_register_camera(struct s3c_fimc_camera *cam)  ① s3c_fimc_register_camera给谁调用                {                    for (i = 0; i < S3C_FIMC_MAX_CTRLS; i++)                          s3c_fimc.ctrl[i].in_cam = s3c_fimc.camera[cam->id];                }                s3c_fimc_set_active_camera(struct s3c_fimc_control *ctrl, int id)                {                    ctrl->in_cam = s3c_fimc.camera[id];                    s3c_fimc_select_camera(ctrl);                }            }        }        //4  创建文件节点  /dev下看到三个video设备节点,video0,video1,video2        video_register_device(ctrl->vd, VFL_TYPE_GRABBER, ctrl->id)        {            INIT_LIST_HEAD(&vdev->fh_list);            /* Part 1: check device type */            /* Part 2: find a free minor, device node number and device index. */                /* Part 3: Initialize the character device 创建字符设备*/              vdev->cdev = cdev_alloc();            vdev->cdev->ops = &v4l2_fops;            cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);                        /* Part 4: register the device with sysfs */            vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);            vdev->dev.class = &video_class;//创建类            device_register(&vdev->dev);            video_device[vdev->minor] = vdev;        }    }    ① 文件 drivers\media\video\samsung\fimc\Ov965x.c  也就是我们要写的文件ov965x_probe(struct i2c_client *c, const struct i2c_device_id *id){    s3c_fimc_register_camera(&ov965x_data)    {        参数:这里面的信息描述了OV9650相关的所有信息。        static struct s3c_fimc_camera ov965x_data = {            .id         = CONFIG_VIDEO_FIMC_CAM_CH,            .type        = CAM_TYPE_ITU,             //type代表摄像头是ITU的接口            .mode        = ITU_601_YCBCR422_8BIT,    //mode代表摄像头输出的格式是ITU_601_YCBCR422_8BIT            .order422    = CAM_ORDER422_8BIT_YCBYCR, //order422代表YUV三个分量的顺序是YCRYCB,            .clockrate    = 24000000,                    //时钟源的信息            .width        = 640,//800,            .height        = 480,//600,            .offset        = {                .h1 = 0,                .h2 = 0,                .v1 = 0,                .v2 = 0,            },                    .polarity    = { //Polarity代表信号的极性,具体的设置要和摄像头本身的设置一致                .pclk    = 0,                .vsync    = 1,                .href    = 0,                .hsync    = 0,            },                    .initialized    = 0,        }    }} Ov965x.c分析 __init int ov965x_init(void) {    //添加驱动    i2c_add_driver(&ov965x_i2c_driver)      {        ov965x_i2c_driver =  {.probe        = ov965x_probe}        ov965x_probe(struct i2c_client *c, const struct i2c_device_id *id){            s3c_fimc_register_camera(&ov965x_data);            for (i = 0; i < OV965X_INIT_REGS; i++) //用IIC发送数据                ret = i2c_smbus_write_byte_data(c, OV965X_init_reg[i].subaddr, OV965X_init_reg[i].value);        }    } }


 

原创粉丝点击