零、闪光灯配置步骤(以真闪IC:DIO5151为例):
1. 查看硬件原理图,得知闪关灯IC接在cpu的哪两个GPIO上:main_flashlight:(后闪)enable    : GPIO43mode    : GPIO80(H-flashlight模式  L-torch手电筒模式)sub_flashlight:(前摄)enable   : GPIO422. dws配置pin脚:EintMode|Def.Mode  M0|M1|M2|M3|M4|M5|M6|M7|InPull En|InPull SelHigh|Def.Dir|In|Out|OutHigh|VarName1GPIO42  NC      // 有点奇怪NC也能控制?GPIO43         0:GPIO43    1  0  0  1  1  0  1  0  1         0              OUT     0  1   0       GPIO_CAMERA_FLASH_EN_PINGPIO80          0:GPIO80    1  0  0  0  0  0  0  0  1         0              OUT     0  1   0       GPIO_CAMERA_FLASH_MOOD_PIN3. dts配置gpio控制接口:3.1 mt6580.dtsi:+   strobe: strobe {+      compatible = "mediatek,mt6580-strobe";+ };3.2 k80hd_bsp_fwv_512m.dts+  /* STROBE GPIO standardization */+ &pio {+        strobe_intpin_default: strobedefaultcfg {+     };+        main_strobe_oh: mainstrobe@1 {+           pins_cmd_dat {+                pins = <PINMUX_GPIO43__FUNC_GPIO43>;+               slew-rate = <1>;+               output-high;+          };+        };++      main_strobe_ol: mainstrobe@2 {+           pins_cmd_dat {+                pins = <PINMUX_GPIO43__FUNC_GPIO43>;+               slew-rate = <1>;+               output-low;+           };+        };+        main_strobe_mode_oh: mainstrobemode@1 {+          pins_cmd_dat {+                pins = <PINMUX_GPIO80__FUNC_GPIO80>;+               slew-rate = <1>;+               output-high;+          };+        };+        main_strobe_mode_ol: mainstrobemode@2 {+          pins_cmd_dat {+                pins = <PINMUX_GPIO80__FUNC_GPIO80>;+               slew-rate = <1>;+               output-low;+           };+        };+        sub_strobe_oh: substrobe@1 {+         pins_cmd_dat {+                pins = <PINMUX_GPIO42__FUNC_GPIO42>;+               slew-rate = <1>;+               output-high;+          };+        };+        sub_strobe_ol: substrobe@2 {+         pins_cmd_dat {+                pins = <PINMUX_GPIO42__FUNC_GPIO42>;+               slew-rate = <1>;+               output-low;+           };+        };+    };++  &strobe {+     pinctrl-names = "default", "main_strobe_oh", "main_strobe_ol", "main_strobe_mode_oh", "main_strobe_mode_ol", "sub_strobe_oh", "sub_strobe_ol";+     pinctrl-0 = <&strobe_intpin_default>;+      pinctrl-1 = <&main_strobe_oh>;+     pinctrl-2 = <&main_strobe_ol>;+     pinctrl-4 = <&main_strobe_mode_ol>;+        pinctrl-5 = <&sub_strobe_oh>;+      pinctrl-6 = <&sub_strobe_ol>;+      status = "okay";+   };+    /* STROBE GPIO end */3.3 alps/kernel-3.18/drivers/misc/mediatek/flashlight/inc/kd_flashlight.h+    int strobe_gpio_init(struct platform_device *pdev);+   #ifdef CONFIG_KST_SUB_STROBE_SUPPORT+      int sub_strobe_gpio_init(struct platform_device *pdev);+   #endif3.4 alps/kernel-3.18/drivers/misc/mediatek/flashlight/src/mt6580/kd_flashlightlist.c+    #ifdef CONFIG_OF+  #include <linux/of.h>+   #include <linux/of_address.h>+   #include <linux/of_irq.h>+   #endif+    #ifdef CONFIG_OF+  static const struct of_device_id strobe_of_ids[] = {+     {.compatible = "mediatek,mt6580-strobe",},+     {}+    };+    #endifstatic 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 = strobe_of_ids,+  #endif},};+    #ifndef CONFIG_OFstatic struct platform_device flashlight_platform_device = {.name = FLASHLIGHT_DEVNAME,.id = 0,.dev = {}};+   #endifstatic int __init flashlight_init(void){int ret = 0;logI("[flashlight_probe] start ~");+  #ifndef CONFIG_OFret = platform_device_register(&flashlight_platform_device);if (ret) {logI("[flashlight_probe] platform_device_register fail ~");return ret;}+ #endifstatic int flashlight_probe(struct platform_device *dev){int ret = 0, err = 0;logI("[flashlight_probe] start ~");+   #ifdef CONFIG_OF    +      strobe_gpio_init(dev);+    #endif- #ifdef WIN32+  #if 0 //#ifdef WIN323.5 alps/kernel-3.18/drivers/misc/mediatek/flashlight/src/mt6580/constant_flashlight/leds_strobe.c+    struct pinctrl *strobectrl = NULL;+   struct pinctrl_state *main_strobe_oh = NULL;+ struct pinctrl_state *main_strobe_ol = NULL;+ #ifdef CONFIG_KST_REAL_FLASH_MODE+ struct pinctrl_state *main_strobe_mode_oh = NULL;+    struct pinctrl_state *main_strobe_mode_ol = NULL;+    #endif+    static DEFINE_MUTEX(main_strobe_gpio_mutex);+  int strobe_gpio_init(struct platform_device *pdev)+    {+     int ret = 0;++       strobectrl = devm_pinctrl_get(&pdev->dev);+        if (IS_ERR(strobectrl)) {+         dev_err(&pdev->dev, "Cannot find strobe pinctrl!");+          ret = PTR_ERR(strobectrl);+       }++       main_strobe_oh = pinctrl_lookup_state(strobectrl, "main_strobe_oh");+       if (IS_ERR(main_strobe_oh)) {+         ret = PTR_ERR(main_strobe_oh);+           pr_debug("%s : pinctrl err, main_strobe_oh\n", __func__);+       }+     +      main_strobe_ol = pinctrl_lookup_state(strobectrl, "main_strobe_ol");+       if (IS_ERR(main_strobe_ol)) {+         ret = PTR_ERR(main_strobe_ol);+           pr_debug("%s : pinctrl err, main_strobe_ol\n", __func__);+       }+ #ifdef CONFIG_KST_REAL_FLASH_MODE+     main_strobe_mode_oh = pinctrl_lookup_state(strobectrl, "main_strobe_mode_oh");+     if (IS_ERR(main_strobe_mode_oh)) {+            ret = PTR_ERR(main_strobe_mode_oh);+          pr_debug("%s : pinctrl err, main_strobe_mode_oh\n", __func__);+      }+     main_strobe_mode_ol = pinctrl_lookup_state(strobectrl, "main_strobe_mode_ol");+     if (IS_ERR(main_strobe_mode_ol)) {+            ret = PTR_ERR(main_strobe_mode_ol);+          pr_debug("%s : pinctrl err, main_strobe_mode_ol\n", __func__);+      }+ #endif++      return ret;+   }++   void strobe_gpio_set(int level)+   {+     mutex_lock(&main_strobe_gpio_mutex);+      if (level == 0)+         pinctrl_select_state(strobectrl, main_strobe_ol);+     else+          pinctrl_select_state(strobectrl, main_strobe_oh);+     mutex_unlock(&main_strobe_gpio_mutex);+    }++   #ifdef CONFIG_KST_REAL_FLASH_MODE+ void strobe_mode_gpio_set(int level)+  {+     mutex_lock(&main_strobe_gpio_mutex);+      if (level == 0)+         pinctrl_select_state(strobectrl, main_strobe_mode_ol);+        else+          pinctrl_select_state(strobectrl, main_strobe_mode_oh);+        mutex_unlock(&main_strobe_gpio_mutex);+    }+ #endif+    #ifdef CONFIG_KST_REAL_FLASH_MODE+     #define LEDS_TORCH_MODE         0+     #define LEDS_FLASH_MODE         1+     #define LEDS_CUSTOM_MODE_THRES  0+     static int flash_mode_pin = 0;+       #ifdef EN_PWM_CTRL+            static int g_timePWMOutTimeMs=0;+         static struct hrtimer g_timePWMOutTimer;+          void timerPWMInit(void);+          static bool g_enble_led=false;+           ktime_t ktime;+            enum hrtimer_restart ledPWMTimeOutCallback(struct hrtimer *timer)+         {    +             if(g_enble_led == true) {+                   strobe_gpio_set(0);+                   #ifdef CONFIG_KST_FLASHLIGHT_CURRENT_DOWN+                 g_timePWMOutTimeMs=9;+                    #else+                 g_timePWMOutTimeMs=2;+                    #endif+                    ktime = ktime_set( 0, g_timePWMOutTimeMs*1000000 ); //1s+                 g_enble_led = false;+             }+             else if(g_enble_led == false) {+                 strobe_gpio_set(1);+                   #ifdef CONFIG_KST_FLASHLIGHT_CURRENT_DOWN+                 g_timePWMOutTimeMs=1;+                    #else+                 g_timePWMOutTimeMs=8;+                    #endif+                    ktime = ktime_set( 0, g_timePWMOutTimeMs*1000000 ); //1s+                 g_enble_led = true;+              }+             hrtimer_forward(&g_timePWMOutTimer, g_timePWMOutTimer.base->get_time(), ktime);+                return HRTIMER_RESTART;+           }+         void timerPWMInit(void)+           {+             g_timePWMOutTimeMs=5;+                hrtimer_init( &g_timePWMOutTimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );+                g_timePWMOutTimer.function=ledPWMTimeOutCallback;+            }+     #endif+    #endifint FL_Enable(void){+    #if 0...+  #else+     strobe_gpio_set(1);+       +      #ifdef EN_PWM_CTRL   +         ktime = ktime_set( 0, g_timePWMOutTimeMs*1000000 ); //1s+         hrtimer_start( &g_timePWMOutTimer, ktime, HRTIMER_MODE_REL );+         g_enble_led=true;+        #endif+        +  #endifreturn 0;}int FL_Disable(void){+ #if 0...+  #else+     #ifdef EN_PWM_CTRL+            hrtimer_cancel( &g_timePWMOutTimer );+         g_enble_led=false; +      #endif+        strobe_gpio_set(0);+   #endifreturn 0;}int FL_dim_duty(kal_uint32 duty){PK_DBG(" FL_dim_duty line=%d\n", __LINE__);g_duty = duty;+    #ifdef CONFIG_KST_REAL_FLASH_MODE+     PK_DBG("FL_dim_duty %d, thres %d", duty, LEDS_CUSTOM_MODE_THRES);+       +      flash_mode_pin = 0;+      if(duty < LEDS_CUSTOM_MODE_THRES)+          strobe_mode_gpio_set(LEDS_TORCH_MODE);+        else {+            flash_mode_pin = 1;+          strobe_mode_gpio_set(LEDS_FLASH_MODE);+        }++       if((g_timeOutTimeMs == 0) && (duty > LEDS_CUSTOM_MODE_THRES))+        {+         PK_DBG("FL_dim_duty %d > thres %d, FLASH mode but timeout %d", duty, LEDS_CUSTOM_MODE_THRES, g_timeOutTimeMs);+           strobe_mode_gpio_set(LEDS_TORCH_MODE);+            flash_mode_pin = 0;+      }+ #endifreturn 0;}int FL_Init(void){...+ #ifdef EN_PWM_CTRL+        timerPWMInit();+   #endif3.6 alps/kernel-3.18/drivers/misc/mediatek/flashlight/src/mt6580/sub_strobe.c+   #ifdef CONFIG_KST_SUB_STROBE_SUPPORT    // 此宏包括全部为新加+      static DEFINE_SPINLOCK(g_strobeSMPLock);static DEFINE_MUTEX(sub_strobe_gpio_mutex);struct pinctrl *substrobectrl = NULL;struct pinctrl_state *sub_strobe_oh = NULL;struct pinctrl_state *sub_strobe_ol = NULL;static u32 strobe_Res = 0;static u32 strobe_Timeus = 0;static int g_duty=-1;static int g_timeOutTimeMs=0;static DEFINE_MUTEX(g_strobeSem);static struct work_struct workTimeOut;int sub_strobe_gpio_init(struct platform_device *pdev){int ret = 0;substrobectrl = devm_pinctrl_get(&pdev->dev);if (IS_ERR(substrobectrl)) {dev_err(&pdev->dev, "Cannot find sub strobe pinctrl!");ret = PTR_ERR(substrobectrl);}sub_strobe_oh = pinctrl_lookup_state(substrobectrl, "sub_strobe_oh");if (IS_ERR(sub_strobe_oh)) {ret = PTR_ERR(sub_strobe_oh);pr_debug("%s : pinctrl err, sub_strobe_oh\n", __func__);}sub_strobe_ol = pinctrl_lookup_state(substrobectrl, "sub_strobe_ol");if (IS_ERR(sub_strobe_ol)) {ret = PTR_ERR(sub_strobe_ol);pr_debug("%s : pinctrl err, sub_strobe_ol\n", __func__);}return ret;}void sub_strobe_gpio_set(int level){mutex_lock(&sub_strobe_gpio_mutex);if (level == 0)pinctrl_select_state(substrobectrl, sub_strobe_ol);elsepinctrl_select_state(substrobectrl, sub_strobe_oh);mutex_unlock(&sub_strobe_gpio_mutex);}int SUB_FL_Enable(void){sub_strobe_gpio_set(1);PK_DBG(" SUB_FL_Enable line=%d\n",__LINE__);return 0;}int SUB_FL_Disable(void){sub_strobe_gpio_set(0);PK_DBG(" SUB_FL_Disable line=%d\n",__LINE__);return 0;}int SUB_FL_dim_duty(kal_uint32 duty){PK_DBG(" SUB_FL_dim_duty line=%d\n",__LINE__);g_duty = duty;return 0;}int SUB_FL_Init(void){PK_DBG(" SUB_FL_Init line=%d\n",__LINE__);return 0;}int SUB_FL_Uninit(void){SUB_FL_Disable();return 0;}static void Sub_work_timeOutFunc(struct work_struct *data){SUB_FL_Disable();PK_DBG("ledTimeOut_callback\n");}enum hrtimer_restart Sub_ledTimeOutCallback(struct hrtimer *timer){schedule_work(&workTimeOut);return HRTIMER_NORESTART;}static struct hrtimer g_timeOutTimer;void Sub_timerInit(void){INIT_WORK(&workTimeOut, Sub_work_timeOutFunc);g_timeOutTimeMs=1000; //1shrtimer_init( &g_timeOutTimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL );g_timeOutTimer.function=Sub_ledTimeOutCallback;}static int Sub_constant_flashlight_flashlight_ioctl(unsigned int cmd, unsigned long arg){int i4RetValue = 0;int ior_shift;int iow_shift;int iowr_shift;ior_shift = cmd - (_IOR(FLASHLIGHT_MAGIC,0, int));iow_shift = cmd - (_IOW(FLASHLIGHT_MAGIC,0, int));iowr_shift = cmd - (_IOWR(FLASHLIGHT_MAGIC,0, int));PK_DBG("LM3642 Sub_constant_flashlight_flashlight_ioctl() line=%d ior_shift=%d, iow_shift=%d iowr_shift=%d arg=%d\n",__LINE__, ior_shift, iow_shift, iowr_shift,(int)arg);switch(cmd){case FLASH_IOC_SET_TIME_OUT_TIME_MS:PK_DBG("FLASH_IOC_SET_TIME_OUT_TIME_MS: %d\n",(int)arg);g_timeOutTimeMs=arg;break;case FLASH_IOC_SET_DUTY :PK_DBG("FLASHLIGHT_DUTY: %d\n",(int)arg);SUB_FL_dim_duty(arg);break;case FLASH_IOC_SET_STEP:PK_DBG("FLASH_IOC_SET_STEP: %d\n",(int)arg);break;case FLASH_IOC_SET_ONOFF :PK_DBG("FLASHLIGHT_ONOFF: %d\n",(int)arg);if(arg==1){int s;int ms;if(g_timeOutTimeMs>1000){s = g_timeOutTimeMs/1000;ms = g_timeOutTimeMs - s*1000;}else{s = 0;ms = g_timeOutTimeMs;}if(g_timeOutTimeMs!=0){ktime_t ktime;ktime = ktime_set( s, ms*1000000 );hrtimer_start( &g_timeOutTimer, ktime, HRTIMER_MODE_REL );}SUB_FL_Enable();}else{SUB_FL_Disable();hrtimer_cancel( &g_timeOutTimer );}break;default :PK_DBG(" No such command \n");i4RetValue = -EPERM;break;}return i4RetValue;}static int Sub_constant_flashlight_open(void *pArg){int i4RetValue = 0;PK_DBG("Sub_constant_flashlight_open line=%d\n", __LINE__);if (0 == strobe_Res){SUB_FL_Init();Sub_timerInit();}PK_DBG("Sub_constant_flashlight_open line=%d\n", __LINE__);spin_lock_irq(&g_strobeSMPLock);if(strobe_Res){PK_ERR(" busy!\n");i4RetValue = -EBUSY;}else{strobe_Res += 1;}spin_unlock_irq(&g_strobeSMPLock);PK_DBG("Sub_constant_flashlight_open line=%d\n", __LINE__);return i4RetValue;}static int Sub_constant_flashlight_release(void *pArg){PK_DBG(" Sub_constant_flashlight_release\n");if (strobe_Res){spin_lock_irq(&g_strobeSMPLock);strobe_Res = 0;strobe_Timeus = 0;spin_unlock_irq(&g_strobeSMPLock);SUB_FL_Uninit();}PK_DBG(" Done\n");return 0;}FLASHLIGHT_FUNCTION_STRUCT    Sub_constantFlashlightFunc={Sub_constant_flashlight_open,Sub_constant_flashlight_release,Sub_constant_flashlight_flashlight_ioctl};MUINT32 subStrobeInit(PFLASHLIGHT_FUNCTION_STRUCT *pfFunc){if (pfFunc != NULL){*pfFunc = &Sub_constantFlashlightFunc;}return 0;}+    // 以上全部为新加+    #else...MUINT32 subStrobeInit(PFLASHLIGHT_FUNCTION_STRUCT *pfFunc){if (pfFunc != NULL)*pfFunc = &subStrobeFunc;return 0;}+   #endif============sub strobe需要配置修改hal层,以下为hal层=======================3.7 alps/vendor/mediatek/proprietary/custom/mt6580/hal/flashlight/flash_tuning_custom2.h+   #ifdef KST_SUB_FLASH_SUPPORT+      #define SUB_FLASH_SUPPORT 1+   #else#define SUB_FLASH_SUPPORT 0+  #endif3.8 alps/vendor/mediatek/proprietary/custom/mt6580/hal/imgsensor_metadata/common/config_static_metadata_common.hSTATIC_METADATA_BEGIN(DEVICE, CAMERA, COMMON)switch  (rInfo.getDeviceId()){case 0:case 1:+   #if defined(KST_SUB_FLASH_SUPPORT)      +          CONFIG_ENTRY_VALUE(MTK_FLASH_INFO_AVAILABLE_TRUE, MUINT8)+ #elseCONFIG_ENTRY_VALUE(MTK_FLASH_INFO_AVAILABLE_FALSE, MUINT8)+   #endif                      CONFIG_METADATA_END()break;default:3.9 配置: alps\kernel-3.18\arch\arm64\configs\xxx_debug_defconfigCONFIG_MTK_FLASHLIGHT=yCONFIG_KST_SUB_STROBE_SUPPORT=y      // 前闪配置CONFIG_KST_REAL_FLASH_MODE=y        // 后真闪配置 - 有一个模式引脚CONFIG_CUSTOM_KERNEL_FLASHLIGHT="constant_flashlight"3.10 配置: alps\device\xxx\xxx\ProjectConfig.mk+   AUTO_ADD_GLOBAL_DEFINE_BY_VALUE = KST_MISC_CUSTOM // 添加:KST_MISC_CUSTOM+   KST_MISC_CUSTOM = KST_SUB_FLASH_SUPPORT        // 前闪配置CUSTOM_KERNEL_FLASHLIGHT=constant_flashlightCUSTOM_HAL_FLASHLIGHT=constant_flashlight零一、mt6739平台(kernel-4.4 ):1. dws配置pin脚:EintMode|Def.Mode   M0|M1|M2|M3|M4|M5|M6|M7|InPull En|InPull SelHigh|Def.Dir|In|Out|OutHigh|VarName1GPIO42  NC      // 有点奇怪NC也能控制?GPIO10         0:GPIO10    1  0  0  1  1  0  1  0  1         0              OUT     0  1   0       GPIO_FLASH_LED_ENGPIO13 NC      // 有点奇怪NC也能控制?2. dts配置gpio控制接口:2.1 mt6580.dtsi:- flashlights_rt4505: flashlights_rt4505 {-       compatible = "mediatek,flashlights_rt4505";- };+    strobe: strobe {+      compatible = "mediatek,flashlights_dummy_gpio";decouple = <0>;channel@1 {type = <0>;ct = <0>;part = <0>;};channel@2 {type = <1>;ct = <0>;part = <0>;+        };+    };2.2 k39tv1_bsp_1g.dts+   /* FLASHLIGHT GPIO standardization */+ &strobe {pinctrl-names = "xxx_high", "xxx_low", "sub_xxx_high", "sub_xxx_low";pinctrl-0 = <&xxx_high>;pinctrl-1 = <&xxx_low>;pinctrl-2 = <&sub_xxx_high>;pinctrl-3 = <&sub_xxx_low>;status = "okay";};&pio {xxx_high: xxx_high {pins_cmd_dat {pins = <PINMUX_GPIO10__FUNC_GPIO10>;slew-rate = <1>;output-high;};};xxx_low: xxx_low {pins_cmd_dat {pins = <PINMUX_GPIO10__FUNC_GPIO10>;slew-rate = <1>;output-low;};};sub_xxx_high: sub_xxx_high {pins_cmd_dat {pins = <PINMUX_GPIO13__FUNC_GPIO13>;slew-rate = <1>;output-high;};};sub_xxx_low: sub_xxx_low {pins_cmd_dat {pins = <PINMUX_GPIO13__FUNC_GPIO13>;slew-rate = <1>;output-low;};};+    };+    /* FLASHLIGHT end */3. kernel-4.4/drivers/misc/mediatek/flashlight/flashlights-dummy-gpio.c#define DUMMY_PINCTRL_PIN_XXX 0#define DUMMY_PINCTRL_PINSTATE_LOW 0#define DUMMY_PINCTRL_PINSTATE_HIGH 1#define DUMMY_PINCTRL_STATE_XXX_HIGH "xxx_high"#define DUMMY_PINCTRL_STATE_XXX_LOW  "xxx_low"static struct pinctrl *dummy_pinctrl;static struct pinctrl_state *dummy_xxx_high;static struct pinctrl_state *dummy_xxx_low;+  #ifdef CONFIG_KST_SUB_STROBE_SUPPORT+  #define SUB_DUMMY_PINCTRL_PIN_XXX 1+   #define SUB_DUMMY_PINCTRL_PINSTATE_LOW 0+  #define SUB_DUMMY_PINCTRL_PINSTATE_HIGH 1+ #define SUB_DUMMY_PINCTRL_STATE_XXX_HIGH "sub_xxx_high"+ #define SUB_DUMMY_PINCTRL_STATE_XXX_LOW  "sub_xxx_low"+  static struct pinctrl_state *sub_dummy_xxx_high;+  static struct pinctrl_state *sub_dummy_xxx_low;+   #endifstatic int dummy_pinctrl_init(struct platform_device *pdev){int ret = 0;/* get pinctrl */dummy_pinctrl = devm_pinctrl_get(&pdev->dev);if (IS_ERR(dummy_pinctrl)) {pr_err("Failed to get flashlight pinctrl.\n");ret = PTR_ERR(dummy_pinctrl);}/* TODO: Flashlight XXX pin initialization */dummy_xxx_high = pinctrl_lookup_state(dummy_pinctrl, DUMMY_PINCTRL_STATE_XXX_HIGH);if (IS_ERR(dummy_xxx_high)) {pr_err("Failed to init (%s)\n", DUMMY_PINCTRL_STATE_XXX_HIGH);ret = PTR_ERR(dummy_xxx_high);}dummy_xxx_low = pinctrl_lookup_state(dummy_pinctrl, DUMMY_PINCTRL_STATE_XXX_LOW);if (IS_ERR(dummy_xxx_low)) {pr_err("Failed to init (%s)\n", DUMMY_PINCTRL_STATE_XXX_LOW);ret = PTR_ERR(dummy_xxx_low);}+        #ifdef CONFIG_KST_SUB_STROBE_SUPPORT+      /* TODO: sub Flashlight XXX pin initialization */+     sub_dummy_xxx_high = pinctrl_lookup_state(dummy_pinctrl, SUB_DUMMY_PINCTRL_STATE_XXX_HIGH);+      if (IS_ERR(sub_dummy_xxx_high)) {+         pr_err("Failed to init (%s)\n", SUB_DUMMY_PINCTRL_STATE_XXX_HIGH);+          ret = PTR_ERR(sub_dummy_xxx_high);+       }+     sub_dummy_xxx_low = pinctrl_lookup_state(dummy_pinctrl, SUB_DUMMY_PINCTRL_STATE_XXX_LOW);+        if (IS_ERR(sub_dummy_xxx_low)) {+          pr_err("Failed to init (%s)\n", SUB_DUMMY_PINCTRL_STATE_XXX_LOW);+           ret = PTR_ERR(sub_dummy_xxx_low);+        }+     #endifreturn ret;}static int dummy_pinctrl_set(int pin, int state){...switch (pin) {case DUMMY_PINCTRL_PIN_XXX:if (state == DUMMY_PINCTRL_PINSTATE_LOW && !IS_ERR(dummy_xxx_low))pinctrl_select_state(dummy_pinctrl, dummy_xxx_low);else if (state == DUMMY_PINCTRL_PINSTATE_HIGH && !IS_ERR(dummy_xxx_high))pinctrl_select_state(dummy_pinctrl, dummy_xxx_high);elsepr_err("set err, pin(%d) state(%d)\n", pin, state);break;+      #ifdef CONFIG_KST_SUB_STROBE_SUPPORT+      case SUB_DUMMY_PINCTRL_PIN_XXX:+           if (state == SUB_DUMMY_PINCTRL_PINSTATE_LOW && !IS_ERR(sub_dummy_xxx_low))+              pinctrl_select_state(dummy_pinctrl, sub_dummy_xxx_low);+           else if (state == SUB_DUMMY_PINCTRL_PINSTATE_HIGH && !IS_ERR(sub_dummy_xxx_high))+               pinctrl_select_state(dummy_pinctrl, sub_dummy_xxx_high);+          else+              pr_err("set err, pin(%d) state(%d)\n", pin, state);+         break;+        #endif  ...}static int dummy_enable(void){int pin = 0, state = 1; //0;return dummy_pinctrl_set(pin, state);}/* flashlight disable function */static int dummy_disable(void){int pin = 0, state = 0;return dummy_pinctrl_set(pin, state);}+ #ifdef CONFIG_KST_SUB_STROBE_SUPPORT+  static int sub_dummy_enable(void)+ {+     int pin = 1, state = 1;+     return dummy_pinctrl_set(pin, state);+ }+ static int sub_dummy_disable(void)+    {+     int pin = 1, state = 0;+     return dummy_pinctrl_set(pin, state);+ }+ #endifstatic int dummy_ioctl(unsigned int cmd, unsigned long arg){struct flashlight_dev_arg *fl_arg;int channel;ktime_t ktime;fl_arg = (struct flashlight_dev_arg *)arg;channel = fl_arg->channel;switch (cmd) {...case FLASH_IOC_SET_ONOFF:pr_debug("FLASH_IOC_SET_ONOFF(%d): %d\n",channel, (int)fl_arg->arg);if (fl_arg->arg == 1) {if (dummy_timeout_ms) {ktime = ktime_set(dummy_timeout_ms / 1000,(dummy_timeout_ms % 1000) * 1000000);hrtimer_start(&dummy_timer, ktime, HRTIMER_MODE_REL);}+           #ifdef CONFIG_KST_SUB_STROBE_SUPPORT+          if(channel == 0)+                dummy_enable();+           else if(channel == 1)+               sub_dummy_enable();+           #elsedummy_enable();+          #endif} else {+            #ifdef CONFIG_KST_SUB_STROBE_SUPPORT+          if(channel == 0)+                dummy_disable();+          else if(channel == 1)+               sub_dummy_disable();+          #elsedummy_disable();+         #endifhrtimer_cancel(&dummy_timer);}break;...}4.vendor/mediatek/proprietary/custom/mt6739/hal/flashlight/flash_tuning_custom2.h-    #if MTKCAM_SUB_FLASHLIGHT_SUPPORT+ #ifdef KST_SUB_FLASH_SUPPORT        // 改成用我们的宏控制,这个宏配置在ProjectConfig.mk#define SUB_FLASH_SUPPORT 1#else#define SUB_FLASH_SUPPORT 0#endif5. vendor/mediatek/proprietary/hardware/mtkcam/legacy/platform/mt6739/core/featureio/drv/strobe/flashlight_drv.cppint FlashlightDrv::setOnOff(int a_isOn){...if(m_duty > mOnDuty)mOnDuty = m_duty;int minPreOnTime;-     err = getPreOnTimeMsDuty(m_duty, &minPreOnTime);+     getPreOnTimeMsDuty(m_duty, &minPreOnTime);如若闪光灯还是无功能: 检查驱动代码,最好是先找一个ok的工程,从那边移植过来一、FlashLight(strobe)概要1.FlashLiht分为真闪和假闪,真闪: 需要一个IC - 查bom可知v618上贴的是DIO5151(10pin)假闪: 由一个三极管实现电流放大兼容: 通常硬件上对真闪假闪做了兼容,即真假闪的电路都实现,二者使能脚为同一引脚,贴ic为真闪,不贴即为假闪(软件不需要作区分)2.真闪可以选择模式(闪光灯/手电筒),通过对ic的GPIO_FLASH_STROBE引脚操作(HIGH - 闪光灯  LOW - 手电筒)闪关灯: 电流可为500mA手电筒: 电流应该限制为100mA怎切换:    HIGH - 闪光灯  LOW - 手电筒3.驱动中实现了一个定时器来控制闪光灯的时长,闪光灯亮20s就自动灭,实测: camera拍照闪光灯的关闭由上层ioctl关闭(log显示)实测: 手电筒不会20s自动灭 - ???二、调试1.真假闪均可以通过PWM的占空比控制闪光的亮度 - 已验证okalps\kernel-3.18\drivers\misc\mediatek\flashlight\src\mt6735\constant_flashlight\leds_strobe.cenum hrtimer_restart ledPWMTimeOutCallback(struct hrtimer *timer){    if(g_enble_led == true) {strobe_gpio_set(0);g_timePWMOutTimeMs=2;     // 低电平(灭灯)占空比2/10ktime = ktime_set( 0, g_timePWMOutTimeMs*800000 ); //1sg_enble_led = false;}else if(g_enble_led == false) {strobe_gpio_set(1);     g_timePWMOutTimeMs=8;      // 高电平(亮灯)占空比8/10ktime = ktime_set( 0, g_timePWMOutTimeMs*800000 ); //1sg_enble_led = true;}hrtimer_forward(&g_timePWMOutTimer, g_timePWMOutTimer.base->get_time(), ktime);return HRTIMER_RESTART;}2. 方便测量电流 - 控制循环闪烁alps\kernel-3.18\drivers\misc\mediatek\flashlight\src\mt6735\constant_flashlight\leds_strobe.ccase FLASH_IOC_SET_ONOFF:PK_DBG("FLASHLIGHT_ONOFF: %d\n", (int)arg);printk("201707 [%s] [%d] FLASH_IOC_SET_ONOFF: %d \n", __func__, __LINE__, (int)arg);if (arg == 1) {int s;int ms;/*//==============================int i  = 0;for(i = 0 ; i < 3; i++){printk("201707 [%s] [%d] set(LEDS_TORCH_MODE) \n", __func__, __LINE__);strobe_mode_gpio_set(LEDS_TORCH_MODE);     // 手电筒模式mdelay(5);strobe_gpio_set(1);           // 输出1 - 亮mdelay(10000);strobe_gpio_set(0);         // 输出0 - 灭mdelay(1000);printk("201707 [%s] [%d] set(LEDS_FLASH_MODE) \n", __func__, __LINE__);strobe_mode_gpio_set(LEDS_FLASH_MODE);      // 闪光灯模式mdelay(5);strobe_gpio_set(1);           // 输出1 - 亮mdelay(4000);strobe_gpio_set(0);          // 输出0 - 灭mdelay(1000);}//==============================*/案例一:    真闪IC:DIO5151(10pin) - 400ma的闪光灯电流只持续400ms,过后自动变小更换pin对pin的另一个闪光灯IC(SGM3141B), 电流正常案例二: 39平台实现前后闪光灯1. mt6739上mtk默认的闪光灯是使用rt4505这个ic来控制的,而当前我们的硬件电路的前后闪光灯的是假闪修改k39tv1_bsp_1g_defconfig- #CONFIG_MTK_FLASHLIGHT_RT4505=y+  CONFIG_MTK_FLASHLIGHT_DUMMY_GPIO=y2. 在mt6739.dts中这样添加闪光灯的配置+  strobe: strobe {+      compatible = "mediatek,flashlights_dummy_gpio";+    };使之和flashlights-dummy-gpio.c相匹配#define DUMMY_DTNAME "mediatek,flashlights_dummy_gpio"static const struct of_device_id dummy_gpio_of_match[] = {{.compatible = DUMMY_DTNAME},{},};3. flashlights-dummy-gpio.c虽然加载起来了,但在摄像头界面打开闪光灯,或者点击手电筒图标时,并不会执行FLASH_IOC_SET_ONOFF这个case来操作GPIO控制语句static int dummy_ioctl(unsigned int cmd, unsigned long arg){……case FLASH_IOC_SET_ONOFF:pr_debug("FLASH_IOC_SET_ONOFF(%d): %d\n",   // log未打印……}4. 查看闪光灯从hal层往kernel端的调用流程使用git grep -n "FLASH_IOC_SET_ONOFF" alps/vendor/mediatek/proprietary/命令,查找FLASH_IOC_SET_ONOFF是从哪个hal的cpp代码下发到驱动的,发现在如下代码内有调用alps/vendor/mediatek/proprietary/hardware/mtkcam/legacy/platform/mt6739/core/featureio/drv/strobe/flashlight_drv.cppint FlashlightDrv::setOnOff(int a_isOn){int hasHw;hasHw = hasFlashHw();if(hasHw != 1)return 0;logI("setOnOff() isOn = %d\n",a_isOn);if(checkValid()!=0)return StrobeDrv::STROBE_UNKNOWN_ERROR;int err = 0;StrobeGlobalDriver* pKDrv;pKDrv = StrobeGlobalDriver::getInstance();if (a_isOn == 1) {if(m_isOn == 0) {mTurnOnTime = getMs();mOnDuty = m_duty;}if(m_duty > mOnDuty)mOnDuty = m_duty;int minPreOnTime;err = getPreOnTimeMsDuty(m_duty, &minPreOnTime);//在此处添加调试信息,发现err是小于0的,追踪getPreOnTimeMsDuty的函数定义。if (minPreOnTime > 100)minPreOnTime = 100;else if (minPreOnTime < 0)minPreOnTime = -1;if (err < 0) {logI("no preon");} else {if(minPreOnTime == -1) {logI("no preon(preontime=-1)");} else {logI("preon support %d",m_preOnTime);if (m_preOnTime == -1) {setPreOn();sleepMs(minPreOnTime);} else {int curTime;int sleepTimeMs;curTime = getMs();sleepTimeMs = (minPreOnTime-(curTime-m_preOnTime));logI("preon sleep %d ms", sleepTimeMs);if(sleepTimeMs > minPreOnTime)sleepTimeMs = minPreOnTime;if(sleepTimeMs > 0) {sleepMs( sleepTimeMs);}}}}err = pKDrv->sendCommand(FLASH_IOC_SET_ONOFF, mTypeId, mCtId, 1);//在此处添加调试信息,发现并未打印信息出来,在前面的语句添加调试信息。} else if(a_isOn == 0) {if (m_isOn == 1) {mTurnOffTime= getMs();if((mTurnOffTime-mTurnOnTime > mTimeOutTime) && (mTimeOutTime != 0))logE("TimeOut");}m_preOnTime=-1;err = pKDrv->sendCommand(FLASH_IOC_SET_ONOFF, mTypeId, mCtId, 0);//在此处添加调试信息,发现并未打印信息出来,在前面的语句添加调试信息。} else {err = STROBE_ERR_PARA_INVALID;}if (err < 0) {logE("setOnOff() err=%d\n", err);}if(!err)m_isOn = a_isOn;return err;}5. FLASH_IOC_GET_PRE_ON_TIME_MS_DUTY 和 FLASH_IOC_GET_PRE_ON_TIME_MS 未在flashlights-dummy-gpio.c定义,hal层通过ioctl未获取到返回值,导致flashlight_drv.cpp未执行到err = pKDrv->sendCommand(FLASH_IOC_SET_ONOFF, mTypeId, mCtId, 1);err = pKDrv->sendCommand(FLASH_IOC_SET_ONOFF, mTypeId, mCtId, 0);alps/vendor/mediatek/proprietary/hardware/mtkcam/legacy/platform/mt6739/core/featureio/drv/strobe/flashlight_drv.cppint FlashlightDrv::getPreOnTimeMsDuty(int duty, int* ms){logI("getPreOnTimeMsDuty()");StrobeGlobalDriver* pKDrv;pKDrv = StrobeGlobalDriver::getInstance();int err;err = pKDrv->sendCommand(FLASH_IOC_GET_PRE_ON_TIME_MS_DUTY, mTypeId, mCtId, (long)duty);err = pKDrv->sendCommandRet(FLASH_IOC_GET_PRE_ON_TIME_MS, mTypeId, mCtId, ms);logI("getPreOnTimeMs=%d err=%d", *ms, err);return err;}git grep -n "sendCommand" alps/vendor/mediatek/proprietary/hardware/mtkcam/legacy/platform/mt6739/alps/vendor/mediatek/proprietary/hardware/mtkcam/legacy/platform/mt6739/core/featureio/drv/strobe/strobe_global_driver.cppint StrobeGlobalDriver::sendCommandRet(int cmd, int typeId, int ctId, int *arg){Mutex::Autolock lock(mLock);return sendCommandRet_nolock(cmd, typeId, ctId, arg);}int StrobeGlobalDriver::sendCommandRet_nolock(int cmd, int typeId, int ctId, int *arg){if (mStrobeHandle < 0) {logE("sendCommand() mStrobeHandle <= 0 ~");return StrobeDrv::STROBE_UNKNOWN_ERROR;}/* setup arguments *//* TODO: redefine ioctl argument */struct flashlight_user_arg stbArg;stbArg.type_id = typeId;stbArg.ct_id = ctId;stbArg.arg = 0;/* send ioctl */int ret;ret = ioctl(mStrobeHandle, cmd, &stbArg);*arg = stbArg.arg;return ret;}int StrobeGlobalDriver::sendCommand(int cmd, int typeId, int ctId, int arg){Mutex::Autolock lock(mLock);return sendCommand_nolock(cmd, typeId, ctId, arg);}int StrobeGlobalDriver::sendCommand_nolock(int cmd, int typeId, int ctId, int arg){if (mStrobeHandle < 0) {logE("sendCommand() mStrobeHandle <= 0 ~");return StrobeDrv::STROBE_UNKNOWN_ERROR;}/* setup arguments */struct flashlight_user_arg stbArg;stbArg.type_id = typeId;stbArg.ct_id = ctId;stbArg.arg = arg;/* send ioctl */return ioctl(mStrobeHandle, cmd, &stbArg);}6. 不做getPreOnTimeMsDuty返回值的判断就能进行对FLASH_IOC_SET_ONOFF的ioctl调用alps/vendor/mediatek/proprietary/hardware/mtkcam/legacy/platform/mt6739/core/featureio/drv/strobe/flashlight_drv.cppint FlashlightDrv::setOnOff(int a_isOn){……int err = 0;StrobeGlobalDriver* pKDrv;pKDrv = StrobeGlobalDriver::getInstance();if (a_isOn == 1) {if(m_isOn == 0) {mTurnOnTime = getMs();mOnDuty = m_duty;}if(m_duty > mOnDuty)mOnDuty = m_duty;int minPreOnTime;/*err = */getPreOnTimeMsDuty(m_duty, &minPreOnTime);//在此处不把getPreOnTimeMsDuty的返回值赋给err即可。if (minPreOnTime > 100)minPreOnTime = 100;else if (minPreOnTime < 0)minPreOnTime = -1;if (err < 0) {logI("no preon");} else {……}7. 代码修改7.1 mt6739.dtsstrobe: strobe {compatible = "mediatek,flashlights_dummy_gpio";decouple = <0>;channel@1 {type = <0>;ct = <0>;part = <0>;};channel@2 {type = <1>;ct = <0>;part = <0>;};};7.2 k39tv1_bsp_1g.dts&strobe {pinctrl-names = "xxx_high", "xxx_low", "sub_xxx_high", "sub_xxx_low";pinctrl-0 = <&xxx_high>;pinctrl-1 = <&xxx_low>;pinctrl-2 = <&sub_xxx_high>;pinctrl-3 = <&sub_xxx_low>;status = "okay";};&pio {xxx_high: xxx_high {pins_cmd_dat {pins = <PINMUX_GPIO10__FUNC_GPIO10>;slew-rate = <1>;output-high;};};xxx_low: xxx_low {pins_cmd_dat {pins = <PINMUX_GPIO10__FUNC_GPIO10>;slew-rate = <1>;output-low;};};sub_xxx_high: sub_xxx_high {pins_cmd_dat {pins = <PINMUX_GPIO13__FUNC_GPIO13>;slew-rate = <1>;output-high;};};sub_xxx_low: sub_xxx_low {pins_cmd_dat {pins = <PINMUX_GPIO13__FUNC_GPIO13>;slew-rate = <1>;output-low;};};};7.3 flashlights-dummy-gpio.cstatic int dummy_ioctl(unsigned int cmd, unsigned long arg){……case FLASH_IOC_SET_ONOFF:pr_debug("FLASH_IOC_SET_ONOFF(%d): %d\n",channel, (int)fl_arg->arg);if (fl_arg->arg == 1) {if (dummy_timeout_ms) {ktime = ktime_set(dummy_timeout_ms / 1000,(dummy_timeout_ms % 1000) * 1000000);hrtimer_start(&dummy_timer, ktime, HRTIMER_MODE_REL);}#ifdef CONFIG_KST_SUB_STROBE_SUPPORTif(channel == 0)dummy_enable();  //支持前后假闪的后闪使用pinctrl的方式使能对应GPIOelse if(channel == 1)sub_dummy_enable();   //支持前后假闪的后闪使用pinctrl的方式使能对应GPIO#elsedummy_enable(); //只支持后假闪的后闪使用pinctrl的方式使能对应GPIO#endif} else {#ifdef CONFIG_KST_SUB_STROBE_SUPPORTif(channel == 0)dummy_disable(); //支持前后假闪的后闪使用pinctrl的方式关闭对应GPIOelse if(channel == 1)sub_dummy_disable();  //支持前后假闪的后闪使用pinctrl的方式关闭对应GPIO#elsedummy_disable();    //只支持后假闪的后闪使用pinctrl的方式关闭对应GPIO#endifhrtimer_cancel(&dummy_timer);}break;……}xxx.mk中配置是否支持前假闪的宏#主板型号及内核宏定义配置 KST_KERNEL_BOARD_CUSTOM00 = KST_BOARD_V630KKST_KERNEL_BOARD_CUSTOM01 = KST_SUB_STROBE_SUPPORT // 作用在kernel configKST_KERNEL_BOARD_CUSTOM02 = KST_KERNEL_BOARD_CUSTOM03 = KST_KERNEL_BOARD_CUSTOM04 = KST_KERNEL_BOARD_CUSTOM05 = KST_KERNEL_BOARD_CUSTOM06 = KST_KERNEL_BOARD_CUSTOM07 = KST_KERNEL_BOARD_CUSTOM08 = KST_KERNEL_BOARD_CUSTOM09 = #Misc 配置KST_MISC_CUSTOM= KST_SUB_FLASH_SUPPORT // 作用在ProjectConfig.mk

