netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
@ 2006-05-25 15:16 Ivo van Doorn
  2006-05-29 15:58 ` Ivo van Doorn
  0 siblings, 1 reply; 17+ messages in thread
From: Ivo van Doorn @ 2006-05-25 15:16 UTC (permalink / raw)
  To: netdev

[-- Attachment #1: Type: text/plain, Size: 10016 bytes --]

Add radiobtn driver.
This driver creates an iput device for each registered button
and will poll the device frequently to check the latest status of the button.
Once the status has changed it will try to enable or disable the radio
and send an event to the input device.

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>

diff -uprN wireless-dev/drivers/input/misc/Kconfig wireless-dev-radiobtn/drivers/input/misc/Kconfig
--- wireless-dev/drivers/input/misc/Kconfig	2006-04-27 00:52:53.000000000 +0200
+++ wireless-dev-radiobtn/drivers/input/misc/Kconfig	2006-05-25 16:29:23.000000000 +0200
@@ -79,4 +79,13 @@ config HP_SDC_RTC
 	  Say Y here if you want to support the built-in real time clock
 	  of the HP SDC controller.
 
+config RADIOBTN
+	tristate "Hardware radio button support"
+	help
+	  Say Y here if you have an integrated WiFi or Bluetooth device
+	  which contains an hardware button for enabling or disabling the radio.
+	  When this driver is used, this driver will make sure the radio will
+	  be correctly enabled and disabled when needed. It will then also
+	  use the created input device to signal user space of this event
+	  which allows userspace to take additional actions.
 endif
diff -uprN wireless-dev/drivers/input/misc/Makefile wireless-dev-radiobtn/drivers/input/misc/Makefile
--- wireless-dev/drivers/input/misc/Makefile	2006-04-27 00:52:53.000000000 +0200
+++ wireless-dev-radiobtn/drivers/input/misc/Makefile	2006-05-25 16:25:43.000000000 +0200
@@ -11,3 +11,4 @@ obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
 obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_IXP4XX_BEEPER)	+= ixp4xx-beeper.o
+obj-$(CONFIG_RADIOBTN)			+= radiobtn.o
diff -uprN wireless-dev/drivers/input/misc/radiobtn.c wireless-dev-radiobtn/drivers/input/misc/radiobtn.c
--- wireless-dev/drivers/input/misc/radiobtn.c	1970-01-01 01:00:00.000000000 +0100
+++ wireless-dev-radiobtn/drivers/input/misc/radiobtn.c	2006-05-25 16:23:59.000000000 +0200
@@ -0,0 +1,158 @@
+/*
+	Copyright (C) 2006 Ivo van Doorn
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the
+	Free Software Foundation, Inc.,
+	59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+	Radio hardware button support
+	Poll frequently all registered hardware for hardware button status,
+	if changed enabled or disable the radio of that hardware device.
+	Send signal to input device to inform userspace about the new status.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/radiobtn.h>
+
+MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
+MODULE_VERSION("1.0");
+MODULE_DESCRIPTION("Radio hardware button support");
+MODULE_LICENSE("GPL");
+
+void radiobtn_poll(unsigned long data)
+{
+	struct radio_button *radiobtn = (struct radio_button*)data;
+	int state;
+
+	/*
+	 * Poll for the new state.
+	 * Check if the state has changed.
+	 */
+	state = !!radiobtn->button_poll(radiobtn->data);
+	if (state != radiobtn->current_state) {
+		radiobtn->current_state = state;
+
+		/*
+		 * Enable or disable the radio when this
+		 * should be done in software.
+		 */
+		if (state && radiobtn->enable_radio)
+			radiobtn->enable_radio(radiobtn->data);
+		else if (!state && radiobtn->disable_radio)
+			radiobtn->disable_radio(radiobtn->data);
+
+		/*
+		 * Report key event.
+		 */
+		input_report_key(radiobtn->input_dev, KEY_RADIO, 1);
+		input_sync(radiobtn->input_dev);
+		input_report_key(radiobtn->input_dev, KEY_RADIO, 0);
+		input_sync(radiobtn->input_dev);
+	}
+
+	/*
+	 * Check if polling has been disabled.
+	 */
+	if (radiobtn->poll_delay != 0) {
+		radiobtn->poll_timer.expires =
+			jiffies + msecs_to_jiffies(radiobtn->poll_delay);
+		add_timer(&radiobtn->poll_timer);
+	}
+}
+
+int radiobtn_register_device(struct radio_button *radiobtn)
+{
+	int status;
+
+	/*
+	 * Check if all mandatory fields have been set.
+	 */
+	if (radiobtn->poll_delay == 0 || radiobtn->button_poll == NULL)
+		return -EINVAL;
+
+	/*
+	 * Allocate, initialize and register input device.
+	 */
+	radiobtn->input_dev = input_allocate_device();
+	if (!radiobtn->input_dev) {
+		printk(KERN_ERR "Failed to allocate input device %s.\n",
+			radiobtn->dev_name);
+		return -ENOMEM;
+	}
+
+	radiobtn->input_dev->name = "Radio button";
+	radiobtn->input_dev->phys = strcat("radiobtn/", radiobtn->dev_name);
+	radiobtn->input_dev->id.bustype = BUS_HOST;
+	set_bit(KEY_RADIO, radiobtn->input_dev->keybit);
+
+	status = input_register_device(radiobtn->input_dev);
+	if (status) {
+		printk(KERN_ERR "Failed to register input device %s.\n",
+			radiobtn->dev_name);
+		input_free_device(radiobtn->input_dev);
+		return status;
+	}
+
+	/*
+	 * Initialize timer.
+	 */
+	init_timer(&radiobtn->poll_timer);
+	radiobtn->poll_timer.function = radiobtn_poll;
+	radiobtn->poll_timer.data = (unsigned long)radiobtn;
+	radiobtn->poll_timer.expires =
+		jiffies + msecs_to_jiffies(radiobtn->poll_delay);
+	add_timer(&radiobtn->poll_timer);
+
+	printk(KERN_INFO "Created new %s: %s.\n",
+		radiobtn->input_dev->name, radiobtn->input_dev->phys);
+
+	return 0;
+}
+
+void radiobtn_unregister_device(struct radio_button *radiobtn)
+{
+	/*
+	 * Stop timer.
+	 */
+	radiobtn->poll_delay = 0;
+	del_timer_sync(&radiobtn->poll_timer);
+
+	/*
+	 * Remove input device.
+	 */
+	input_unregister_device(radiobtn->input_dev);
+	input_free_device(radiobtn->input_dev);
+}
+
+static int __init radiobtn_init(void)
+{
+	printk(KERN_INFO "Loading radio button driver.\n");
+	return 0;
+}
+
+static void __exit radiobtn_exit(void)
+{
+	printk(KERN_INFO "Unloading radio button driver.\n");
+}
+
+EXPORT_SYMBOL(radiobtn_register_device);
+EXPORT_SYMBOL(radiobtn_unregister_device);
+
+module_init(radiobtn_init);
+module_exit(radiobtn_exit);
diff -uprN wireless-dev/include/linux/radiobtn.h wireless-dev-radiobtn/include/linux/radiobtn.h
--- wireless-dev/include/linux/radiobtn.h	1970-01-01 01:00:00.000000000 +0100
+++ wireless-dev-radiobtn/include/linux/radiobtn.h	2006-05-25 15:02:33.000000000 +0200
@@ -0,0 +1,83 @@
+/*
+	Copyright (C) 2006 Ivo van Doorn
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the
+	Free Software Foundation, Inc.,
+	59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+	Radio hardware button support
+	Laptops are quite often equiped with support with a hardware button
+	to enabled and disable the radio of the integrated wireless network
+	or bluetooth interface.
+	Altough some devices will make sure that when pressed the radio
+	is disabled in hardware, other device depend on the software
+	to enabled or disable the radio accordingly.
+	This driver will create an input device and will poll registered
+	hardware frequently to listen if the button has been pressed.
+	When the device requires the software to disable or enable
+	the radio it will do so correctly, but it will also in all cases
+	send a signal to the input device to inform any listening daemon
+	the state has changed and will allow userspace to handle certain
+	tasks as well if required.
+ */
+
+#ifndef RADIOBTN_H
+#define RADIOBTN_H
+
+#include <linux/input.h>
+
+/**
+ * struct radio_button - radio hardware structure.
+ * @dev_name: Name of the interface. This will become the name
+ * 	of the input device created in /dev/radio/.
+ * @data: Private data which will be passed along with the radio handlers.
+ * @button_poll(unsigned long data): Handler which will be called
+ * 	with the poll_delay interval.
+ * @enable_radio(unsigned long data): Optional handler to enable the radio
+ * 	once the button has been pressed when the hardware does not do this
+ * 	automaticly.
+ * @disable_radio(unsigned long data): Optional handler to disable the radio
+ * 	once the button has been pressed when the hardware does not do this
+ * 	automaticly.
+ * @poll_delay: Delay in msecs between each poll.
+ * @current_state: Current state of the button.
+ * @input_dev: Pointer to input device for this radio button.
+ * 	(Should not be touched by driver)
+ * @poll_timer: Timer used to poll for the button status.
+ *	(Should not be touched by driver)
+ */
+struct radio_button {
+	const char *dev_name;
+
+	unsigned long data;
+
+	int (*button_poll)(unsigned long data);
+	void (*enable_radio)(unsigned long data);
+	void (*disable_radio)(unsigned long data);
+
+	unsigned int poll_delay;
+
+	unsigned int current_state;
+
+	struct input_dev *input_dev;
+
+	struct timer_list poll_timer;
+}
+
+int radiobtn_register_device(struct radio_button *);
+void radiobtn_unregister_device(struct radio_button *);
+
+#endif /* RADIOBTN_H */

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-05-25 15:16 [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn Ivo van Doorn
@ 2006-05-29 15:58 ` Ivo van Doorn
  2006-05-30 21:43   ` Francois Romieu
  0 siblings, 1 reply; 17+ messages in thread
From: Ivo van Doorn @ 2006-05-29 15:58 UTC (permalink / raw)
  To: netdev

[-- Attachment #1: Type: text/plain, Size: 10010 bytes --]

Hi,

I made a small update on this patch, only a small compile fix
and small bugfix.

The thing I would like to know now, is if the current approach
is the desired situation.

- Should only 1 input device be created, or multiple devices?

- Should instead of KEY_RADIO new keys be created (KEY_RADIO_WIFI
and KEY_RADIO_BLUETOOTH for example) or should instead input_event
be used and instead of "1", other values be passed to indicate the device which
has triggered the event?

Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 4bad588..212caad 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -79,4 +79,14 @@ config HP_SDC_RTC
 	  Say Y here if you want to support the built-in real time clock
 	  of the HP SDC controller.
 
+config RADIOBTN
+	tristate "Hardware radio button support"
+	help
+	  Say Y here if you have an integrated WiFi or Bluetooth device
+	  which contains an hardware button for enabling or disabling the radio.
+	  When this driver is used, this driver will make sure the radio will
+	  be correctly enabled and disabled when needed. It will then also
+	  use the created input device to signal user space of this event
+	  which allows userspace to take additional actions.
+
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 415c491..9af3d98 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
 obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_IXP4XX_BEEPER)	+= ixp4xx-beeper.o
+obj-$(CONFIG_RADIOBTN)			+= radiobtn.o
\ No newline at end of file
diff --git a/drivers/input/misc/radiobtn.c b/drivers/input/misc/radiobtn.c
new file mode 100644
index 0000000..8d3b84a
--- /dev/null
+++ b/drivers/input/misc/radiobtn.c
@@ -0,0 +1,163 @@
+/*
+	Copyright (C) 2006 Ivo van Doorn
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the
+	Free Software Foundation, Inc.,
+	59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+	Radio hardware button support
+	Poll frequently all registered hardware for hardware button status,
+	if changed enabled or disable the radio of that hardware device.
+	Send signal to input device to inform userspace about the new status.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/radiobtn.h>
+
+MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
+MODULE_VERSION("1.0");
+MODULE_DESCRIPTION("Radio hardware button support");
+MODULE_LICENSE("GPL");
+
+void radiobtn_poll(unsigned long data)
+{
+	struct radio_button *radiobtn = (struct radio_button*)data;
+	int state;
+
+	/*
+	 * Poll for the new state.
+	 * Check if the state has changed.
+	 */
+	state = !!radiobtn->button_poll(radiobtn->data);
+	if (state != radiobtn->current_state) {
+		radiobtn->current_state = state;
+
+		/*
+		 * Enable or disable the radio when this
+		 * should be done in software.
+		 */
+		if (state && radiobtn->enable_radio)
+			radiobtn->enable_radio(radiobtn->data);
+		else if (!state && radiobtn->disable_radio)
+			radiobtn->disable_radio(radiobtn->data);
+
+		/*
+		 * Report key event.
+		 */
+		input_report_key(radiobtn->input_dev, KEY_RADIO, 1);
+		input_sync(radiobtn->input_dev);
+		input_report_key(radiobtn->input_dev, KEY_RADIO, 0);
+		input_sync(radiobtn->input_dev);
+	}
+
+	/*
+	 * Check if polling has been disabled.
+	 */
+	if (radiobtn->poll_delay != 0) {
+		radiobtn->poll_timer.expires =
+			jiffies + msecs_to_jiffies(radiobtn->poll_delay);
+		add_timer(&radiobtn->poll_timer);
+	}
+}
+
+int radiobtn_register_device(struct radio_button *radiobtn)
+{
+	int status;
+
+	/*
+	 * Check if all mandatory fields have been set.
+	 */
+	if (radiobtn->poll_delay == 0 || radiobtn->button_poll == NULL)
+		return -EINVAL;
+
+	/*
+	 * Allocate, initialize and register input device.
+	 */
+	radiobtn->input_dev = input_allocate_device();
+	if (!radiobtn->input_dev) {
+		printk(KERN_ERR "Failed to allocate input device %s.\n",
+			radiobtn->dev_name);
+		return -ENOMEM;
+	}
+
+	radiobtn->input_dev->name = "Radio button";
+	radiobtn->input_dev->phys = strcat("radiobtn/", radiobtn->dev_name);
+	radiobtn->input_dev->id.bustype = BUS_HOST;
+	set_bit(KEY_RADIO, radiobtn->input_dev->keybit);
+
+	status = input_register_device(radiobtn->input_dev);
+	if (status) {
+		printk(KERN_ERR "Failed to register input device %s.\n",
+			radiobtn->dev_name);
+		input_free_device(radiobtn->input_dev);
+		return status;
+	}
+
+	/*
+	 * Set the initial state of the button.
+	 */
+	radiobtn->current_state = radiobtn->button_poll(radiobtn->data);
+
+	/*
+	 * Initialize timer.
+	 */
+	init_timer(&radiobtn->poll_timer);
+	radiobtn->poll_timer.function = radiobtn_poll;
+	radiobtn->poll_timer.data = (unsigned long)radiobtn;
+	radiobtn->poll_timer.expires =
+		jiffies + msecs_to_jiffies(radiobtn->poll_delay);
+	add_timer(&radiobtn->poll_timer);
+
+	printk(KERN_INFO "Created new %s: %s.\n",
+		radiobtn->input_dev->name, radiobtn->input_dev->phys);
+
+	return 0;
+}
+
+void radiobtn_unregister_device(struct radio_button *radiobtn)
+{
+	/*
+	 * Stop timer.
+	 */
+	radiobtn->poll_delay = 0;
+	del_timer_sync(&radiobtn->poll_timer);
+
+	/*
+	 * Remove input device.
+	 */
+	input_unregister_device(radiobtn->input_dev);
+	input_free_device(radiobtn->input_dev);
+}
+
+static int __init radiobtn_init(void)
+{
+	printk(KERN_INFO "Loading radio button driver.\n");
+	return 0;
+}
+
+static void __exit radiobtn_exit(void)
+{
+	printk(KERN_INFO "Unloading radio button driver.\n");
+}
+
+EXPORT_SYMBOL(radiobtn_register_device);
+EXPORT_SYMBOL(radiobtn_unregister_device);
+
+module_init(radiobtn_init);
+module_exit(radiobtn_exit);
diff --git a/include/linux/radiobtn.h b/include/linux/radiobtn.h
new file mode 100644
index 0000000..3467606
--- /dev/null
+++ b/include/linux/radiobtn.h
@@ -0,0 +1,84 @@
+/*
+	Copyright (C) 2006 Ivo van Doorn
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the
+	Free Software Foundation, Inc.,
+	59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+	Radio hardware button support
+	Laptops are quite often equiped with support with a hardware button
+	to enabled and disable the radio of the integrated wireless network
+	or bluetooth interface.
+	Altough some devices will make sure that when pressed the radio
+	is disabled in hardware, other device depend on the software
+	to enabled or disable the radio accordingly.
+	This driver will create an input device and will poll registered
+	hardware frequently to listen if the button has been pressed.
+	When the device requires the software to disable or enable
+	the radio it will do so correctly, but it will also in all cases
+	send a signal to the input device to inform any listening daemon
+	the state has changed and will allow userspace to handle certain
+	tasks as well if required.
+ */
+
+#ifndef RADIOBTN_H
+#define RADIOBTN_H
+
+#include <linux/input.h>
+
+/**
+ * struct radio_button - radio hardware structure.
+ * @dev_name: Name of the interface. This will become the name
+ * 	of the input device created in /dev/radio/.
+ * @data: Private data which will be passed along with the radio handlers.
+ * @button_poll(unsigned long data): Handler which will be called
+ * 	with the poll_delay interval.
+ * @enable_radio(unsigned long data): Optional handler to enable the radio
+ * 	once the button has been pressed when the hardware does not do this
+ * 	automaticly.
+ * @disable_radio(unsigned long data): Optional handler to disable the radio
+ * 	once the button has been pressed when the hardware does not do this
+ * 	automaticly.
+ * @poll_delay: Delay in msecs between each poll.
+ * @current_state: Current state of the button.
+ * 	(Should not be touched by driver)
+ * @input_dev: Pointer to input device for this radio button.
+ * 	(Should not be touched by driver)
+ * @poll_timer: Timer used to poll for the button status.
+ *	(Should not be touched by driver)
+ */
+struct radio_button {
+	const char *dev_name;
+
+	unsigned long data;
+
+	int (*button_poll)(unsigned long data);
+	void (*enable_radio)(unsigned long data);
+	void (*disable_radio)(unsigned long data);
+
+	unsigned int poll_delay;
+
+	unsigned int current_state;
+
+	struct input_dev *input_dev;
+
+	struct timer_list poll_timer;
+};
+
+int radiobtn_register_device(struct radio_button *);
+void radiobtn_unregister_device(struct radio_button *);
+
+#endif /* RADIOBTN_H */

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-05-29 15:58 ` Ivo van Doorn
@ 2006-05-30 21:43   ` Francois Romieu
  2006-05-31 17:31     ` Ivo van Doorn
  0 siblings, 1 reply; 17+ messages in thread
