From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ivo van Doorn Subject: [RFC PATCH 1/2] Hardware button support for Wireless cards: radiobtn Date: Thu, 25 May 2006 17:16:00 +0200 Message-ID: <200605251716.00742.IvDoorn@gmail.com> Mime-Version: 1.0 Content-Type: multipart/signed; boundary="nextPart1242254.2aO1YWcpD1"; protocol="application/pgp-signature"; micalg=pgp-sha1 Content-Transfer-Encoding: 7bit Return-path: Received: from nf-out-0910.google.com ([64.233.182.185]:46392 "EHLO nf-out-0910.google.com") by vger.kernel.org with ESMTP id S965198AbWEYPN2 (ORCPT ); Thu, 25 May 2006 11:13:28 -0400 Received: by nf-out-0910.google.com with SMTP id b2so181556nfe for ; Thu, 25 May 2006 08:13:27 -0700 (PDT) To: netdev@vger.kernel.org Sender: netdev-owner@vger.kernel.org List-Id: netdev.vger.kernel.org --nextPart1242254.2aO1YWcpD1 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline 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 butto= n. 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 diff -uprN wireless-dev/drivers/input/misc/Kconfig wireless-dev-radiobtn/dr= ivers/input/misc/Kconfig =2D-- 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.00= 0000000 +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. =20 +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/d= rivers/input/misc/Makefile =2D-- wireless-dev/drivers/input/misc/Makefile 2006-04-27 00:52:53.00000000= 0 +0200 +++ wireless-dev-radiobtn/drivers/input/misc/Makefile 2006-05-25 16:25:43.0= 00000000 +0200 @@ -11,3 +11,4 @@ obj-$(CONFIG_INPUT_UINPUT) +=3D uinput.o obj-$(CONFIG_INPUT_WISTRON_BTNS) +=3D wistron_btns.o obj-$(CONFIG_HP_SDC_RTC) +=3D hp_sdc_rtc.o obj-$(CONFIG_INPUT_IXP4XX_BEEPER) +=3D ixp4xx-beeper.o +obj-$(CONFIG_RADIOBTN) +=3D radiobtn.o diff -uprN wireless-dev/drivers/input/misc/radiobtn.c wireless-dev-radiobtn= /drivers/input/misc/radiobtn.c =2D-- wireless-dev/drivers/input/misc/radiobtn.c 1970-01-01 01:00:00.000000= 000 +0100 +++ wireless-dev-radiobtn/drivers/input/misc/radiobtn.c 2006-05-25 16:23:59= =2E000000000 +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 +#include +#include +#include +#include + +MODULE_AUTHOR("Ivo van Doorn "); +MODULE_VERSION("1.0"); +MODULE_DESCRIPTION("Radio hardware button support"); +MODULE_LICENSE("GPL"); + +void radiobtn_poll(unsigned long data) +{ + struct radio_button *radiobtn =3D (struct radio_button*)data; + int state; + + /* + * Poll for the new state. + * Check if the state has changed. + */ + state =3D !!radiobtn->button_poll(radiobtn->data); + if (state !=3D radiobtn->current_state) { + radiobtn->current_state =3D 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 !=3D 0) { + radiobtn->poll_timer.expires =3D + 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 =3D=3D 0 || radiobtn->button_poll =3D=3D NULL) + return -EINVAL; + + /* + * Allocate, initialize and register input device. + */ + radiobtn->input_dev =3D 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 =3D "Radio button"; + radiobtn->input_dev->phys =3D strcat("radiobtn/", radiobtn->dev_name); + radiobtn->input_dev->id.bustype =3D BUS_HOST; + set_bit(KEY_RADIO, radiobtn->input_dev->keybit); + + status =3D 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 =3D radiobtn_poll; + radiobtn->poll_timer.data =3D (unsigned long)radiobtn; + radiobtn->poll_timer.expires =3D + 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 =3D 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/incl= ude/linux/radiobtn.h =2D-- 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.0000= 00000 +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 + +/** + * 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 rad= io + * 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 */ --nextPart1242254.2aO1YWcpD1 Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.2 (GNU/Linux) iD8DBQBEdcowaqndE37Em0gRAnLEAJ9K9Ty9NqJdbRCqqB0t/gqGPcLP+gCcC/Hh +fJXlh2P8MyMA4+zxXOVltc= =+i5/ -----END PGP SIGNATURE----- --nextPart1242254.2aO1YWcpD1--