一.主要文件

kernel-4.19/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_hw.c

1.1 主要函数

imgsensor_hw.c共计就四个函数:

  • imgsensor_hw_init
  • imgsensor_hw_power
  • imgsensor_hw_power_sequence
  • imgsensor_hw_release_all

看名字就可以知道函数实现的功能。

1.2 上电相关的结构体

  • pdev[IMGSENSOR_HW_ID_MAX_NUM]这个结构体指针数组用来保存控制上电方式的设备(gpio/regulator)和控制时钟相关的设备,这个结构主要保存了一些函数指针,用来调用设备的init、set等方法。

  • sensor_pwr[IMGSENSOR_SENSOR_IDX_MAX_NUM]用来保存上电方式和上电顺序等信息,这是一个数组,可以保存多个sensor的信息。
    ppwr_info保存pin的信息,比如状态,延迟等,指针类型,通过加减操作移动到下一个位置,和数组差不多,能保存多个pin。
    id[]数组用来保存每个pin的上电方式。

二.上电流程

2.1 imgsensor_hw_init()

在probe()函数中已经初始化上电所需要的信息,用到了imgsensor_hw_init()函数:

enum IMGSENSOR_RETURN imgsensor_hw_init(struct IMGSENSOR_HW *phw) {struct IMGSENSOR_HW_SENSOR_POWER *psensor_pwr;struct IMGSENSOR_HW_CFG *pcust_pwr_cfg;struct IMGSENSOR_HW_CUSTOM_POWER_INFO *ppwr_info;int i, j;char str_prop_name[LENGTH_FOR_SNPRINTF];//LENGTH_FOR_SNPRINTF 256struct device_node *of_node= of_find_compatible_node(NULL, NULL, "mediatek,camera_hw");/* 初始化pdev数组,绑定上电和时钟控制设备 */for (i = 0; i < IMGSENSOR_HW_ID_MAX_NUM; i++) {//IMGSENSOR_HW_ID_MAX_NUM 3if (hw_open[i] != NULL)(hw_open[i])(&phw->pdev[i]);if (phw->pdev[i]->init != NULL)(phw->pdev[i]->init)(phw->pdev[i]->pinstance);}for (i = 0; i < IMGSENSOR_SENSOR_IDX_MAX_NUM; i++) {//IMGSENSOR_SENSOR_IDX_MAX_NUM 3psensor_pwr = &phw->sensor_pwr[i];pcust_pwr_cfg = imgsensor_custom_config;while (pcust_pwr_cfg->sensor_idx != i &&pcust_pwr_cfg->sensor_idx != IMGSENSOR_SENSOR_IDX_NONE)//IMGSENSOR_SENSOR_IDX_NONE 6pcust_pwr_cfg++;if (pcust_pwr_cfg->sensor_idx == IMGSENSOR_SENSOR_IDX_NONE)continue;ppwr_info = pcust_pwr_cfg->pwr_info;while (ppwr_info->pin != IMGSENSOR_HW_PIN_NONE) {//IMGSENSOR_HW_PIN_NONE 0for (j = 0; j < IMGSENSOR_HW_ID_MAX_NUM; j++)//IMGSENSOR_HW_ID_MAX_NUM 3if (ppwr_info->id == phw->pdev[j]->id)break;psensor_pwr->id[ppwr_info->pin] = j;ppwr_info++;}}/* 读设备树,? */for (i = 0; i < IMGSENSOR_SENSOR_IDX_MAX_NUM; i++) {memset(str_prop_name, 0, sizeof(str_prop_name));snprintf(str_prop_name,sizeof(str_prop_name),"cam%d_%s",i,"enable_sensor");if (of_property_read_string(of_node,str_prop_name,&phw->enable_sensor_by_index[i]) < 0) {pr_info("Property cust-sensor not defined\n");phw->enable_sensor_by_index[i] = NULL;}}return IMGSENSOR_RETURN_SUCCESS;
}

分析这个函数,依次做了下面这些事:

1.第一个for循环初始化了pdev数组,绑定上电和时钟控制设备。程序中hw_open数组定义如下:

enum IMGSENSOR_RETURN
(*hw_open[IMGSENSOR_HW_ID_MAX_NUM])(struct IMGSENSOR_HW_DEVICE **) = {imgsensor_hw_regulator_open,imgsensor_hw_gpio_open,imgsensor_hw_mclk_open
};

