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; }
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; }