Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2118759
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: Android平台

2014-02-20 14:21:38

1. 驱动初始化
在drivers/media/video/sp0a19.c中
device_initcall_sync(sp0a_mod_init);
  1. static struct i2c_driver sp0a_i2c_driver = {
  2.     .driver = {
  3.         .name = SP0A_NAME_STRING(),
  4.     },
  5.     .probe        = sp0a_probe,
  6.     .remove        = sp0a_remove,
  7.     .id_table    = sp0a_id,
  8. };

  9. static int __init sp0a_mod_init(void)
  10. {
  11.     return i2c_add_driver(&sp0a_i2c_driver);
  12. }
在probe函数中
  1. static int sp0a_probe(struct i2c_client *client, const struct i2c_device_id *did)
  2. {
  3.     struct sp0a *sp0a;
  4.     struct soc_camera_device *icd = client->dev.platform_data;
  5.     struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
  6.     struct soc_camera_link *icl;

  7.     icl = to_soc_camera_link(icd);    
  8.     sp0a = kzalloc(sizeof(struct sp0a), GFP_KERNEL);
  9.     v4l2_i2c_subdev_init(&sp0a->subdev, client, &sp0a_subdev_ops);   
  10.     icd->ops        = &sp0a_ops;
  11.     sp0a->info_priv.fmt = sp0a_colour_fmts[0];
  12.     sp0a_video_probe(icd, client);
  13.     return ret;
  14. }
函数指针的注册过程
v4l2_i2c_subdev_init(&sp0a->subdev, client, &sp0a_subdev_ops);
  1. static struct v4l2_subdev_core_ops sp0a_subdev_core_ops = {
  2.     .init        = sp0a_init,
  3.     .g_ctrl        = sp0a_g_control,
  4.     .s_ctrl        = sp0a_s_control,
  5.     .g_ext_ctrls = sp0a_g_ext_controls,
  6.     .s_ext_ctrls = sp0a_s_ext_controls,
  7.     .g_chip_ident    = sp0a_g_chip_ident,
  8.     .ioctl = sp0a_ioctl,
  9. };

  10. static struct v4l2_subdev_video_ops sp0a_subdev_video_ops = {
  11.     .s_mbus_fmt    = sp0a_s_fmt,
  12.     .g_mbus_fmt    = sp0a_g_fmt,
  13.     .try_mbus_fmt    = sp0a_try_fmt,
  14.     .enum_mbus_fmt    = sp0a_enum_fmt,
  15. };

  16. static struct v4l2_subdev_ops sp0a_subdev_ops = {
  17.     .core    = &sp0a_subdev_core_ops,
  18.     .video = &sp0a_subdev_video_ops,
  19. };

icd->ops        = &sp0a_ops;
  1. static struct soc_camera_ops sp0a_ops =
  2. {
  3.     .suspend = sp0a_suspend,
  4.     .resume = sp0a_resume,
  5.     .set_bus_param        = sp0a_set_bus_param,
  6.     .query_bus_param    = sp0a_query_bus_param,
  7.     .controls        = sp0a_controls,
  8.     .menus = sp0a_menus,
  9.     .num_controls        = ARRAY_SIZE(sp0a_controls),
  10.     .num_menus        = ARRAY_SIZE(sp0a_menus),
  11. };
  1. static int sp0a_video_probe(struct soc_camera_device *icd,  struct i2c_client *client)
  2. {
  3.     char pid = 0;
  4.     int ret;
  5.     struct sp0a *sp0a = to_sp0a(client);
  6.     if ( g_bIsAtvStart )
  7.     {
  8.         return 0;
  9.     }
  10.     //.add power.sheng 2012.09.04

  11.     /* We must have a parent by now. And it cannot be a wrong one.
  12.      * So this entire test is completely redundant. */
  13.     if (!icd->dev.parent ||
  14.      to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
  15.         return -ENODEV;

  16.     if (sp0a_ioctrl(icd, Sensor_PowerDown, 0) < 0) {
  17.         ret = -ENODEV;
  18.         goto sp0a_video_probe_err;
  19.     }

  20.     /* soft reset */
  21.    /* ret = sp0a_write(client, 0x12, 0x80);
  22.     if (ret != 0)
  23.     {
  24.         SP0A_TR("soft reset %s failed\n",SP0A_NAME_STRING());
  25.         return -ENODEV;
  26.     }
  27.     mdelay(50); *///delay 5 microseconds

  28.     /* check if it is an sp0a sp0a */
  29.     ret = sp0a_read(client, 0x02, &pid);
  30.     if (ret != 0) {
  31.         SP0A_TR("%s read chip id high byte failed\n",SP0A_NAME_STRING());
  32.         ret = -ENODEV;
  33.         goto sp0a_video_probe_err;
  34.     }

  35.     SP0A_DG("\n %s pid = 0x%x\n", SP0A_NAME_STRING(), pid);
  36.     if (pid == SP0A_ID) {
  37.         sp0a->model = SP0A_V4L2_IDENT;
  38.     } else {
  39.         SP0A_TR("error: %s mismatched pid = 0x%x\n", SP0A_NAME_STRING(), pid);
  40.         ret = -ENODEV;
  41.         goto sp0a_video_probe_err;
  42.     }

  43.     return 0;

  44. sp0a_video_probe_err:

  45.     return ret;
  46. }



阅读(2459) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~