也就是保存了三个函数指针,调用这三个函数就可以初始化pdev数组,例如imgsensor_hw_regulator_open()函数定义如下:

static struct IMGSENSOR_HW_DEVICE device = {.pinstance = (void *) &reg_instance,.init      = regulator_init,.set       = regulator_set,.release   = regulator_release,.id        = IMGSENSOR_HW_ID_REGULATOR
};enum IMGSENSOR_RETURN imgsensor_hw_regulator_open(struct IMGSENSOR_HW_DEVICE **pdevice) {*pdevice = &device;return IMGSENSOR_RETURN_SUCCESS;
}

可以看到就是绑定了一些操作函数,通过对某个pin脚调用set函数就可以完成对它的上电操作。

2.第二个for循环是为sensor设置上电顺序,前面提到的enum IMGSENSOR_HW_ID id[IMGSENSOR_HW_PIN_MAX_NUM]数组就保存了当前sensor引脚的上电方式。

分析代码,这里有一个数组imgsensor_custom_config[ ],它的作用是配置sensor每个引脚的上电方式,在imgsensor_cfg_table.c中:

struct IMGSENSOR_HW_CFG imgsensor_custom_config[] = {{IMGSENSOR_SENSOR_IDX_MAIN,//sensor_idIMGSENSOR_I2C_DEV_0,//sensor_i2c dev{           //上电方式                                      pin脚{IMGSENSOR_HW_ID_MCLK, IMGSENSOR_HW_PIN_MCLK},{IMGSENSOR_HW_ID_REGULATOR, IMGSENSOR_HW_PIN_AVDD},{IMGSENSOR_HW_ID_REGULATOR, IMGSENSOR_HW_PIN_DOVDD},{IMGSENSOR_HW_ID_GPIO,      IMGSENSOR_HW_PIN_DVDD},{IMGSENSOR_HW_ID_GPIO, IMGSENSOR_HW_PIN_PDN},{IMGSENSOR_HW_ID_GPIO, IMGSENSOR_HW_PIN_RST},{IMGSENSOR_HW_ID_NONE, IMGSENSOR_HW_PIN_NONE},},},/* 省略部分代码 */
};

首先通过第一个while循环将sensorid和当前要操作的sensor对应起来,然后通过第二个while循环来拿到imgsensor_custom_config[]中的上电方式,将这个上电方式与一开始初始化的pdev中的设备对应起来,得到pdev对应设备的索引 j ,最后通过赋值操作把上电方式和引脚保存到enum IMGSENSOR_HW_ID id[IMGSENSOR_HW_PIN_MAX_NUM]这个数组中,匹配结果如下:

3.最后一个for循环读设备树,读到的是sensor的名字,在后面imgsensor_hw_power()函数会进行字符串匹配验证,这里的作用以后在探究。

2.2imgsensor_hw_power()

就是用来上电的函数:

enum IMGSENSOR_RETURN imgsensor_hw_power(struct IMGSENSOR_HW *phw,struct IMGSENSOR_SENSOR *psensor,char *curr_sensor_name,enum IMGSENSOR_HW_POWER_STATUS pwr_status) {enum IMGSENSOR_SENSOR_IDX sensor_idx = psensor->inst.sensor_idx;char str_index[LENGTH_FOR_SNPRINTF];int ret = 0;pr_info("sensor_idx %d, power %d curr_sensor_name %s, enable list %s\n",sensor_idx,pwr_status,curr_sensor_name,phw->enable_sensor_by_index[(uint32_t) sensor_idx] == NULL? "NULL": phw->enable_sensor_by_index[(uint32_t) sensor_idx]);if (phw->enable_sensor_by_index[(uint32_t) sensor_idx] &&!strstr(phw->enable_sensor_by_index[(uint32_t) sensor_idx], curr_sensor_name))return IMGSENSOR_RETURN_ERROR;ret = snprintf(str_index, sizeof(str_index), "%d", sensor_idx);if (ret == 0) {pr_info("Error! snprintf allocate 0");ret = IMGSENSOR_RETURN_ERROR;return ret;}imgsensor_hw_power_sequence(phw,sensor_idx,pwr_status,platform_power_sequence,str_index);imgsensor_hw_power_sequence(phw,sensor_idx,pwr_status,sensor_power_sequence,curr_sensor_name);return IMGSENSOR_RETURN_SUCCESS;
}

这个函数主要就调用了imgsensor_hw_power_sequence(),这里调用了两次,主要是第四个参数不同,platform_power_sequence[]配置的是平台上电顺序,sensor_power_sequence[]配置的是sensor上电顺序,它们都在imgsensor_cfg_table.c中。在某个sensor上电的时候会匹配上其中一种进行上电。

2.3 imgsensor_hw_power_sequence()

static enum IMGSENSOR_RETURN imgsensor_hw_power_sequence(struct IMGSENSOR_HW *phw,enum IMGSENSOR_SENSOR_IDX sensor_idx,enum IMGSENSOR_HW_POWER_STATUS pwr_status,struct IMGSENSOR_HW_POWER_SEQ *ppower_sequence,char *pcurr_idx) {struct IMGSENSOR_HW_SENSOR_POWER *psensor_pwr =&phw->sensor_pwr[sensor_idx];struct IMGSENSOR_HW_POWER_SEQ *ppwr_seq = ppower_sequence;struct IMGSENSOR_HW_POWER_INFO *ppwr_info;struct IMGSENSOR_HW_DEVICE *pdev;int pin_cnt = 0;/* 匹配上电的方式,是platform还是sensor */while (ppwr_seq < ppower_sequence + IMGSENSOR_HW_SENSOR_MAX_NUM &&ppwr_seq->name != NULL) {if (!strcmp(ppwr_seq->name, PLATFORM_POWER_SEQ_NAME)) {if (sensor_idx == ppwr_seq->_idx)break;} else {if (!strcmp(ppwr_seq->name, pcurr_idx))break;}ppwr_seq++;}if (ppwr_seq->name == NULL) {return IMGSENSOR_RETURN_ERROR;}ppwr_info = ppwr_seq->pwr_info;/* 依次为pin上电 */while (ppwr_info->pin != IMGSENSOR_HW_PIN_NONE &&ppwr_info < ppwr_seq->pwr_info + IMGSENSOR_HW_POWER_INFO_MAX) {if (pwr_status == IMGSENSOR_HW_POWER_STATUS_ON &&ppwr_info->pin != IMGSENSOR_HW_PIN_UNDEF) {/* 匹配上电的设备,是gpio还是regulator等等 */pdev = phw->pdev[psensor_pwr->id[ppwr_info->pin]];if (pdev->set != NULL)/* 调用设备的set()进行上电 */pdev->set(pdev->pinstance,sensor_idx,ppwr_info->pin,ppwr_info->pin_state_on);mdelay(ppwr_info->pin_on_delay);}ppwr_info++;pin_cnt++;}/* 下电方式类似 */if (pwr_status == IMGSENSOR_HW_POWER_STATUS_OFF) {while (pin_cnt) {ppwr_info--;pin_cnt--;if (ppwr_info->pin != IMGSENSOR_HW_PIN_UNDEF) {pdev =phw->pdev[psensor_pwr->id[ppwr_info->pin]];mdelay(ppwr_info->pin_on_delay);if (pdev->set != NULL)pdev->set(pdev->pinstance,sensor_idx,ppwr_info->pin,ppwr_info->pin_state_off);}}}/* wait for power stable */if (pwr_status == IMGSENSOR_HW_POWER_STATUS_ON)mdelay(5);return IMGSENSOR_RETURN_SUCCESS;
}

这里匹配上电的设备就用到了上面那个id[]数组,通过pin的序号拿到其上电所需要的对应的设备,然后set即可完成上电。

暂时写到这里,别的后面在写,希望大家提出意见,共同学习。

MTK camera驱动浅析(2)相关推荐