From: Francois Romieu @ 2006-05-30 21:43 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: netdev

Ivo van Doorn <ivdoorn@gmail.com> :
[...]
> diff --git a/drivers/input/misc/radiobtn.c b/drivers/input/misc/radiobtn.c
> new file mode 100644
> index 0000000..8d3b84a
> --- /dev/null
> +++ b/drivers/input/misc/radiobtn.c
[...]
> +void radiobtn_poll(unsigned long data)

static ?

[...]
> +int radiobtn_register_device(struct radio_button *radiobtn)
> +{
> +	int status;
> +
> +	/*
> +	 * Check if all mandatory fields have been set.
> +	 */
> +	if (radiobtn->poll_delay == 0 || radiobtn->button_poll == NULL)
> +		return -EINVAL;
> +
> +	/*
> +	 * Allocate, initialize and register input device.
> +	 */
> +	radiobtn->input_dev = input_allocate_device();
> +	if (!radiobtn->input_dev) {
> +		printk(KERN_ERR "Failed to allocate input device %s.\n",
> +			radiobtn->dev_name);
> +		return -ENOMEM;
> +	}
> +
> +	radiobtn->input_dev->name = "Radio button";
> +	radiobtn->input_dev->phys = strcat("radiobtn/", radiobtn->dev_name);

The first parameter of strcat() must be big enough to contain the whole
string.

-- 
Ueimor

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-05-30 21:43   ` Francois Romieu
@ 2006-05-31 17:31     ` Ivo van Doorn
  2006-05-31 18:05       ` Ivo van Doorn
  0 siblings, 1 reply; 17+ messages in thread
From: Ivo van Doorn @ 2006-05-31 17:31 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev

[-- Attachment #1: Type: text/plain, Size: 1314 bytes --]

On Tuesday 30 May 2006 23:43, Francois Romieu wrote:
> Ivo van Doorn <ivdoorn@gmail.com> :
> [...]
> > diff --git a/drivers/input/misc/radiobtn.c b/drivers/input/misc/radiobtn.c
> > new file mode 100644
> > index 0000000..8d3b84a
> > --- /dev/null
> > +++ b/drivers/input/misc/radiobtn.c
> [...]
> > +void radiobtn_poll(unsigned long data)
> 
> static ?

Good point. Will fix this immediately.

> [...]
> > +int radiobtn_register_device(struct radio_button *radiobtn)
> > +{
> > +	int status;
> > +
> > +	/*
> > +	 * Check if all mandatory fields have been set.
> > +	 */
> > +	if (radiobtn->poll_delay == 0 || radiobtn->button_poll == NULL)
> > +		return -EINVAL;
> > +
> > +	/*
> > +	 * Allocate, initialize and register input device.
> > +	 */
> > +	radiobtn->input_dev = input_allocate_device();
> > +	if (!radiobtn->input_dev) {
> > +		printk(KERN_ERR "Failed to allocate input device %s.\n",
> > +			radiobtn->dev_name);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	radiobtn->input_dev->name = "Radio button";
> > +	radiobtn->input_dev->phys = strcat("radiobtn/", radiobtn->dev_name);
> 
> The first parameter of strcat() must be big enough to contain the whole
> string.

Will replace it with
sprintf(wrqu->name, "radiobtn/", radiobtn->dev_name);

Thanks.

Ivo

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-05-31 17:31     ` Ivo van Doorn
@ 2006-05-31 18:05       ` Ivo van Doorn
  2006-06-02 14:30         ` Ivo van Doorn
  0 siblings, 1 reply; 17+ messages in thread
From: Ivo van Doorn @ 2006-05-31 18:05 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev

[-- Attachment #1: Type: text/plain, Size: 1601 bytes --]

On Wednesday 31 May 2006 19:31, Ivo van Doorn wrote:
> On Tuesday 30 May 2006 23:43, Francois Romieu wrote:
> > Ivo van Doorn <ivdoorn@gmail.com> :
> > [...]
> > > diff --git a/drivers/input/misc/radiobtn.c b/drivers/input/misc/radiobtn.c
> > > new file mode 100644
> > > index 0000000..8d3b84a
> > > --- /dev/null
> > > +++ b/drivers/input/misc/radiobtn.c
> > [...]
> > > +void radiobtn_poll(unsigned long data)
> > 
> > static ?
> 
> Good point. Will fix this immediately.
> 
> > [...]
> > > +int radiobtn_register_device(struct radio_button *radiobtn)
> > > +{
> > > +	int status;
> > > +
> > > +	/*
> > > +	 * Check if all mandatory fields have been set.
> > > +	 */
> > > +	if (radiobtn->poll_delay == 0 || radiobtn->button_poll == NULL)
> > > +		return -EINVAL;
> > > +
> > > +	/*
> > > +	 * Allocate, initialize and register input device.
> > > +	 */
> > > +	radiobtn->input_dev = input_allocate_device();
> > > +	if (!radiobtn->input_dev) {
> > > +		printk(KERN_ERR "Failed to allocate input device %s.\n",
> > > +			radiobtn->dev_name);
> > > +		return -ENOMEM;
> > > +	}
> > > +
> > > +	radiobtn->input_dev->name = "Radio button";
> > > +	radiobtn->input_dev->phys = strcat("radiobtn/", radiobtn->dev_name);
> > 
> > The first parameter of strcat() must be big enough to contain the whole
> > string.
> 
> Will replace it with
> sprintf(wrqu->name, "radiobtn/", radiobtn->dev_name);

Or actually, I don't think the radiobtn/ won't be actually needed as prefix.
The name passed to the radiobtn driver by the driver should be sufficient.

Ivo

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-05-31 18:05       ` Ivo van Doorn
@ 2006-06-02 14:30         ` Ivo van Doorn
  2006-06-03  8:45           ` Stefan Rompf
  0 siblings, 1 reply; 17+ messages in thread
From: Ivo van Doorn @ 2006-06-02 14:30 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev

[-- Attachment #1: Type: text/plain, Size: 9871 bytes --]

> > > The first parameter of strcat() must be big enough to contain the whole
> > > string.
> > 
> > Will replace it with
> > sprintf(wrqu->name, "radiobtn/", radiobtn->dev_name);
> 
> Or actually, I don't think the radiobtn/ won't be actually needed as prefix.
> The name passed to the radiobtn driver by the driver should be sufficient.

Updated version,

Signed-off-by Ivo van Doorn <IvDoorn@gmail.com>

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 4bad588..212caad 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -79,4 +79,14 @@ config HP_SDC_RTC
 	  Say Y here if you want to support the built-in real time clock
 	  of the HP SDC controller.
 
+config RADIOBTN
+	tristate "Hardware radio button support"
+	help
+	  Say Y here if you have an integrated WiFi or Bluetooth device
+	  which contains an hardware button for enabling or disabling the radio.
+	  When this driver is used, this driver will make sure the radio will
+	  be correctly enabled and disabled when needed. It will then also
+	  use the created input device to signal user space of this event
+	  which allows userspace to take additional actions.
+
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 415c491..9af3d98 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
 obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_IXP4XX_BEEPER)	+= ixp4xx-beeper.o
+obj-$(CONFIG_RADIOBTN)			+= radiobtn.o
\ No newline at end of file
diff --git a/drivers/input/misc/radiobtn.c b/drivers/input/misc/radiobtn.c
new file mode 100644
index 0000000..4379abe
--- /dev/null
+++ b/drivers/input/misc/radiobtn.c
@@ -0,0 +1,163 @@
+/*
+	Copyright (C) 2006 Ivo van Doorn
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the
+	Free Software Foundation, Inc.,
+	59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+	Radio hardware button support
+	Poll frequently all registered hardware for hardware button status,
+	if changed enabled or disable the radio of that hardware device.
+	Send signal to input device to inform userspace about the new status.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/radiobtn.h>
+
+MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
+MODULE_VERSION("1.0");
+MODULE_DESCRIPTION("Radio hardware button support");
+MODULE_LICENSE("GPL");
+
+static void radiobtn_poll(unsigned long data)
+{
+	struct radio_button *radiobtn = (struct radio_button*)data;
+	int state;
+
+	/*
+	 * Poll for the new state.
+	 * Check if the state has changed.
+	 */
+	state = !!radiobtn->button_poll(radiobtn->data);
+	if (state != radiobtn->current_state) {
+		radiobtn->current_state = state;
+
+		/*
+		 * Enable or disable the radio when this
+		 * should be done in software.
+		 */
+		if (state && radiobtn->enable_radio)
+			radiobtn->enable_radio(radiobtn->data);
+		else if (!state && radiobtn->disable_radio)
+			radiobtn->disable_radio(radiobtn->data);
+
+		/*
+		 * Report key event.
+		 */
+		input_report_key(radiobtn->input_dev, KEY_RADIO, 1);
+		input_sync(radiobtn->input_dev);
+		input_report_key(radiobtn->input_dev, KEY_RADIO, 0);
+		input_sync(radiobtn->input_dev);
+	}
+
+	/*
+	 * Check if polling has been disabled.
+	 */
+	if (radiobtn->poll_delay != 0) {
+		radiobtn->poll_timer.expires =
+			jiffies + msecs_to_jiffies(radiobtn->poll_delay);
+		add_timer(&radiobtn->poll_timer);
+	}
+}
+
+int radiobtn_register_device(struct radio_button *radiobtn)
+{
+	int status;
+
+	/*
+	 * Check if all mandatory fields have been set.
+	 */
+	if (radiobtn->poll_delay == 0 || radiobtn->button_poll == NULL)
+		return -EINVAL;
+
+	/*
+	 * Allocate, initialize and register input device.
+	 */
+	radiobtn->input_dev = input_allocate_device();
+	if (!radiobtn->input_dev) {
+		printk(KERN_ERR "Failed to allocate input device %s.\n",
+			radiobtn->dev_name);
+		return -ENOMEM;
+	}
+
+	radiobtn->input_dev->name = "Radio button";
+	radiobtn->input_dev->phys = radiobtn->dev_name;
+	radiobtn->input_dev->id.bustype = BUS_HOST;
+	set_bit(KEY_RADIO, radiobtn->input_dev->keybit);
+
+	status = input_register_device(radiobtn->input_dev);
+	if (status) {
+		printk(KERN_ERR "Failed to register input device %s.\n",
+			radiobtn->dev_name);
+		input_free_device(radiobtn->input_dev);
+		return status;
+	}
+
+	/*
+	 * Set the initial state of the button.
+	 */
+	radiobtn->current_state = radiobtn->button_poll(radiobtn->data);
+
+	/*
+	 * Initialize timer.
+	 */
+	init_timer(&radiobtn->poll_timer);
+	radiobtn->poll_timer.function = radiobtn_poll;
+	radiobtn->poll_timer.data = (unsigned long)radiobtn;
+	radiobtn->poll_timer.expires =
+		jiffies + msecs_to_jiffies(radiobtn->poll_delay);
+	add_timer(&radiobtn->poll_timer);
+
+	printk(KERN_INFO "Created new %s: %s.\n",
+		radiobtn->input_dev->name, radiobtn->input_dev->phys);
+
+	return 0;
+}
+
+void radiobtn_unregister_device(struct radio_button *radiobtn)
+{
+	/*
+	 * Stop timer.
+	 */
+	radiobtn->poll_delay = 0;
+	del_timer_sync(&radiobtn->poll_timer);
+
+	/*
+	 * Remove input device.
+	 */
+	input_unregister_device(radiobtn->input_dev);
+	input_free_device(radiobtn->input_dev);
+}
+
+static int __init radiobtn_init(void)
+{
+	printk(KERN_INFO "Loading radio button driver.\n");
+	return 0;
+}
+
+static void __exit radiobtn_exit(void)
+{
+	printk(KERN_INFO "Unloading radio button driver.\n");
+}
+
+EXPORT_SYMBOL(radiobtn_register_device);
+EXPORT_SYMBOL(radiobtn_unregister_device);
+
+module_init(radiobtn_init);
+module_exit(radiobtn_exit);
diff --git a/include/linux/radiobtn.h b/include/linux/radiobtn.h
new file mode 100644
index 0000000..3467606
--- /dev/null
+++ b/include/linux/radiobtn.h
@@ -0,0 +1,84 @@
+/*
+	Copyright (C) 2006 Ivo van Doorn
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the
+	Free Software Foundation, Inc.,
+	59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+	Radio hardware button support
+	Laptops are quite often equiped with support with a hardware button
+	to enabled and disable the radio of the integrated wireless network
+	or bluetooth interface.
+	Altough some devices will make sure that when pressed the radio
+	is disabled in hardware, other device depend on the software
+	to enabled or disable the radio accordingly.
+	This driver will create an input device and will poll registered
+	hardware frequently to listen if the button has been pressed.
+	When the device requires the software to disable or enable
+	the radio it will do so correctly, but it will also in all cases
+	send a signal to the input device to inform any listening daemon
+	the state has changed and will allow userspace to handle certain
+	tasks as well if required.
+ */
+
+#ifndef RADIOBTN_H
+#define RADIOBTN_H
+
+#include <linux/input.h>
+
+/**
+ * struct radio_button - radio hardware structure.
+ * @dev_name: Name of the interface. This will become the name
+ * 	of the input device created in /dev/radio/.
+ * @data: Private data which will be passed along with the radio handlers.
+ * @button_poll(unsigned long data): Handler which will be called
+ * 	with the poll_delay interval.
+ * @enable_radio(unsigned long data): Optional handler to enable the radio
+ * 	once the button has been pressed when the hardware does not do this
+ * 	automaticly.
+ * @disable_radio(unsigned long data): Optional handler to disable the radio
+ * 	once the button has been pressed when the hardware does not do this
+ * 	automaticly.
+ * @poll_delay: Delay in msecs between each poll.
+ * @current_state: Current state of the button.
+ * 	(Should not be touched by driver)
+ * @input_dev: Pointer to input device for this radio button.
+ * 	(Should not be touched by driver)
+ * @poll_timer: Timer used to poll for the button status.
+ *	(Should not be touched by driver)
+ */
+struct radio_button {
+	const char *dev_name;
+
+	unsigned long data;
+
+	int (*button_poll)(unsigned long data);
+	void (*enable_radio)(unsigned long data);
+	void (*disable_radio)(unsigned long data);
+
+	unsigned int poll_delay;
+
+	unsigned int current_state;
+
+	struct input_dev *input_dev;
+
+	struct timer_list poll_timer;
+};
+
+int radiobtn_register_device(struct radio_button *);
+void radiobtn_unregister_device(struct radio_button *);
+
+#endif /* RADIOBTN_H */

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-06-02 14:30         ` Ivo van Doorn
@ 2006-06-03  8:45           ` Stefan Rompf
  2006-06-04  8:02             ` Ivo van Doorn
  0 siblings, 1 reply; 17+ messages in thread
From: Stefan Rompf @ 2006-06-03  8:45 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: Francois Romieu, netdev

Am Freitag 02 Juni 2006 16:30 schrieb Ivo van Doorn:

> > Or actually, I don't think the radiobtn/ won't be actually needed as
> > prefix. The name passed to the radiobtn driver by the driver should be
> > sufficient.
>
> Updated version,
>
> Signed-off-by Ivo van Doorn <IvDoorn@gmail.com>

I don't like the patch in it's current form. Many notebooks have a number of 
additional keys that need to be queried/polled using the same interface, but 
just one button is to control the radio, the rest are multimedia keys that 
just need to be forwarded to userspace. Or maybe a bluetooth key.

Some systems require suspend/resume support, others remember state of the 
wireless button automatically. For a perfect example, look at 
drivers/input/misc/wistron_btns.c.

So you should create an "extra laptop buttons" interface. Though it may be 
hard to assure that this generalization layer between input system and 
hardware is still a win for the driver developer.

Stefan

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-06-03  8:45           ` Stefan Rompf
@ 2006-06-04  8:02             ` Ivo van Doorn
  2006-06-04 10:14               ` Stefan Rompf
  0 siblings, 1 reply; 17+ messages in thread
From: Ivo van Doorn @ 2006-06-04  8:02 UTC (permalink / raw)
  To: Stefan Rompf; +Cc: Francois Romieu, netdev, rt2400-devel

[-- Attachment #1: Type: text/plain, Size: 1063 bytes --]

On Saturday 3 June 2006 10:45, Stefan Rompf wrote:
> Am Freitag 02 Juni 2006 16:30 schrieb Ivo van Doorn:
> 
> > > Or actually, I don't think the radiobtn/ won't be actually needed as
> > > prefix. The name passed to the radiobtn driver by the driver should be
> > > sufficient.
> >
> > Updated version,
> >
> > Signed-off-by Ivo van Doorn <IvDoorn@gmail.com>
> 
> I don't like the patch in it's current form. Many notebooks have a number of 
> additional keys that need to be queried/polled using the same interface, but 
> just one button is to control the radio, the rest are multimedia keys that 
> just need to be forwarded to userspace. Or maybe a bluetooth key.

Except for the bluetooth radio key (which should be supported by the radiobtn interface as well)
the other buttons have support through already excisting input devices if I am correct.
This radiobtn driver is there to poll the device frequently about the radio state only
since that is one of the few buttons that is not sending anything to userspace at the moment.

Ivo

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-06-04  8:02             ` Ivo van Doorn
@ 2006-06-04 10:14               ` Stefan Rompf
  2006-06-04 11:44                 ` Ivo van Doorn
  2006-06-17 15:05                 ` Ivo van Doorn
  0 siblings, 2 replies; 17+ messages in thread
From: Stefan Rompf @ 2006-06-04 10:14 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: Francois Romieu, netdev, rt2400-devel

Am Sonntag 04 Juni 2006 10:02 schrieb Ivo van Doorn:

> Except for the bluetooth radio key (which should be supported by the
> radiobtn interface as well) the other buttons have support through already
> excisting input devices if I am correct.

You are wrong for quite a bunch of laptop models. That's why I pointed you to 
the wistron_btns driver. Alternatively, look at the acerhk driver 
(http://www2.informatik.hu-berlin.de/~tauber/acerhk/). Many systems have a 
number of additional buttons that need to be handled by a special driver, all 
sent to userspace, and just one of them to trigger the wireless card. Other 
models just handle the button in ACPI and generate an additional ACPI event.

Looking at the RT2400-driver, I see what you want to accomplish: Take the view 
of the WLAN card on the hardware controlled button enable/disable and 
generate events on it. However, in many cases it is another driver (see 
above) that sets or clears this state, and this should be the instance to 
send the input event.

Note that I do not have objections against the driver being included in the 
kernel - it just does not qualify as generic radiobutton support, but I know 
it's hard to find a good name ;-)

Looking at the code only: There should be an additional non-polling interface 
for drivers that can generate events on the own.

Stefan

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-06-04 10:14               ` Stefan Rompf
@ 2006-06-04 11:44                 ` Ivo van Doorn
  2006-06-17 15:05                 ` Ivo van Doorn
  1 sibling, 0 replies; 17+ messages in thread
From: Ivo van Doorn @ 2006-06-04 11:44 UTC (permalink / raw)
  To: Stefan Rompf; +Cc: Francois Romieu, netdev, rt2400-devel

[-- Attachment #1: Type: text/plain, Size: 2464 bytes --]

On Sunday 4 June 2006 12:14, Stefan Rompf wrote:
> Am Sonntag 04 Juni 2006 10:02 schrieb Ivo van Doorn:
> 
> > Except for the bluetooth radio key (which should be supported by the
> > radiobtn interface as well) the other buttons have support through already
> > excisting input devices if I am correct.
> 
> You are wrong for quite a bunch of laptop models. That's why I pointed you to 
> the wistron_btns driver. Alternatively, look at the acerhk driver 
> (http://www2.informatik.hu-berlin.de/~tauber/acerhk/). Many systems have a 
> number of additional buttons that need to be handled by a special driver, all 
> sent to userspace, and just one of them to trigger the wireless card. Other 
> models just handle the button in ACPI and generate an additional ACPI event.

Ok, indeed a valid point.
Would it be better when the radio_button structure contains a list
of button structures each with its own poll function and current state.
And the radiobtn will loop through the list after each poll_delay time calling
all poll functions. That way drivers can specify themselves which buttons need to be polled.

By renaming enable_radio and disable_radio in the radiobtn structure it could
be made more generic for sending a certain event to the device and not only
an instruction for the radio.

> Looking at the RT2400-driver, I see what you want to accomplish: Take the view 
> of the WLAN card on the hardware controlled button enable/disable and 
> generate events on it. However, in many cases it is another driver (see 
> above) that sets or clears this state, and this should be the instance to 
> send the input event.
> 
> Note that I do not have objections against the driver being included in the 
> kernel - it just does not qualify as generic radiobutton support, but I know 
> it's hard to find a good name ;-)

Thats true. :)
Now lets see how this thing can be made a but more generic. ;)

> Looking at the code only: There should be an additional non-polling interface 
> for drivers that can generate events on the own.

Welll if the enable_radio and disable_radio are being renamed to a more
generic send_event for sending an event to the driver or something,
something similar can be done for the other way around I think, another handler
to send an event from driver to radiobtn. But should such an event also trigger
a call back to the driver, or should only the input event be triggered?

Ivo

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-06-04 10:14               ` Stefan Rompf
  2006-06-04 11:44                 ` Ivo van Doorn
@ 2006-06-17 15:05                 ` Ivo van Doorn
  2006-06-22 15:55                   ` Jiri Benc
  1 sibling, 1 reply; 17+ messages in thread
From: Ivo van Doorn @ 2006-06-17 15:05 UTC (permalink / raw)
  To: Stefan Rompf; +Cc: Francois Romieu, netdev, rt2400-devel

[-- Attachment #1: Type: text/plain, Size: 14016 bytes --]

> > Except for the bluetooth radio key (which should be supported by the
> > radiobtn interface as well) the other buttons have support through already
> > excisting input devices if I am correct.
> 
> You are wrong for quite a bunch of laptop models. That's why I pointed you to 
> the wistron_btns driver. Alternatively, look at the acerhk driver 
> (http://www2.informatik.hu-berlin.de/~tauber/acerhk/). Many systems have a 
> number of additional buttons that need to be handled by a special driver, all 
> sent to userspace, and just one of them to trigger the wireless card. Other 
> models just handle the button in ACPI and generate an additional ACPI event.
> 
> Looking at the RT2400-driver, I see what you want to accomplish: Take the view 
> of the WLAN card on the hardware controlled button enable/disable and 
> generate events on it. However, in many cases it is another driver (see 
> above) that sets or clears this state, and this should be the instance to 
> send the input event.
> 
> Note that I do not have objections against the driver being included in the 
> kernel - it just does not qualify as generic radiobutton support, but I know 
> it's hard to find a good name ;-)
> 
> Looking at the code only: There should be an additional non-polling interface 
> for drivers that can generate events on the own.

Sorry for the late reply, but I have been quite busy with other things lately.
I have created an updated patch, that is more generic than the previous.
I have also renamed it to "laptopkey".

With this approach more buttons can be registered,
it includes the optional field to report an update of the key status
to the driver that registered it, and it supports for non-polling keys.

By default all events will go over the default input device, but a driver
can choose to create additional input devices.

Signed-off-by Ivo van Doorn <IvDoorn@gmail.com>

---

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 4bad588..097ae8c 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -79,4 +79,12 @@ config HP_SDC_RTC
 	  Say Y here if you want to support the built-in real time clock
 	  of the HP SDC controller.
 
+config LAPTOPKEY
+	tristate "Laptop keys support"
+	help
+	 Say Y here if you have laptop with additional keys like hardware
+	 wireless or bluetooth radio control, or other (programmable) keys.
+	 This driver will create an input device to which other hardware
+	 drivers can register their keys to.
+
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 415c491..e691fab 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
 obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
 obj-$(CONFIG_HP_SDC_RTC)		+= hp_sdc_rtc.o
 obj-$(CONFIG_INPUT_IXP4XX_BEEPER)	+= ixp4xx-beeper.o
+obj-$(CONFIG_LAPTOPKEY)			+= laptopkey.o
diff --git a/drivers/input/misc/laptopkey.c b/drivers/input/misc/laptopkey.c
new file mode 100644
index 0000000..7731554
--- /dev/null
+++ b/drivers/input/misc/laptopkey.c
@@ -0,0 +1,231 @@
+/*
+	Copyright (C) 2006 Ivo van Doorn
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the
+	Free Software Foundation, Inc.,
+	59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/laptopkey.h>
+
+MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
+MODULE_VERSION("1.0");
+MODULE_DESCRIPTION("Laptop keys support");
+MODULE_LICENSE("GPL");
+
+/*
+ * Default laptop_key_device structure.
+ */
+static struct laptop_key_device default_keydev = {
+	.dev_name	= "laptopbtn",
+	.delay		= 100,
+};
+
+void laptopkey_key_event(struct laptop_key *key, int status)
+{
+	/*
+	 * Check if the hardware needs to be informed of
+	 * the status change.
+	 */
+	if (key->key_event)
+		key->key_event(key->data, status);
+
+	/*
+	 * Send input event to userspace.
+	 */
+	input_report_key(key->keydev->input_dev, key->key, status);
+	input_sync(key->keydev->input_dev);
+
+}
+
+static void laptopkey_poll(unsigned long data)
+{
+	struct laptop_key_device *keydev = (struct laptop_key_device *)data;
+	struct laptop_key *key;
+	struct list_head *entry;
+	int status;
+
+	list_for_each(entry, &keydev->list){
+		key = list_entry(entry, struct laptop_key, entry);
+
+		/*
+		 * Check if this key requires polling.
+		 * Otherwise just skip this key,
+		 * and move to the next one.
+		 */
+		if (!key->key_poll)
+			continue;
+
+		/*
+		 * Poll the status, and report a key event
+		 * when the status has changed.
+		 */
+		status = !!key->key_poll(key->data);
+		if (status != key->current_status) {
+			laptopkey_key_event(key, status);
+			key->current_status = status;
+		}
+	}
+
+	/*
+	 * Check if the polling can continue.
+	 */
+	if (keydev->delay == 0)
+		return;
+
+	mod_timer(&keydev->timer, jiffies + msecs_to_jiffies(keydev->delay));
+}
+
+void laptopkey_dev_add_key(struct laptop_key_device *keydev,
+			  struct laptop_key *key)
+{
+	/*
+	 * If polling is enabled, obtain the initial
+	 * status from the polling functions, otherwise
+	 * set it to 0.
+	 */
+	if (key->key_poll)
+		key->current_status = key->key_poll(key->data);
+	else
+		key->current_status = 0;
+
+	/*
+	 * Add key to key device.
+	 */
+	key->keydev = keydev;
+	list_add(&key->entry, &keydev->list);
+
+	/*
+	 * Add key to the input device.
+	 */
+	set_bit(key->key, keydev->input_dev->keybit);
+}
+
+void laptopkey_dev_del_key(struct laptop_key_device *keydev,
+			   struct laptop_key *key)
+{
+	/*
+	 * Remove list from device.
+	 */
+	list_del(&key->entry);
+
+	/*
+	 * Remove key to the input device.
+	 */
+	clear_bit(key->key, keydev->input_dev->keybit);
+}
+
+void laptopkey_add_key(struct laptop_key *key)
+{
+	laptopkey_dev_add_key(&default_keydev, key);
+}
+
+void laptopkey_del_key(struct laptop_key *key)
+{
+	laptopkey_dev_del_key(&default_keydev, key);
+}
+
+int laptopkey_register_device(struct laptop_key_device *keydev)
+{
+	int status;
+
+	/*
+	 * Create the input device
+	 */
+	keydev->input_dev = input_allocate_device();
+	if (!keydev->input_dev) {
+		printk(KERN_ERR "Failed to allocate input device %s.\n",
+			keydev->dev_name);
+		return -ENOMEM;
+	}
+
+	/*
+	 * Initialize the input device
+	 */
+	keydev->input_dev->name = "Laptop keys";
+	keydev->input_dev->phys = keydev->dev_name;
+	keydev->input_dev->id.bustype = BUS_HOST;
+
+	/*
+	 * Register the input device
+	 */
+	status = input_register_device(keydev->input_dev);
+	if (status) {
+		printk(KERN_ERR "Failed to register input device %s.\n",
+			keydev->dev_name);
+		input_free_device(keydev->input_dev);
+		return status;
+	}
+
+	/*
+	 * Initialize list head.
+	 */
+	INIT_LIST_HEAD(&keydev->list);
+
+	/*
+	 * Initialize timer.
+	 */
+	init_timer(&keydev->timer);
+	keydev->timer.function = laptopkey_poll;
+	keydev->timer.data = (unsigned long)keydev;
+	keydev->timer.expires = jiffies + msecs_to_jiffies(keydev->delay);
+	add_timer(&keydev->timer);
+
+	printk(KERN_INFO "Created new %s: %s.\n",
+		keydev->input_dev->name, keydev->input_dev->phys);
+
+	return 0;
+}
+
+void laptopkey_unregister_device(struct laptop_key_device *keydev)
+{
+	/*
+	 * Clear the delay field before deleting the timer,
+	 * to prevent the scheduled work to rearm itself.
+	 */
+	keydev->delay = 0;
+	del_timer_sync(&keydev->timer);
+
+	/*
+	 * Remove input device.
+	 */
+	input_unregister_device(keydev->input_dev);
+	input_free_device(keydev->input_dev);
+}
+
+static int __init radiobtn_init(void)
+{
+	printk(KERN_INFO "Loading radio button driver.\n");
+	return laptopkey_register_device(&default_keydev);
+}
+
+static void __exit radiobtn_exit(void)
+{
+	laptopkey_unregister_device(&default_keydev);
+	printk(KERN_INFO "Unloading radio button driver.\n");
+}
+
+EXPORT_SYMBOL(laptopkey_add_key);
+EXPORT_SYMBOL(laptopkey_del_key);
+EXPORT_SYMBOL(laptopkey_register_device);
+EXPORT_SYMBOL(laptopkey_unregister_device);
+EXPORT_SYMBOL(laptopkey_dev_add_key);
+EXPORT_SYMBOL(laptopkey_dev_del_key);
+EXPORT_SYMBOL(laptopkey_key_event);
+
+module_init(radiobtn_init);
+module_exit(radiobtn_exit);
diff --git a/include/linux/laptopkey.h b/include/linux/laptopkey.h
new file mode 100644
index 0000000..063ecf5
--- /dev/null
+++ b/include/linux/laptopkey.h
@@ -0,0 +1,131 @@
+/*
+	Copyright (C) 2006 Ivo van Doorn
+
+	This program is free software; you can redistribute it and/or modify
+	it under the terms of the GNU General Public License as published by
+	the Free Software Foundation; either version 2 of the License, or
+	(at your option) any later version.
+
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+	GNU General Public License for more details.
+
+	You should have received a copy of the GNU General Public License
+	along with this program; if not, write to the
+	Free Software Foundation, Inc.,
+	59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+	Laptop keys support
+
+	INTRODUCTION
+	Laptops are quite often equiped with additional hardware keys.
+	This includes the radio keys for wireless and bluetooth devices,
+	but also other (programmable) keys.
+	This driver will create a generic layer between hardware and
+	userspace. Drivers can add keys to the input device for
+	frequent polling and reporting the status to userspace.
+
+	INPUT DEVICES
+	When loading this driver the main input device is directly created.
+	When desired drivers can also register a new laptop_key_device
+	which creates a new input device to which the laptop keys can be
+	registered.
+
+	POLLING
+	In the laptop_key_device structure the delay is set, this delay
+	is used to determine the polling interval in which each key will be
+	polled for its status. When the key_poll field is not set, the
+	key will not be polled.
+
+	STATUS REPORTING
+	When the status has changed, an input event will be send to userspace.
+	The key field will be used as reported key in that input event.
+	When the status of the key has changed, this event will also be send to
+	the driver that registered the key when the key_event field has been
+	set. It is also possible for keys to skip the polling and inform
+	this driver of the event directly.
+ */
+
+#ifndef LAPTOPKEY_H
+#define LAPTOPKEY_H
+
+#include <linux/input.h>
+#include <linux/list.h>
+
+/**
+ * struct laptop_key_device - laptop key device structure
+ * @dev_name: Name of the input device.
+ * @delay: When polling is required for any of the keys,
+ *	this polling delay (in ms) will be used.
+ * @list: All laptop keys are part of a linked list.
+ *	This field should not be touched by any driver.
+ * @input_dev: This is the input device created for this laptop_key_device.
+ *	This field should not be touched by any driver.
+ * @timer: The timer structure for the frequent polling of the keys.
+ *	This field should not be touched by any driver.
+ */
+struct laptop_key_device {
+	const char *dev_name;
+
+	unsigned int delay;
+
+	struct list_head list;
+
+	struct input_dev *input_dev;
+
+	struct timer_list timer;
+};
+
+/**
+ * struct laptop_key - laptop key structure
+ * @key: Key type that is send to userspace.
+ *	should be any of the KEY_* defines from <linux/input.h>
+ * @data: private data that is send as argument with the
+ *	functions key_poll and key_event.
+ * @current_status: Current status of the button is stored here.
+ * @key_poll: This function is used to determine the current state
+ *	of the key. This field only needs to be set when polling is required.
+ * @key_event: This function is used when the key status has changed, it will
+ *	then send the new key status as argument to inform the hardware
+ *	of the change. This field is only required when the hardware needs to
+ *	be informed of the change.
+ * @keydev: laptop_key_device structure this key is attached to.
+ *	This field should not be touched by any driver.
+ * @entry: All laptop keys are part of a linked list. This field should not
+ *	be touched by any driver.
+ */
+struct laptop_key {
+	unsigned int key;
+	unsigned long data;
+	int current_status;
+
+	int (*key_poll)(unsigned long data);
+	void (*key_event)(unsigned long data, int status);
+
+	struct laptop_key_device *keydev;
+	struct list_head entry;
+};
+
+/*
+ * Functions when using the main input device.
+ */
+void laptopkey_add_key(struct laptop_key *);
+void laptopkey_del_key(struct laptop_key *);
+
+/*
+ * Functions when using a seperate input device.
+ */
+int laptopkey_register_device(struct laptop_key_device *);
+void laptopkey_unregister_device(struct laptop_key_device *);
+void laptopkey_dev_add_key(struct laptop_key_device *, struct laptop_key *);
+void laptopkey_dev_del_key(struct laptop_key_device *, struct laptop_key *);
+
+/*
+ * Manually report a key event.
+ */
+void laptopkey_key_event(struct laptop_key *, int status);
+
+#endif /* LAPTOPKEY_H */

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-06-17 15:05                 ` Ivo van Doorn
@ 2006-06-22 15:55                   ` Jiri Benc
  2006-06-23 11:08                     ` Vojtech Pavlik
  2006-06-23 18:53                     ` Ivo van Doorn
  0 siblings, 2 replies; 17+ messages in thread
From: Jiri Benc @ 2006-06-22 15:55 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: Stefan Rompf, Francois Romieu, netdev, Vojtech Pavlik

On Sat, 17 Jun 2006 17:05:55 +0200, Ivo van Doorn wrote:
> With this approach more buttons can be registered,
> it includes the optional field to report an update of the key status
> to the driver that registered it, and it supports for non-polling keys.

I think this is not specific to networking anymore, so it should go to
lkml. Please be sure to Cc: input devices maintainer, Dmitry Torokhov.

Regarding rfkill button, I talked about that with Vojtech Pavlik (Cc:ed)
and he suggests this solution:

- driver is responsible for turning on/off radio when the input device
  is not opened;
- when something opens the input device, it receives input events and 
  gets responsible to turn on/off the radio (by ioctl or putting the 
  network interfaces up/down).

This is of course not possible for all hardware, but it gives the most
flexibility while keeping the possibility to switch of the radio without
userspace support.

Thanks,

 Jiri

-- 
Jiri Benc
SUSE Labs

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-06-22 15:55                   ` Jiri Benc
@ 2006-06-23 11:08                     ` Vojtech Pavlik
  2006-06-23 18:51                       ` Ivo van Doorn
  2006-06-23 18:53                     ` Ivo van Doorn
  1 sibling, 1 reply; 17+ messages in thread
From: Vojtech Pavlik @ 2006-06-23 11:08 UTC (permalink / raw)
  To: Jiri Benc; +Cc: Ivo van Doorn, Stefan Rompf, Francois Romieu, netdev

On Thu, Jun 22, 2006 at 05:55:46PM +0200, Jiri Benc wrote:

> On Sat, 17 Jun 2006 17:05:55 +0200, Ivo van Doorn wrote:
> > With this approach more buttons can be registered,
> > it includes the optional field to report an update of the key status
> > to the driver that registered it, and it supports for non-polling keys.
> 
> I think this is not specific to networking anymore, so it should go to
> lkml. Please be sure to Cc: input devices maintainer, Dmitry Torokhov.
> 
> Regarding rfkill button, I talked about that with Vojtech Pavlik (Cc:ed)
> and he suggests this solution:
> 
> - driver is responsible for turning on/off radio when the input device
>   is not opened;
> - when something opens the input device, it receives input events and 
>   gets responsible to turn on/off the radio (by ioctl or putting the 
>   network interfaces up/down).
> 
> This is of course not possible for all hardware, but it gives the most
> flexibility while keeping the possibility to switch of the radio without
> userspace support.
 
Let me elaborate a little bit on the possible implementation:

	1) 802.11 card drivers will implement an input device for each card in
	the system that has a user-controlled RF-Kill button or switch.

	2) 802.11 card drivers will implement an interface to enable/disable the
	radio, be it through a call, ioctl, or whatever, that is accessible from
	both the kernel and userspace.

	3) ACPI buttons drivers, and keyboard drivers will generate KEY_RFKILL
	on machines where RF-Kill keys are reported using ACPI events or
	keyboard scancodes.

	3) A rfkill.ko input handler module will be implemented, that listens to
	the SW_RFKILL and KEY_RFKILL events from all devices in the system, and
	will enable/disable radios on all 802.11 devices in the system.

The above will make the RF-Kill button work under all real scenarios as
user expects - it will enable/disable the radio. In the case where a
user has an additional PCMCIA card, both the radios will be disabled by
presing the RF-Kill button, which is arguably what the user expects.
Even BlueTooth or other RF technologies (CDMA, EDGE) can hook into this
mechanism.

	4) When userspace wants to take over the control over RF-Kill, and start
	additional services based on that, it can open the input devices to get
	the state of the buttons/switches, AND it can issue the EVIOCGRAB
	ioctl() to prevent the rfkill.ko and any other handlers from getting the
	events.

