8M sensor mt9e013 驱动

1.  最上层的数据结构 v4l2_i2c_data,V4L2设备mt9e013的i2c数据表示:
   1. static struct v4l2_i2c_driver_data v4l2_i2c_data = {
   2.     .name = MT9E013_NAME,
   3.     .probe = mt9e013_probe,
   4.     .remove = mt9e013_remove,
   5.     .id_table = mt9e013_id,
   6. };
v4l2_i2c_driver_data 原型定义:
   1. struct v4l2_i2c_driver_data {
   2.     const char * const name;
   3.     int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);
   4.     int (*probe)(struct i2c_client *client, const struct i2c_device_id *id);
   5.     int (*remove)(struct i2c_client *client);
   6.     int (*suspend)(struct i2c_client *client, pm_message_t state);
   7.     int (*resume)(struct i2c_client *client);
   8.     const struct i2c_device_id *id_table;
   9. };
2. mt9e013_probe()
   1. static int mt9e013_probe(struct i2c_client *client,
   2.              const struct i2c_device_id *id)
   3. {
   4.     struct mt9e013_device *dev;                 //mt9e013_device 是最上层的模型,里面包含了很多数据结构,后面介绍
   5.     int ret;
   6.     _dev_info(&client->dev, "mt9e013 probe\n");
   7.

   8.     /* allocate sensor device & init sub device */
   9.     dev = kzalloc(sizeof(*dev), GFP_KERNEL);    //分配dev内存,并置0
  10.     if (!dev) {
  11.         v4l2_err(client, "%s: out of memory\n", __func__);
  12.         return -ENOMEM;
  13.     }
  14.

  15.     dev->fmt_idx = 0;
  16.     v4l2_i2c_subdev_init(&(dev->sd), client, &mt9e013_ops);  //i2c v4l2子设备初始化 添加mt9e013_ops。
  17.

  18.     dev->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;    //this subdev needs a device node.
  19.     dev->pad.flags = MEDIA_PAD_FLAG_OUTPUT;
  20.     dev->sd.entity.ops = &mt9e013_entity_ops;       //entity operation
  21.     dev->format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
  22.

  23.     /* REVISIT: Do we need media controller? */
  24.     ret = media_entity_init(&dev->sd.entity, 1, &dev->pad, 0);  //media entity init
  25.     if (ret) {
  26.         mt9e013_remove(client);
  27.         return ret;
  28.     }
  29.

  30.     return 0;
  31. }
3. mt9e013_device 相关数据结构:

a. struct v4l2_subdev

  1. /* Each instance of a subdev driver should create this struct, either
  2.    stand-alone or embedded in a larger struct.
  3.  */
  4. struct v4l2_subdev {
  5. #if defined(CONFIG_MEDIA_CONTROLLER)
  6.     struct media_entity entity;
  7. #endif
  8.     struct list_head list;
  9.     struct module*owner;
  10.     u32 flags;
  11.     struct v4l2_device *v4l2_dev;
  12.     const struct v4l2_subdev_ops*ops;
  13.     /* The control handler of this subdev. May be NULL. */
  14.     struct v4l2_ctrl_handler *ctrl_handler;
  15.     /* name must be unique */
  16.     char name[V4L2_SUBDEV_NAME_SIZE];
  17.     /* can be used to group similar subdevs, value is driver-specific */
  18.     u32 grp_id;
  19.     /* pointer to private data */
  20.     void *dev_priv;
  21.     void *host_priv;
  22.     /* subdev device node */
  23.     struct video_device devnode;
  24.     unsigned int initialized;
  25.     /* number of events to be allocated on open */
  26.     unsigned int nevents;
  27. };
b. struct media_pad

  1. struct media_pad{
  2.     struct media_entity *entity;    /* Entity this pad belongs to */
  3.     u16 index;            /* Pad index in the entity pads array */
  4.     unsigned long flags;        /* Pad flags (MEDIA_PAD_FLAG_*) */
  5. };