  1. MTK Camera驱动移植

    对于MTK Camera驱动移植一般分为四部分: 1.硬件IO口配置: 2.Camera驱动移植: 3.上电时序: 4.修改i2c控制器: 硬件电路: 1.GPIO配置 打开 mediatek\dct ...

  2. Camera5 MTK camera驱动框架介绍

    一.概序: 前文已经介绍了camera驱动部分的内容Camera4 MTK camera驱动结构介绍,这里在回顾下之前的框架图, 这篇主要介绍红框部分的内容: imgsensor起到承上启下的作用,在 ...

  3. Camera4 MTK camera驱动结构介绍

    一.概述: MTK  camera主要的内容在hal层,现在有hal1/hal3,当下主流的使用的是hal3,驱动主要负责sensor 电源的控制以及sensor相关寄存器的操作,MTK采用设备和驱动 ...

  4. Android MTK Camera驱动代码分析

    一.Camera调用过程:      imgsensor起到承上启下的作用,在系统起来时会创建整个camera驱动运行的环境,其中主要的文件和函数如下框图所示,先设备挂载时会调用注册platform设 ...

  5. Android Camera驱动开发入门必备知识

    camera驱动开发所需要具备基础知识,如果你还没有了解过camera模块,那么这些基础必备的知识,将会对你比较有用,俗话说"磨刀不误砍柴工",基本功配置好了,相信你在做camer ...

