static void pm8058_drvx_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) { struct pm8058_led_data *ldata; int *pduties; ldata = container_of(led_cdev, struct pm8058_led_data, ldev); pmic_low_current_led_set_current(ldata->bank - 4, 0); cancel_delayed_work_sync(&ldata->led_delayed_work); /*pr_err("%s: ++, brightness=%d\n", __func__, brightness);*/ if (brightness) { if (ldata->flags & PM8058_LED_LTU_EN) { pmic_low_current_led_set_ext_signal(ldata->bank - 4, ldata->bank - 3); pmic_low_current_led_set_current(ldata->bank - 4, 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); } else pmic_low_current_led_set_current(ldata->bank - 4, ldata->out_current); } else { if (ldata->flags & PM8058_LED_LTU_EN) { if (ldata->flags & PM8058_LED_FADE_EN) { 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(1000)); return ; } pm8058_pwm_lut_enable(ldata->pwm_led, 0); } pmic_low_current_led_set_current(ldata->bank - 4, 0); } }
static void fbx_leds_pwm_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) { int idx = 0; if (!strcmp(led_cdev->name, "red")) idx = FBX_R_LED; else if (!strcmp(led_cdev->name, "green")) idx = FBX_G_LED; else if (!strcmp(led_cdev->name, "button-backlight")) idx = FBX_CAPS_KEY_LED; dev_info(led_cdev->dev, "%s: IDX[%d] %s %d\n", __func__, idx, brightness?"ON":"OFF", brightness); mutex_lock(&fbx_leds_pwm_dd->led_state_lock); if (brightness) { if (fbx_leds_pwm_dd->led_state[idx] != FBX_LED_ON) { if (idx == FBX_CAPS_KEY_LED) { /* * KD 2011-10-13 * Oh do come on. This board supports PWM brightness and the wonderful * people at Foxconn didn't bother with simple division? Give me a f*ing * break. Fixed so you can CHOOSE how bright your keypad LED is. * 255 * 78 = approximately the previous 20000 value, 0 = 0, otherwise * proportional. Note that we have to */ // pwm_config(fbx_leds_pwm_dd->pwm[idx], 20000, 20000); pwm_config(fbx_leds_pwm_dd->pwm[idx], (brightness * 78), 20000); pwm_enable(fbx_leds_pwm_dd->pwm[idx]); } else { pm8058_pwm_lut_config(fbx_leds_pwm_dd->pwm[idx], 20000, fbx_leds_pwm_dd->duty_pct, 8, 0, 63, 0, 0, PM_PWM_LUT_RAMP_UP); pm8058_pwm_lut_enable(fbx_leds_pwm_dd->pwm[idx], 1); } fbx_leds_pwm_dd->led_state[idx] = FBX_LED_ON; } } else { if (idx == FBX_CAPS_KEY_LED) pwm_disable(fbx_leds_pwm_dd->pwm[idx]); else pm8058_pwm_lut_enable(fbx_leds_pwm_dd->pwm[idx], 0); fbx_leds_pwm_dd->led_state[idx] = FBX_LED_OFF; } mutex_unlock(&fbx_leds_pwm_dd->led_state_lock); }
static void fbx_leds_pwm_led_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) { int idx = 0; if (!strcmp(led_cdev->name, "red")) idx = FBX_R_LED; else if (!strcmp(led_cdev->name, "green")) idx = FBX_G_LED; else if (!strcmp(led_cdev->name, "button-backlight")) idx = FBX_CAPS_KEY_LED; dev_info(led_cdev->dev, "%s: IDX[%d] %s %d\n", __func__, idx, brightness?"ON":"OFF", brightness); mutex_lock(&fbx_leds_pwm_dd->led_state_lock); if (brightness) { if (fbx_leds_pwm_dd->led_state[idx] != FBX_LED_ON) { if (idx == FBX_CAPS_KEY_LED) { pwm_config(fbx_leds_pwm_dd->pwm[idx], (brightness * 78), 20000); //Correction for keypad led brightness by tickerguy@github, Since 255 * 78 = approximately the previous 20000 value, 0 = 0, otherwise proportional pwm_enable(fbx_leds_pwm_dd->pwm[idx]); } else { pm8058_pwm_lut_config(fbx_leds_pwm_dd->pwm[idx], 20000, fbx_leds_pwm_dd->duty_pct, 8, 0, 63, 0, 0, PM_PWM_LUT_RAMP_UP ); pm8058_pwm_lut_enable(fbx_leds_pwm_dd->pwm[idx], 1); } fbx_leds_pwm_dd->led_state[idx] = FBX_LED_ON; } } else { if (idx == FBX_CAPS_KEY_LED) pwm_disable(fbx_leds_pwm_dd->pwm[idx]); else pm8058_pwm_lut_enable(fbx_leds_pwm_dd->pwm[idx], 0); fbx_leds_pwm_dd->led_state[idx] = FBX_LED_OFF; } mutex_unlock(&fbx_leds_pwm_dd->led_state_lock); }
static void led_drvx_do_work(struct work_struct *work) { struct pm8058_led_data *ldata; ldata = container_of(work, struct pm8058_led_data, led_delayed_work.work); /*pr_err("%s: ++, ldata->bank=%d\n", __func__, ldata->bank);*/ pm8058_pwm_lut_enable(ldata->pwm_led, 0); pmic_low_current_led_set_current(ldata->bank - 4, 0); }
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); }
static ssize_t fbx_leds_pwm_blink_solid_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { int on; int idx = 0; struct led_classdev *led_cdev = dev_get_drvdata(dev); if (!strcmp(led_cdev->name, "red")) idx = FBX_R_LED; else if (!strcmp(led_cdev->name, "green")) idx = FBX_G_LED; else if (!strcmp(led_cdev->name, "button-backlight")) idx = FBX_CAPS_KEY_LED; sscanf(buf, "%d", &on); dev_info(led_cdev->dev, "%s: IDX[%d] %s\n", __func__, idx, on?"BLINK":"STOP"); mutex_lock(&fbx_leds_pwm_dd->led_state_lock); if (on) { if (fbx_leds_pwm_dd->led_state[idx] != FBX_LED_BLINK) { pm8058_pwm_lut_config(fbx_leds_pwm_dd->pwm[idx], 20000, fbx_leds_pwm_dd->duty_pct, 8, 0, 63, fbx_leds_pwm_dd->pause_lo_ms, fbx_leds_pwm_dd->pause_hi_ms, PM_PWM_BLINK); pm8058_pwm_lut_enable(fbx_leds_pwm_dd->pwm[idx], 1); fbx_leds_pwm_dd->led_state[idx] = FBX_LED_BLINK; } } else { if (fbx_leds_pwm_dd->led_state[idx] == FBX_LED_BLINK) { pm8058_pwm_lut_enable(fbx_leds_pwm_dd->pwm[idx], 0); fbx_leds_pwm_dd->led_state[idx] = FBX_LED_OFF; } } mutex_unlock(&fbx_leds_pwm_dd->led_state_lock); return size; }
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 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); }