MTK平台pwm模式闪光灯驱动配置

  1. 供电引脚配置:
    除flash torch两个供电引脚按照常规配置gpio模式外,需另外将ENM pin配置成pwm模式。在dtsi中添加如下代码:
flash_light_pwm_pin: flash_light_pwm_pin {
     
    pins_cmd_dat {
     
        pinmux = <PINMUX_GPIOxxx__FUNC_PWMx>;
        slew-rate = <1>;
        output-high;
    };
};
  1. 驱动文件:
    包含pwm头文件:
    #include

  2. 闪光灯flash/torch模式下的电流控制:
    (1) flash mode:
    No matter the status of ENM, only when ENF = “1”, Flash mode is in active and the flashing current is equal to IRF * D, D is the duty cycle of PWM signal at ENM pin, the frequency of PWM is largerthan 15KHz
    对应代码:

flashlight_pinctrl_set(FLASHLIGHT_PINCTRL_PIN_FLASH, 0);
flashlight_pinctrl_set(FLASHLIGHT_PINCTRL_PIN_PWM_EN, 1);
mt_flashlight_led_set_pwm(0, tempPWM);    //设置pwm占空比,以实现控制flash电流大小
udelay(500);
flashlight_pinctrl_set(FLASHLIGHT_PINCTRL_PIN_FLASH, 1);

(2) torch mode:
When ENF = “0” and the timer of ENM = “1” is not less than 5ms, Movie/Torch mode will be in active. The LED current should be equal to IRM * D, D is the duty cycle of PWM signal at ENM pin. This PWM signal is sent to ENM pin after the first pulse which “1” level time is more than 5ms. When ENF = “0” and the ENM = “0” is not less than 5ms, the chip will enter into shutdown mode.
对应代码:

flashlight_pinctrl_set(FLASHLIGHT_PINCTRL_PIN_FLASH, 0);
flashlight_pinctrl_set(FLASHLIGHT_PINCTRL_PIN_PWM_GPIO, 1);
mdelay(6);
flashlight_pinctrl_set(FLASHLIGHT_PINCTRL_PIN_PWM_EN, 1);
mt_flashlight_led_set_pwm(0, 40);

在flash_tuning_custom.cpp中将torch duty设置为24以上的数值(示例中flash共设置24个duty),用于与flash模式做区分。驱动中检测到torch的duty时直接调用torch的使能逻辑。

  1. mt_flashlight_led_set_pwm的实现:
int mt_flashlight_led_set_pwm(int pwm_num, u32 level)
{
     
    struct pwm_spec_config pwm_setting;
    memset(&pwm_setting, 0, sizeof(struct pwm_spec_config));
    /*pwm_no is by IC HW design, this value is different by different IC(MTK doc: PWM UserGuide) ——从dws里面查看?*/
    pwm_setting.pwm_no = pwm_num;
    /*OLD or FIFO*/
    pwm_setting.mode = PWM_MODE_OLD;
    /*use channel in pmic, or not, default is FALSE*/
    pwm_setting.pmic_pad = 0;
    /*分频系数*/
    pwm_setting.clk_div = CLK_DIV32;
    /*src clk is by IC HW design, this value is different by different IC(MTK doc: PWM UserGuide) ——未找到查找对应src的方法*/
    pwm_setting.clk_src = PWM_CLK_OLD_MODE_BLOCK;
    /*FALSE: after the PWM wave send finished, the voltage level of this GPIO is low
       TRUE: after the PWM wave send finished, the voltage level of this GPIO is high*/
    pwm_setting.PWM_MODE_OLD_REGS.IDLE_VALUE = 0;   
    /* FALSE: there is no interval time between 2 complete waveform
        TRUE: interval time between 2 complete waveform, the interval time = DATA_WIDTH*/
    pwm_setting.PWM_MODE_OLD_REGS.GUARD_VALUE = 0;
    /* Guard的长度,old mode下是无效值 */
    pwm_setting.PWM_MODE_OLD_REGS.GDURATION = 0;
    /* waveform numbers. WAVE_NUM= 0 means PWM will send output always, until disable pwm, the waveform will stoped */
    pwm_setting.PWM_MODE_OLD_REGS.WAVE_NUM = 0;
    /* the time of onecomplete waveform, 此处含义是一个完整波形包含100个clk */
    pwm_setting.PWM_MODE_OLD_REGS.DATA_WIDTH = 100;
    /* the time of high voltage level in one complete waveform, it means duty cycle, 此处含义是一个完整波形中高电平的时长为level个clk */
    pwm_setting.PWM_MODE_OLD_REGS.THRESH = level;
    pwm_set_spec_config(&pwm_setting);
    return 0;
}
  1. 定义pwm使用的level tab:
    static int g_duty_array[FLASHLIGHT_LEVEL_NUM] = {8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100};
    level tab用于根据不同的duty设置不同等级的THRESH, 从而达到实现控制亮度的目的。详细代码实现:
    xxx_enable中,flash模式时:
{
     
……
    if (g_flash_duty < FLASHLIGHT_LEVEL_NUM)
        tempPWM = g_duty_array[g_flash_duty];
    else
        tempPWM = g_duty_array[LED3201_LEVEL_NUM - 1];
    ……
    mt_flashlight_led_set_pwm(3, tempPWM);
    ……
}

你可能感兴趣的:(linux)