flashlight驱动和HAL分析

一.HAL层分析
Flash_cct.cpp (vendor\mediatek\proprietary\hardware\mtkcam\legacy\platform\mt6735\hal\aaa\flash_mgr)

1.初始化
int FlashlightDrv::init()
    init_real
        err = pKDrv->init(mSensorDev, mStrobeId);
            //Strobe_global_driver.cpp (vendor\mediatek\proprietary\hardware\mtkcam\legacy\platform\mt6735\core\featureio\drv\strobe)
           StrobeGlobalDriver::init(int sensorDev, int strobeId)
               openkd_nolock(); //打开设备
                   mStrobeHandle = open(STROBE_DEV_NAME, O_RDWR); //打开/dev/kd_camera_flashlight
               sendCommand_nolock(FLASHLIGHTIOC_X_SET_DRIVER, sensorDev, strobeId, 0);
                   return ioctl(mStrobeHandle, cmd, &stbArg); //发送 FLASHLIGHTIOC_X_SET_DRIVER

2.开关闪光灯
FlashlightDrv::setOnOff(int a_isOn)
    err = getPreOnTimeMsDuty(m_duty, &minPreOnTime); //这里是空
    err = pKDrv->sendCommand(FLASH_IOC_SET_ONOFF, mSensorDev, mStrobeId, 1); //打开闪关灯




二.平台驱动分析
Kd_flashlightlist.c (kernel-3.18\drivers\misc\mediatek\flashlight\src\mt6735)

1.初始化
#ifdef CONFIG_OF
static const struct of_device_id FLASHLIGHT_of_match[] = {
{.compatible = "mediatek,mt6755-flashlight"},
{},
};
#endif

static struct platform_driver flashlight_platform_driver = {
.probe = flashlight_probe,
.remove = flashlight_remove,
.shutdown = flashlight_shutdown,
.driver = {
  .name = FLASHLIGHT_DEVNAME,
  .owner = THIS_MODULE,
#ifdef CONFIG_OF
.of_match_table = FLASHLIGHT_of_match,
#endif
  },
};
static struct platform_device flashlight_platform_device = {
.name = FLASHLIGHT_DEVNAME,
.id = 0,
.dev = {
}
};


flashlight_init
    ret = platform_device_register(&flashlight_platform_device);
    ret = platform_driver_register(&flashlight_platform_driver);  //匹配进入flashlight_probe函数


2.flashlight_probe函数
static const struct file_operations flashlight_fops = {
.owner = THIS_MODULE,
.unlocked_ioctl = flashlight_ioctl,
.open = flashlight_open,
.release = flashlight_release,
#ifdef CONFIG_COMPAT
.compat_ioctl = my_ioctl_compat,
#endif
};

flashlight_probe
   alloc_chrdev_region(&flashlight_devno, 0, 1, FLASHLIGHT_DEVNAME); //分配,名称kd_camera_flashlight
   cdev_init(&flashlight_cdev, &flashlight_fops); //初始化
   err = cdev_add(&flashlight_cdev, flashlight_devno, 1); //加入系统,/dev/kd_camera_flashlight
   flashlight_class = class_create(THIS_MODULE, "flashlightdrv");
   device_create(flashlight_class, NULL, flashlight_devno, NULL, FLASHLIGHT_DEVNAME); //sys/class/flashlightdrv/kd_camera_flashlight
   init_waitqueue_head(&flashlight_private.read_wait); //初始化等待队列
    /* GPIO pinctrl initial */
   flashlight_gpio_init(dev); //初始化一些接口
        flashlight_pinctrl = devm_pinctrl_get(&pdev->dev);
        flashlight_hwen_high = pinctrl_lookup_state(flashlight_pinctrl, "hwen_high");


4.open函数
flashlight_open
   globalInit();
        for (i = 0; i < e_Max_Sensor_Dev_Num; i++)  //e_Max_Sensor_Dev_Num = 3 ,分别是前摄,后摄,辅助后摄
   for (j = 0; j < e_Max_Strobe_Num_Per_Dev; j++) {  //e_Max_Strobe_Num_Per_Dev = 2 ,最多双闪
gLowBatDuty[i][j] = -1;
g_strobePartId[i][j] = 1;
for (k = 0; k < e_Max_Part_Num_Per_Dev; k++)
g_pFlashInitFunc[i][j][k] = 0;
}        


