static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl) { unsigned long pwm_rate = pwmbl->pwmc.mck; unsigned long prescale = DIV_ROUND_UP(pwm_rate, (pwmbl->pdata->pwm_frequency * pwmbl->pdata->pwm_compare_max)) - 1; prescale = fls(prescale); if (prescale > 0xf) prescale = 0xf; pwm_channel_writel(&pwmbl->pwmc, PWM_CMR, prescale); pwm_channel_writel(&pwmbl->pwmc, PWM_CDTY, pwmbl->pdata->pwm_duty_min + pwmbl->bldev->props.brightness); pwm_channel_writel(&pwmbl->pwmc, PWM_CPRD, pwmbl->pdata->pwm_compare_max); dev_info(&pwmbl->pdev->dev, "Atmel PWM backlight driver " "(%lu Hz)\n", pwmbl->pwmc.mck / pwmbl->pdata->pwm_compare_max / (1 << prescale)); return pwm_channel_enable(&pwmbl->pwmc); }
static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl) { unsigned long pwm_rate = pwmbl->pwmc.mck; unsigned long prescale = DIV_ROUND_UP(pwm_rate, (pwmbl->pdata->pwm_frequency * pwmbl->pdata->pwm_compare_max)) - 1; /* * Prescale must be power of two and maximum 0xf in size because of * hardware limit. PWM speed will be: * PWM module clock speed / (2 ^ prescale). */ prescale = fls(prescale); if (prescale > 0xf) prescale = 0xf; pwm_channel_writel(&pwmbl->pwmc, PWM_CMR, prescale); pwm_channel_writel(&pwmbl->pwmc, PWM_CDTY, pwmbl->pdata->pwm_duty_min + pwmbl->bldev->props.brightness); pwm_channel_writel(&pwmbl->pwmc, PWM_CPRD, pwmbl->pdata->pwm_compare_max); dev_info(&pwmbl->pdev->dev, "Atmel PWM backlight driver " "(%lu Hz)\n", pwmbl->pwmc.mck / pwmbl->pdata->pwm_compare_max / (1 << prescale)); return pwm_channel_enable(&pwmbl->pwmc); }
static int atmel_pwm_bl_set_intensity(struct backlight_device *bd) { struct atmel_pwm_bl *pwmbl = bl_get_data(bd); int intensity = bd->props.brightness; int pwm_duty; if (bd->props.power != FB_BLANK_UNBLANK) intensity = 0; if (bd->props.fb_blank != FB_BLANK_UNBLANK) intensity = 0; if (pwmbl->pdata->pwm_active_low) pwm_duty = pwmbl->pdata->pwm_duty_min + intensity; else pwm_duty = pwmbl->pdata->pwm_duty_max - intensity; if (pwm_duty > pwmbl->pdata->pwm_duty_max) pwm_duty = pwmbl->pdata->pwm_duty_max; if (pwm_duty < pwmbl->pdata->pwm_duty_min) pwm_duty = pwmbl->pdata->pwm_duty_min; if (!intensity) { if (pwmbl->gpio_on != -1) { gpio_set_value(pwmbl->gpio_on, 0 ^ pwmbl->pdata->on_active_low); } pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty); pwm_channel_disable(&pwmbl->pwmc); } else { pwm_channel_enable(&pwmbl->pwmc); pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty); if (pwmbl->gpio_on != -1) { gpio_set_value(pwmbl->gpio_on, 1 ^ pwmbl->pdata->on_active_low); } } return 0; }