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 相关数据结构:

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

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

  18.     struct media_pad *pads;        /* Pads array (num_pads elements) */
  19.     struct media_link *links;    /* Links array (max_links elements)*/
  20.

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

  23.     int stream_count;        /* Stream count for the entity. */
  24.     int use_count;            /* Use count for the entity. */
  25.

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

  28.     union {
  29.         /* Node specifications */
  30.         struct {
  31.             u32 major;
  32.             u32 minor;
  33.         } v4l;
  34.         struct {
  35.             u32 major;
  36.             u32 minor;
  37.         } fb;
  38.         struct {
  39.             u32 card;
  40.             u32 device;
  41.             u32 subdevice;
  42.         } alsa;
  43.         int dvb;
  44.

  45.         /* Sub-device specifications */
  46.         /* Nothing needed yet */
  47.     };
  48. };


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.

   3.


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

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

  37.     entity->group_id = 0;
  38.     entity->max_links = max_links;
  39.     entity->num_links = 0;
  40.     entity->num_backlinks = 0;
  41.     entity->num_pads = num_pads;
  42.     entity->pads = pads;
  43.     entity->links = links;
  44.

  45.     for (i = 0; i < num_pads; i++) {
  46.         pads[i].entity = entity;
  47.         pads[i].index = i;
  48.     }
  49.

  50.     return 0;
  51. }
  52. 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.

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

  10.     return 0;
  11. }


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值