lkml.org 
[lkml]   [2007]   [Jul]   [2]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
/
DateMon, 2 Jul 2007 09:43:59 -0400
From"Dmitry Torokhov" <>
SubjectRe: blink driver power saving
On 7/2/07, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
>
> I was thinking about something like the atached (untested and sorry
> for using attachment). It shoudl blink just one led (numLock) on any
> keyboard that has such LED (and allows to control it).
>

Argh, bad one. This one shoudl be better.

-- 
Dmitry
/*
 * Debug driver that continuosly blink LEDs on keyboards
 *
 * Copyright (c) 2007 Dmitry Torokhov
 */
/*
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */
#include <linux/module.h>
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/init.h>

MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
MODULE_DESCRIPTION("Blink driver");
MODULE_LICENSE("GPL");

struct blinker {
	struct delayed_work work;
	struct input_handle handle;
	int state;
};
static void blink_task_handler(struct work_struct *work)
{
	struct blinker *blinker = container_of(work, struct blinker, work.work);
	blinker->state = !blinker->state;
	input_inject_event(&blinker->handle, EV_LED, LED_NUML, blinker->state);
	schedule_delayed_work(&blinker->work, msecs_to_jiffies(250));
}
static void blink_event(struct input_handle *handle, unsigned int type,
		        unsigned int code, int down)
{
	/*
	 * This is a very rare handler that does not process any input
	 * events; just injects them.
	 */
}
static int blink_connect(struct input_handler *handler, struct input_dev *dev,
			  const struct input_device_id *id)
{
	struct blinker *blinker;
	struct input_handle *handle;
	int error;
	blinker = kzalloc(sizeof(struct blinker), GFP_KERNEL);
	if (!blinker)
		return -ENOMEM;
	INIT_DELAYED_WORK(&blinker->work, blink_task_handler);

	handle = &blinker->handle;
	handle->dev = dev;
	handle->handler = handler;
	handle->name = "blink";
	handle->private = blinker;

	error = input_register_handle(handle);
	if (error)
		goto err_free_handle;
	error = input_open_device(handle);
	if (error)
		goto err_unregister_handle;
	schedule_delayed_work(&blinker->work, 0);

	return 0;

 err_unregister_handle:
	input_unregister_handle(handle);
 err_free_handle:
	kfree(handle);
	return error;
}
static void blink_disconnect(struct input_handle *handle)
{
	struct blinker *blinker = handle->private;
	cancel_rearming_delayed_work(&blinker->work);
	input_close_device(handle);
	input_unregister_handle(handle);
	kfree(blinker);
}
static const struct input_device_id blink_ids[] = {
	{
		.flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_LEDBIT,
		.evbit = { BIT(EV_LED) },
		.ledbit = { [LONG(LED_NUML)] = BIT(LED_NUML) },
	},
	{ }
};
static struct input_handler blink_handler = {
	.event		= blink_event,
	.connect	= blink_connect,
	.disconnect	= blink_disconnect,
	.name		= "blink",
	.id_table	= blink_ids,
};
static int __init blink_handler_init(void)
{
	return input_register_handler(&blink_handler);
}
static void __exit blink_handler_exit(void)
{
	input_unregister_handler(&blink_handler);
	flush_scheduled_work();
}
module_init(blink_handler_init);
module_exit(blink_handler_exit);
\
 
 \ /
  Last update: 2007-07-02 15:47    [from the cache]
©2003-2008