1. camera内核驱动框架图

rk3288 android6.0 camera子系统 - kernel分析

上图摘自RKDocs目录中文档Camera_for_RockChipSDK参考说明_v4.1.pdf

图中rk29需改成rk30, 即将添加的camera sensor,寄存器是放在hardware/rockchip/camera/中,不需要图中的ov2655.c部分。

 

流程:
v4l2-xxx --> soc_camera --> rk30_camera_oneframe.c --> generic_sensor.c -->  xxx_sensor.c

Rockchip为sonsor做了个公用驱动generic_sensor.c,留出公共接口给不同的sonsor使用。

 

      1. host驱动

Camera Host驱动主要实现如下:

1、videobuf 回调以及控制;

2、VIP Controller 设置;

3、Camera 休眠唤醒;

4、IPP scale 控制;

        1. videobuf 回调以及控制

由参考文档得知,使用videobuf 机制必须实现videobuf_queue_ops 结构体中的4 个

回调函数。驱动对videobuf 的控制流程如下:

rk3288 android6.0 camera子系统 - kernel分析

 

 

 

        1. VIP Controller 设置

VIP 控制器的设置主要涉及:VIP 各工作时钟控制、VIP 输出时钟(Sensor 工作时钟)

输出、VIP 采集时序极性控制;

以上控制主要集中在以下函数中:

rk_camera_set_bus_param;

rk_camera_setup_format;

rk_camera_set_fmt;

 

        1. Camera 休眠唤醒

VIP 控制器在休眠唤醒中需要寄存器进行备份设置,在唤醒时将备份的寄存器值重新恢

复到寄存器中。

 

        1. IPP Scale 控制

Sensor 能够输出的分辨率不一定能够完全满足用户的需求,这个时候就必须对sensor

的输出图像进行scale。

在使用到IPP scale 时,vip 采集的buf就不能是用户提供的videobuf,vip 驱动必须

获取一段buf 作为采集用,采集结束后将该段buf 中的数据利用IPP 进行scale 处理,同时

将输出到用户指定的videobuf 中,最后唤醒因获取该videobuf 而睡眠的进程。IPP 处理必

须在内核线程中进行处理。

 

        1. 代码分析

查看概述章节,可知设备注册代码为rk30_camera.c

  1. static int rk_register_camera_devices(void)  
  2. {  
  3.     ……
  4.   
  5.     rk_cif_sensor_init();  
  6.   
  7.     new_camera = rk_camera_platform_data.register_dev_new;  
  8.    
  9.     ……
  10.  
  11.     #if RK_SUPPORT_CIF0  
  12.     if (host_registered_0) {  
  13.         platform_device_register(&rk_device_camera_host_0);//host_0 has sensor  
  14.     }   //host_device_register  
  15.     #endif  
  16.       
  17.     #if RK_SUPPORT_CIF1  
  18.     if (host_registered_1) {  
  19.         platform_device_register(&rk_device_camera_host_1);//host_1 has sensor  
  20.     }  //host_device_register  
  21.     #endif  
  22.   
  23.   
  24.     if (rk_camera_platform_data.sensor_register)        
  25.        (rk_camera_platform_data.sensor_register)();   //call rk_sensor_register()  
  26.   
  27.     return 0;  
  28. }  

 

rk_cif_sensor_init做了一些初始化工作, 开始进入函数platform_device_register

 

  1. static int rk_cif_sensor_init(void)  
  2. {  
  3.       
  4.     debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()/n", __FILE__, __LINE__,__FUNCTION__);  
  5.     platform_driver_register(&rk_cif_driver);     
  6.           
  7.     platform_driver_register(&rk_sensor_driver);      
  8.   
  9.     return 0;  
  10. }  
  11.   
  12. static struct platform_driver rk_cif_driver =  
  13. {  
  14.     .driver     = {  
  15.         .name   = RK_CIF_NAME,                
  16.         .owner = THIS_MODULE,  
  17.         .of_match_table = of_match_ptr(of_match_cif),  
  18.     },  
  19.     .probe      = rk_dts_cif_probe,  
  20.     .remove     = rk_dts_cif_remove,  
  21. };  
  22.   
  23. static struct platform_driver rk_sensor_driver =  
  24. {  
  25.     .driver     = {  
  26.         .name   = RK_SENSOR_NAME,                
  27.         .owner  = THIS_MODULE,  
  28.         .of_match_table = of_match_ptr(of_match_sensor),  
  29.     },  
  30.     .probe      = rk_dts_sensor_probe,  
  31.     .remove     = rk_dts_sensor_remove,  
  32. };  

根据cif, sensor设备树中内容,匹配到相关初始化值,注册平台驱动

  1.  struct platform_device rk_device_camera_host_0 = {  
  2.     .name         = RK29_CAM_DRV_NAME,  
  3.     .id       = RK_CAM_PLATFORM_DEV_ID_0,               /* This is used to put cameras on this interface*/   
  4.     .num_resources= 2,  
  5.     .resource     = rk_camera_resource_host_0,  
  6.     .dev            = {  
  7.         .dma_mask = &rockchip_device_camera_dmamask,  
  8.         .coherent_dma_mask = 0xffffffffUL,  
  9.         .platform_data  = &rk_camera_platform_data,  
  10.     }  
  11. };  

