netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ivo van Doorn <ivdoorn@gmail.com>
To: netdev@vger.kernel.org
Subject: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
Date: Thu, 25 May 2006 17:16:00 +0200	[thread overview]
Message-ID: <200605251716.00742.IvDoorn@gmail.com> (raw)

[-- 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 --]

             reply	other threads:[~2006-05-25 15:13 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-05-25 15:16 Ivo van Doorn [this message]
2006-05-29 15:58 ` [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200605251716.00742.IvDoorn@gmail.com \
    --to=ivdoorn@gmail.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).