This allows simple implementation of dbus notifications and
NetworkManager-style configuration of network interfaces.

-- 
Vojtech Pavlik
Director SuSE Labs

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-06-23 11:08                     ` Vojtech Pavlik
@ 2006-06-23 18:51                       ` Ivo van Doorn
  2006-06-23 19:32                         ` Vojtech Pavlik
  0 siblings, 1 reply; 17+ messages in thread
From: Ivo van Doorn @ 2006-06-23 18:51 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Jiri Benc, Stefan Rompf, Francois Romieu, netdev

[-- Attachment #1: Type: text/plain, Size: 3088 bytes --]

Hi,

> > On Sat, 17 Jun 2006 17:05:55 +0200, Ivo van Doorn wrote:
> > > With this approach more buttons can be registered,
> > > it includes the optional field to report an update of the key status
> > > to the driver that registered it, and it supports for non-polling keys.
> > 
> > I think this is not specific to networking anymore, so it should go to
> > lkml. Please be sure to Cc: input devices maintainer, Dmitry Torokhov.
> > 
> > Regarding rfkill button, I talked about that with Vojtech Pavlik (Cc:ed)
> > and he suggests this solution:
> > 
> > - driver is responsible for turning on/off radio when the input device
> >   is not opened;
> > - when something opens the input device, it receives input events and 
> >   gets responsible to turn on/off the radio (by ioctl or putting the 
> >   network interfaces up/down).
> > 
> > This is of course not possible for all hardware, but it gives the most
> > flexibility while keeping the possibility to switch of the radio without
> > userspace support.
>  
> Let me elaborate a little bit on the possible implementation:
> 
> 	1) 802.11 card drivers will implement an input device for each card in
> 	the system that has a user-controlled RF-Kill button or switch.

So basicly 1 input device for every single wireless driver that implements
the RF-Kill button?
Is there any particular reason for not using 1 input device shared by all?

> 	2) 802.11 card drivers will implement an interface to enable/disable the
> 	radio, be it through a call, ioctl, or whatever, that is accessible from
> 	both the kernel and userspace.

Userspace could switch off the radio by using the txpower ioctl of
ifdown/ifup. Or should an approach call be implemented?

> 	3) ACPI buttons drivers, and keyboard drivers will generate KEY_RFKILL
> 	on machines where RF-Kill keys are reported using ACPI events or
> 	keyboard scancodes.

Why both an input and ACPI event?
With ACPI restricted to x86 only, wouldn't a more generic approach be desired?

> 	3) A rfkill.ko input handler module will be implemented, that listens to
> 	the SW_RFKILL and KEY_RFKILL events from all devices in the system, and
> 	will enable/disable radios on all 802.11 devices in the system.
>
> The above will make the RF-Kill button work under all real scenarios as
> user expects - it will enable/disable the radio. In the case where a
> user has an additional PCMCIA card, both the radios will be disabled by
> presing the RF-Kill button, which is arguably what the user expects.
> Even BlueTooth or other RF technologies (CDMA, EDGE) can hook into this
> mechanism.
> 
> 	4) When userspace wants to take over the control over RF-Kill, and start
> 	additional services based on that, it can open the input devices to get
> 	the state of the buttons/switches, AND it can issue the EVIOCGRAB
> 	ioctl() to prevent the rfkill.ko and any other handlers from getting the
> 	events.
>
> This allows simple implementation of dbus notifications and
> NetworkManager-style configuration of network interfaces.
> 

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-06-22 15:55                   ` Jiri Benc
  2006-06-23 11:08                     ` Vojtech Pavlik
@ 2006-06-23 18:53                     ` Ivo van Doorn
  1 sibling, 0 replies; 17+ messages in thread