struct media_entity

  1. struct media_entity{
  2.     struct list_head list;
  3.     struct media_device *parent;    /* Media device this entity belongs to*/
  4.     u32 id;                /* Entity ID, unique in the parent media
  5.                      * device context */
  6.     const char*name;        /* Entity name */
  7.     u32 type;            /* Entity type (MEDIA_ENTITY_TYPE_*) */
  8.     u32 revision;            /* Entity revision, driver specific */
  9.     unsigned long flags;        /* Entity flags (MEDIA_ENTITY_FLAG_*) */
  10.     u32 group_id;            /* Entity group ID */

  11.     u16 num_pads;            /* Number of input and output pads */
  12.     u16 num_links;            /* Number of existing links, both
  13.                      * enabled and disabled */
  14.     u16 num_backlinks;        /* Number of backlinks */
  15.     u16 max_links;            /* Maximum number of links */

  16.     struct media_pad *pads;        /* Pads array (num_pads elements) */
  17.     struct media_link *links;    /* Links array (max_links elements)*/

  18.     const struct media_entity_operations *ops;    /* Entity operations */ //这个比较重要

  19.     int stream_count;        /* Stream count for the entity. */
  20.     int use_count;            /* Use count for the entity. */

  21.     struct media_pipeline *pipe;    /* Pipeline this entity belongs to. */

  22.     union {
  23.         /* Node specifications */
  24.         struct {
  25.             u32 major;
  26.             u32 minor;
  27.         } v4l;
  28.         struct {
  29.             u32 major;
  30.             u32 minor;
  31.         } fb;
  32.         struct {
  33.             u32 card;
  34.             u32 device;
  35.             u32 subdevice;
  36.         } alsa;
  37.         int dvb;

  38.         /* Sub-device specifications */
  39.         /* Nothing needed yet */
  40.     };
  41. };
c. struct v4l2_mbus_framfmt

  1. /**
  2.  * struct v4l2_mbus_framefmt - frame format on the media bus
  3.  * @width:    frame width
  4.  * @height:    frame height
  5.  * @code:    data format code (from enum v4l2_mbus_pixelcode)
  6.  * @field:    used interlacing type (from enum v4l2_field)
  7.  * @colorspace:    colorspace of the data (from enum v4l2_colorspace)
  8.  */
  9. struct v4l2_mbus_framefmt {
  10.     __u32            width;
  11.     __u32            height;
  12.     __u32            code;
  13.     __u32            field;
  14.     __u32            colorspace;
  15. };
d. struct camera_sensor_platform_data

  1. struct camera_sensor_platform_data{
  2.     int (*gpio_ctrl)(struct v4l2_subdev*subdev, int flag);
  3.     int (*flisclk_ctrl)(struct v4l2_subdev*subdev, int flag);
  4.     int (*power_ctrl)(struct v4l2_subdev*subdev, int flag);
  5.     int (*csi_cfg)(struct v4l2_subdev*subdev, int flag);
  6. };

4. v4l2_i2c_subdev_init(),这里执行了2个动作,一个是设置V4L2子设备数据,一个是设置I2C client数据

  1. /* I2C Helper functions */


  2. void v4l2_i2c_subdev_init(struct v4l2_subdev*sd, struct i2c_client *client,
  3.         const struct v4l2_subdev_ops *ops)
  4. {
  5.     v4l2_subdev_init(sd, ops);
  6.     sd->flags|= V4L2_SUBDEV_FL_IS_I2C;
  7.     /* the owner is the same as the i2c_client's driver owner */
  8.     sd->owner= client->driver->driver.owner;
  9.     /* i2c_client and v4l2_subdev point to one another */
  10.     v4l2_set_subdevdata(sd, client);     //设置V4L2 子设备数据
  11.     i2c_set_clientdata(client, sd);      //设置I2C client 数据
  12.     /* initialize name */
  13.     snprintf(sd->name,sizeof(sd->name),"%s %d-%04x",
  14.         client->driver->driver.name, i2c_adapter_id(client->adapter),
  15.         client->addr);
  16. }
  17. EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
5. mt9e013_ops

  1. static const struct v4l2_subdev_ops mt9e013_ops= {   //v4l2_subdev operation, 表示vl42 子设备所具有的能力。
  2.     .core =&mt9e013_core_ops,
  3.     .video =&mt9e013_video_ops,
  4.     .pad =&mt9e013_pad_ops,
  5. };
a. mt9e013_core_ops V4L2 IOCTL 传下来的具体执行函数

  1. static const struct v4l2_subdev_core_ops mt9e013_core_ops= {
  2.     .g_chip_ident = mt9e013_g_chip_ident,  //获得Id
  3.     .s_config = mt9e013_s_config,          //配置
  4.     .queryctrl = mt9e013_queryctrl,        //query control能力
  5.     .g_ctrl = mt9e013_g_ctrl,             //get control
  6.     .s_ctrl = mt9e013_s_ctrl,             //set control
  7.     .s_power = mt9e013_s_power,           //set power
  8.     .ioctl = mt9e013_ioctl,               //ioctl
  9.     .init = mt9e013_init,
  10. };
b. mt9e013_video_ops : v4l2 接口传下来的视频相关的操作

  1. static const struct v4l2_subdev_video_ops mt9e013_video_ops= {
  2.     .s_stream = mt9e013_s_stream,                      //set stream
  3.     .enum_framesizes = mt9e013_enum_framesizes,         //enum framesizes
  4.     .enum_frameintervals = mt9e013_enum_frameintervals,   
  5.     .enum_mbus_fmt = mt9e013_enum_mbus_fmt,
  6.     .try_mbus_fmt = mt9e013_try_mbus_fmt,        // try format
  7.     .g_mbus_fmt = mt9e013_g_mbus_fmt,            // get format
  8.     .s_mbus_fmt = mt9e013_s_mbus_fmt,            //set format
  9. };
