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
网友评论