  6. MTK平台开机初始化时 camera驱动流程|MTK camera调试常见几十种问题处理方法

    转载:https://www.jianshu.com/p/75ab1d82bbd3 mtk的驱动多是以模块加载的方式(module_init():module_exit():)加载到内核中去的:正因为 ...

  7. 【Mtk Camera Hal到驱动的流程(1)】

    Mtk Camera Hal到驱动的流程(1) (1)架构介绍 (A)Camera 的框架分为 Kernel 部分和 Hal 部分 Kernel部分: image sensor driver -- 负 ...

  8. mtk android tv软件架构,MTK 平台Camera 驱动架构

    Platform_driver 这个结构体包含 Probe(). Remove()等函数来完成驱动的填充. b)设备的注册: 对 platform_device 的定义通常在 BSP 的板级文件( k ...

  9. mtk camera 移植步骤

    mtk camera 移植步骤: 1, Kernel层驱动代码文件添加 /mediatek/custom/doov92_wet_tdd/kernel/imgsensor/下添加imx179_mipi_ ...

最新文章

  1. 理解koa-router 路由一般使用
  2. [No000039]操作系统Operating Systems用户级线程User Threads
  3. 根据卡号获取银行卡名字
  4. proe输入数字时成双出现_罗斯蒙特温度变送器3144P单只和双只输入输出的的含义...
  5. openssl/ssl.h file not found mac 完美解决
  6. 单片机C语言拉高1位,第二讲 单片机C语言之12864液晶显示
  7. Python 列表拷贝
  8. LVS+Keepalived实现负载均衡和双机热备
  9. HDU 3590 PP and QQ(反nim博弈,删边游戏)
  10. http抓包神器:Charles for Mac 特别版v4.6
  11. oracle——监听(一、多实例监听配置)
  12. Python Day2
  13. 采集gpu_GPU是怎么处理游戏画面?一文看懂显卡的工作原理,原来这么简单
  14. ADB登录验证暴力破解工具
  15. html自动刷新插件谷歌,Super Auto Refresh:定时自动重新刷新网页
  16. 如何录用有竞业限制协议的员工?
  17. linux 重启网卡报错 RTNETLINK answers: File exists”的解决方法
  18. 联想台式电脑修复计算机,处理联想一键恢复电脑系统教程
  19. 9元包一年 阿里宝与腾讯王卡10G/月全国流量
  20. 最佳实践|如何写出简单高效的 Flink SQL?

热门文章

  1. 优品课堂python下载_Python 网络爬虫数据采集 【优品课堂】
  2. 固定资产管理php,PHPOA系统让固定资产管理不再困难
  3. 【PS/PSD】冬季中国风鸟类水墨写意素材
  4. 兄弟连兄弟会前端好不好
  5. K8s:渐进式入门服务网格 Istio (一)
  6. 3w最简单led灯电路图_led灯驱动电源电路图大全(六款模拟电路设计原理图详解) - 全文...
  7. 吭吭唧唧写shader--实现一个模型在屏幕指定区域的渲染
  8. 浅谈软件测试常见概念【小鸡崽可以看看反正不亏】
  9. 郑州航空工业管理学院计算机就业怎么样,郑州航空工业管理学院什么专业工资最高?...
  10. grub美化的一些方法