From: Ivo van Doorn @ 2006-06-23 18:53 UTC (permalink / raw)
  To: Jiri Benc; +Cc: Stefan Rompf, Francois Romieu, netdev, Vojtech Pavlik

[-- Attachment #1: Type: text/plain, Size: 762 bytes --]

On Thursday 22 June 2006 17:55, Jiri Benc wrote:
> On Sat, 17 Jun 2006 17:05:55 +0200, Ivo van Doorn wrote:
> > With this approach more buttons can be registered,
> > it includes the optional field to report an update of the key status
> > to the driver that registered it, and it supports for non-polling keys.
> 
> I think this is not specific to networking anymore, so it should go to
> lkml. Please be sure to Cc: input devices maintainer, Dmitry Torokhov.

Thanks, I am currently discussing the driver with developers
from button drivers like acerhk and acpi_acer.
If I am sending the driver to the lkml will depend on their
reaction and input for the driver. No use sending drivers to
lkml when no other driver will want to use it. ;)

Ivo

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-06-23 18:51                       ` Ivo van Doorn
@ 2006-06-23 19:32                         ` Vojtech Pavlik
  2006-06-23 21:35                           ` Ivo van Doorn
  0 siblings, 1 reply; 17+ messages in thread
From: Vojtech Pavlik @ 2006-06-23 19:32 UTC (permalink / raw)
  To: Ivo van Doorn; +Cc: Jiri Benc, Stefan Rompf, Francois Romieu, netdev

On Fri, Jun 23, 2006 at 08:51:33PM +0200, Ivo van Doorn wrote:

> > > This is of course not possible for all hardware, but it gives the most
> > > flexibility while keeping the possibility to switch of the radio without
> > > userspace support.
> >  
> > Let me elaborate a little bit on the possible implementation:
> > 
> > 	1) 802.11 card drivers will implement an input device for each card in
> > 	the system that has a user-controlled RF-Kill button or switch.
> 
> So basicly 1 input device for every single wireless driver that implements
> the RF-Kill button?

Yes.

> Is there any particular reason for not using 1 input device shared by all?

Yes.

In the unlikely case where there are two devices which implement a
rfkill button in the system, the input core doesn't have a way how to
express the state of these two different buttons with the same meaning
(and hence the same code - KEY_RFKILL) in a single input device.

You'd have to assign a range of codes to the shared device, which goes
agains the design of the Linux inpu layer.

Anyway, for the most common case, where you have a single RF-Kill key in
the whole system, there will not be any difference to using the shared
device.

What do you consider the benefits of using a shared input device?

> > 	2) 802.11 card drivers will implement an interface to enable/disable the
> > 	radio, be it through a call, ioctl, or whatever, that is accessible from
> > 	both the kernel and userspace.
> 
> Userspace could switch off the radio by using the txpower ioctl of
> ifdown/ifup. Or should an approach call be implemented?

I'm an input guy, the details of how to disable the radio I'll leave up
to you - the WiFi folks on netdev.

You may want to consider that the radio chip usually synthesizes a
frequency that it mixes with the incoming signal to frequency-shift it
to a low frequency which then can be demodulated. Because of that, even
the receiver, when working, can affect devices nearby. This is why FM
radio receivers are not allowed on airplanes.

Hardware RF-Kill disables both RX and TX, by stopping the radio chip.
Setting TX power to an extremely low value might not be the same.

On the other hand, you may define in the API that setting TX power to
zero also disables the receiver.

> > 	3) ACPI buttons drivers, and keyboard drivers will generate KEY_RFKILL
> > 	on machines where RF-Kill keys are reported using ACPI events or
> > 	keyboard scancodes.
> 
> Why both an input and ACPI event?
> With ACPI restricted to x86 only, wouldn't a more generic approach be desired?

I was talking about the ACPI EC sending us an event. This is how are
ACPI buttons implemented in certain notebooks. I definitely don't want
to use the acpi events as received by acpid now as the interface. Sorry
for the confusion.

> > 	3) A rfkill.ko input handler module will be implemented, that listens to
> > 	the SW_RFKILL and KEY_RFKILL events from all devices in the system, and
> > 	will enable/disable radios on all 802.11 devices in the system.
> >
> > The above will make the RF-Kill button work under all real scenarios as
> > user expects - it will enable/disable the radio. In the case where a
> > user has an additional PCMCIA card, both the radios will be disabled by
> > presing the RF-Kill button, which is arguably what the user expects.
> > Even BlueTooth or other RF technologies (CDMA, EDGE) can hook into this
> > mechanism.
> > 
> > 	4) When userspace wants to take over the control over RF-Kill, and start
> > 	additional services based on that, it can open the input devices to get
> > 	the state of the buttons/switches, AND it can issue the EVIOCGRAB
> > 	ioctl() to prevent the rfkill.ko and any other handlers from getting the
> > 	events.
> >
> > This allows simple implementation of dbus notifications and
> > NetworkManager-style configuration of network interfaces.

-- 
Vojtech Pavlik
Director SuSE Labs

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
  2006-06-23 19:32                         ` Vojtech Pavlik
