Ejemplo n.º 1
0
static ssize_t led_r_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	struct leds_dev_data *info = dev_get_drvdata(dev);
	struct pm8xxx_led_config *led_cfg;
	unsigned int brightness = 0;
	unsigned int num_digits = size;
	unsigned int loop_cnt = 0;
	int temp;

	printk(KERN_DEBUG "led_r brightness =%s, numdigs=%u\n",
			buf, num_digits);
	while ((buf[loop_cnt] >= '0') && (buf[loop_cnt] <= '9') &&
			(loop_cnt < num_digits)) {
		brightness = brightness*10 + (buf[loop_cnt] - '0');
		loop_cnt++;
	}

	printk(KERN_DEBUG "led_r brightness =%u\n", brightness);

	if (brightness < 0 || brightness > 255) {
		printk(KERN_WARNING "led_r brightness is out of range");
		return -1;
	}
	temp = pm8xxx_led_get(&info->led[PM8XXX_LED_PAT7_RED].cdev);

	if (brightness == 0 && temp == 0)
		return size;
	if (atomic_read(&info->op_flag))
		atomic_set(&info->op_flag, 0);

	pm8xxx_led_work_pat_led_off(info);

	mutex_lock(&info->led_work_lock);

	led_cfg = &info->pdata->configs[PM8XXX_LED_PAT7_RED];

	pm8xxx_set_led_mode_and_max_brightness(&info->led[PM8XXX_LED_PAT7_RED],
				led_cfg->mode, led_cfg->max_current);
	__pm8xxx_led_work(&info->led[PM8XXX_LED_PAT7_RED],
			led_cfg->max_current);
	if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL)
		pm8xxx_led_pwm_configure(&info->led[PM8XXX_LED_PAT7_RED], 0, 0);

	if (brightness && (info->pdata->led_power_on))
		info->pdata->led_power_on(1);
	pm8xxx_led_set(&info->led[PM8XXX_LED_PAT7_RED].cdev, brightness);
	mutex_unlock(&info->led_work_lock);

	return size;

}
Ejemplo n.º 2
0
static void pm8xxx_led_work(struct work_struct *work)
{
	int rc;

	struct pm8xxx_led_data *led = container_of(work,
					 struct pm8xxx_led_data, work);

	if (led->pwm_dev == NULL) {
		__pm8xxx_led_work(led, led->cdev.brightness);
	} else {
		rc = pm8xxx_led_pwm_work(led);
		if (rc)
			pr_err("could not configure PWM mode for LED:%d\n",
								led->id);
	}
}
Ejemplo n.º 3
0
static void pm8xxx_led_work_pat_led_off(struct leds_dev_data *info)
{
	int loop_cnt;

	mutex_lock(&info->led_work_lock);
	if (info->pdata->led_power_on)
		info->pdata->led_power_on(0);
	for (loop_cnt = 0 ; loop_cnt < ((info->pdata->led_core->num_leds) - 1) ;
		      loop_cnt++) {
		__pm8xxx_led_work(&info->led[loop_cnt], 0);
		if (info->led[loop_cnt].pwm_dev != NULL)
			pwm_free(info->led[loop_cnt].pwm_dev);
	}

	mutex_unlock(&info->led_work_lock);

}
Ejemplo n.º 4
0
static void pm8xxx_led_work_pat_full_chrg(struct work_struct *work)
{
	struct leds_dev_data *info =
		container_of(work, struct leds_dev_data, work_pat_full_chrg);
	struct pm8xxx_led_config *led_cfg;

	if (!atomic_read(&info->op_flag)) {
		pr_info("LED turns off before turns on, op:%d\n",
						atomic_read(&info->op_flag));
		return;
	}

	pm8xxx_led_work_pat_led_off(info);
	mutex_lock(&info->led_work_lock);

		led_cfg = &info->pdata->configs[PM8XXX_LED_PAT5_GREEN];

	pm8xxx_set_led_mode_and_max_brightness(
	&info->led[PM8XXX_LED_PAT5_GREEN],
	led_cfg->mode, led_cfg->max_current);

	__pm8xxx_led_work(&info->led[PM8XXX_LED_PAT5_GREEN],
	led_cfg->max_current);

	if (low_powermode) {
		led_cfg->pwm_duty_cycles->duty_pcts[0] 
				= 100/LOW_POWERMODE_DIVIDER;
		led_cfg->pwm_duty_cycles->duty_pcts[1] 
				= 100/LOW_POWERMODE_DIVIDER;
	} else {
		led_cfg->pwm_duty_cycles->duty_pcts[0] = 100;
		led_cfg->pwm_duty_cycles->duty_pcts[1] = 100;
	}

	if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL)
		pm8xxx_led_pwm_configure(&info->led[PM8XXX_LED_PAT5_GREEN],
		0, 0);

	pm8xxx_led_set(&info->led[PM8XXX_LED_PAT5_GREEN].cdev,
			led_cfg->max_current);

	mutex_unlock(&info->led_work_lock);

}
Ejemplo n.º 5
0
static void pm8xxx_led_work_pat_powering(struct work_struct *work)
{
	struct leds_dev_data *info =
		container_of(work, struct leds_dev_data, work_pat_powering);
	struct pm8xxx_led_config *led_cfg;
	int loop_cnt;

	if (!atomic_read(&info->op_flag)) {
		pr_info("LED turns off before turns on, op:%d\n",
						atomic_read(&info->op_flag));
		return;
	}

	pm8xxx_led_work_pat_led_off(info);
	mutex_lock(&info->led_work_lock);

	for (loop_cnt = PM8XXX_LED_PAT6_GREEN ;
			loop_cnt <= PM8XXX_LED_PAT6_BLUE ;
			loop_cnt++) {
		led_cfg = &info->pdata->configs[loop_cnt];

		pm8xxx_set_led_mode_and_max_brightness(&info->led[loop_cnt],
				led_cfg->mode, led_cfg->max_current);

		__pm8xxx_led_work(&info->led[loop_cnt], led_cfg->max_current);

		if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL)
			pm8xxx_led_pwm_configure(&info->led[loop_cnt],
					200, 200);
	}
	pm8xxx_led_set(&info->led[PM8XXX_LED_PAT6_GREEN].cdev,
			led_cfg->max_current);
	pm8xxx_led_set(&info->led[PM8XXX_LED_PAT6_BLUE].cdev,
			led_cfg->max_current);

	mutex_unlock(&info->led_work_lock);
}
Ejemplo n.º 6
0
static ssize_t led_blink_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	struct leds_dev_data *info = dev_get_drvdata(dev);
	struct pm8xxx_led_config *led_cfg;
	unsigned int brightness_r = 0;
	unsigned int brightness_g = 0;
	unsigned int brightness_b = 0;
	unsigned int loop_cnt = 0;
	unsigned int delayon = 0;
	unsigned int delayoff = 0;
	unsigned int argb_count = 0;
	bool is_blinking;

	printk(KERN_ALERT "[LED_blink_store] is \"%s\" (pid %i)\n",
	current->comm, current->pid);
	printk(KERN_ALERT "led_blink input =%s, size=%d\n", buf, size);

	if (size < 7) {
		printk(KERN_DEBUG "led_blink: Invlid input\n");
		return size;
	}
	if (buf[8] == ' ') { /*case of RGB delay_on delay_off*/
		for (loop_cnt = 9; loop_cnt < size-1; loop_cnt++) {
			delayon = delayon*10 + (buf[loop_cnt] - '0');
			if (buf[loop_cnt+1] == ' ') {
				loop_cnt += 2;
				break;
			}
		}
		for (; loop_cnt < size-1; loop_cnt++)
			delayoff = delayoff*10 + (buf[loop_cnt] - '0');
	}
	 else if (buf[10] == ' ') { /*case of ARGB delay_on delay_off*/
		argb_count = 1;
		for (loop_cnt = 11; loop_cnt < size-1; loop_cnt++) {
				delayon = delayon*10 + (buf[loop_cnt] - '0');
				if (buf[loop_cnt+1] == ' ') {
					loop_cnt += 2;
					break;
				}
			}
		for (; loop_cnt < size-1; loop_cnt++)
			delayoff = delayoff*10 + (buf[loop_cnt] - '0');
		}
	 else if (size > 9) {  /*case of ARGB*/
		argb_count = 1;
	}
	atomic_set(&info->op_flag , 0);
	/*buf[0], buf[1] contains 0x, so ignore it. case of RGB*/
	if (!argb_count) {
		brightness_r = hex_to_dec(buf[2], buf[3]);
		brightness_g = hex_to_dec(buf[4], buf[5]);
		brightness_b = hex_to_dec(buf[6], buf[7]);
	}
	/*buf[0], buf[1] contains 0x, so ignore it.
	buf[2], buf[3] contains A (alpha value), ignore it.case of ARGB*/
	 else {
		brightness_r = hex_to_dec(buf[4], buf[5]);
		brightness_g = hex_to_dec(buf[6], buf[7]);
		brightness_b = hex_to_dec(buf[8], buf[9]);
	}

	is_blinking = delayon > 0 || delayoff > 0;

	pm8xxx_led_work_pat_led_off(info);
	mutex_lock(&info->led_work_lock);

	led_cfg = &info->pdata->configs[PM8XXX_LED_PAT8_BLUE];
	brightness_b = brightness_b * 100 / 255;
	led_cfg->pwm_duty_cycles->duty_pcts[0] = is_blinking ? 0 : brightness_b;
	led_cfg->pwm_duty_cycles->duty_pcts[1] = brightness_b;
	pm8xxx_set_led_mode_and_max_brightness(&info->led[PM8XXX_LED_PAT8_BLUE],
				led_cfg->mode, led_cfg->max_current);
	__pm8xxx_led_work(&info->led[PM8XXX_LED_PAT8_BLUE],
			led_cfg->max_current);
	if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL)
		pm8xxx_led_pwm_configure(&info->led[PM8XXX_LED_PAT8_BLUE],
				delayoff, delayon);

	led_cfg = &info->pdata->configs[PM8XXX_LED_PAT8_GREEN];
	brightness_g = brightness_g * 100 / 255;
	led_cfg->pwm_duty_cycles->duty_pcts[0] = is_blinking ? 0 : brightness_g;
	led_cfg->pwm_duty_cycles->duty_pcts[1] = brightness_g;
	pm8xxx_set_led_mode_and_max_brightness(
			&info->led[PM8XXX_LED_PAT8_GREEN],
			led_cfg->mode, led_cfg->max_current);
	__pm8xxx_led_work(&info->led[PM8XXX_LED_PAT8_GREEN],
			led_cfg->max_current);
	if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL)
		pm8xxx_led_pwm_configure(&info->led[PM8XXX_LED_PAT8_GREEN],
				delayoff, delayon);

	led_cfg = &info->pdata->configs[PM8XXX_LED_PAT8_RED];
	brightness_r = brightness_r * 100 / 255;
	led_cfg->pwm_duty_cycles->duty_pcts[0] = is_blinking ? 0 : brightness_r;
	led_cfg->pwm_duty_cycles->duty_pcts[1] = brightness_r;
	pm8xxx_set_led_mode_and_max_brightness(&info->led[PM8XXX_LED_PAT8_RED],
				led_cfg->mode, led_cfg->max_current);
	__pm8xxx_led_work(&info->led[PM8XXX_LED_PAT8_RED],
			led_cfg->max_current);
	if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL)
		pm8xxx_led_pwm_configure(&info->led[PM8XXX_LED_PAT8_RED],
		delayoff, delayon);

	if ((brightness_r || brightness_g || brightness_b) &&
	(info->pdata->led_power_on))
		info->pdata->led_power_on(1);
	printk(KERN_DEBUG "[LED] USER : R:%d,G:%d,B:%d\n",
		brightness_r, brightness_g, brightness_b);
	pm8xxx_led_set(&info->led[PM8XXX_LED_PAT8_RED].cdev,
		led_cfg->max_current);
	pm8xxx_led_set(&info->led[PM8XXX_LED_PAT8_GREEN].cdev,
		led_cfg->max_current);
	pm8xxx_led_set(&info->led[PM8XXX_LED_PAT8_BLUE].cdev,
		led_cfg->max_current);

	mutex_unlock(&info->led_work_lock);

	return size;

}
Ejemplo n.º 7
0
static int __devinit pm8xxx_led_probe(struct platform_device *pdev)
{
	const struct led_platform_data *pcore_data;
	struct led_info *curr_led;
	struct pm8xxx_led_config *led_cfg;
	struct pm8xxx_led_data *led, *led_dat;
	struct leds_dev_data *info;
	struct pm8xxx_led_platform_data *pdata ;
	int rc = -1, i = 0;
	pdata = pdev->dev.platform_data;
	if (pdata == NULL) {
		dev_err(&pdev->dev, "platform data not supplied\n");
		return -EINVAL;
	}

	pcore_data = pdata->led_core;

	if (pcore_data->num_leds != pdata->num_configs) {
		dev_err(&pdev->dev, "#no. of led configs and #no. of led"
				"entries are not equal\n");
		return -EINVAL;
	}

	led = kcalloc(pcore_data->num_leds, sizeof(*led), GFP_KERNEL);
	if (led == NULL) {
		dev_err(&pdev->dev, "failed to alloc memory\n");
		return -ENOMEM;
	}

	info = kzalloc(sizeof(*info), GFP_KERNEL);
	if (!info) {
		dev_err(&pdev->dev, "fail to memory allocation.\n");
		rc = -ENOMEM;
		goto fail_mem_check;
	}

	info->pdata = pdata;
	info->led = led;

	for (i = 0; i < pcore_data->num_leds; i++) {
		curr_led	= &pcore_data->leds[i];
		led_dat		= &led[i];
		led_cfg		= &pdata->configs[i];

		led_dat->id     = led_cfg->id;
		led_dat->pwm_channel = led_cfg->pwm_channel;
		led_dat->pwm_period_us = led_cfg->pwm_period_us;
		led_dat->pwm_duty_cycles = led_cfg->pwm_duty_cycles;

		if (!((led_dat->id >= PM8XXX_ID_LED_KB_LIGHT) &&
				(led_dat->id <= PM8XXX_ID_FLASH_LED_1))) {
			dev_err(&pdev->dev, "invalid LED ID (%d) specified\n",
						 led_dat->id);
			rc = -EINVAL;
			goto fail_id_check;
		}

		led_dat->cdev.name		= curr_led->name;
		led_dat->cdev.default_trigger   = curr_led->default_trigger;
		led_dat->cdev.brightness_set    = pm8xxx_led_set;
		led_dat->cdev.brightness_get    = pm8xxx_led_get;
		led_dat->cdev.brightness	= LED_OFF;
		led_dat->cdev.flags		= curr_led->flags;
		led_dat->dev			= &pdev->dev;

		rc =  get_init_value(led_dat, &led_dat->reg);
		if (rc < 0)
			goto fail_id_check;

		rc = pm8xxx_set_led_mode_and_max_brightness(led_dat,
					led_cfg->mode, led_cfg->max_current);
		if (rc < 0)
			goto fail_id_check;

		mutex_init(&led_dat->lock);
		INIT_WORK(&led_dat->work, pm8xxx_led_work);
		if (led_dat->id == PM8XXX_ID_LED_KB_LIGHT)
			__pm8xxx_led_work(led_dat, LED_FULL);
		else
			__pm8xxx_led_work(led_dat, LED_OFF);
	}

	platform_set_drvdata(pdev, info);

	led_virtual_dev(info);

	low_powermode = 0;

	return 0;

fail_id_check:
	if (i > 0) {
		for (i = i - 1; i >= 0; i--) {
			mutex_destroy(&led[i].lock);
			led_classdev_unregister(&led[i].cdev);
			if (led[i].pwm_dev != NULL)
				pwm_free(led[i].pwm_dev);
		}
	}
	kfree(info);
fail_mem_check:
	kfree(led);
	return rc;
}
static int __devinit pm8xxx_led_probe(struct platform_device *pdev)
{
	const struct pm8xxx_led_platform_data *pdata = pdev->dev.platform_data;
	const struct led_platform_data *pcore_data;
	struct led_info *curr_led;
	struct pm8xxx_led_data *led, *led_dat;
	struct pm8xxx_led_config *led_cfg;
	int rc, i;

	if (pdata == NULL) {
		dev_err(&pdev->dev, "platform data not supplied\n");
		return -EINVAL;
	}

	pcore_data = pdata->led_core;

	if (pcore_data->num_leds != pdata->num_configs) {
		dev_err(&pdev->dev, "#no. of led configs and #no. of led"
				"entries are not equal\n");
		return -EINVAL;
	}

	led = kcalloc(pcore_data->num_leds, sizeof(*led), GFP_KERNEL);
	if (led == NULL) {
		dev_err(&pdev->dev, "failed to alloc memory\n");
		return -ENOMEM;
	}

	for (i = 0; i < pcore_data->num_leds; i++) {
		curr_led	= &pcore_data->leds[i];
		led_dat		= &led[i];
		led_cfg		= &pdata->configs[i];

		led_dat->id     = led_cfg->id;
		led_dat->pwm_channel = led_cfg->pwm_channel;
		led_dat->pwm_period_us = led_cfg->pwm_period_us;
		led_dat->pwm_duty_cycles = led_cfg->pwm_duty_cycles;
#ifdef CONFIG_MACH_MSM8960_MMI
		led_dat->led_ctrl = led_cfg->led_ctrl;
		led_dat->do_blink = 0;
		if (led_dat->pwm_duty_cycles == NULL)
			led_dat->pwm_duty_cycles = &pm8xxx_default_pwm_duty_cycles;
#endif

		if (!((led_dat->id >= PM8XXX_ID_LED_KB_LIGHT) &&
				(led_dat->id <= PM8XXX_ID_FLASH_LED_1))) {
			dev_err(&pdev->dev, "invalid LED ID (%d) specified\n",
						 led_dat->id);
			rc = -EINVAL;
			goto fail_id_check;
		}

		led_dat->cdev.name		= curr_led->name;
		led_dat->cdev.default_trigger   = curr_led->default_trigger;
		led_dat->cdev.brightness_set    = pm8xxx_led_set;
		led_dat->cdev.brightness_get    = pm8xxx_led_get;
#ifdef CONFIG_MACH_MSM8960_MMI
		led_dat->cdev.blink_set         = pm8xxx_led_blink_set;
#endif
		led_dat->cdev.brightness	= LED_OFF;
		led_dat->cdev.flags		= curr_led->flags;
		led_dat->dev			= &pdev->dev;

		rc =  get_init_value(led_dat, &led_dat->reg);
		if (rc < 0)
			goto fail_id_check;

		rc = pm8xxx_set_led_mode_and_max_brightness(led_dat,
					led_cfg->mode, led_cfg->max_current);
		if (rc < 0)
			goto fail_id_check;

		mutex_init(&led_dat->lock);
		INIT_WORK(&led_dat->work, pm8xxx_led_work);

		rc = led_classdev_register(&pdev->dev, &led_dat->cdev);
		if (rc) {
			dev_err(&pdev->dev, "unable to register led %d,rc=%d\n",
						 led_dat->id, rc);
			goto fail_id_check;
		}

		if (led_cfg->mode != PM8XXX_LED_MODE_MANUAL) {
			__pm8xxx_led_work(led_dat,
					led_dat->cdev.max_brightness);

			if (led_dat->pwm_channel != -1) {
				led_dat->cdev.max_brightness = LED_FULL;
				rc = pm8xxx_led_pwm_configure(led_dat);
				if (rc) {
					dev_err(&pdev->dev, "failed to "
					"configure LED, error: %d\n", rc);
					goto fail_id_check;
				}
			}
		} else {
			__pm8xxx_led_work(led_dat, LED_OFF);
		}
	}

	platform_set_drvdata(pdev, led);

	return 0;

fail_id_check:
	if (i > 0) {
		for (i = i - 1; i >= 0; i--) {
			mutex_destroy(&led[i].lock);
			led_classdev_unregister(&led[i].cdev);
			if (led[i].pwm_dev != NULL)
				pwm_free(led[i].pwm_dev);
		}
	}
	kfree(led);
	return rc;
}