20. FlashLight调试日志相关推荐

  1. TWR_MPC8309调试日志

    版权声明:本文为博主原创文章,未经博主允许不得转载. TWR_MPC8309调试日志 --------By Moresung Chan , At 12:00 ,Sep 16,2012 一.软硬件: P ...

  2. paip.提升效率--调试--日志系统日志参数含义---python

    paip.提升效率--调试--日志系统日志参数含义---python #同时向控制台和文件输出日志 #日志参数含义 import logging log_format = '%(filename)s ...

  3. 位于/var/log目录下的20个Linux日志文件

    位于/var/log目录下的20个Linux日志文件[译] from:http://buptguo.com/2014/01/16/linux-var-log-files/ 原文地址:20 Linux ...

  4. nginx 学习笔记(5) nginx调试日志

    为启动一个调试日志,nginx需要在构建时配置城支持调试模式. ./configure --with-debug ... 而且调试级别应该使用err_log指令来设置: err_log /path/t ...

  5. 小明分享|LVGL调试日志

    LVGL仿真调试日志-内存溢出 错误日志: Warn: Couldn't allocate memory (lv_mem.c #208 lv_mem_alloc()) Warn: Couldn't a ...

  6. java servlet 调试日志 logger sae_java servlet 调试日志 lo

    java servlet 调试日志 lo [2021-02-10 08:32:08]  简介: php去除nbsp的方法:首先创建一个PHP代码示例文件:然后通过"preg_replace( ...

  7. Nginx调试日志[emerg]: invalid log level “debug_http” in /path/conf/nginx.conf:XX

    配置日志的时候重启nginx报错:[emerg]: invalid log level "debug_http" in /path/conf/nginx.conf:XX,看到这篇文 ...

  8. 1.3【展讯平台】Android 驱动(Kernel)、系统(framework) 定制,调试日志

    前言 [展讯平台]Android 4.4 驱动(Kernel).系统(framework) 定制,调试日志 正文 1:提高串口日志等级 查看 adb shell cat /proc/sys/kerne ...

  9. 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。

    24-Jul-2022 17:18:15.259 信息 [RMI TCP Connection(3)-127.0.0.1] org.apache.jasper.servlet.TldScanner.s ...