c. mt9e013_pad_ops :  media 帧设置方面的操作

  1. /* REVISIT: Do we need pad operations? */
  2. static conststruct v4l2_subdev_pad_ops mt9e013_pad_ops = {
  3.     .enum_mbus_code = mt9e013_enum_mbus_code,
  4.     .enum_frame_size = mt9e013_enum_frame_size,      // frame size
  5.     .get_fmt = mt9e013_get_pad_format,               // get format
  6.     .set_fmt = mt9e013_set_pad_format,               // set format
  7. };

6. mt9e013_entity_ops

  1. static const struct media_entity_operations mt9e013_entity_ops= {
  2.     .set_power = v4l2_subdev_set_power,   //设置v4l2子设备电源
  3. };
media_entity_operations 原型定义:

  1. struct media_entity_operations{
  2.     int (*link_setup)(struct media_entity*entity,
  3.              const struct media_pad *local,
  4.              const struct media_pad *remote, u32 flags);
  5.     int (*set_power)(struct media_entity*entity, int power);
  6. };
7.  media_entity_init

  1. /**
  2.  * media_entity_init - Initialize a media entity
  3.  *
  4.  * @num_pads: Total number of input and output pads.
  5.  * @extra_links: Initial estimate of the number of extra links.
  6.  * @pads: Array of 'num_pads' pads.
  7.  *
  8.  * The total number of pads is an intrinsic property of entities known by the
  9.  * entity driver, while the total number of links depends on hardware design
  10.  * and is an extrinsic property unknown to the entity driver. However, in most
  11.  * use cases the entity driver can guess the number of links which can safely
  12.  * be assumed to be equal to or larger than the number of pads.
  13.  *
  14.  * For those reasons the links array can be preallocated based on the entity
  15.  * driver guess and will be reallocated later if extra links need to be
  16.  * created.
  17.  *
  18.  * This function allocates a links array with enough space to hold at least
  19.  * 'num_pads' + 'extra_links' elements. The media_entity::max_links field will
  20.  * be set to the number of allocated elements.
  21.  *
  22.  * The pads array is managed by the entity driver and passed to
  23.  * media_entity_init() where its pointer will be stored in the entity structure.
  24.  */
  25. int
  26. media_entity_init(struct media_entity*entity, u16 num_pads,
  27.          struct media_pad *pads, u16 extra_links)
  28. {
  29.     struct media_link *links;
  30.     unsigned int max_links = num_pads + extra_links;
  31.     unsigned int i;

  32.     links = kzalloc(max_links* sizeof(links[0]), GFP_KERNEL);
  33.     if (links== NULL)
  34.         return -ENOMEM;

  35.     entity->group_id= 0;
  36.     entity->max_links= max_links;
  37.     entity->num_links= 0;
  38.     entity->num_backlinks= 0;
  39.     entity->num_pads= num_pads;
  40.     entity->pads= pads;
  41.     entity->links= links;

  42.     for (i= 0; i < num_pads; i++){
  43.         pads[i].entity= entity;
  44.         pads[i].index= i;
  45.     }

  46.     return 0;
  47. }
  48. EXPORT_SYMBOL_GPL(media_entity_init);
struct media_link

  1. struct media_link{
  2.     struct media_pad *source;    /* Source pad */
  3.     struct media_pad *sink;        /* Sink pad */
  4.     struct media_link *reverse;    /* Link in the reverse direction */
  5.     unsigned long flags;        /* Link flags (MEDIA_LINK_FLAG_*) */
  6. };
8. mt9e013_remove

  1. static int mt9e013_remove(struct i2c_client*client)
  2. {
  3.     struct v4l2_subdev *sd = i2c_get_clientdata(client);  //先根据i2c client, 来获得v4l2 子设备。
  4.     struct mt9e013_device *dev = to_mt9e013_sensor(sd);   //通过container_of(v4l2_subdev),来获得包含它的 最上层mt9e013设备。

  5.     dev->platform_data->csi_cfg(sd, 0);
  6.     v4l2_device_unregister_subdev(sd); //注销v4l2子设备。
  7.     kfree(dev);

  8.     return 0;
  9. }












struct mt9e013_device

   1. /* mt9e013 device structure */
   2. struct mt9e013_device {
   3.     struct v4l2_subdev sd;         //表示V4L2 子设备属性
   4.     struct media_pad pad;
   5.     struct v4l2_mbus_framefmt format;
   6.

   7.     struct camera_sensor_platform_data *platform_data;
   8.     int fmt_idx;
   9.     int    status;
  10.     u8 res;
  11.     u8 type;
  12.     u16    sensor_id;
  13.     u8    sensor_revision;
  14.

  15.     unsigned int intg_factor;
  16. };


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值