#define RK29_CAM_DRV_NAME "rk312x-camera"

rk30_camera_oneframe.c通过这个名与之匹配。

  1. static struct platform_driver rk_camera_driver =  
  2. {  
  3.     .driver     = {  
  4.         .name   = RK29_CAM_DRV_NAME,       /*host */        
  5.     },  
  6.     .probe      = rk_camera_probe,  
  7.     .remove     = (rk_camera_remove),  
  8. };  
  9.   
  10. static int rk_camera_init_async(void *unused)  
  11. {  
  12.   
  13.     debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);  
  14.     platform_driver_register(&rk_camera_driver);      
  15.     return 0;  
  16. }  
  17.   
  18. static int __init rk_camera_init(void)  
  19. {  
  20.   
  21.     debug_printk( "/$$$$$$$$$$$$$$$$$$$$$$//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);  
  22.   
  23.     kthread_run(rk_camera_init_async, NULL, "rk_camera_init");  
  24.       
  25.     return 0;  
  26. }  

 

 

  1. static struct soc_camera_host_ops rk_soc_camera_host_ops =  
  2. {  
  3.     .owner      = THIS_MODULE,  
  4.     .add        = rk_camera_add_device,  
  5.     .remove     = rk_camera_remove_device,  
  6.     .suspend    = rk_camera_suspend,  
  7.     .resume     = rk_camera_resume,  
  8.     .enum_frameinervals = rk_camera_enum_frameintervals,  
  9.     .cropcap    = rk_camera_cropcap,  
  10.     .set_crop   = rk_camera_set_crop,  
  11.     .get_crop   = rk_camera_get_crop,  
  12.     .get_formats    = rk_camera_get_formats,   
  13.     .put_formats    = rk_camera_put_formats,  
  14.     .set_fmt    = rk_camera_set_fmt,  
  15.     .try_fmt    = rk_camera_try_fmt,  
  16.     .init_videobuf  = rk_camera_init_videobuf,  
  17.     .reqbufs    = rk_camera_reqbufs,  
  18.     .poll       = rk_camera_poll,  
  19.     .querycap   = rk_camera_querycap,  
  20.     .set_bus_param  = rk_camera_set_bus_param,  
  21.     .s_stream = rk_camera_s_stream,   /* [email protected] : Add stream control for host */  
  22.     .set_ctrl = rk_camera_set_ctrl,  
  23.     .controls = rk_camera_controls,  
  24.     .num_controls = ARRAY_SIZE(rk_camera_controls)  
  25. };  

上面列出了一些功能,最后提供给用户空间使用。

 

 

 

 

      1. kernel层方式添加sensor

查看概述章节,用gc0329.c为例.

需要取消hal层添加摄像头的功能,代码位置:

hardware/rockchip/camera/CameraHal_board_xml_parse.cpp

//register i2c device

int err = RegisterSensorDevice(pCamInfo);

 

make menuconfig 中加入gc0329 也加入设备树内容。

 

        1. 设备树内容

kernel/arch/arm/boot/dts/rk3288-cif-sensor.dtsi

  1. #include "rk3288.dtsi"   
  2. #include "rk3288-pinctrl.dtsi"  
  3. #include "../../mach-rockchip/rk_camera_sensor_info.h"  
  4. /{  
  5.     rk3288_cif_sensor: rk3288_cif_sensor{  
  6.             compatible = "rockchip,sensor";  
  7.             status = "disabled";  
  8.               
  9.      gc0329{  
  10.         is_front = <0>;  
  11.         rockchip,power = <&gpio0 GPIO_C1 GPIO_ACTIVE_HIGH>;  
  12.         //rockchip,power_pmu_name1 = "rk818_ldo4";  
  13.         //rockchip,power_pmu_voltage1 = <2800000>;  
  14.         //rockchip,power_pmu_name2 = "rk818_ldo8";  
  15.         //rockchip,power_pmu_voltage2 = <1800000>;  
  16.         rockchip,powerdown = <&gpio2 GPIO_B4 GPIO_ACTIVE_HIGH>;  
  17.         //rockchip,powerdown_pmu = "";  
  18.         //rockchip,powerdown_pmu_voltage = <3000000>;  
  19.         pwdn_active = <gc0329_PWRDN_ACTIVE>;  
  20.         pwr_active = <PWR_ACTIVE_HIGH>;  
  21.         mir = <0>;  
  22.         flash_attach = <1>;  
  23.         //rockchip,flash = <>;  
  24.         flash_active = <1>;  
  25.         resolution = <gc0329_FULL_RESOLUTION>;  
  26.         powerup_sequence = <gc0329_PWRSEQ>;  
  27.         orientation = <0>;        
  28.         i2c_add = <gc0329_I2C_ADDR>;  
  29.         i2c_rata = <100000>;  
  30.         i2c_chl = <3>;  
  31.         cif_chl = <0>;  
  32.         mclk_rate = <24>;  
  33.         };  
  34.     };  
  35. };  

gc0329_I2C_ADDR kernel/arch/arm/mach-rockchip/rk_camera_sensor_info.h

 

        1. 代码分析

kernel/drivers/media/video/gc0309.c

gc0309的实现。结合generic_sensor.c, 实现不同于其它sensor的代码。

 

  1. #define SENSOR_NAME RK29_CAM_SENSOR_GC0329  
  2. #define SENSOR_V4L2_IDENT V4L2_IDENT_GC0329  
  3. #define SENSOR_ID 0xc0  
  4. #define SENSOR_BUS_PARAM                     (V4L2_MBUS_MASTER |\  
  5.                                              V4L2_MBUS_PCLK_SAMPLE_RISING|V4L2_MBUS_HSYNC_ACTIVE_HIGH| V4L2_MBUS_VSYNC_ACTIVE_HIGH|\  
  6.                                              V4L2_MBUS_DATA_ACTIVE_HIGH  |SOCAM_MCLK_24MHZ)  

