static ssize_t pm8xxx_led_off_timer_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf, size_t count)
{
	struct led_classdev *led_cdev;
	struct pm8xxx_led_data *ldata;
	int min, sec;
	uint16_t off_timer;
	ktime_t interval;
	ktime_t next_alarm;

	min = -1;
	sec = -1;
	sscanf(buf, "%d %d", &min, &sec);

	if (min < 0 || min > 255)
		return -EINVAL;
	if (sec < 0 || sec > 255)
		return -EINVAL;
	led_cdev = (struct led_classdev *) dev_get_drvdata(dev);
	ldata = container_of(led_cdev, struct pm8xxx_led_data, cdev);

	LED_INFO("Setting %s off_timer to %d min %d sec \n", led_cdev->name, min, sec);
	off_timer = min * 60 + sec;

	alarm_cancel(&ldata->led_alarm);
	cancel_work_sync(&ldata->led_work);
	if (off_timer) {
		interval = ktime_set(off_timer, 0);
		next_alarm = ktime_add(alarm_get_elapsed_realtime(), interval);
		alarm_start_range(&ldata->led_alarm, next_alarm, next_alarm);
	}
	return count;
}
static void led_enable_set(u16 reg, int value)
{
	int ret;
	uint8_t ctrldata;

	LED_INFO("%s, reg=0x%X, value=%d\n", __func__, reg, value);

	/* set bit ALTFUNCEN = 0 */
	ret = intel_scu_ipc_ioread8(CHGDETGPO_REG, &ctrldata);
	if (ret) {
		LED_ERR(" IPC Failed to read %d\n", ret);
	}
	ctrldata &= ~(BIT(6));
	ret = intel_scu_ipc_iowrite8(CHGDETGPO_REG, ctrldata);
	if (ret) {
			LED_ERR(" IPC Failed to write %d\n", ret);
	}

	ret = intel_scu_ipc_ioread8(reg, &ctrldata);
	if (ret) {
		LED_ERR(" IPC Failed to read %d\n", ret);
	}
	if (value)
		ctrldata |= (BIT(5)|BIT(4)|BIT(0));
	else
		ctrldata &= ~(BIT(5)|BIT(4)|BIT(0));
	ret = intel_scu_ipc_iowrite8(reg, ctrldata);
	if (ret) {
			LED_ERR(" IPC Failed to write %d\n", ret);
	}
	power_on_flag = value;
}
static ssize_t pm8xxx_led_currents_store(struct device *dev,
					 struct device_attribute *attr,
					 const char *buf, size_t count)
{
	int currents = 0;
	struct led_classdev *led_cdev;
	struct pm8xxx_led_data *ldata;

	sscanf(buf, "%d", &currents);
	if (currents < 0)
		return -EINVAL;

	led_cdev = (struct led_classdev *)dev_get_drvdata(dev);
	ldata = container_of(led_cdev, struct pm8xxx_led_data, cdev);

	LED_INFO("%s: bank %d currents %d\n", __func__, ldata->bank, currents);
	if (currents <= 60)
	ldata->out_current = currents;

	ldata->cdev.brightness_set(led_cdev, 0);
	if (currents)
		ldata->cdev.brightness_set(led_cdev, 255);

	return count;
}
static void led_work_func(struct work_struct *work)
{
	struct pm8xxx_led_data *ldata;
	int rc, offset;
	u8 level;

	ldata = container_of(work, struct pm8xxx_led_data, led_work);
	LED_INFO("%s: bank %d sync %d\n", __func__, ldata->bank, ldata->led_sync);
	pwm_disable(ldata->pwm_led);
	if (ldata->gpio_status_switch != NULL)
		ldata->gpio_status_switch(0);
	if(ldata->led_sync) {
		if (!strcmp(ldata->cdev.name, "green")){
			if (green_back_led_data->gpio_status_switch != NULL)
				green_back_led_data->gpio_status_switch(0);
			pwm_disable(green_back_led_data->pwm_led);
			level = ( 0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
			offset = PM8XXX_LED_OFFSET(green_back_led_data->id);
			green_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
			green_back_led_data->reg |= level;
			rc = pm8xxx_writeb(green_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), green_back_led_data->reg);
		}
		if (!strcmp(ldata->cdev.name, "amber")){
			if (amber_back_led_data->gpio_status_switch != NULL)
				amber_back_led_data->gpio_status_switch(0);
			pwm_disable(amber_back_led_data->pwm_led);
			level = ( 0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
			offset = PM8XXX_LED_OFFSET(amber_back_led_data->id);
			amber_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
			amber_back_led_data->reg |= level;
			rc = pm8xxx_writeb(amber_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), amber_back_led_data->reg);
		}
	}
}
void pm8xxx_led_current_set_for_key(int brightness_key)
{
	int rc, offset;
	static u8 level, register_key;

	LED_INFO("%s brightness_key: %d\n", __func__,brightness_key);
#ifdef CONFIG_BB_MOD
	printk("[BB] current_set_for_key  %d \n", brightness_key);
#endif

	if (brightness_key) {
		flag_hold_virtual_key = 1;
		level = (40 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
		offset = PM8XXX_LED_OFFSET(for_key_led_data->id);
		register_key	= pm8xxxx_led_pwm_mode(for_key_led_data->id);
		register_key &= ~PM8XXX_DRV_LED_CTRL_MASK;
		register_key |= level;
		rc = pm8xxx_writeb(for_key_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), register_key);
		if (rc)
			LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, PM8XXX_ID_LED_0, rc);
			pwm_config(for_key_led_data->pwm_led, 320000, 640000);
			pwm_enable(for_key_led_data->pwm_led);
	} else {
		pwm_disable(for_key_led_data->pwm_led);
		level = (0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
		offset = PM8XXX_LED_OFFSET(for_key_led_data->id);
		register_key	= pm8xxxx_led_pwm_mode(for_key_led_data->id);
		register_key &= ~PM8XXX_DRV_LED_CTRL_MASK;
		register_key |= level;
		rc = pm8xxx_writeb(for_key_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), register_key);
		if (rc)
			LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, PM8XXX_ID_LED_0, rc);
		if (virtual_key_state != 0){
			level = 0;
			register_key = 0;
			level = (40 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
			offset = PM8XXX_LED_OFFSET(for_key_led_data->id);
			register_key    = pm8xxxx_led_pwm_mode(for_key_led_data->id);
			register_key &= ~PM8XXX_DRV_LED_CTRL_MASK;
			register_key |= level;
			rc = pm8xxx_writeb(for_key_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), register_key);
			if (rc)
				LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, PM8XXX_ID_LED_0, rc);
			pwm_config(for_key_led_data->pwm_led, 64000, 64000);
			pwm_enable(for_key_led_data->pwm_led);
		}
		flag_hold_virtual_key = 0;

	}
}
Beispiel #6
0
static void pm8xxx_led_gpio_set(struct led_classdev *led_cdev, enum led_brightness brightness)
{
	struct pm8xxx_led_data *led = container_of(led_cdev,  struct pm8xxx_led_data, cdev);
	LED_INFO("%s, bank:%d, brightness:%d\n", __func__, led->bank, brightness);
	if (led->gpio_status_switch != NULL)
		led->gpio_status_switch(0);
	pwm_disable(led->pwm_led);
	if (brightness) {
		if (led->gpio_status_switch != NULL)
			led->gpio_status_switch(1);
		pwm_config(led->pwm_led, 64000, 64000);
		pwm_enable(led->pwm_led);
	}
}
static ssize_t pm8xxx_led_pwm_coefficient_store(struct device *dev,
					 struct device_attribute *attr,
					 const char *buf, size_t count)
{
	int pwm_coefficient1 = 0;
	struct led_classdev *led_cdev;
	struct pm8xxx_led_data *ldata;

	sscanf(buf, "%d", &pwm_coefficient1);
	if ((pwm_coefficient1 < 0) || (pwm_coefficient1 > 100)) {
		LED_INFO("%s: pwm_coefficient = %d, out of range.\n",
			__func__, pwm_coefficient1);
		return -EINVAL;
	}

	led_cdev = (struct led_classdev *)dev_get_drvdata(dev);
	ldata = container_of(led_cdev, struct pm8xxx_led_data, cdev);

	LED_INFO("%s: pwm_coefficient %d\n", __func__, pwm_coefficient1);

	ldata->pwm_coefficient = pwm_coefficient1;

	return count;
}
static int asus_led_remove(struct i2c_client *client)
{
	struct led_info_priv *priv;
	int i;

	LED_INFO("%s +++ \n", __func__);
	priv = dev_get_drvdata(&client->dev);
	for (i = 0; i < priv->num_leds; i++) {
#ifdef CONTROL_LED
		device_remove_file(priv->leds[i].cdev.dev, &dev_attr_disable);
#endif
		device_remove_file(priv->leds[i].cdev.dev, &dev_attr_blink);
		delete_led(&priv->leds[i]);
	}
	dev_set_drvdata(&client->dev, NULL);
	kfree(priv);

	return 0;
}
static ssize_t pm8xxx_led_lut_coefficient_store(struct device *dev,
					 struct device_attribute *attr,
					 const char *buf, size_t count)
{
	int lut_coefficient1 = 0;
	int i;
	struct led_classdev *led_cdev;
	struct pm8xxx_led_data *ldata;

	sscanf(buf, "%d", &lut_coefficient1);
	if (lut_coefficient1 < 0)
		return -EINVAL;

	led_cdev = (struct led_classdev *)dev_get_drvdata(dev);
	ldata = container_of(led_cdev, struct pm8xxx_led_data, cdev);

	LED_INFO("%s: lut_coefficient %d\n", __func__, lut_coefficient1);
	for (i = 0; i < 16; i++) {
		dutys_array[i] = (*(ldata->duties + i)) * lut_coefficient1 / 100;
	}
	lut_coefficient = lut_coefficient1;
	return count;
}
void led_brightness_set(int led, int brightness) {	//led=0:red, led=1:green
	LED_INFO("%s +++ , brightness=%d, led=%d\n", __func__, brightness, led);
	if(brightness==0) {
		if((led==0)&&(red_led_flag==1)) {
			led_i2c_write(led_client, SELECT1_REG, (led_i2c_read(led_client, SELECT1_REG)&(~RED_BIT)));
			red_led_flag = 0;
		}else if((led==1)&&(green_led_flag==1)) {
			led_i2c_write(led_client, SELECT1_REG, (led_i2c_read(led_client, SELECT1_REG)&(~GREEN_BIT)));
			green_led_flag = 0;
		}
		if((red_led_flag==0)&&(green_led_flag==0)&&(red_blink_flag==0)&&(green_blink_flag==0))
			led_enable_set(INDCAT_EN, 0);
	}else if(brightness>0&&brightness<=255) {
		led_enable_set(INDCAT_EN, 1);
		if(led==0) {
			led_i2c_write(led_client, SELECT1_REG, (led_i2c_read(led_client, SELECT1_REG)|RED_BIT));
			red_led_flag = 1;
		}else if(led==1) {
			led_i2c_write(led_client, SELECT1_REG, (led_i2c_read(led_client, SELECT1_REG)|GREEN_BIT));
			green_led_flag = 1;
		}
	}
}
static int __devinit pm8xxx_led_probe(struct platform_device *pdev)
{
	const struct pm8xxx_led_platform_data *pdata = pdev->dev.platform_data;
	struct pm8xxx_led_configure *curr_led;
	struct pm8xxx_led_data *led, *led_dat;
	int i, j, ret = -ENOMEM;

	if (pdata == NULL) {
		LED_ERR("platform data not supplied\n");
		return -EINVAL;
	}

	led = kcalloc(pdata->num_leds + 1, sizeof(*led), GFP_KERNEL);
	if (led == NULL) {
		LED_ERR("failed to alloc memory\n");
		return -ENOMEM;
	}
	wake_lock_init(&pmic_led_wake_lock, WAKE_LOCK_SUSPEND, "pmic_led");
	g_led_work_queue = create_workqueue("pm8xxx-led");
	if (g_led_work_queue == NULL) {
		LED_ERR("failed to create workqueue\n");
		goto err_create_work_queue;
	}

	for (i = 0; i < pdata->num_leds; i++) {
		curr_led			= &pdata->leds[i];
		led_dat				= &led[i];
		led_dat->cdev.name		= curr_led->name;
		led_dat->id     		= curr_led->flags;
		led_dat->bank			= curr_led->flags;
		led_dat->function_flags		= curr_led->function_flags;
		led_dat->start_index		= curr_led->start_index;
		led_dat->duty_time_ms		= curr_led->duty_time_ms;
		led_dat->period_us		= curr_led->period_us;
		led_dat->duites_size		= curr_led->duites_size;
		led_dat->lut_flag		= curr_led->lut_flag;
		led_dat->out_current		= curr_led->out_current;
		led_dat->duties			= &(curr_led->duties[0]);
		led_dat->led_sync		= curr_led->led_sync;
		led_dat->pwm_led 		= pwm_request(led_dat->bank, led_dat->cdev.name);
		led_dat->lpm_power      = curr_led->lpm_power;
		if (curr_led->duties[1]) {
			for (j = 0; j < 64; j++)
				dutys_array[j] = *(led_dat->duties + j);
		}

		if( curr_led->pwm_coefficient > 0 )
			led_dat->pwm_coefficient	= curr_led->pwm_coefficient;
		else
			led_dat->pwm_coefficient	= 100;

		if (curr_led->blink_duty_per_2sec > 0)
			led_dat->blink_duty_per_2sec = curr_led->blink_duty_per_2sec;
		else
			led_dat->blink_duty_per_2sec = 64000;

		switch (led_dat->id) {
		case PM8XXX_ID_GPIO24:
		case PM8XXX_ID_GPIO25:
		case PM8XXX_ID_GPIO26:
			led_dat->cdev.brightness_set = pm8xxx_led_gpio_set;
			if (curr_led->gpio_status_switch != NULL)
				led_dat->gpio_status_switch = curr_led->gpio_status_switch;
			break;
		case PM8XXX_ID_LED_0:
		case PM8XXX_ID_LED_1:
		case PM8XXX_ID_LED_2:
			led_dat->cdev.brightness_set    = pm8xxx_led_current_set;
			if (led_dat->function_flags & LED_PWM_FUNCTION) {
				led_dat->reg		= pm8xxxx_led_pwm_mode(led_dat->id);
				INIT_DELAYED_WORK(&led[i].fade_delayed_work, led_fade_do_work);
			} else
				led_dat->reg		= PM8XXX_LED_MODE_MANUAL;
			break;
		case PM8XXX_ID_LED_KB_LIGHT:
			break;
		}
		led_dat->cdev.brightness	= LED_OFF;
		led_dat->dev			= &pdev->dev;

		ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
		if (ret) {
			LED_ERR("unable to register led %d,ret=%d\n", led_dat->id, ret);
			goto err_register_led_cdev;
		}
		// blink buttons
		if (led_dat->id == PM8XXX_ID_LED_0) {
			// storing buttons light dev for blinking
			led_cdev_buttons = &led_dat->cdev;
			ret = device_create_file(led_dat->cdev.dev, &dev_attr_blink_buttons);
			if (ret < 0) {
				LED_ERR("%s: Failed to create %d attr blink_buttons\n", __func__, i);
				goto err_register_attr_currents;
			}
		}
		// blink buttons end

		if (led_dat->id >= PM8XXX_ID_LED_2 && led_dat->id <= PM8XXX_ID_LED_0) {
			ret = device_create_file(led_dat->cdev.dev, &dev_attr_currents);
			if (ret < 0) {
				LED_ERR("%s: Failed to create %d attr currents\n", __func__, i);
				goto err_register_attr_currents;
			}
		}

		if (led_dat->id >= PM8XXX_ID_LED_2 && led_dat->id <= PM8XXX_ID_LED_0) {
			ret = device_create_file(led_dat->cdev.dev, &dev_attr_lut_coefficient);
			if (ret < 0) {
				LED_ERR("%s: Failed to create %d attr lut_coefficient\n", __func__, i);
				goto err_register_attr_lut_coefficient;
			}
		}

		if ((led_dat->id <= PM8XXX_ID_GPIO26) || (led_dat->id <= PM8XXX_ID_LED_2) ||
		    (led_dat->id <= PM8XXX_ID_LED_1)) {
			ret = device_create_file(led_dat->cdev.dev, &dev_attr_pwm_coefficient);
			if (ret < 0) {
				LED_ERR("%s: Failed to create %d attr pwm_coefficient\n", __func__, i);
				goto err_register_attr_pwm_coefficient;
			}
		}
		if (led_dat->function_flags & LED_BLINK_FUNCTION) {
			INIT_DELAYED_WORK(&led[i].blink_delayed_work, led_blink_do_work);
			ret = device_create_file(led_dat->cdev.dev, &dev_attr_blink);
			if (ret < 0) {
				LED_ERR("%s: Failed to create %d attr blink\n", __func__, i);
				goto err_register_attr_blink;
			}

			ret = device_create_file(led_dat->cdev.dev, &dev_attr_off_timer);
			if (ret < 0) {
				LED_ERR("%s: Failed to create %d attr off timer\n", __func__, i);
				goto err_register_attr_off_timer;
			}
			alarm_init(&led[i].led_alarm, ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP, led_alarm_handler);
			INIT_WORK(&led[i].led_work, led_work_func); 
		}

		if (!strcmp(led_dat->cdev.name, "button-backlight")) {
			for_key_led_data = led_dat;
		}
		if (!strcmp(led_dat->cdev.name, "green-back")) {
			LED_INFO("%s: green-back, 000 probe, led_dat = %x\n", __func__, (unsigned int)led_dat);
			green_back_led_data = led_dat;
		}
		if (!strcmp(led_dat->cdev.name, "amber-back")) {
			LED_INFO("%s: amber-back\n", __func__);
			amber_back_led_data = led_dat;
		}

	}

	pm8xxx_leds = led;

	platform_set_drvdata(pdev, led);

	return 0;

err_register_attr_off_timer:
	if (i > 0) {
		for (i = i - 1; i >= 0; i--) {
			if (led[i].function_flags & LED_BLINK_FUNCTION)
				device_remove_file(led[i].cdev.dev, &dev_attr_off_timer);
		}
	}
	i = pdata->num_leds;
err_register_attr_blink:
	if (i > 0) {
		for (i = i - 1; i >= 0; i--) {
			if (led[i].function_flags & LED_BLINK_FUNCTION)
				device_remove_file(led[i].cdev.dev, &dev_attr_blink);
		}
	}
	i = pdata->num_leds;
err_register_attr_pwm_coefficient:
	if (i > 0) {
		for (i = i - 1; i >= 0; i--) {
			if (led[i].function_flags <= PM8XXX_ID_GPIO26)
				device_remove_file(led[i].cdev.dev, &dev_attr_pwm_coefficient);
		}
	}
	i = pdata->num_leds;
err_register_attr_lut_coefficient:
	if (i > 0) {
		for (i = i - 1; i >= 0; i--) {
			if (led[i].function_flags >= PM8XXX_ID_LED_2 && led[i].function_flags <= PM8XXX_ID_LED_0)
				device_remove_file(led[i].cdev.dev, &dev_attr_lut_coefficient);
		}
	}
	i = pdata->num_leds;

err_register_attr_currents:
	if (i > 0) {
		for (i = i - 1; i >= 0; i--) {
			if (led[i].function_flags >= PM8XXX_ID_LED_2 && led[i].function_flags <= PM8XXX_ID_LED_0)
				device_remove_file(led[i].cdev.dev, &dev_attr_currents);
		}
	}
	i = pdata->num_leds;
err_register_led_cdev:
	if (i > 0) {
		for (i = i - 1; i >= 0; i--) {
			pwm_free(led[i].pwm_led);
			led_classdev_unregister(&led[i].cdev);
		}
	}
	destroy_workqueue(g_led_work_queue);
err_create_work_queue:
	kfree(led);
	wake_lock_destroy(&pmic_led_wake_lock);
	return ret;
}
static ssize_t pm8xxx_led_blink_store(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf, size_t count)
{
	struct led_classdev *led_cdev;
	struct pm8xxx_led_data *ldata;
	int val;
	int level, offset;
	int led_is_green;

	val = -1;
	sscanf(buf, "%u", &val);
	if (val < 0 || val > 255)
		return -EINVAL;
	current_blink= val;
	led_cdev = (struct led_classdev *) dev_get_drvdata(dev);
	ldata = container_of(led_cdev, struct pm8xxx_led_data, cdev);

	LED_INFO("%s: bank %d blink %d sync %d\n", __func__, ldata->bank, val, ldata->led_sync);
	printk("%s: [BB] bank %d blink %d sync %d\n", __func__, ldata->bank, val, ldata->led_sync);
	if (!strcmp(ldata->cdev.name, "green")) {
		led_is_green = 1;
	}
	if (!strcmp(ldata->cdev.name, "amber")) {
		led_is_green = 0;
	}

	switch (val) {
	case BLINK_STOP:
		if (ldata->gpio_status_switch != NULL)
			ldata->gpio_status_switch(0);
		pwm_disable(ldata->pwm_led);

		if(ldata->led_sync) {
			if 	(!strcmp(ldata->cdev.name, "green")) {
				if (green_back_led_data->gpio_status_switch != NULL)
					green_back_led_data->gpio_status_switch(0);
				pwm_disable(green_back_led_data->pwm_led);
			}
			if 	(!strcmp(ldata->cdev.name, "amber")) {
				if (amber_back_led_data->gpio_status_switch != NULL)
					amber_back_led_data->gpio_status_switch(0);
				pwm_disable(amber_back_led_data->pwm_led);
			}
		}
		if (blink_buttons > 0) {
			if (led_is_green == 1) {
				green_blink_value = 0;
			} else {
				amber_blink_value = 0;
			}
			pm8xxx_buttons_blink(0);
		}
		break;
	case BLINK_UNCHANGE:
		pwm_disable(ldata->pwm_led);
		if (led_cdev->brightness) {
			if (ldata->gpio_status_switch != NULL)
				ldata->gpio_status_switch(1);
			pwm_config(ldata->pwm_led, 6400 * ldata->pwm_coefficient / 100, 6400);
			pwm_enable(ldata->pwm_led);

			if(ldata->led_sync) {
				if	(!strcmp(ldata->cdev.name, "green")) {
					if (green_back_led_data->gpio_status_switch != NULL)
						green_back_led_data->gpio_status_switch(1);
					pwm_config(green_back_led_data->pwm_led, 64000, 64000);
					pwm_enable(green_back_led_data->pwm_led);
				}
				if	(!strcmp(ldata->cdev.name, "amber")) {
					if (amber_back_led_data->gpio_status_switch != NULL)
						amber_back_led_data->gpio_status_switch(1);
					pwm_config(amber_back_led_data->pwm_led, 64000, 64000);
					pwm_enable(amber_back_led_data->pwm_led);
				}
			}
			if (blink_buttons > 0 && val > 0) {
				if (led_is_green == 1) {
					green_blink_value = 1;
				} else {
					amber_blink_value = 1;
				}
				pm8xxx_buttons_blink(1);
			}
		} else {
			pwm_disable(ldata->pwm_led);
			if (ldata->gpio_status_switch != NULL)
				ldata->gpio_status_switch(0);

			if(ldata->led_sync) {
				if (!strcmp(ldata->cdev.name, "green")){
					if (green_back_led_data->gpio_status_switch != NULL)
						green_back_led_data->gpio_status_switch(0);
					pwm_disable(green_back_led_data->pwm_led);
					level = ( 0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
					offset = PM8XXX_LED_OFFSET(green_back_led_data->id);
					green_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
					green_back_led_data->reg |= level;
					pm8xxx_writeb(green_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), green_back_led_data->reg);
				}
				if (!strcmp(ldata->cdev.name, "amber")){
					if (amber_back_led_data->gpio_status_switch != NULL)
						amber_back_led_data->gpio_status_switch(0);
					pwm_disable(amber_back_led_data->pwm_led);
					level = ( 0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
					offset = PM8XXX_LED_OFFSET(amber_back_led_data->id);
					amber_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
					amber_back_led_data->reg |= level;
					pm8xxx_writeb(amber_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), amber_back_led_data->reg);
				}
			}
			if (blink_buttons > 0) {
				if (led_is_green == 1) {
					green_blink_value = 0;
				} else {
					amber_blink_value = 0;
				}
				pm8xxx_buttons_blink(0);
			}
		}
		break;
	case BLINK_64MS_PER_2SEC:
		if (ldata->gpio_status_switch != NULL)
			ldata->gpio_status_switch(1);
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, ldata->blink_duty_per_2sec, 2000000);
		pwm_enable(ldata->pwm_led);

		if(ldata->led_sync) {
			if	(!strcmp(ldata->cdev.name, "green")) {
				if (green_back_led_data->gpio_status_switch != NULL)
					green_back_led_data->gpio_status_switch(1);
				pwm_disable(green_back_led_data->pwm_led);
				pwm_config(green_back_led_data->pwm_led, ldata->blink_duty_per_2sec, 2000000);
				pwm_enable(green_back_led_data->pwm_led);
			}
			if	(!strcmp(ldata->cdev.name, "amber")) {
				if (amber_back_led_data->gpio_status_switch != NULL)
					amber_back_led_data->gpio_status_switch(1);
				pwm_disable(amber_back_led_data->pwm_led);
				pwm_config(amber_back_led_data->pwm_led, ldata->blink_duty_per_2sec, 2000000);
				pwm_enable(amber_back_led_data->pwm_led);
			}
		}
		if (blink_buttons > 0 && val > 0) {
			if (led_is_green == 1) {
				green_blink_value = 1;
			} else {
				amber_blink_value = 1;
			}
			pm8xxx_buttons_blink(1);
		}
		break;
	case BLINK_64MS_ON_310MS_PER_2SEC:
		cancel_delayed_work_sync(&ldata->blink_delayed_work);
		pwm_disable(ldata->pwm_led);
		ldata->duty_time_ms = 64;
		ldata->period_us = 2000000;

		if(ldata->led_sync) {
			if	(!strcmp(ldata->cdev.name, "green")) {
				pwm_disable(green_back_led_data->pwm_led);
				green_back_led_data->duty_time_ms = 64;
				green_back_led_data->period_us = 2000000;
			}
			if	(!strcmp(ldata->cdev.name, "amber")) {
				pwm_disable(amber_back_led_data->pwm_led);
				amber_back_led_data->duty_time_ms = 64;
				amber_back_led_data->period_us = 2000000;
			}
		}
		queue_delayed_work(g_led_work_queue, &ldata->blink_delayed_work,
				   msecs_to_jiffies(310));
		break;
	case BLINK_64MS_ON_2SEC_PER_2SEC:
		cancel_delayed_work_sync(&ldata->blink_delayed_work);
		pwm_disable(ldata->pwm_led);
		ldata->duty_time_ms = 64;
		ldata->period_us = 2000000;

		if(ldata->led_sync) {
			if	(!strcmp(ldata->cdev.name, "green")) {
				pwm_disable(green_back_led_data->pwm_led);
				green_back_led_data->duty_time_ms = 64;
				green_back_led_data->period_us = 2000000;
			}
			if	(!strcmp(ldata->cdev.name, "amber")) {
				pwm_disable(amber_back_led_data->pwm_led);
				amber_back_led_data->duty_time_ms = 64;
				amber_back_led_data->period_us = 2000000;
			}
		}
		queue_delayed_work(g_led_work_queue, &ldata->blink_delayed_work,
				   msecs_to_jiffies(1000));
		break;
	case BLINK_1SEC_PER_2SEC:
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, 1000000, 2000000);
		pwm_enable(ldata->pwm_led);

		if(ldata->led_sync) {
			if	(!strcmp(ldata->cdev.name, "green")) {
				pwm_disable(green_back_led_data->pwm_led);
				pwm_config(green_back_led_data->pwm_led, 1000000, 2000000);
				pwm_enable(green_back_led_data->pwm_led);
			}
			if	(!strcmp(ldata->cdev.name, "amber")) {
				pwm_disable(amber_back_led_data->pwm_led);
				pwm_config(amber_back_led_data->pwm_led, 1000000, 2000000);
				pwm_enable(amber_back_led_data->pwm_led);
			}
		}
		break;
	default:
		LED_ERR("%s: bank %d did not support blink type %d\n", __func__, ldata->bank, val);
		return -EINVAL;
	}

	return count;
}
static void pm8xxx_led_gpio_set(struct led_classdev *led_cdev, enum led_brightness brightness)
{
	int rc, offset;
	u8 level;

	struct pm8xxx_led_data *led = container_of(led_cdev,  struct pm8xxx_led_data, cdev);
	LED_INFO("%s, bank:%d, brightness:%d sync: %d\n", __func__, led->bank, brightness, led->led_sync);
	if (led->gpio_status_switch != NULL)
		led->gpio_status_switch(0);
	pwm_disable(led->pwm_led);
	if(led->led_sync) {
		if (!strcmp(led->cdev.name, "green")){
			if (green_back_led_data->gpio_status_switch != NULL)
				green_back_led_data->gpio_status_switch(0);
			pwm_disable(green_back_led_data->pwm_led);
			level = ( 0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
			offset = PM8XXX_LED_OFFSET(green_back_led_data->id);
			green_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
			green_back_led_data->reg |= level;
			rc = pm8xxx_writeb(green_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), green_back_led_data->reg);
		}
		if (!strcmp(led->cdev.name, "amber")){
			if (amber_back_led_data->gpio_status_switch != NULL)
				amber_back_led_data->gpio_status_switch(0);
			pwm_disable(amber_back_led_data->pwm_led);
			level = ( 0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
			offset = PM8XXX_LED_OFFSET(amber_back_led_data->id);
			amber_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
			amber_back_led_data->reg |= level;
			rc = pm8xxx_writeb(amber_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), amber_back_led_data->reg);
		}
	}
	if (brightness) {
		if (led->gpio_status_switch != NULL)
			led->gpio_status_switch(1);
		pwm_config(led->pwm_led, 6400 * led->pwm_coefficient / 100, 6400);
		pwm_enable(led->pwm_led);
		if(led->led_sync) {
			if 	(!strcmp(led->cdev.name, "green")) {
				if (green_back_led_data->gpio_status_switch != NULL)
					green_back_led_data->gpio_status_switch(1);
				level = (green_back_led_data->out_current << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
				offset = PM8XXX_LED_OFFSET(green_back_led_data->id);
				green_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
				green_back_led_data->reg |= level;
				rc = pm8xxx_writeb(green_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), green_back_led_data->reg);
				pwm_config(green_back_led_data->pwm_led, 64000, 64000);
				pwm_enable(green_back_led_data->pwm_led);
			}
			if 	(!strcmp(led->cdev.name, "amber")) {
				if (amber_back_led_data->gpio_status_switch != NULL)
					amber_back_led_data->gpio_status_switch(1);
				level = (amber_back_led_data->out_current << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
				offset = PM8XXX_LED_OFFSET(amber_back_led_data->id);
				amber_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
				amber_back_led_data->reg |= level;
				rc = pm8xxx_writeb(amber_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), amber_back_led_data->reg);
				pwm_config(amber_back_led_data->pwm_led, 64000, 64000);
				pwm_enable(amber_back_led_data->pwm_led);
			}
		}
	}
}
static void pm8xxx_led_current_set_flagged(struct led_classdev *led_cdev, enum led_brightness brightness, int blink)
{
	struct pm8xxx_led_data *led = container_of(led_cdev,  struct pm8xxx_led_data, cdev);
	int rc, offset;
	u8 level;

	int *pduties;

	LED_INFO("%s, bank:%d, brightness:%d\n", __func__, led->bank, brightness);
	cancel_delayed_work_sync(&led->fade_delayed_work);
	virtual_key_state = brightness;
	if (flag_hold_virtual_key == 1) {
		LED_INFO("%s, key control \n", __func__);
		return;
	}

	if(brightness) {
		level = (led->out_current << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
		offset = PM8XXX_LED_OFFSET(led->id);
		led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
		led->reg |= level;
		rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg);
		if (rc)
			LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc);

		if (led->function_flags & LED_BRETH_FUNCTION) {
			if (blink == 0) {
				buttons_led_is_on = 1;
				// no blink needed
				pduties = &dutys_array[0];
				pm8xxx_pwm_lut_config(led->pwm_led,
							led->period_us,
							pduties,
							led->duty_time_ms,
							led->start_index,
							led->duites_size,
							0, 0,
							led->lut_flag);
			} else {
				pduties = &dutys_array[0];
				// LUT_LOOP for blinking
				pm8xxx_pwm_lut_config(led->pwm_led,
							led->period_us,
							pduties,
							led->duty_time_ms, // slower, 2x
							led->start_index,
							led->duites_size * 8, // 16 duty entries -> original size * 2, + 6 * 8 zeroes for pause
							0, 0,
							PM_PWM_LUT_LOOP | PM_PWM_LUT_PAUSE_HI_EN);
			}
			pm8xxx_pwm_lut_enable(led->pwm_led, 0);
			pm8xxx_pwm_lut_enable(led->pwm_led, 1);
		} else {
			pwm_config(led->pwm_led, 6400 * led->pwm_coefficient / 100, 6400);
			pwm_enable(led->pwm_led);
		}
	} else {
		if (led->function_flags & LED_BRETH_FUNCTION) {
			buttons_led_is_on = 0;
			wake_lock_timeout(&pmic_led_wake_lock, HZ*2);
			pduties = &dutys_array[8];
			pm8xxx_pwm_lut_config(led->pwm_led,
						led->period_us,
						pduties,
						led->duty_time_ms,
						led->start_index,
						led->duites_size,
						0, 0,
						led->lut_flag);
			pm8xxx_pwm_lut_enable(led->pwm_led, 0);
			pm8xxx_pwm_lut_enable(led->pwm_led, 1);
			queue_delayed_work(g_led_work_queue,
						&led->fade_delayed_work,
						msecs_to_jiffies(led->duty_time_ms*led->duites_size));
		} else {
			pwm_disable(led->pwm_led);
			level = (0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
			offset = PM8XXX_LED_OFFSET(led->id);
			led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
			led->reg |= level;
			rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg);
			if (rc)
				LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc);
		}
	}
}
static ssize_t blink_store(struct device *dev,
        struct device_attribute *attr,
        const char *buf, size_t count)
{
	struct led_classdev *led_cdev = dev_get_drvdata(dev);
	struct led_info_data *led_dat = container_of(led_cdev, struct led_info_data, cdev);
	int value;

	sscanf(buf, "%d", &value);
	LED_INFO("%s +++, value=%d, led=%s\n", __func__, value, led_dat->cdev.name);
#ifdef CONTROL_LED
	if(disable_led_flag==0) {
#endif
		if(value==0) {
			/* stop blink */
			if((!strcmp(led_dat->cdev.name, "red"))&&(power_on_flag==1)) {
				led_i2c_write(led_client, SELECT1_REG, (led_i2c_read(led_client, SELECT1_REG)&(~RED_BIT)));
				led_i2c_write(led_client, SELECT1_REG, (led_i2c_read(led_client, SELECT2_REG)&(~RED_BIT)));
				red_blink_flag = 0;
				red_led_flag = 0;
			}else if((!strcmp(led_dat->cdev.name, "green"))&&(power_on_flag==1)) {
				led_i2c_write(led_client, SELECT1_REG, (led_i2c_read(led_client, SELECT1_REG)&(~GREEN_BIT)));
				led_i2c_write(led_client, SELECT1_REG, (led_i2c_read(led_client, SELECT2_REG)&(~GREEN_BIT)));
				green_blink_flag = 0;
				green_led_flag = 0;
			}
			/*power off*/
			if((red_led_flag==0)&&(green_led_flag==0)&&(red_blink_flag==0)&&(green_blink_flag==0))
				led_enable_set(INDCAT_EN, 0);
		}
		else if(value>0&&value<=100) {
			/* power on*/
			led_enable_set(INDCAT_EN, 1);
			/* start blink */
			if(!strcmp(led_dat->cdev.name, "red")) {
				led_i2c_write(led_client, SELECT1_REG, (led_i2c_read(led_client, SELECT1_REG)|RED_BIT));
				led_i2c_write(led_client, SELECT2_REG, (led_i2c_read(led_client, SELECT2_REG)|RED_BIT));
				led_i2c_write(led_client, FADE_ON_TIME_REG, 0x40);
				led_i2c_write(led_client, FULLY_ON_TIME_REG, 0x41);
				led_i2c_write(led_client, F_FULLY_OFF_TIME_REG, 0x4C);
				led_i2c_write(led_client, FADE_OFF_TIME_REG, 0x40);
				led_i2c_write(led_client, S_FULLY_OFF_TIME_REG, 0x4C);
				red_led_flag = 1;
				red_blink_flag = 1;
			}else if(!strcmp(led_dat->cdev.name, "green")) {
				led_i2c_write(led_client, SELECT1_REG, (led_i2c_read(led_client, SELECT1_REG)|GREEN_BIT));
				led_i2c_write(led_client, SELECT2_REG, (led_i2c_read(led_client, SELECT2_REG)|GREEN_BIT));
				led_i2c_write(led_client, FADE_ON_TIME_REG, 0x40);
				led_i2c_write(led_client, FULLY_ON_TIME_REG, 0x41);
				led_i2c_write(led_client, F_FULLY_OFF_TIME_REG, 0x4A);
				led_i2c_write(led_client, FADE_OFF_TIME_REG, 0x40);
				led_i2c_write(led_client, S_FULLY_OFF_TIME_REG, 0x4A);
				green_led_flag = 1;
				green_blink_flag = 1;
			}
		}else
			LED_INFO("%s, incorrect pwm value:%d (0-100).\n", __func__, value);
#ifdef CONTROL_LED
	}
#endif
	return count;
}
Beispiel #16
0
extern void pm8xxx_led_current_set(struct led_classdev *led_cdev, enum led_brightness brightness)
{
    struct pm8xxx_led_data *led = container_of(led_cdev,  struct pm8xxx_led_data, cdev);
	int rc, offset;
	u8 level;

	int *pduties;

	LED_INFO("%s, bank:%d, brightness:%d\n", __func__, led->bank, brightness);
	cancel_delayed_work_sync(&led->fade_delayed_work);
	virtual_key_state = brightness;
	if (flag_hold_virtual_key == 1) {
		LED_INFO("%s, key control \n", __func__);
		return;
	}

	if(brightness) {
		level = (led->out_current << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
		offset = PM8XXX_LED_OFFSET(led->id);
		led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
		led->reg |= level;
		rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg);
		if (rc)
			LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc);

		if (led->function_flags & LED_BRETH_FUNCTION) {
			pduties = led->duties;
			pm8xxx_pwm_lut_config(led->pwm_led,
						led->period_us,
						pduties,
						led->duty_time_ms,
						led->start_index,
						led->duites_size,
						0, 0,
						led->lut_flag);
			pm8xxx_pwm_lut_enable(led->pwm_led, 0);
			pm8xxx_pwm_lut_enable(led->pwm_led, 1);
		} else {
			pwm_config(led->pwm_led, 64000, 64000);
			pwm_enable(led->pwm_led);
		}
	} else {
		if (led->function_flags & LED_BRETH_FUNCTION) {
			wake_lock_timeout(&pmic_led_wake_lock, HZ*2);
			pduties = led->duties + led->duites_size;
			pm8xxx_pwm_lut_config(led->pwm_led,
						led->period_us,
						pduties,
						led->duty_time_ms,
						led->start_index,
						led->duites_size,
						0, 0,
						led->lut_flag);
			pm8xxx_pwm_lut_enable(led->pwm_led, 0);
			pm8xxx_pwm_lut_enable(led->pwm_led, 1);
			queue_delayed_work(g_led_work_queue,
						&led->fade_delayed_work,
						msecs_to_jiffies(led->duty_time_ms*led->duites_size));
		} else {
			pwm_disable(led->pwm_led);
			level = (0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
			offset = PM8XXX_LED_OFFSET(led->id);
			led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
			led->reg |= level;
			rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg);
			if (rc)
				LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc);
		}
	}
	// checking for buttons device
	if (led_cdev_buttons == led_cdev)
	{
		printk("[BB] led_current_set %d \n", brightness);
		if (brightness>0)
		{
			// screen turning off together with buttons led
			buttons_turning_on_with_screen_on = 1;
		} else
		{
			// screen turning off together without buttons led
			buttons_turning_on_with_screen_on = 0;
		}
	}
	// no blink needed
	pm8xxx_led_current_set_flagged( led_cdev, brightness, 0);
}
Beispiel #17
0
static ssize_t pm8xxx_led_blink_store(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf, size_t count)
{
	struct led_classdev *led_cdev;
	struct pm8xxx_led_data *ldata;
	int val;

	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 pm8xxx_led_data, cdev);

	LED_INFO("%s: bank %d blink %d\n", __func__, ldata->bank, val);

	switch (val) {
	case BLINK_STOP:
		if (ldata->gpio_status_switch != NULL)
			ldata->gpio_status_switch(0);
		pwm_disable(ldata->pwm_led);
		break;
	case BLINK_UNCHANGE:
		pwm_disable(ldata->pwm_led);
		if (led_cdev->brightness) {
			if (ldata->gpio_status_switch != NULL)
				ldata->gpio_status_switch(1);
			pwm_config(ldata->pwm_led, 64000, 64000);
			pwm_enable(ldata->pwm_led);
		} else {
			pwm_disable(ldata->pwm_led);
			if (ldata->gpio_status_switch != NULL)
				ldata->gpio_status_switch(0);
		}
		break;
	case BLINK_64MS_PER_2SEC:
		if (ldata->gpio_status_switch != NULL)
			ldata->gpio_status_switch(1);
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, 64000, 2000000);
		pwm_enable(ldata->pwm_led);
		break;
	case BLINK_64MS_ON_310MS_PER_2SEC:
		cancel_delayed_work_sync(&ldata->blink_delayed_work);
		pwm_disable(ldata->pwm_led);
		ldata->duty_time_ms = 64;
		ldata->period_us = 2000000;
		queue_delayed_work(g_led_work_queue, &ldata->blink_delayed_work,
				   msecs_to_jiffies(310));
		break;
	case BLINK_64MS_ON_2SEC_PER_2SEC:
		cancel_delayed_work_sync(&ldata->blink_delayed_work);
		pwm_disable(ldata->pwm_led);
		ldata->duty_time_ms = 64;
		ldata->period_us = 2000000;
		queue_delayed_work(g_led_work_queue, &ldata->blink_delayed_work,
				   msecs_to_jiffies(1000));
		break;
	case BLINK_1SEC_PER_2SEC:
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, 1000000, 2000000);
		pwm_enable(ldata->pwm_led);
		break;
	default:
		LED_ERR("%s: bank %d did not support blink type %d\n", __func__, ldata->bank, val);
		return -EINVAL;
	}

	return count;
}
Beispiel #18
0
static void pm8xxx_led_current_set(struct led_classdev *led_cdev, enum led_brightness brightness)
{
	struct pm8xxx_led_data *led = container_of(led_cdev,  struct pm8xxx_led_data, cdev);
	int rc, offset;
	u8 level;

	int *pduties;

	LED_INFO("%s, bank:%d, brightness:%d\n", __func__, led->bank, brightness);
	cancel_delayed_work_sync(&led->fade_delayed_work);
	virtual_key_state = brightness;
	if (flag_hold_virtual_key == 1) {
		LED_INFO("%s, key control \n", __func__);
		return;
	}

	if(brightness) {
		level = (led->out_current << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;

		offset = PM8XXX_LED_OFFSET(led->id);
		led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
		led->reg |= level;
		rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg);
		if (rc)
			LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc);

		if (led->function_flags & LED_BRETH_FUNCTION) {
			pduties = led->duties;
			pm8xxx_pwm_lut_config(led->pwm_led,
						led->period_us,
						pduties,
						led->duty_time_ms,
						led->start_index,
						led->duites_size,
						0, 0,
						led->lut_flag);
			pm8xxx_pwm_lut_enable(led->pwm_led, 0);
			pm8xxx_pwm_lut_enable(led->pwm_led, 1);
		} else {
			pwm_config(led->pwm_led, 64000, 64000);
			pwm_enable(led->pwm_led);
		}
	} else {
		if (led->function_flags & LED_BRETH_FUNCTION) {
			pduties = led->duties + led->duites_size;
			pm8xxx_pwm_lut_config(led->pwm_led,
						led->period_us,
						pduties,
						led->duty_time_ms,
						led->start_index,
						led->duites_size,
						0, 0,
						led->lut_flag);
			pm8xxx_pwm_lut_enable(led->pwm_led, 0);
			pm8xxx_pwm_lut_enable(led->pwm_led, 1);
			queue_delayed_work(g_led_work_queue,
						&led->fade_delayed_work,
						msecs_to_jiffies(led->duty_time_ms*led->duites_size));
		} else {
			pwm_disable(led->pwm_led);
			level = (0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
			offset = PM8XXX_LED_OFFSET(led->id);
			led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
			led->reg |= level;
			rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg);
			if (rc)
				LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc);
		}
	}
}