最新文章

  1. 【编程珠玑】读书笔记 第二章 算法
  2. matlab温度数据怎么滤波_卡尔曼滤波算法思想理解 Kalman filter 第一篇
  3. 性能测试vs负载测试vs压力测试
  4. 5天不再惧怕多线程——第三天 互斥体
  5. Javascript图像处理之将彩色图转换成灰度图
  6. 内嵌tomcat启动速度慢
  7. ssh-copy-id password
  8. Tiled Map的使用说明
  9. 海康威视相机 RTSP 传输延迟解决方案
  10. 大道至简---软件工程实践者的思想--------------第二章读后感---是懒人造就了方法...
  11. hadoop学习之路(2)
  12. vulnhub靶场——THE PLANETS:EARTH
  13. 计算机化工应用答案,计算机化工应用习题与解答.pdf
  14. 智能小车的超声波避障
  15. 我的世界游侠联机教程
  16. AD转换 ADC设计
  17. tiny4412 裸机程序 七、重定位代码到DRAM【转】
  18. 简单了解软件开发的生命周期和流程、思想
  19. FastStone Capture监视器上拍摄和拍摄
  20. [转]如何能成为一名真正电子工程师

热门文章

  1. 大数据Hadoop(二十):MapReduce的排序和序列化
  2. STC52单片机 第三个定时器 定时器2详解
  3. 马建强老师谈如何做好PPT演讲演示
  4. 计算机考证二级可以考几个证
  5. 如何把wordpress从本地服务器迁移到网站主机上
  6. 安卓时间显示TextClock显示日期时间,24小时制和12小时制(自定义时间)
  7. ZED双目相机获取左右视图代码
  8. Java后端--52--Mybatis1:Mybatis入门
  9. 时间序列预测(二)—— AR模型
  10. 【C# / Algorithm】输出任意阶回旋矩阵