diff options
author | Nick Pelly <npelly@google.com> | 2009-06-11 10:49:48 -0700 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2010-09-29 17:49:22 -0700 |
commit | f8b1da33486a2e3ca83238207e5d237994097536 (patch) | |
tree | 31bc928ac88596dfcd92876bb31088df4201a1c0 /drivers/misc | |
parent | 22165896d5542280b4e54cbe1d4661b98af49a38 (diff) |
wl127x-rfkill: Add power control driver for TI WL127X Bluetooth chips
Signed-off-by: Nick Pelly <npelly@google.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/Kconfig | 8 | ||||
-rw-r--r-- | drivers/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/misc/wl127x-rfkill.c | 121 |
3 files changed, 130 insertions, 0 deletions
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index a08f69200967..ef8646b10ce9 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -405,6 +405,14 @@ config BMP085 To compile this driver as a module, choose M here: the module will be called bmp085. +config WL127X_RFKILL + tristate "Bluetooth power control driver for TI wl127x" + depends on RFKILL + default n + ---help--- + Creates an rfkill entry in sysfs for power control of Bluetooth + TI wl127x chips. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index db51cb118c37..b48ad06772ed 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -38,3 +38,4 @@ obj-y += eeprom/ obj-y += cb710/ obj-$(CONFIG_VMWARE_BALLOON) += vmw_balloon.o obj-$(CONFIG_ARM_CHARLCD) += arm-charlcd.o +obj-$(CONFIG_WL127X_RFKILL) += wl127x-rfkill.o diff --git a/drivers/misc/wl127x-rfkill.c b/drivers/misc/wl127x-rfkill.c new file mode 100644 index 000000000000..f5b95152948b --- /dev/null +++ b/drivers/misc/wl127x-rfkill.c @@ -0,0 +1,121 @@ +/* + * Bluetooth TI wl127x rfkill power control via GPIO + * + * Copyright (C) 2009 Motorola, Inc. + * Copyright (C) 2008 Texas Instruments + * Initial code: Pavan Savoy <pavan.savoy@gmail.com> (wl127x_power.c) + * + * 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/module.h> +#include <linux/init.h> +#include <linux/gpio.h> +#include <linux/rfkill.h> +#include <linux/platform_device.h> +#include <linux/wl127x-rfkill.h> + +static int wl127x_rfkill_set_power(void *data, enum rfkill_state state) +{ + int nshutdown_gpio = (int) data; + + switch (state) { + case RFKILL_STATE_UNBLOCKED: + gpio_set_value(nshutdown_gpio, 1); + break; + case RFKILL_STATE_SOFT_BLOCKED: + gpio_set_value(nshutdown_gpio, 0); + break; + default: + printk(KERN_ERR "invalid bluetooth rfkill state %d\n", state); + } + return 0; +} + +static int wl127x_rfkill_probe(struct platform_device *pdev) +{ + int rc = 0; + struct wl127x_rfkill_platform_data *pdata = pdev->dev.platform_data; + enum rfkill_state default_state = RFKILL_STATE_SOFT_BLOCKED; /* off */ + + rc = gpio_request(pdata->nshutdown_gpio, "wl127x_nshutdown_gpio"); + if (unlikely(rc)) + return rc; + + rc = gpio_direction_output(pdata->nshutdown_gpio, 0); + if (unlikely(rc)) + return rc; + + rfkill_set_default(RFKILL_TYPE_BLUETOOTH, default_state); + wl127x_rfkill_set_power(NULL, default_state); + + pdata->rfkill = rfkill_allocate(&pdev->dev, RFKILL_TYPE_BLUETOOTH); + if (unlikely(!pdata->rfkill)) + return -ENOMEM; + + pdata->rfkill->name = "wl127x"; + pdata->rfkill->state = default_state; + /* userspace cannot take exclusive control */ + pdata->rfkill->user_claim_unsupported = 1; + pdata->rfkill->user_claim = 0; + pdata->rfkill->data = (void *) pdata->nshutdown_gpio; + pdata->rfkill->toggle_radio = wl127x_rfkill_set_power; + + rc = rfkill_register(pdata->rfkill); + + if (unlikely(rc)) + rfkill_free(pdata->rfkill); + + return 0; +} + +static int wl127x_rfkill_remove(struct platform_device *pdev) +{ + struct wl127x_rfkill_platform_data *pdata = pdev->dev.platform_data; + + rfkill_unregister(pdata->rfkill); + rfkill_free(pdata->rfkill); + gpio_free(pdata->nshutdown_gpio); + + return 0; +} + +static struct platform_driver wl127x_rfkill_platform_driver = { + .probe = wl127x_rfkill_probe, + .remove = wl127x_rfkill_remove, + .driver = { + .name = "wl127x-rfkill", + .owner = THIS_MODULE, + }, +}; + +static int __init wl127x_rfkill_init(void) +{ + return platform_driver_register(&wl127x_rfkill_platform_driver); +} + +static void __exit wl127x_rfkill_exit(void) +{ + platform_driver_unregister(&wl127x_rfkill_platform_driver); +} + +module_init(wl127x_rfkill_init); +module_exit(wl127x_rfkill_exit); + +MODULE_ALIAS("platform:wl127x"); +MODULE_DESCRIPTION("wl127x-rfkill"); +MODULE_AUTHOR("Motorola"); +MODULE_LICENSE("GPL"); |