zoukankan      html  css  js  c++  java
  • Embeded linux之摄像头驱动

     一、摄像头平台层                                                                                                  

    driversmediavideomxccapturemxc_v4l2_capture.c 

    module_init(camera_init);

    随后,进行加载下一个驱动,如果遇到摄像头设备层对应驱动,举例adv7180解码芯片

    driversmediavideomxccaptureadv7180.c 

    module_init(adv7180_init);

    static __init int adv7180_init(void)
    {
       u8 err = i2c_add_driver(&adv7180_i2c_driver);

       return err;
    }

    static struct i2c_driver adv7180_i2c_driver = {
       .driver = {
           .owner = THIS_MODULE,
           .name = "adv7180",
          },
       .probe = adv7180_probe,
       .remove = adv7180_detach,
       .id_table = adv7180_id,
    };

    static __init int camera_init(void)
    {

      u8 err = platform_driver_register(&mxc_v4l2_driver);//将mxc_v4l2_driver这个驱动注册到platform平台上面,如果有匹配的设备的话,就会调用到mxc_v4l2_driver里面的probe函数
      return err;
    }

    static struct platform_driver mxc_v4l2_driver = {
       .driver = {
           .name = "mxc_v4l2_capture",
         },
       .probe = mxc_v4l2_probe,
       .remove = mxc_v4l2_remove,
       .suspend = mxc_v4l2_suspend,
       .resume = mxc_v4l2_resume,
       .shutdown = NULL,
    };

    /*

     *struct platform_device {
     *  const char * name;
     *  int  id;
     *  struct device dev;
     *  u32  num_resources;
     *  struct resource * resource;
     *  const struct platform_device_id *id_entry;
     *  struct mfd_cell *mfd_cell;
     *  struct pdev_archdata archdata;
     *};

     */

     static int mxc_v4l2_probe(struct platform_device *pdev)

    {

      ...

      cam_data *cam = kmalloc(sizeof(cam_data), GFP_KERNEL);

      init_camera_struct(cam, pdev);//初始化cam_data结构体

      v4l2_int_device_register(cam->self);

      ...

    }

    /*私有数据的结构体关系

     *struct cam_data           driversmediavideomxccapturemxc_v4l2_capture.h
     *->struct video_device       includemediav4l2-dev.h 
     *   ->struct device      includelinuxdevice.h
     *     ->struct device_private   driversasease.h
     *       ->void *driver_data;

     */

    static void init_camera_struct(cam_data *cam, struct platform_device *pdev)

    {

      ...

      cam->video_dev = video_device_alloc();//分配一个video_device结构体

      *(cam->video_dev) = mxc_v4l_template;//设置ops操作->v4l2_file_operations->mxc_v4l_ioctl->mxc_v4l_do_ioctl->VIDIOC_*_IOCTL:{...}

      video_set_drvdata(cam->video_dev, cam);//将cam设置为cam->video_dev的私有数据->dev_set_drvdata -> dev->p->driver_data = data;

      cam->crop_bounds.left = 0;           //这里只是初始化crop参数默认值

      cam->crop_bounds.width = 640;

      cam->crop_bounds.top = 0;

      cam->crop_bounds.height = 480;

      cam->crop_current = cam->crop_defrect = cam->crop_bounds;

      cam->enc_callback = camera_callback;

      cam->self = kmalloc(sizeof(struct v4l2_int_device), GFP_KERNEL);

      cam->self->module = THIS_MODULE;
      cam->self->type = v4l2_int_type_master;
      cam->self->u.master = &mxc_v4l2_master;//后面会调用

      ...

    }

    int v4l2_int_device_register(struct v4l2_int_device *d)
    {
       ...
      v4l2_int_device_try_attach_all();

      ...
    }

    void v4l2_int_device_try_attach_all(void)

    {  

      struct v4l2_int_device *m, *s;  

      list_for_each_entry(m, &int_list, head)
      {

        if (m->type != v4l2_int_type_master) continue;//从int_list链表中取出type类型为v4l2_int_type_master的结构体保存在m中

        list_for_each_entry(s, &int_list, head)
        {

          if (s->type != v4l2_int_type_slave)continue;//从int_list链表中取出type类型为v4l2_int_type_slave的结构体保存在s中

          if (s->u.slave->master)continue;//如果存在s->u.slave->master则跳过继续寻找

          s->u.slave->master = m;//找到master设备和第一个没有设置master的slave设备,并将从设备的master设置为找到的master

          if (m->u.master->attach(s))//调用m的u.master->atach(s)函数,即cam->self->u.master = &mxc_v4l2_master;设置的函数

          {

            ...

          }

        }

      }

    }

    static struct v4l2_int_master mxc_v4l2_master = {
      .attach = mxc_v4l2_master_attach,
      .detach = mxc_v4l2_master_detach,
    };

    static int mxc_v4l2_master_attach(struct v4l2_int_device *slave)

    {

      ...

       cam->crop_bounds.top = cam->crop_bounds.left = 0;//crop参数都是根据slave结构体来设置的,这里是根据真正slave设备中获取到的参数来填充crop参数
       cam->crop_bounds.width = cam_fmt.fmt.pix.width;
       cam->crop_bounds.height = cam_fmt.fmt.pix.height;

       cam->crop_defrect.top = cam->crop_defrect.left = 0;
       cam->crop_defrect.width = cam_fmt.fmt.pix.width;
       cam->crop_defrect.height = cam_fmt.fmt.pix.height;

       cam->crop_current.top = cam->crop_current.left = 0;
       cam->crop_current.width = cam_fmt.fmt.pix.width;
       cam->crop_current.height = cam_fmt.fmt.pix.height;

      ...

    }

    二、摄像头设备层                                                                                                 

  • 相关阅读:
    Android 常见工具类封装
    Android Logcat 封装类
    Android 四大组件之 " Activity "
    "浅谈Android"第一篇:Android系统简介
    罗列的书单
    关于多层架构一些思考
    LeetCode 330. Patching Array
    LeetCode 315. Count of Smaller Numbers After Self(线段树,树状数组)
    LeetCode 316. Remove Duplicate Letters(贪心)
    LeetCode 327. Count of Range Sum(线段树)
  • 原文地址:https://www.cnblogs.com/pokerface/p/6526353.html
Copyright © 2011-2022 走看看