From: Ivo van Doorn <ivdoorn@gmail.com>
To: Francois Romieu <romieu@fr.zoreil.com>
Cc: netdev@vger.kernel.org
Subject: Re: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn
Date: Fri, 2 Jun 2006 16:30:30 +0200 [thread overview]
Message-ID: <200606021630.34544.IvDoorn@gmail.com> (raw)
In-Reply-To: <200605312005.31067.IvDoorn@gmail.com>
[-- 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 --]
next prev parent reply other threads:[~2006-06-02 14:27 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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=200606021630.34544.IvDoorn@gmail.com \
--to=ivdoorn@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=romieu@fr.zoreil.com \
/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).