@ 2006-06-23 21:35                           ` Ivo van Doorn
  0 siblings, 0 replies; 17+ messages in thread
From: Ivo van Doorn @ 2006-06-23 21:35 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Jiri Benc, Stefan Rompf, Francois Romieu, netdev

[-- Attachment #1: Type: text/plain, Size: 4276 bytes --]

> > So basicly 1 input device for every single wireless driver that implements
> > the RF-Kill button?
> 
> Yes.
> 
> > Is there any particular reason for not using 1 input device shared by all?
> 
> Yes.
> 
> In the unlikely case where there are two devices which implement a
> rfkill button in the system, the input core doesn't have a way how to
> express the state of these two different buttons with the same meaning
> (and hence the same code - KEY_RFKILL) in a single input device.
> 
> You'd have to assign a range of codes to the shared device, which goes
> agains the design of the Linux inpu layer.
> 
> Anyway, for the most common case, where you have a single RF-Kill key in
> the whole system, there will not be any difference to using the shared
> device.
> 
> What do you consider the benefits of using a shared input device?

Well it is a matter of preference, especially on how this rfkill.ko would
be implemented. When the user has 2 buttons, should all radios
(wifi, bluetooth etc) be switched off by pressing each individual key
or just 1 key to switch off everything.
But now that I am further thinking about this, (and looking on how
my laptop currently works with 1 wifi button and 1 bluetooth button)
perhaps multiple input devices would indeed be best.
userspace can decide if more interfaces should be attached to the button
or not. And this would be the preferred situation.

> > Userspace could switch off the radio by using the txpower ioctl of
> > ifdown/ifup. Or should an approach call be implemented?
> 
> I'm an input guy, the details of how to disable the radio I'll leave up
> to you - the WiFi folks on netdev.

:)

> You may want to consider that the radio chip usually synthesizes a
> frequency that it mixes with the incoming signal to frequency-shift it
> to a low frequency which then can be demodulated. Because of that, even
> the receiver, when working, can affect devices nearby. This is why FM
> radio receivers are not allowed on airplanes.
> 
> Hardware RF-Kill disables both RX and TX, by stopping the radio chip.
> Setting TX power to an extremely low value might not be the same.
> 
> On the other hand, you may define in the API that setting TX power to
> zero also disables the receiver.

ok, no need for new ioctl calls in that case I believe.
Using the txpower the radio can be switched on and off, without giving a low or 0 as value.
But the decision to use ifup and ifdown or iwconfig txpower on/off could be done later,
since it can handled in user space.

> > > 	3) ACPI buttons drivers, and keyboard drivers will generate KEY_RFKILL
> > > 	on machines where RF-Kill keys are reported using ACPI events or
> > > 	keyboard scancodes.
> > 
> > Why both an input and ACPI event?
> > With ACPI restricted to x86 only, wouldn't a more generic approach be desired?
> 
> I was talking about the ACPI EC sending us an event. This is how are
> ACPI buttons implemented in certain notebooks. I definitely don't want
> to use the acpi events as received by acpid now as the interface. Sorry
> for the confusion.

ah ok. :)

> > > 	3) A rfkill.ko input handler module will be implemented, that listens to
> > > 	the SW_RFKILL and KEY_RFKILL events from all devices in the system, and
> > > 	will enable/disable radios on all 802.11 devices in the system.
> > >
> > > The above will make the RF-Kill button work under all real scenarios as
> > > user expects - it will enable/disable the radio. In the case where a
> > > user has an additional PCMCIA card, both the radios will be disabled by
> > > presing the RF-Kill button, which is arguably what the user expects.
> > > Even BlueTooth or other RF technologies (CDMA, EDGE) can hook into this
> > > mechanism.
> > > 
> > > 	4) When userspace wants to take over the control over RF-Kill, and start
> > > 	additional services based on that, it can open the input devices to get
> > > 	the state of the buttons/switches, AND it can issue the EVIOCGRAB
> > > 	ioctl() to prevent the rfkill.ko and any other handlers from getting the
> > > 	events.
> > >
> > > This allows simple implementation of dbus notifications and
> > > NetworkManager-style configuration of network interfaces.
> 

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2006-06-23 21:31 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-05-25 15:16 [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn Ivo van Doorn
2006-05-29 15:58 ` Ivo van Doorn
2006-05-30 21:43   ` Francois Romieu
2006-05-31 17:31     ` Ivo van Doorn
2006-05-31 18:05       ` Ivo van Doorn
2006-06-02 14:30         ` Ivo van Doorn
2006-06-03  8:45           ` Stefan Rompf
2006-06-04  8:02             ` Ivo van Doorn
2006-06-04 10:14               ` Stefan Rompf
2006-06-04 11:44                 ` Ivo van Doorn
2006-06-17 15:05                 ` Ivo van Doorn
2006-06-22 15:55                   ` Jiri Benc
2006-06-23 11:08                     ` Vojtech Pavlik
2006-06-23 18:51                       ` Ivo van Doorn
2006-06-23 19:32                         ` Vojtech Pavlik
2006-06-23 21:35                           ` Ivo van Doorn
2006-06-23 18:53                     ` Ivo van Doorn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).