<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          MTK Camera驅(qū)動(dòng)上電與初始化

          共 7863字,需瀏覽 16分鐘

           ·

          2021-03-26 08:00

          和你一起終身學(xué)習(xí),這里是程序員Android

          經(jīng)典好文推薦,通過閱讀本文,您將收獲以下知識點(diǎn):

          一、概序

          這篇主要介紹紅框部分的內(nèi)容:

          程序員Android 轉(zhuǎn)于網(wǎng)絡(luò)

          imgsensor起到承上啟下的作用,在系統(tǒng)起來時(shí)會(huì)創(chuàng)建整個(gè)camera驅(qū)動(dòng)運(yùn)行的環(huán)境,其中主要的文件和函數(shù)如下框圖所示,先通過platform_driver_register函數(shù)注冊platform設(shè)備,在匹配成功后會(huì)調(diào)用probe函數(shù)進(jìn)行初始相關(guān)的設(shè)備:

          程序員Android 轉(zhuǎn)于網(wǎng)絡(luò)

          其中camera的三路電壓的上電方式可以通過GPIO來控制,也可以通過PMIC(REGULATOR)的方式來進(jìn)行控制,在imgsensor_hw中通過不同的pdev信息,調(diào)用不同的set函數(shù)。涉及的文件路徑:

          kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor.c
          kernel-4.9/drivers/misc/mediatek/imgsensor/src/common/v1/imgsensor_hw.c
          kernel-4.9/drivers/misc/mediatek/imgsensor/src/mt6765/camera_hw/regulator/regulator.c
          kernel-4.9/drivers/misc/mediatek/imgsensor/src/mt6765/camera_hw/gpio/gpio.c

          二、上電相關(guān)的結(jié)構(gòu)體之間的聯(lián)系

          (1) IMGSENSOR_HW結(jié)構(gòu)體:

          IMGSENSOR_HW結(jié)構(gòu)體包含了pdev(gpio/regulator)的設(shè)備結(jié)構(gòu)體和上電時(shí)序相關(guān)的結(jié)構(gòu)體:

          程序員Android 轉(zhuǎn)于網(wǎng)絡(luò)

          (2) 上電時(shí)序控制相關(guān):

          上電方式控制: GPIO? REGULATOR?

          程序員Android 轉(zhuǎn)于網(wǎng)絡(luò)

          上電時(shí)序控制結(jié)構(gòu)體:

          程序員Android 轉(zhuǎn)于網(wǎng)絡(luò)

          三、系統(tǒng)初始化:

          1、設(shè)備加載:

          imgsensor和其他的驅(qū)動(dòng)模塊相同,也是通過module_init來初始化模塊,在init中注冊platform總線驅(qū)動(dòng),從而需要對應(yīng)的platform_driver結(jié)構(gòu)體信息:

          static const struct of_device_id gimgsensor_of_device_id[] = {
          { .compatible = "mediatek,camera_hw", },
          {}
          };

          static struct platform_driver gimgsensor_platform_driver = {
          .probe = imgsensor_probe,
          .remove = imgsensor_remove,
          .suspend = imgsensor_suspend,
          .resume = imgsensor_resume,
          .driver = {
          .name = "image_sensor",
          .owner = THIS_MODULE,
          #ifdef CONFIG_OF
          .of_match_table = gimgsensor_of_device_id,
          #endif
          }
          };

          當(dāng)gimgsensor_of_device_id的信息在dtsmatch上以后回調(diào)執(zhí)行到對應(yīng)的probe函數(shù),probe中主要注冊了sensor drv的字符設(shè)備和初始化imgsensor的硬件信息(時(shí)鐘及上電):

          static int imgsensor_probe(struct platform_device *pdev)
          {
          /* Register char driver */
          imgsensor_driver_register();

          gpimgsensor_hw_platform_device = pdev;

          imgsensor_clk_init(&pgimgsensor->clk);
          imgsensor_hw_init(&pgimgsensor->hw);
          imgsensor_i2c_create();
          imgsensor_proc_init();

          atomic_set(&pgimgsensor->imgsensor_open_cnt, 0);
          return 0;
          }

          2、imgsensor_driver_register創(chuàng)建字符設(shè)備

          //字符設(shè)備的file_operation結(jié)構(gòu)體
          static const struct file_operations gimgsensor_file_operations = {
          .owner = THIS_MODULE,
          .open = imgsensor_open,
          .release = imgsensor_release,
          .unlocked_ioctl = imgsensor_ioctl,
          #ifdef CONFIG_COMPAT
          .compat_ioctl = imgsensor_compat_ioctl
          #endif
          };

          static inline int imgsensor_driver_register(void){
          //分配一個(gè)設(shè)備號和nanme
          alloc_chrdev_region(&dev_no, 0, 1, IMGSENSOR_DEV_NAME)

          /* Allocate driver */
          gpimgsensor_cdev = cdev_alloc();

          /* Attatch file operation. */
          cdev_init(gpimgsensor_cdev, &gimgsensor_file_operations);

          /* Add to system */
          cdev_add(gpimgsensor_cdev, dev_no, 1);

          gpimgsensor_class = class_create(THIS_MODULE, "sensordrv");

          device_create(gpimgsensor_class, NULL, dev_no, NULL, IMGSENSOR_DEV_NAME);
          }

          3、imgsensor_clk_init 時(shí)鐘初始化:

          enum IMGSENSOR_RETURN imgsensor_clk_init(struct IMGSENSOR_CLK *pclk)
          {
          int i;
          struct platform_device *pplatform_dev = gpimgsensor_hw_platform_device;

          /* get all possible using clocks */
          for (i = 0; i < IMGSENSOR_CCF_MAX_NUM; i++)
          pclk->imgsensor_ccf[i] =
          devm_clk_get(&pplatform_dev->dev, gimgsensor_mclk_name[i]);

          return IMGSENSOR_RETURN_SUCCESS;
          }

          4、imgsensor_hw_init電壓初始化:

          (1) 依次調(diào)用GPIO/REGULATOR/MCLKinit接口;

          (2) 解析出imgsensor_custom_config,獲取到對應(yīng)sensor的對應(yīng)管腳(DVDD/AVDD...)的上電方式(GPIO/REGULATOR);

          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];
          struct device_node *of_node
          = of_find_compatible_node(NULL, NULL, "mediatek,camera_hw");
          //依次調(diào)用GPIO/REGULATOR/MCLK的init接口;
          for (i = 0; i < IMGSENSOR_HW_ID_MAX_NUM; i++) {
          if (hw_open[i] != NULL)
          (hw_open[i])(&phw->pdev[i]);

          if (phw->pdev[i]->init != NULL)
          (phw->pdev[i]->init)(phw->pdev[i]->pinstance);
          }
          //解析出imgsensor_custom_config
          for (i = 0; i < IMGSENSOR_SENSOR_IDX_MAX_NUM; i++) {
          psensor_pwr = &phw->sensor_pwr[i];

          pcust_pwr_cfg = imgsensor_custom_config;//上電時(shí)序
          while (pcust_pwr_cfg->sensor_idx != i)
          pcust_pwr_cfg++;

          //退出循環(huán)
          if (pcust_pwr_cfg->sensor_idx == IMGSENSOR_SENSOR_IDX_NONE)
          continue;

          //ppwr_info對應(yīng){IMGSENSOR_HW_ID_GPIO, IMGSENSOR_HW_PIN_AVDD}
          ppwr_info = pcust_pwr_cfg->pwr_info;

          while (ppwr_info->pin != IMGSENSOR_HW_PIN_NONE) {
          //查詢imgsensor_custom_config中ID_PIN 是否在GPIO/REGULATOR/Mclk中?
          for (j = 0; j < IMGSENSOR_HW_ID_MAX_NUM; j++){
          if (ppwr_info->id == phw->pdev[j]->id)
          break;
          }
          //將對應(yīng)sensor的對應(yīng)PIN(DVDD/AVDD...)設(shè)置為系統(tǒng)的ID_PIN(GPIO/REGULATOR/MCKL)
          psensor_pwr->id[ppwr_info->pin] = j;
          ppwr_info++;
          }
          }

          //判斷dts中是否設(shè)定對應(yīng)的index為對應(yīng)的name,如:cam3_enable_sensor = "gc2375hmain3_mipi_raw";
          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;
          }

          5、imgsensor_i2c_create I2C設(shè)備初始化:

          enum IMGSENSOR_RETURN imgsensor_i2c_create(void)
          {
          int i;

          for (i = 0; i < IMGSENSOR_I2C_DEV_MAX_NUM; i++)
          i2c_add_driver(&gi2c_driver[i]);

          return IMGSENSOR_RETURN_SUCCESS;
          }

          6、具體類型的上電介紹(以pmic控制的regulator方式為例)

          前面imgsensor_hw_init中有去調(diào)用imgsensor_hw_regulator_openregulator_init

          (1) 傳入對應(yīng)的設(shè)備的device結(jié)構(gòu)體

          static struct IMGSENSOR_HW_DEVICE device = {
          .pinstance = (void *)&reg_instance,
          .init = regulator_init,//開機(jī)初始化時(shí)調(diào)用
          .set = regulator_set,//在上電設(shè)置電壓時(shí)會(huì)調(diào)用
          .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;
          }

          (2) 調(diào)用對應(yīng)的init進(jìn)行初始化

          因?yàn)?code style="box-sizing: border-box;font-size: 12px;font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;padding: 2px 4px;border: none;vertical-align: middle;white-space: pre-wrap;color: rgb(199, 37, 78);background-color: rgb(242, 242, 242);">MTK平臺(tái)的PMIC上電是通過統(tǒng)一的REGULATOR進(jìn)行統(tǒng)一管理的,每一種上電方式需要申請對應(yīng)typeregulator控制的結(jié)構(gòu)體,才可以來進(jìn)行設(shè)置:

          enum REGULATOR_TYPE {
          REGULATOR_TYPE_VCAMA,
          REGULATOR_TYPE_VCAMD,
          REGULATOR_TYPE_VCAMIO,
          REGULATOR_TYPE_MAX_NUM
          };

          static enum IMGSENSOR_RETURN regulator_init(void *pinstance)
          {
          struct REGULATOR *preg = (struct REGULATOR *)pinstance;
          struct device *pdevice;
          struct device_node *pof_node;
          int j, i;
          char str_regulator_name[LENGTH_FOR_SNPRINTF];

          pdevice = gimgsensor_device;

          for (j = IMGSENSOR_SENSOR_IDX_MIN_NUM;j < IMGSENSOR_SENSOR_IDX_MAX_NUM;j++) {
          for (i = 0; i < REGULATOR_TYPE_MAX_NUM; i++) {
          snprintf(str_regulator_name,
          sizeof(str_regulator_name),
          "cam%d_%s", j,
          regulator_control[i].pregulator_type);
          preg->pregulator[j][i] =
          regulator_get(pdevice, str_regulator_name);

          if (preg->pregulator[j][i] == NULL)
          pr_err("regulator[%d][%d] %s fail!\n",
          j, i, str_regulator_name);

          atomic_set(&preg->enable_cnt[j][i], 0);
          }
          }
          pdevice->of_node = pof_node;
          imgsensor_oc_init();
          return IMGSENSOR_RETURN_SUCCESS;
          }

          到這里imgsensor部分的內(nèi)容,就還有對上(hal層)承接的ioctl相關(guān)的內(nèi)容沒有介紹,這部分的內(nèi)容會(huì)在后續(xù)的整個(gè)系統(tǒng)調(diào)用流程中進(jìn)行梳理。

          友情推薦:

          Android 開發(fā)干貨集錦

          至此,本篇已結(jié)束。轉(zhuǎn)載網(wǎng)絡(luò)的文章,小編覺得很優(yōu)秀,歡迎點(diǎn)擊閱讀原文,支持原創(chuàng)作者,如有侵權(quán),懇請聯(lián)系小編刪除,歡迎您的建議與指正。同時(shí)期待您的關(guān)注,感謝您的閱讀,謝謝!

          點(diǎn)個(gè)在看,方便您使用時(shí)快速查找!

          瀏覽 101
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产五月天婷婷 | 成人无码做爱视频 | 不卡高清无码在线 | 久久免费短视频 | 大鸡巴免费在线观看 |