美文网首页
[Camera]RK平台摄像头驱动

[Camera]RK平台摄像头驱动

作者: Letcos | 来源:发表于2020-02-14 19:39 被阅读0次
    platform:rk3399
    OS:Android 7.1
    Kernel:4.4
    参考:
    1. KrisFei https://blog.csdn.net/kris_fei/article/details/79298971
    

    简介

    ​ RK平台抽象出了一个公共的camera驱动,给应用层提供通用的camera驱动注册和操作接口。这样将camera驱动和配置全部抽离到用户空间,不需要重新编译和调试内核,极大的简化了camera的移植和调试。

    ​ 除USB摄像头走v4l2之外,其余类型的摄像头均走RK自己定义的一套公共Camera驱动接口。

    • CameraUSBAdapter: USB接口类型的摄像头,走v4l2.
    • CameraIspSOCAdapter:dvp接口,isp控制器接收。
    • CameraIspAdapter:mipi接口,isp控制器接收,不走v4l2.
    • CameraSOCAdapter:dvp接口,VIP控制器接收。

    重要数据结构

    数据结构

    //isp设备描述结构体
    typedef struct camsys_dev_s {
        unsigned int          dev_id;
        camsys_irq_t          irq;
        camsys_devmems_t      devmems;
        struct miscdevice     miscdev;
        void                  *clk;
        camsys_phyinfo_t      *mipiphy;
        camsys_phyinfo_t      cifphy;
    
        camsys_exdevs_t       extdevs;
        struct list_head      list;
        struct platform_device *pdev;
    
        void                  *soc;
    
        camsys_meminfo_t     *csiphy_reg;
        camsys_meminfo_t     *dsiphy_reg;
        camsys_meminfo_t     *isp0_reg;
    
        unsigned long         rk_grf_base;
        unsigned long         rk_cru_base;
        unsigned long         rk_isp_base;
        atomic_t              refcount;
        struct iommu_domain *domain;
        camsys_dma_buf_t dma_buf[CAMSYS_DMA_BUF_MAX_NUM];
        int dma_buf_cnt;
    
        int (*clkin_cb)(void *ptr, unsigned int on);
        int (*clkout_cb)(void *ptr, unsigned int on, unsigned int clk);
        int (*reset_cb)(void *ptr, unsigned int on);
    
        int (*phy_cb)
            (camsys_extdev_t *extdev,
            camsys_sysctrl_t *devctl, void *ptr);
        int (*iomux)(camsys_extdev_t *extdev, void *ptr);
        int (*platform_remove)(struct platform_device *pdev);
        int (*flash_trigger_cb)(void *ptr, int mode, unsigned int on);
        int (*iommu_cb)(void *ptr, camsys_sysctrl_t *devctl);
    } camsys_dev_t;
    
    //内存信息描述结构体
    typedef struct camsys_meminfo_s {
        unsigned char name[32];
        unsigned long phy_base;
        unsigned long vir_base;
        unsigned int size;
        unsigned int vmas;
        struct list_head list;
    } camsys_meminfo_t;
    
    //phy信息描述结构体
    typedef struct camsys_phyinfo_s {
        unsigned int             phycnt;
        void                     *clk;
        camsys_meminfo_t         *reg;
        int (*clkin_cb)(void *ptr, unsigned int on);
        int (*ops)(void *ptr, camsys_mipiphy_t *phy);
        int (*remove)(struct platform_device *pdev);
    } camsys_phyinfo_t;
    
    //中断连接描述结构体
    typedef struct camsys_irqcnnt_s {
        int          pid;
        unsigned int timeout;             //us
    
        unsigned int mis;
        unsigned int icr;
    } camsys_irqcnnt_t;
    

    ioctl codes

    IOCTL CODES 说明
    CAMSYS_VERCHK 检查驱动版本和头文件版本
    CAMSYS_I2CRD 读i2c寄存器
    CAMSYS_I2CWR 写i2c寄存器
    CAMSYS_SYSCTRL sysctl控制(vdd,gpio,clk,phyflash,iommu)
    CAMSYS_REGRD
    CAMSYS_REGWR
    CAMSYS_REGISTER_DEVIO 注册camera
    CAMSYS_DEREGISTER_DEVIO 注销camera
    CAMSYS_IRQCONNECT 中断连接
    CAMSYS_IRQWAIT 中断等待
    CAMSYS_IRQDISCONNECT 中断断开
    CAMSYS_QUREYMEM 查询i2c或寄存器映射
    CAMSYS_QUREYIOMMU 查询是否是能IOMMU

    rk_camsys

    ISP

    camsys_platform_probe(struct platform_device *pdev) //ISP probe
        -->camsys_soc_init(CHIP_TYPE);     //根据CHIP_TYPE 选择对应的配置函数
           -->camsys_soc_p->soc_cfg = camsys_rk3399_cfg;
        --->irq_id = irq_of_parse_and_map(dev->of_node, 0); //映射中断
       ---->    INIT_LIST_HEAD(&camsys_dev->extdevs.list);   //初始化camera 链表(支持两个camera)
        ---->  INIT_LIST_HEAD(&camsys_dev->extdevs.active);  //初始化打开设备链表
        ---->  INIT_LIST_HEAD(&camsys_dev->list);   //初始化isp链表(支持两个isp)
       //注册mipiphy驱动
        if (camsys_mipiphy_probe_cb(pdev, camsys_dev) < 0) {
                camsys_err("Mipi phy probe failed!");
            }
       //注册camsys_marvin驱动
         camsys_mrv_probe_cb(pdev, camsys_dev);
      //初始化ext flash链表
        camsys_init_ext_fsh_module();
    

    mipiphy

    主要填充camsys_phyinfo_s结构体

    //获取mipiphy数量
    err = of_property_read_u32(dev->of_node,"rockchip,isp,mipiphy", &mipiphy_cnt);
    
    //初始化meminfo
    camsys_dev->mipiphy[i].reg = meminfo;
    
    //初始化clk
    camsys_dev->mipiphy[i].clk = (void *)phyclk;
    
    //初始化成员函数
    camsys_dev->mipiphy[i].phycnt = mipiphy_cnt;
    camsys_dev->mipiphy[i].clkin_cb = camsys_mipiphy_clkin_cb;
    camsys_dev->mipiphy[i].ops = camsys_mipiphy_ops;
    camsys_dev->mipiphy[i].remove = camsys_mipiphy_remove_cb;
    
    //获取cru基址
    camsys_dev->rk_cru_base = (unsigned long)of_iomap(node, 0);
    
    //获取grf基址
    camsys_dev->rk_grf_base = (unsigned long)of_iomap(node, 0);
    

    camsys_marvin

    struct file_operations camsys_fops = {
        .owner =            THIS_MODULE,
        .open =          camsys_open,
        .release =        camsys_release,
        .unlocked_ioctl =   camsys_ioctl,
        .mmap =          camsys_mmap,
        .compat_ioctl = camsys_ioctl_compat,
    };
    
    camsys_mrv_probe_cb
        -->err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq,   //申请中断
                        IRQF_SHARED, CAMSYS_MARVIN_IRQNAME,
                        camsys_dev);
        ---> pm_runtime_enable(&pdev->dev); //使能pm
        ---> clk_set_rate(mrv_clk->isp, 210000000); //初始化clk
            clk_set_rate(mrv_clk->isp_jpe, 210000000); 
       ---->domain = iommu_domain_alloc(&platform_bus_type); //根据bus type配domain
       -----> err = iommu_get_dma_cookie(domain);  //根据domain获取DMA-API资源
       --->group = iommu_group_alloc(); //分配一个group
       ---->err = iommu_group_add_device(group, &pdev->dev); //将dev添加到IOMMU group
       ----> camsys_dev->iommu_cb = camsys_mrv_drm_iommu_cb; // dma_buf map
       -----> err = misc_register(&camsys_dev->miscdev); //注册杂项设备camsys_marvin1
       ---->camsys_dev->dev_id = CAMSYS_DEVID_MARVIN;   //初始化dev_id
        camsys_dev->platform_remove = camsys_mrv_remove_cb;  //初始化probe_remove函数
    

    ext_flash

    重要结构体

    struct rt8547_platform_data {
        int flen_gpio;
        int flen_active;
        int ctl_gpio;
        int ctl_active;
        int flset_gpio;
        int flset_active;
        unsigned char def_lvp:4;
        unsigned char def_tol:3;
    };
    
    typedef struct ext_fsh_info_s{
        struct      platform_device pdev;
        char*       dev_model;    
        struct      list_head         list;
    }ext_fsh_info_t;
    

    注册flash dev(rt8547)

    camsys_register_ext_fsh_dev  //CAMSYS_REGISTER_DEVIO 中注册
        --->platform_device_register(&new_dev->pdev) //注册rt8547平台驱动
        ---->list_add_tail(&new_dev->list, &g_ext_fsh_devs.dev_list); //将flash设备添加到链表
    

    flash ctrl

    mode:
        0:  CAM_ENGINE_FLASH_OFF = 0x00,
        1:  CAM_ENGINE_FLASH_AUTO = 0x01,
        2:  CAM_ENGINE_FLASH_ON = 0x02,
        3:  CAM_ENGINE_FLASH_RED_EYE = 0x03,
        5:  CAM_ENGINE_FLASH_TORCH = 0x05
    

    个人博客:https://www.letcos.top/

    相关文章

      网友评论

          本文标题:[Camera]RK平台摄像头驱动

          本文链接:https://www.haomeiwen.com/subject/tabjfhtx.html