5.ioctl函数
flashlight_ioctl
    err = flashlight_ioctl_core(file, cmd, arg);
        copyRet = copy_from_user(&kdArg, (void *)arg, sizeof(kdStrobeDrvArg)); //从用户空间拷贝参数
        case FLASHLIGHTIOC_X_SET_DRIVER: //设置闪光灯驱动
            i4RetValue = setFlashDrv(kdArg.sensorDev, kdArg.strobeId);
                sensorDevIndex = getSensorDevIndex(sensorDev); //得到是前摄还是后摄
                strobeIndex = getStrobeIndex(strobeId); //获得是单闪光还是双闪
                partId = g_strobePartId[sensorDevIndex][strobeIndex];  //这里是1
                partIndex = getPartIndex(partId); //数组中的位置
                    return partId - 1;
                ppF = &g_pFlashInitFunc[sensorDevIndex][strobeIndex][partIndex]; //获得对应函数的指针结构体
                constantFlashlightInit(ppF); //获取具体闪光灯的操作函数指针
                    *pfFunc = &constantFlashlightFunc;
                (*ppF)->flashlight_open(0); //初始化闪光灯
                        具体闪光灯的flashlight_open
                    
        case FLASH_IOC_SET_ONOFF: //打开关闭闪关灯
            pF = g_pFlashInitFunc[sensorDevIndex][strobeIndex][partIndex];
            kicker_pbm_by_flash(kdArg.arg);
    i4RetValue = pF->flashlight_ioctl(cmd, kdArg.arg);
                具体驱动的flashlight_ioctl



三.具体闪光驱动分析
Leds_strobe.c (kernel-3.18\drivers\misc\mediatek\flashlight\src\mt6735\constant_flashlight)

1.打开接口
constant_flashlight_open
   FL_init();
        flashlight_gpio_set(FLASH_GPIO_EN,FLASH_GPIO_LOW);  //使能脚为低
flashlight_gpio_set(FLASH_GPIO_MODEM,FLASH_GPIO_LOW); //模式脚为低
        INIT_WORK(&workTimeOut, work_timeOutFunc); //初始化工作队列,单独分析1
   timerInit();
        g_timeOutTimeMs=1000; //1s
hrtimer_init( &g_timeOutTimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );
g_timeOutTimer.function=ledTimeOutCallback; //设置1S的定时器,单独分析2,ledTimeOutCallback

单独分析1
work_timeOutFunc
    FL_disable();  //关闭闪光灯
        flashlight_gpio_set(FLASH_GPIO_EN,FLASH_GPIO_LOW);
flashlight_gpio_set(FLASH_GPIO_MODEM,FLASH_GPIO_LOW);

单独分析2
ledTimeOutCallback
    schedule_work(&workTimeOut);  //启动工作队列


2.ioctrl接口
constant_flashlight_ioctl
    case FLASH_IOC_SET_TIME_OUT_TIME_MS: //设置开启的时间
        g_timeOutTimeMs=arg;
    case FLASH_IOC_SET_DUTY :  //设置闪灯的段数(0--32)
        g_duty=arg;
    FL_dim_duty(arg);
    case FLASH_IOC_SET_STEP:  //设置步进
        g_step=arg;
    FL_step(arg);
    case FLASH_IOC_SET_ONOFF :  //开关闪光灯
        if(arg==1) // //如果是打开,设置超时时间
            ktime = ktime_set( 0, g_timeOutTimeMs*1000000 );
   hrtimer_start( &g_timeOutTimer, ktime, HRTIMER_MODE_REL ); //定时器到时间会关闭闪光
            FL_enable();  //打开
        g_strobe_On=1; 
        else //如果是关闭
            FL_disable(); //关闭
    hrtimer_cancel( &g_timeOutTimer ); //取消定时器
    g_strobe_On=0;
     






posted @ 2020-11-25 14:35  luoyuna  阅读(567)  评论(0编辑  收藏  举报