Camera 驱动加载
来源:互联网 发布:手机网络共享怎么设置 编辑:程序博客网 时间:2024/06/04 19:37
一、概述
一般在 Linux 设备驱动模型中,我们只需要关心总线、设备、驱动这三个实体。总线会充当红娘对加载于其上的设备与驱动进行配对,对于 Camera 模块也不例外,下面从总线、设备、驱动的角度来分析 Camera 模块驱动的注册、匹配与加载过程。本文以MTK平台为例。
二、驱动加载过程
驱动加载都是以module_init(XXX)开始,如下所示:
module_init(CAMERA_HW_i2C_init);
1、入口函数
/*======================================================= * CAMERA_HW_i2C_init() *======================================================*/static int __init CAMERA_HW_i2C_init(void){ PK_DBG("[camerahw_probe] start\n");#ifndef CONFIG_OF int ret = 0; //注册平台总线的设备 ret = platform_device_register(&camerahw_platform_device); if (ret) { PK_ERR("[camerahw_probe] platform_device_register fail\n"); return ret; } ret = platform_device_register(&camerahw2_platform_device); if (ret) { PK_ERR("[camerahw2_probe] platform_device_register fail\n"); return ret; }#endif //注册平台总线的驱动 if (platform_driver_register(&g_stCAMERA_HW_Driver)) { PK_ERR("failed to register CAMERA_HW driver\n"); return -ENODEV; } if (platform_driver_register(&g_stCAMERA_HW_Driver2)) { PK_ERR("failed to register CAMERA_HW driver\n"); return -ENODEV; } /* FIX-ME: linux-3.10 procfs API changed *///在proc下创建driver/camsensor这个节点,用于前置摄像头进行adb效果调试 proc_create("driver/camsensor", 0, NULL, &fcamera_proc_fops);//在proc下创建driver/camsensor2这个节点,用于后置摄像头进行adb效果调试 proc_create("driver/camsensor2", 0, NULL, &fcamera_proc_fops2); proc_create("driver/camsensor3", 0, NULL, &fcamera_proc_fops3); /* Camera information */ memset(mtk_ccm_name, 0, camera_info_size); proc_create(PROC_CAMERA_INFO, 0, NULL, &fcamera_proc_fops1); ………… return 0;}
CAMERA_HW_i2C_init函数主要做的是首先要进行I2C总线板极设备的注册及初始化工作,然后注册platform总线的driver,通过g_stCAMERA_HW_Driver结构体里面的name来与device进行匹配。同时,在函数里面还在proc目录下创建了driver/camsensor和driver/camsensor2两个节点,这样做主要是方便sensor的IC原厂FAE利用adb进行效果调试的。
2、g_stCAMERA_HW_Driver结构体
static struct platform_driver g_stCAMERA_HW_Driver = { .probe = CAMERA_HW_probe,//匹配成功则调用 .remove = CAMERA_HW_remove, .suspend = CAMERA_HW_suspend,//休眠时调用 .resume = CAMERA_HW_resume,//唤醒时调用 .driver = { .name = "image_sensor", .owner = THIS_MODULE,#ifdef CONFIG_OF .of_match_table = CAMERA_HW_of_ids,#endif }};
g_stCAMERA_HW_Driver结构体中主要有probe、remove、suspend等接口的实现,尤其是probe接口为设备注册的匹配函数,在driver与device匹配后就会调用 .probe = CAMERA_HW_probe进入CAMERA_HW_probe函数。
3、探测函数CAMERA_HW_probe
static int CAMERA_HW_probe(struct platform_device *pdev){#if !defined(CONFIG_MTK_CLKMGR) Get_ccf_clk(pdev);#endif#if !defined(CONFIG_MTK_LEGACY)/*GPIO Pin control*/ mtkcam_gpio_init(pdev);//GPIO管脚通过pinctl进行初始化#endif //注册I2C驱动 return i2c_add_driver(&CAMERA_HW_i2c_driver);}
4、CAMERA_HW_i2c_driver结构体
struct i2c_driver CAMERA_HW_i2c_driver = { .probe = CAMERA_HW_i2c_probe, .remove = CAMERA_HW_i2c_remove, .driver = { .name = CAMERA_HW_DRVNAME1, .owner = THIS_MODULE,#ifdef CONFIG_OF .of_match_table = CAMERA_HW_i2c_of_ids,#endif }, .id_table = CAMERA_HW_i2c_id,};
sensor驱动最终还是会注册I2C设备,I2C总线的注册其实跟platform总线的注册大致相同,注册完I2C driver后就会进行匹配,匹配成功后系统就会调用CAMERA_HW_i2c_driver 结构体里面的 .probe = CAMERA_HW_i2c_probe。
5、探测函数CAMERA_HW_probe
static int CAMERA_HW_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id){ int i4RetValue = 0; PK_DBG("[CAMERA_HW] Attach I2C\n"); /* get sensor i2c client */ spin_lock(&kdsensor_drv_lock); g_pstI2Cclient = client; /* set I2C clock rate */ g_pstI2Cclient->timing = 100;/* 100k */ g_pstI2Cclient->ext_flag &= ~I2C_POLLING_FLAG; /* No I2C polling busy waiting */ spin_unlock(&kdsensor_drv_lock); /* Register char driver */ i4RetValue = RegisterCAMERA_HWCharDrv();//注册一个字符设备 if (i4RetValue) { PK_ERR("[CAMERA_HW] register char device failed!\n"); return i4RetValue; } /* spin_lock_init(&g_CamHWLock); */#if !defined(CONFIG_MTK_LEGACY) Get_Cam_Regulator();//获取电源#endif PK_DBG("[CAMERA_HW] Attached!!\n"); return 0;}
6、字符设备注册
static inline int RegisterCAMERA_HWCharDrv(void){#if CAMERA_HW_DYNAMIC_ALLOCATE_DEVNO // 动态分配一个字符设备 if (alloc_chrdev_region(&g_CAMERA_HWdevno, 0, 1, CAMERA_HW_DRVNAME1)) { PK_DBG("[CAMERA SENSOR] Allocate device no failed\n"); return -EAGAIN; }#else // 静态分配一个字符设备 if (register_chrdev_region(g_CAMERA_HWdevno , 1 , CAMERA_HW_DRVNAME1)) { PK_DBG("[CAMERA SENSOR] Register device no failed\n"); return -EAGAIN; }#endif /* Allocate driver */ g_pCAMERA_HW_CharDrv = cdev_alloc(); // 申请一个cdev结构体 if (NULL == g_pCAMERA_HW_CharDrv) { unregister_chrdev_region(g_CAMERA_HWdevno, 1); PK_DBG("[CAMERA SENSOR] Allocate mem for kobject failed\n"); return -ENOMEM; } /* Attatch file operation. */ //关联到file_operation进入字符设备 cdev_init(g_pCAMERA_HW_CharDrv, &g_stCAMERA_HW_fops); g_pCAMERA_HW_CharDrv->owner = THIS_MODULE; /* Add to system */ //将我们分配的字符设备,attach上file_operation添加到system if (cdev_add(g_pCAMERA_HW_CharDrv, g_CAMERA_HWdevno, 1)) { PK_DBG("[mt6516_IDP] Attatch file operation failed\n"); unregister_chrdev_region(g_CAMERA_HWdevno, 1); return -EAGAIN; } //创建一个sensordrv类 sensor_class = class_create(THIS_MODULE, "sensordrv"); if (IS_ERR(sensor_class)) { int ret = PTR_ERR(sensor_class); PK_DBG("Unable to create class, err = %d\n", ret); return ret; } sensor_device = device_create(sensor_class, NULL, g_CAMERA_HWdevno, NULL, CAMERA_HW_DRVNAME1); return 0;}
camera的模块驱动为字符驱动,所以RegisterCAMERA_HWCharDrv函数主要是对camera_image进行字符驱动注册,代码开始先判断是否定义了CAMERA_HW_DYNAMIC_ALLOCATE_DEVNO变量来判断动态还是静态分配一个字符设备,然后通过cdev_alloc申请了一个cdev结构体后,通过cdev_init将g_stCAMERA_HW_fops关联到字符设备,g_stCAMERA_HW_fops是HAL层与内核驱动进行交互的渠道。然后就是将我们分配的字符设备,attach上file_operation添加到system,最后在sys/class目录下创建一个sensordrv类。
三、总结
到目前为止,我们大致了解camera驱动模块大致的加载过程,值得注意的是注册字符设备时,关联着结构体g_stCAMERA_HW_fops;下一篇将围绕这个结构体,一起分析HAL层与驱动的交互过程
- Camera 驱动加载
- 关于linux中camera驱动的加载
- camera 驱动
- camera 驱动
- camera驱动
- camera驱动
- camera驱动移植总结
- camera驱动相关
- Android Camera驱动分析
- camera hi253驱动
- camera 模组驱动优化
- mtk6572 Camera驱动配置
- Camera sensor驱动
- camera驱动 for android
- s5pv210 camera驱动分析
- camera驱动 v4l2/fimc
- camera 模组驱动优化
- camera 模组驱动优化
- linux 内核设备驱动初始化的实现(转)
- 在Ubuntu 16.04 安装sogou 输入法详细讲解
- jQuery选择器
- /lib64/libc.so.6: version `GLIBC_2.14' not found
- 知识点1:你是怎么理解面向对象和面向过程的
- Camera 驱动加载
- TRM59900.00 NONE(https://www.ngs.noaa.gov/ANTCAL/LoadFile?file=TRM59900.00_NONE.atx)
- ARM 指令的条件码
- Golang 优化之路——空结构
- ruby基础记录
- 第四次上机实验
- SQLSERVER聚合函数
- Python 绘制函数图形
- C语言综合实践-----C程序操作