예제 #1
0
static int blinkm_led_common_set(struct led_classdev *led_cdev,
				 enum led_brightness value, int color)
{
	/* led_brightness is 0, 127 or 255 - we just use it here as-is */
	struct blinkm_led *led = cdev_to_blmled(led_cdev);
	struct blinkm_data *data = i2c_get_clientdata(led->i2c_client);

	switch (color) {
	case RED:
		/* bail out if there's no change */
		if (data->next_red == (u8) value)
			return 0;
		data->next_red = (u8) value;
		break;
	case GREEN:
		/* bail out if there's no change */
		if (data->next_green == (u8) value)
			return 0;
		data->next_green = (u8) value;
		break;
	case BLUE:
		/* bail out if there's no change */
		if (data->next_blue == (u8) value)
			return 0;
		data->next_blue = (u8) value;
		break;

	default:
		dev_err(&led->i2c_client->dev, "BlinkM: unknown color.\n");
		return -EINVAL;
	}

	blinkm_transfer_hw(led->i2c_client, BLM_GO_RGB);
	dev_dbg(&led->i2c_client->dev,
			"# DONE # next_red = %d, next_green = %d,"
			" next_blue = %d\n",
			data->next_red, data->next_green,
			data->next_blue);
	return 0;
}
예제 #2
0
static int blinkm_led_common_set(struct led_classdev *led_cdev,
				 enum led_brightness value, int color)
{
	/* led_brightness is 0, 127 or 255 - we just use it here as-is */
	struct blinkm_led *led = cdev_to_blmled(led_cdev);
	struct blinkm_data *data = i2c_get_clientdata(led->i2c_client);
	struct blinkm_work *bl_work;

	switch (color) {
	case RED:
		/* bail out if there's no change */
		if (data->next_red == (u8) value)
			return 0;
		/* we assume a quite fast sequence here ([off]->on->off)
		 * think of network led trigger - we cannot blink that fast, so
		 * in case we already have a off->on->off transition queued up,
		 * we refuse to queue up more.
		 * Revisit: fast-changing brightness. */
		if (atomic_read(&led->active) > 1)
			return 0;
		data->next_red = (u8) value;
		break;
	case GREEN:
		/* bail out if there's no change */
		if (data->next_green == (u8) value)
			return 0;
		/* we assume a quite fast sequence here ([off]->on->off)
		 * Revisit: fast-changing brightness. */
		if (atomic_read(&led->active) > 1)
			return 0;
		data->next_green = (u8) value;
		break;
	case BLUE:
		/* bail out if there's no change */
		if (data->next_blue == (u8) value)
			return 0;
		/* we assume a quite fast sequence here ([off]->on->off)
		 * Revisit: fast-changing brightness. */
		if (atomic_read(&led->active) > 1)
			return 0;
		data->next_blue = (u8) value;
		break;

	default:
		dev_err(&led->i2c_client->dev, "BlinkM: unknown color.\n");
		return -EINVAL;
	}

	bl_work = kzalloc(sizeof(*bl_work), GFP_ATOMIC);
	if (!bl_work)
		return -ENOMEM;

	atomic_inc(&led->active);
	dev_dbg(&led->i2c_client->dev,
			"#TO_SCHED# next_red = %d, next_green = %d,"
			" next_blue = %d, active = %d\n",
			data->next_red, data->next_green,
			data->next_blue, atomic_read(&led->active));

	/* a fresh work _item_ for each change */
	bl_work->blinkm_led = led;
	INIT_WORK(&bl_work->work, led_work);
	/* queue work in own queue for easy sync on exit*/
	schedule_work(&bl_work->work);

	return 0;
}