Tegra平台back camera 驱动实现四

camera驱动的实现

 本篇文章主要介绍camera驱动的实现,这将会结合代码来叙述,这理解摄像头驱动需要三个前提,分别是:

摄像头基本的工作原理

platform_device和platform_driver工作原理

Linux内核I2C驱动架构

        驱动的编写主要有配置GPIO、I2C、MIPI、电压、时钟等, 编写驱动代码,调通camera sensor驱动,并实现前后置双camera的切换。根据芯片手册,实现基本功能 - 预览, 拍照, 录像, 效果(scene, effect, ev, iso, wb, contrast等等)。当然还要实现进阶扩展功能 - 防抖, 自动对焦, 闪光灯, 固件升级, 720P, wdr, panorama等。本篇只讲述些基本的功能实现。

配置GPIO口和芯片上电时序(power on sequence)

        查看datesheet芯片上电时序如下图所示:

Android Tegra平台back camera 驱动实现四 camera驱动的实现

上电时序一

Android Tegra平台back camera 驱动实现四 camera驱动的实现

上电时序二

        对应代码如下:

C/C++代码
  1. static struct camera_gpios yuv5_sensor_gpio_keys[] = {  
  2.     [0] = CAMERA_GPIO("cam_power_en", CAMERA_POWER_GPIO, 1, 0, GPIO_FREE),  
  3.     [1] = CAMERA_GPIO("yuv5_sensor_pwdn", YUV5_PWR_DN_GPIO, 0, 0, GPIO_FREE),  
  4.     [2] = CAMERA_GPIO("yuv5_sensor_rst_lo", YUV5_RST_L_GPIO, 1, 0, GPIO_FREE),  
  5. };  
  6. static int yuv5_sensor_power_on(void)  
  7. {  
  8.     int ret;  
  9.     int i;  
  10.     pr_err("%s: sandow pmu\n", __func__);  
  11.     for (i = 0; i < ARRAY_SIZE(yuv5_sensor_gpio_keys); i++) {  
  12.                 tegra_gpio_enable(yuv5_sensor_gpio_keys[i].gpio);  
  13.         ret = gpio_request(yuv5_sensor_gpio_keys[i].gpio,  
  14.             yuv5_sensor_gpio_keys[i].name);  
  15.         if (ret < 0) {  
  16.             pr_err("%s: gpio_request failed for gpio #%d\n",  
  17.                 __func__, i);  
  18.             goto fail;  
  19.         }  
  20.         gpio_direction_output(yuv5_sensor_gpio_keys[i].gpio,  
  21.             yuv5_sensor_gpio_keys[i].enabled);  
  22.                 gpio_export(yuv5_sensor_gpio_keys[i].gpio, false);  
  23.     }  
  24.   
  25.     return 0;  
  26. fail:  
  27.     while (i--)  
  28.         gpio_free(yuv5_sensor_gpio_keys[i].gpio);  
  29.     return ret;  
  30. }  
  31.   
  32. static int yuv5_sensor_power_off(void)  
  33. {  
  34.     int i;  
  35.     int gpio_pw_dn, gpio_camera_power;  
  36.     pr_err("%s: sandow pmu\n", __func__);  
  37.     //set 5M to power-down     
  38.     gpio_direction_output(YUV5_PWR_DN_GPIO,1);  
  39.     //cut off power          
  40.     gpio_direction_output(CAMERA_POWER_GPIO,0);  
  41.       
  42.     gpio_pw_dn = gpio_get_value(YUV5_PWR_DN_GPIO);  
  43.     gpio_camera_power= gpio_get_value(CAMERA_POWER_GPIO);     
  44.       
  45.     printk("%s: sandow pmu gpio_pw_dn: %d, camera_power: %d", __func__, gpio_pw_dn, gpio_camera_power);  
  46.        
  47.         i = ARRAY_SIZE(yuv5_sensor_gpio_keys);  
  48.     while (i--)  
  49.         gpio_free(yuv5_sensor_gpio_keys[i].gpio);  
  50.     return 0;  
  51. }  
  52.   
  53. struct yuv5_sensor_platform_data yuv5_sensor_data = {  
  54.     .power_on = yuv5_sensor_power_on,  
  55.     .power_off = yuv5_sensor_power_off,  
  56. };  
配置 I2C

        I2C通信本身要注意两点:

        1、SDA第9位ACK位为低时说明从设备有响应;

        2、Slave address,Spec给出的是8位地址,第8位是指Write-0或者Read-1,实际的I2C芯片地址是7位的。Linux源码里struct i2c_board_info的板基信息应填写7位I2C地址。

代码位于:board-ventana-sensors.c

C/C++代码
  1. {  
  2.          I2C_BOARD_INFO(SENSOR_5M_NAME, 0x3D),//I2C slave address  
  3.         .platform_data = &yuv5_sensor_data,  
  4.  },  
  5. ……  
  6. #define SENSOR_5M_NAME  "mt9d111"  
  7. ……  
  8. // platform driver是用来"触发"真正的i2c //driver的注册  
  9. static struct i2c_driver sensor_i2c_driver = {  .driver = {  
  10.         .name = SENSOR_5M_NAME,//与i2c_board_info 的type匹配  
  11.         .owner = THIS_MODULE,  
  12.     },  
  13.     .probe = sensor_probe,// 当有i2c_client和i2c_driver匹配时调用  
  14.     .remove = sensor_remove,  
  15.     .id_table = sensor_id,// //匹配规则  
  16. };  
  17. static struct miscdevice sensor_device = {  
  18.     .minor = MISC_DYNAMIC_MINOR,  
  19.     .name = SENSOR_5M_NAME,  
  20.     .fops = &sensor_fileops,  
  21. };  

        本例的camera驱动代码在/kernel/driver/media/video/tegra下:

        ltc3216.c(LED驱动器LTC3216)、yuv5_sensor.c、yuv_sensor.c、tegra_camera.c。这些源码里面最基础的是tegra_camera.c,这里面注册了一个platform_driver,在相应的平台代码里面有对应的platform_device的描述。这种SOC上的控制器一般都会挂接在platform_bus上以实现在系统初始化时的device和driver的匹配。在driver的probe函数里面,主要完成了资源获取以及misc设备的注册。

平台信息:

C/C++代码
  1. struct yuv5_sensor_platform_data yuv5_sensor_data = {  
  2.     .power_on = yuv5_sensor_power_on,  
  3.     .power_off = yuv5_sensor_power_off,  
  4. };  

        Probe具体流程如下图所示:

Android Tegra平台back camera 驱动实现四 camera驱动的实现


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值