static void pwm_lut_delayed_fade_out(struct work_struct *work) { struct pm8058_led_data *ldata; int id, mode; ldata = container_of(work, struct pm8058_led_data, led_delayed_work.work); id = bank_to_id(ldata->bank); mode = (id == PM_PWM_LED_KPD) ? PM_PWM_CONF_PWM1 : PM_PWM_CONF_PWM1 + (ldata->bank - 4); LED_INFO_LOG("%s \n", __func__); pm8058_pwm_lut_enable(ldata->pwm_led, 0); pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0); }
void button_backlight_flash(int brightness_key) { int milliamps; int id, mode; LED_INFO_LOG("%s brightness_key: %d\n", __func__,brightness_key); pwm_disable(for_key_led_data->pwm_led); id = bank_to_id(for_key_led_data->bank); mode = (id == PM_PWM_LED_KPD) ? PM_PWM_CONF_PWM1 : PM_PWM_CONF_PWM1 + (for_key_led_data->bank - 4); if (brightness_key) { flag_hold_virtual_key = 1; milliamps = (for_key_led_data->flags & PM8058_LED_DYNAMIC_BRIGHTNESS_EN) ? for_key_led_data->out_current * brightness_key / LED_FULL : for_key_led_data->out_current; pm8058_pwm_config_led(for_key_led_data->pwm_led, id, mode, milliamps); pwm_config(for_key_led_data->pwm_led, 320000, 640000); pwm_enable(for_key_led_data->pwm_led); LED_INFO_LOG("%s Button_backlight flash on\n", __func__); } else { pwm_disable(for_key_led_data->pwm_led); pwm_disable(for_key_led_data->pwm_led); pm8058_pwm_config_led(for_key_led_data->pwm_led, id, mode, 0); LED_INFO_LOG("%s Button_backlight flash off\n", __func__); if (virtual_key_state != 0){ milliamps = (for_key_led_data->flags & PM8058_LED_DYNAMIC_BRIGHTNESS_EN) ? for_key_led_data->out_current * brightness_key / LED_FULL : for_key_led_data->out_current; pm8058_pwm_config_led(for_key_led_data->pwm_led, id, mode, milliamps); pwm_config(for_key_led_data->pwm_led, 64000, 64000); pwm_enable(for_key_led_data->pwm_led); LED_INFO_LOG("%s Button_backlight state resume\n", __func__); } flag_hold_virtual_key = 0; } }
static ssize_t pm8058_led_blink_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct led_classdev *led_cdev; struct pm8058_led_data *ldata; int id, mode; int val; int enable = 0; #ifdef CONFIG_HTC_HEADSET_MISC int *pduties; #endif /*struct timespec ts1, ts2;*/ val = -1; sscanf(buf, "%u", &val); if (val < 0 || val > 255) return -EINVAL; led_cdev = (struct led_classdev *) dev_get_drvdata(dev); ldata = container_of(led_cdev, struct pm8058_led_data, ldev); id = bank_to_id(ldata->bank); mode = (id == PM_PWM_LED_KPD) ? PM_PWM_CONF_PWM1 : PM_PWM_CONF_PWM1 + (ldata->bank - 4); if (ldata->flags & PM8058_LED_BLINK_EN) pm8058_pwm_config_led(ldata->pwm_led, id, mode, ldata->out_current); LED_INFO_LOG("%s: bank %d blink %d\n", __func__, ldata->bank, val); enable = (val > 0) ? 1 : 0; if (strcmp(ldata->ldev.name, "charming-led") == 0) charming_led_enable(enable); switch (val) { case -1: /* stop flashing */ pwm_disable(ldata->pwm_led); if (ldata->flags & PM8058_LED_BLINK_EN) pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0); break; case 0: pwm_disable(ldata->pwm_led); if (led_cdev->brightness) { pwm_config(ldata->pwm_led, 6400 * pwm_coefficient / 100, 6400); pwm_enable(ldata->pwm_led); } else { if (ldata->flags & PM8058_LED_BLINK_EN) pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0); } break; case 1: pwm_disable(ldata->pwm_led); pwm_config(ldata->pwm_led, 64000, 2000000); pwm_enable(ldata->pwm_led); break; case 2: cancel_delayed_work_sync(&ldata->led_delayed_work); pwm_disable(ldata->pwm_led); ldata->duty_time_ms = 64; ldata->period_us = 2000000; queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work, msecs_to_jiffies(310)); break; case 3: cancel_delayed_work_sync(&ldata->led_delayed_work); pwm_disable(ldata->pwm_led); ldata->duty_time_ms = 64; ldata->period_us = 2000000; queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work, msecs_to_jiffies(1000)); break; case 4: pwm_disable(ldata->pwm_led); pwm_config(ldata->pwm_led, 1000000, 2000000); #if 0 pwm_conf.pwm_size = 9; pwm_conf.clk = PM_PWM_CLK_1KHZ; pwm_conf.pre_div = PM_PWM_PREDIVIDE_2; pwm_conf.pre_div_exp = 1; pwm_conf.pwm_value = 512/2; pwm_conf.bypass_lut = 1; pwm_configure(ldata->pwm_led, &pwm_conf); #endif pwm_enable(ldata->pwm_led); break; case 5: pwm_disable(ldata->pwm_led); pwm_config(ldata->pwm_led, 100000, 200000); pwm_enable(ldata->pwm_led); break; #ifdef CONFIG_HTC_HEADSET_MISC case 6: pm8058_pwm_config_led(ldata->pwm_led, id, mode, ldata->out_current); pduties = &duties[ldata->start_index]; pm8058_pwm_lut_config(ldata->pwm_led, ldata->period_us, pduties, ldata->duty_time_ms, ldata->start_index, ldata->duites_size, 0, 0, ldata->lut_flag); pm8058_pwm_lut_enable(ldata->pwm_led, 0); pm8058_pwm_lut_enable(ldata->pwm_led, 1); break; case 7: pwm_disable(ldata->pwm_led); pwm_config(ldata->pwm_led, 64000, 4000000); pwm_enable(ldata->pwm_led); break; #endif default: LED_ERR_LOG(KERN_INFO "%s: bank %d not support blink %d\n", __func__, ldata->bank, val); return -EINVAL; } return count; }
extern void pm8058_drvx_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) { struct pm8058_led_data *ldata; int *pduties; int id, mode; int lut_flag; int milliamps; int enable = 0; ldata = container_of(led_cdev, struct pm8058_led_data, ldev); pwm_disable(ldata->pwm_led); cancel_delayed_work_sync(&ldata->led_delayed_work); id = bank_to_id(ldata->bank); mode = (id == PM_PWM_LED_KPD) ? PM_PWM_CONF_PWM1 : PM_PWM_CONF_PWM1 + (ldata->bank - 4); brightness = (brightness > LED_FULL) ? LED_FULL : brightness; brightness = (brightness < LED_OFF) ? LED_OFF : brightness; LED_INFO_LOG("%s: bank %d brightness %d +\n", __func__, ldata->bank, brightness); enable = (brightness) ? 1 : 0; if (strcmp(ldata->ldev.name, "charming-led") == 0) charming_led_enable(enable); lut_flag = ldata->lut_flag & ~(PM_PWM_LUT_LOOP | PM_PWM_LUT_REVERSE); virtual_key_state = enable; if (flag_hold_virtual_key == 1) { LED_INFO_LOG("%s, Return control by button_backlight flash \n", __func__); return; } if (brightness) { milliamps = (ldata->flags & PM8058_LED_DYNAMIC_BRIGHTNESS_EN) ? ldata->out_current * brightness / LED_FULL : ldata->out_current; pm8058_pwm_config_led(ldata->pwm_led, id, mode, milliamps); if (ldata->flags & PM8058_LED_LTU_EN) { pduties = &duty_array[ldata->start_index]; pm8058_pwm_lut_config(ldata->pwm_led, ldata->period_us, pduties, ldata->duty_time_ms, ldata->start_index, ldata->duites_size, 0, 0, lut_flag); pm8058_pwm_lut_enable(ldata->pwm_led, 0); pm8058_pwm_lut_enable(ldata->pwm_led, 1); } else { pwm_config(ldata->pwm_led, 64000, 64000); pwm_enable(ldata->pwm_led); } } else { if (ldata->flags & PM8058_LED_LTU_EN) { wake_lock_timeout(&pmic_led_wake_lock,HZ*2); pduties = &duty_array[ldata->start_index + ldata->duites_size]; pm8058_pwm_lut_config(ldata->pwm_led, ldata->period_us, pduties, ldata->duty_time_ms, ldata->start_index + ldata->duites_size, ldata->duites_size, 0, 0, lut_flag); pm8058_pwm_lut_enable(ldata->pwm_led, 1); queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work, msecs_to_jiffies(ldata->duty_time_ms * ldata->duites_size)); LED_INFO_LOG("%s: bank %d fade out brightness %d -\n", __func__, ldata->bank, brightness); return; } else pwm_disable(ldata->pwm_led); pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0); } LED_INFO_LOG("%s: bank %d brightness %d -\n", __func__, ldata->bank, brightness); }
static ssize_t pm8058_led_blink_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct led_classdev *led_cdev; struct pm8058_led_data *ldata; int id, mode; int val; /*struct timespec ts1, ts2;*/ val = -1; sscanf(buf, "%u", &val); if (val < 0 || val > 255) return -EINVAL; led_cdev = (struct led_classdev *) dev_get_drvdata(dev); ldata = container_of(led_cdev, struct pm8058_led_data, ldev); id = bank_to_id(ldata->bank); mode = (id == PM_PWM_LED_KPD) ? PM_PWM_CONF_PWM1 : PM_PWM_CONF_PWM1 + (ldata->bank - 4); if (ldata->flags & PM8058_LED_BLINK_EN) pm8058_pwm_config_led(ldata->pwm_led, id, mode, ldata->out_current); printk(KERN_INFO "%s: bank %d blink %d +\n", __func__, ldata->bank, val); switch (val) { case -1: /* stop flashing */ pwm_disable(ldata->pwm_led); if (ldata->flags & PM8058_LED_BLINK_EN) pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0); break; case 0: pwm_disable(ldata->pwm_led); if (led_cdev->brightness) { pwm_config(ldata->pwm_led, 64000, 64000); pwm_enable(ldata->pwm_led); } else { if (ldata->flags & PM8058_LED_BLINK_EN) pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0); } break; case 1: pwm_disable(ldata->pwm_led); pwm_config(ldata->pwm_led, 64000, 2000000); pwm_enable(ldata->pwm_led); break; case 2: cancel_delayed_work_sync(&ldata->led_delayed_work); pwm_disable(ldata->pwm_led); ldata->duty_time_ms = 64; ldata->period_us = 2000000; queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work, msecs_to_jiffies(310)); break; case 3: cancel_delayed_work_sync(&ldata->led_delayed_work); pwm_disable(ldata->pwm_led); ldata->duty_time_ms = 64; ldata->period_us = 2000000; queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work, msecs_to_jiffies(1000)); break; case 4: pwm_disable(ldata->pwm_led); pwm_config(ldata->pwm_led, 1000000, 2000000); #if 0 pwm_conf.pwm_size = 9; pwm_conf.clk = PM_PWM_CLK_1KHZ; pwm_conf.pre_div = PM_PWM_PREDIVIDE_2; pwm_conf.pre_div_exp = 1; pwm_conf.pwm_value = 512/2; pwm_conf.bypass_lut = 1; pwm_configure(ldata->pwm_led, &pwm_conf); #endif pwm_enable(ldata->pwm_led); break; default: printk(KERN_INFO "%s: bank %d blink %d -\n", __func__, ldata->bank, val); return -EINVAL; } printk(KERN_INFO "%s: bank %d blink %d -\n", __func__, ldata->bank, val); return count; }
static void pm8058_drvx_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) { struct pm8058_led_data *ldata; int *pduties; int id, mode; int milliamps; ldata = container_of(led_cdev, struct pm8058_led_data, ldev); pwm_disable(ldata->pwm_led); cancel_delayed_work_sync(&ldata->led_delayed_work); id = bank_to_id(ldata->bank); mode = (id == PM_PWM_LED_KPD) ? PM_PWM_CONF_PWM1 : PM_PWM_CONF_PWM1 + (ldata->bank - 4); brightness = (brightness > LED_FULL) ? LED_FULL : brightness; brightness = (brightness < LED_OFF) ? LED_OFF : brightness; printk(KERN_INFO "%s: bank %d brightness %d +\n", __func__, ldata->bank, brightness); if (brightness) { milliamps = (ldata->flags & PM8058_LED_DYNAMIC_BRIGHTNESS_EN) ? ldata->out_current * brightness / LED_FULL : ldata->out_current; pm8058_pwm_config_led(ldata->pwm_led, id, mode, milliamps); if (ldata->flags & PM8058_LED_LTU_EN) { pduties = &duties[ldata->start_index]; pm8058_pwm_lut_config(ldata->pwm_led, ldata->period_us, pduties, ldata->duty_time_ms, ldata->start_index, ldata->duites_size, 0, 0, ldata->lut_flag); pm8058_pwm_lut_enable(ldata->pwm_led, 0); pm8058_pwm_lut_enable(ldata->pwm_led, 1); } else { pwm_config(ldata->pwm_led, 64000, 64000); pwm_enable(ldata->pwm_led); } } else { if (ldata->flags & PM8058_LED_LTU_EN) { wake_lock(&pmic_led_wake_lock); pduties = &duties[ldata->start_index + ldata->duites_size]; pm8058_pwm_lut_config(ldata->pwm_led, ldata->period_us, pduties, ldata->duty_time_ms, ldata->start_index + ldata->duites_size, ldata->duites_size, 0, 0, ldata->lut_flag); pm8058_pwm_lut_enable(ldata->pwm_led, 1); queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work, msecs_to_jiffies(ldata->duty_time_ms * ldata->duty_time_ms)); printk(KERN_INFO "%s: bank %d fade out brightness %d -\n", __func__, ldata->bank, brightness); return; } else pwm_disable(ldata->pwm_led); pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0); } printk(KERN_INFO "%s: bank %d brightness %d -\n", __func__, ldata->bank, brightness); }