重要的宏定义

 

  1. sensor_init_parameters_default_code();  
  2. sensor_v4l2_struct_initialization();  
  3. sensor_probe_default_code();  
  4. sensor_remove_default_code();  
  5. sensor_driver_default_module_code();  

这部分在generic_sensor中实现。

 

kernel/drivers/media/video/generic_sensor.h

  1.   
  2. extern int generic_sensor_softreset(struct i2c_client *client, struct rk_sensor_reg *series);  
  3. extern int generic_sensor_check_id(struct i2c_client *client, struct rk_sensor_reg *series);  
  4. extern int sensor_write_reg2val1(struct i2c_client *client, u16 reg,u8 val);  
  5. extern int sensor_write_reg2val2(struct i2c_client *client, u16 reg,u16 val);  
  6. extern int sensor_write_reg1val1(struct i2c_client *client, u8 reg,u8 val);  
  7. extern int sensor_write_reg1val2(struct i2c_client *client, u8 reg,u16 val);  
  8. extern int sensor_read_reg1val1(struct i2c_client *client, u8 reg,u8* val);  
  9. extern int sensor_read_reg2val1(struct i2c_client *client, u16 reg,u8* val);  
  10. extern int sensor_read_reg1val2(struct i2c_client *client, u8 reg,u16* val);  
  11. extern int sensor_read_reg2val2(struct i2c_client *client, u16 reg,u16* val);  
  12. extern int generic_sensor_write(struct i2c_client *client,struct rk_sensor_reg* sensor_reg);  
  13. extern int generic_sensor_read(struct i2c_client *client, struct rk_sensor_reg* sensor_reg);  
  14. extern int generic_sensor_write_array(struct i2c_client *client, struct rk_sensor_reg *regarray);  
  15. extern int generic_sensor_get_max_min_res(struct rk_sensor_sequence* res_array,int num,struct rk_sensor_seq_info * max_real_res  
  16.                                         ,struct rk_sensor_seq_info * max_res,struct rk_sensor_seq_info *min_res);  
  17. extern int generic_sensor_init(struct v4l2_subdev *sd, u32 val);  
  18. extern int generic_sensor_enum_frameintervals(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival);  
  19. extern int generic_sensor_try_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf);  
  20. extern int generic_sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cmd cmd, int on);  
  21. extern unsigned long generic_sensor_query_bus_param(struct soc_camera_device *icd);  
  22. extern int generic_sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf);  
  23. extern int generic_sensor_set_bus_param(struct soc_camera_device *icd,unsigned long flags);  
  24. extern int generic_sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);  
  25. extern int generic_sensor_s_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl);  
  26. extern int generic_sensor_g_ext_control(struct soc_camera_device *icd , struct v4l2_ext_control *ext_ctrl);  
  27. extern int generic_sensor_s_ext_control(struct soc_camera_device *icd, struct v4l2_ext_control *ext_ctrl);  
  28. extern int generic_sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl);  
  29. extern int generic_sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl);  
  30. extern long generic_sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg);  
  31. extern int generic_sensor_s_power(struct v4l2_subdev *sd, int on);/*yzm*/  
  32. extern int generic_sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index,enum v4l2_mbus_pixelcode *code);  
  33. extern int generic_sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf);  
  34. extern int generic_sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id);  
  35. extern int generic_sensor_af_workqueue_set(struct soc_camera_device *icd, enum rk_sensor_focus_wq_cmd cmd, int var, bool wait);  
  36. extern int generic_sensor_s_stream(struct v4l2_subdev *sd, int enable);  
  37. extern int generic_sensor_writebuf(struct i2c_client *client, char *buf, int buf_size);  
  38. extern int generic_sensor_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *cc);  
  39. extern int generic_sensor_enum_framesizes(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize);  

一些功能函数。

 

相关文章: