From b6747f3843cbfd8a8844fe602c8d6c8a2ff5b5dd Mon Sep 17 00:00:00 2001 From: Erik Gilling Date: Mon, 13 Dec 2010 23:12:46 -0800 Subject: [PATCH] Revert "[ARM] tegra: stingray: Rework Bluetooth rfkill driver." This reverts commit bdc9c8c04726fd6a5a22194e79df7140667c8c20. --- arch/arm/mach-tegra/Makefile | 2 +- .../arm/mach-tegra/board-stingray-bluetooth.c | 315 ------------------ arch/arm/mach-tegra/board-stingray-rfkill.c | 125 +++++++ arch/arm/mach-tegra/board-stingray.c | 14 +- arch/arm/mach-tegra/include/mach/bcm_bt_lpm.h | 27 -- 5 files changed, 129 insertions(+), 354 deletions(-) delete mode 100644 arch/arm/mach-tegra/board-stingray-bluetooth.c create mode 100644 arch/arm/mach-tegra/board-stingray-rfkill.c delete mode 100644 arch/arm/mach-tegra/include/mach/bcm_bt_lpm.h diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 2c0e6d5442a8..75a144d76d87 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -66,7 +66,7 @@ obj-${CONFIG_MACH_STINGRAY} += board-stingray-sensors.o obj-${CONFIG_MACH_STINGRAY} += board-stingray-wlan_nvs.o obj-${CONFIG_MACH_STINGRAY} += board-stingray-touch.o obj-${CONFIG_MACH_STINGRAY} += board-stingray-power.o -obj-${CONFIG_MACH_STINGRAY} += board-stingray-bluetooth.o +obj-${CONFIG_MACH_STINGRAY} += board-stingray-rfkill.o obj-${CONFIG_MACH_STINGRAY} += board-stingray-gps.o obj-${CONFIG_MACH_STINGRAY} += board-stingray-usbnet.o obj-${CONFIG_MACH_STINGRAY} += board-stingray-bootinfo.o diff --git a/arch/arm/mach-tegra/board-stingray-bluetooth.c b/arch/arm/mach-tegra/board-stingray-bluetooth.c deleted file mode 100644 index 023e12c4e748..000000000000 --- a/arch/arm/mach-tegra/board-stingray-bluetooth.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Bluetooth Broadcomm and low power control via GPIO - * - * Copyright (C) 2010 Google, Inc. - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gpio-names.h" - -#define BT_SHUTDOWN_GPIO TEGRA_GPIO_PI7 -#define BT_RESET_GPIO TEGRA_GPIO_PU0 - -#define BT_WAKE_GPIO TEGRA_GPIO_PU1 -#define BT_HOST_WAKE_GPIO TEGRA_GPIO_PU6 - -static struct rfkill *bt_rfkill; - -struct bcm_bt_lpm { - int wake; - int host_wake; - - struct hrtimer enter_lpm_timer; - ktime_t enter_lpm_delay; - - struct uart_port *uport; - - struct wake_lock wake_lock; - char wake_lock_name[100]; -} bt_lpm; - -static int bcm4329_bt_rfkill_set_power(void *data, bool blocked) -{ - // rfkill_ops callback. Turn transmitter on when blocked is false - if (!blocked) { - gpio_direction_output(BT_RESET_GPIO, 1); - gpio_direction_output(BT_SHUTDOWN_GPIO, 1); - } else { - gpio_direction_output(BT_SHUTDOWN_GPIO, 0); - gpio_direction_output(BT_RESET_GPIO, 0); - } - - return 0; -} - -static const struct rfkill_ops bcm4329_bt_rfkill_ops = { - .set_block = bcm4329_bt_rfkill_set_power, -}; - -static void set_wake(int wake) -{ - bt_lpm.wake = wake; - - if (!wake) - wake_unlock(&bt_lpm.wake_lock); - - gpio_set_value(BT_WAKE_GPIO, wake); -} - -static enum hrtimer_restart enter_lpm(struct hrtimer *timer) { - set_wake(0); - - return HRTIMER_NORESTART; -} - -void bcm_bt_lpm_exit_lpm_locked(struct uart_port *uport) { - bt_lpm.uport = uport; - - hrtimer_try_to_cancel(&bt_lpm.enter_lpm_timer); - - set_wake(1); - - hrtimer_start(&bt_lpm.enter_lpm_timer, bt_lpm.enter_lpm_delay, - HRTIMER_MODE_REL); -} -EXPORT_SYMBOL(bcm_bt_lpm_exit_lpm_locked); - -void bcm_bt_rx_done(struct uart_port *uport) { - // Release wake in 500 ms so that higher layers can take it. - wake_lock_timeout(&bt_lpm.wake_lock, HZ/2); -} -EXPORT_SYMBOL(bcm_bt_rx_done); - -static void update_host_wake(int host_wake) -{ - if (host_wake == bt_lpm.host_wake) - return; - bt_lpm.host_wake = host_wake; - if (host_wake) - wake_lock(&bt_lpm.wake_lock); - else { - // Failsafe timeout of wakelock. - // If the host wake pin is asserted and no data is sent, - // when its deasserted we will enter this path - wake_lock_timeout(&bt_lpm.wake_lock, HZ/2); - } - -} - -static irqreturn_t host_wake_isr(int irq, void *dev) -{ - int host_wake; - - host_wake = gpio_get_value(BT_HOST_WAKE_GPIO); - set_irq_type(irq, host_wake ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH); - - if (!bt_lpm.uport) { - bt_lpm.host_wake = host_wake; - return IRQ_HANDLED; - } - - update_host_wake(host_wake); - - return IRQ_HANDLED; -} - -static int bcm_bt_lpm_init(struct platform_device *pdev) -{ - int irq; - int ret; - int rc; - - tegra_gpio_enable(BT_WAKE_GPIO); - rc = gpio_request(BT_WAKE_GPIO, "bcm4329_wake_gpio"); - if (unlikely(rc)) { - tegra_gpio_disable(BT_WAKE_GPIO); - return rc; - } - - tegra_gpio_enable(BT_HOST_WAKE_GPIO); - rc = gpio_request(BT_HOST_WAKE_GPIO, "bcm4329_host_wake_gpio"); - if (unlikely(rc)) { - tegra_gpio_disable(BT_WAKE_GPIO); - tegra_gpio_disable(BT_HOST_WAKE_GPIO); - gpio_free(BT_WAKE_GPIO); - return rc; - } - - hrtimer_init(&bt_lpm.enter_lpm_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - bt_lpm.enter_lpm_delay = ktime_set(1, 0); /* 1 sec */ - bt_lpm.enter_lpm_timer.function = enter_lpm; - - bt_lpm.host_wake = 0; - - irq = gpio_to_irq(BT_HOST_WAKE_GPIO); - ret = request_irq(irq, host_wake_isr, IRQF_TRIGGER_HIGH, - "bt host_wake", NULL); - if (ret) { - tegra_gpio_disable(BT_WAKE_GPIO); - tegra_gpio_disable(BT_HOST_WAKE_GPIO); - - gpio_free(BT_WAKE_GPIO); - gpio_free(BT_HOST_WAKE_GPIO); - return ret; - } - - ret = set_irq_wake(irq, 1); - if (ret) { - tegra_gpio_disable(BT_WAKE_GPIO); - tegra_gpio_disable(BT_HOST_WAKE_GPIO); - - gpio_free(BT_WAKE_GPIO); - gpio_free(BT_HOST_WAKE_GPIO); - return ret; - } - - gpio_direction_output(BT_WAKE_GPIO, 0); - gpio_direction_input(BT_HOST_WAKE_GPIO); - - snprintf(bt_lpm.wake_lock_name, sizeof(bt_lpm.wake_lock_name), - "BTLowPower"); - wake_lock_init(&bt_lpm.wake_lock, WAKE_LOCK_SUSPEND, - bt_lpm.wake_lock_name); - return 0; -} - -static int bcm4329_bluetooth_probe(struct platform_device *pdev) -{ - int rc = 0; - int ret = 0; - - tegra_gpio_enable(BT_RESET_GPIO); - rc = gpio_request(BT_RESET_GPIO, "bcm4329_nreset_gpip"); - if (unlikely(rc)) { - tegra_gpio_disable(BT_RESET_GPIO); - return rc; - } - - tegra_gpio_enable(BT_SHUTDOWN_GPIO); - rc = gpio_request(BT_SHUTDOWN_GPIO, "bcm4329_nshutdown_gpio"); - if (unlikely(rc)) { - tegra_gpio_disable(BT_RESET_GPIO); - tegra_gpio_disable(BT_SHUTDOWN_GPIO); - gpio_free(BT_RESET_GPIO); - return rc; - } - - - bcm4329_bt_rfkill_set_power(NULL, true); - - bt_rfkill = rfkill_alloc("bcm4329 Bluetooth", &pdev->dev, - RFKILL_TYPE_BLUETOOTH, &bcm4329_bt_rfkill_ops, - NULL); - - if (unlikely(!bt_rfkill)) { - tegra_gpio_disable(BT_RESET_GPIO); - tegra_gpio_disable(BT_SHUTDOWN_GPIO); - - gpio_free(BT_RESET_GPIO); - gpio_free(BT_SHUTDOWN_GPIO); - return -ENOMEM; - } - - rfkill_set_states(bt_rfkill, true, false); - - rc = rfkill_register(bt_rfkill); - - if (unlikely(rc)) { - rfkill_destroy(bt_rfkill); - tegra_gpio_disable(BT_RESET_GPIO); - tegra_gpio_disable(BT_SHUTDOWN_GPIO); - - gpio_free(BT_RESET_GPIO); - gpio_free(BT_SHUTDOWN_GPIO); - return -1; - } - - ret = bcm_bt_lpm_init(pdev); - if (ret) { - rfkill_unregister(bt_rfkill); - rfkill_destroy(bt_rfkill); - - tegra_gpio_disable(BT_RESET_GPIO); - tegra_gpio_disable(BT_SHUTDOWN_GPIO); - - gpio_free(BT_RESET_GPIO); - gpio_free(BT_SHUTDOWN_GPIO); - } - - return ret; -} - -static int bcm4329_bluetooth_remove(struct platform_device *pdev) -{ - rfkill_unregister(bt_rfkill); - rfkill_destroy(bt_rfkill); - - tegra_gpio_disable(BT_SHUTDOWN_GPIO); - tegra_gpio_disable(BT_RESET_GPIO); - tegra_gpio_disable(BT_WAKE_GPIO); - tegra_gpio_disable(BT_HOST_WAKE_GPIO); - - gpio_free(BT_SHUTDOWN_GPIO); - gpio_free(BT_RESET_GPIO); - gpio_free(BT_WAKE_GPIO); - gpio_free(BT_HOST_WAKE_GPIO); - - wake_lock_destroy(&bt_lpm.wake_lock); - return 0; -} - -static struct platform_driver bcm4329_bluetooth_platform_driver = { - .probe = bcm4329_bluetooth_probe, - .remove = bcm4329_bluetooth_remove, - .driver = { - .name = "bcm4329_bluetooth", - .owner = THIS_MODULE, - }, -}; - -static int __init bcm4329_bluetooth_init(void) -{ - if (!machine_is_stingray()) - return 0; - - return platform_driver_register(&bcm4329_bluetooth_platform_driver); -} - -static void __exit bcm4329_bluetooth_exit(void) -{ - platform_driver_unregister(&bcm4329_bluetooth_platform_driver); -} - - -module_init(bcm4329_bluetooth_init); -module_exit(bcm4329_bluetooth_exit); - -MODULE_ALIAS("platform:bcm4329"); -MODULE_DESCRIPTION("bcm4329_bluetooth"); -MODULE_AUTHOR("Jaikumar Ganesh "); -MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-tegra/board-stingray-rfkill.c b/arch/arm/mach-tegra/board-stingray-rfkill.c new file mode 100644 index 000000000000..bdad69390dbf --- /dev/null +++ b/arch/arm/mach-tegra/board-stingray-rfkill.c @@ -0,0 +1,125 @@ +/* + * Bluetooth Broadcomm rfkill power control via GPIO + * + * Copyright (C) 2010 Google, Inc. + * + * 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 +#include +#include +#include +#include +#include + +#include "gpio-names.h" + +#define BT_SHUTDOWN_GPIO TEGRA_GPIO_PI7 +#define BT_RESET_GPIO TEGRA_GPIO_PU0 + +static struct rfkill *bt_rfkill; + +static int bcm4329_bt_rfkill_set_power(void *data, bool blocked) +{ + if (blocked) { + gpio_direction_output(BT_SHUTDOWN_GPIO, 0); + gpio_direction_output(BT_RESET_GPIO, 0); + } else { + gpio_direction_output(BT_RESET_GPIO, 1); + gpio_direction_output(BT_SHUTDOWN_GPIO, 1); + } + + return 0; +} + +static const struct rfkill_ops bcm4329_bt_rfkill_ops = { + .set_block = bcm4329_bt_rfkill_set_power, +}; + +static int bcm4329_rfkill_probe(struct platform_device *pdev) +{ + int rc = 0; + bool default_state = true; /* off */ + + tegra_gpio_enable(BT_RESET_GPIO); + rc = gpio_request(BT_RESET_GPIO, "bcm4329_nreset_gpip"); + if (unlikely(rc)) + return rc; + + + tegra_gpio_enable(BT_SHUTDOWN_GPIO); + rc = gpio_request(BT_SHUTDOWN_GPIO, "bcm4329_nshutdown_gpio"); + if (unlikely(rc)) + return rc; + + bcm4329_bt_rfkill_set_power(NULL, default_state); + + bt_rfkill = rfkill_alloc("bcm4329 Bluetooth", &pdev->dev, + RFKILL_TYPE_BLUETOOTH, &bcm4329_bt_rfkill_ops, + NULL); + + if (unlikely(!bt_rfkill)) + return -ENOMEM; + + rfkill_set_states(bt_rfkill, default_state, false); + + rc = rfkill_register(bt_rfkill); + + if (unlikely(rc)) + rfkill_destroy(bt_rfkill); + + return 0; +} + +static int bcm4329_rfkill_remove(struct platform_device *pdev) +{ + rfkill_unregister(bt_rfkill); + rfkill_destroy(bt_rfkill); + gpio_free(BT_SHUTDOWN_GPIO); + gpio_free(BT_RESET_GPIO); + + return 0; +} + +static struct platform_driver bcm4329_rfkill_platform_driver = { + .probe = bcm4329_rfkill_probe, + .remove = bcm4329_rfkill_remove, + .driver = { + .name = "bcm4329_rfkill", + .owner = THIS_MODULE, + }, +}; + +static int __init bcm4329_rfkill_init(void) +{ + if (!machine_is_stingray()) + return 0; + return platform_driver_register(&bcm4329_rfkill_platform_driver); +} + +static void __exit bcm4329_rfkill_exit(void) +{ + platform_driver_unregister(&bcm4329_rfkill_platform_driver); +} + +module_init(bcm4329_rfkill_init); +module_exit(bcm4329_rfkill_exit); + +MODULE_ALIAS("platform:bcm4329"); +MODULE_DESCRIPTION("bcm4329_rfkill"); +MODULE_AUTHOR("Jaikumar Ganesh "); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-tegra/board-stingray.c b/arch/arm/mach-tegra/board-stingray.c index 2123fd81bb66..5a9eb432c776 100644 --- a/arch/arm/mach-tegra/board-stingray.c +++ b/arch/arm/mach-tegra/board-stingray.c @@ -54,9 +54,7 @@ #include #include #include -#include #include -#include #include @@ -455,8 +453,8 @@ static struct platform_device tegra_gart_dev = { .resource = tegra_gart_resources }; -static struct platform_device bcm4329_bluetooth_device = { - .name = "bcm4329_bluetooth", +static struct platform_device bcm4329_rfkill = { + .name = "bcm4329_rfkill", .id = -1, }; @@ -530,15 +528,10 @@ static struct platform_device stingray_nvmap_device = { }, }; -static struct tegra_hsuart_platform_data tegra_uartc_pdata = { - .exit_lpm_cb = bcm_bt_lpm_exit_lpm_locked, - .rx_done_cb = bcm_bt_rx_done, -}; - static struct platform_device *stingray_devices[] __initdata = { &cpcap_otg, &bq24617_device, - &bcm4329_bluetooth_device, + &bcm4329_rfkill, &tegra_uarta_device, &tegra_uartc_device, &tegra_uartd_device, @@ -998,7 +991,6 @@ static void __init tegra_stingray_init(void) tegra_spdif_device.dev.platform_data = &tegra_spdif_pdata; tegra_ehci1_device.dev.platform_data = &tegra_ehci_pdata[0]; - tegra_uartc_device.dev.platform_data = &tegra_uartc_pdata; res = platform_get_resource(&ram_console_device, IORESOURCE_MEM, 0); res->start = ramconsole_start; diff --git a/arch/arm/mach-tegra/include/mach/bcm_bt_lpm.h b/arch/arm/mach-tegra/include/mach/bcm_bt_lpm.h deleted file mode 100644 index 3eabaf478abc..000000000000 --- a/arch/arm/mach-tegra/include/mach/bcm_bt_lpm.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2009 Google, Inc. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * 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. - */ - -#ifndef __ASM_ARCH_BCM_BT_LPM_H -#define __ASM_ARCH_BCM_BT_LPM_H - -#include - -/* Uart driver must call this every time it beings TX, to ensure - * this driver keeps WAKE asserted during TX. Called with uart - * spinlock held. */ -extern void bcm_bt_lpm_exit_lpm_locked(struct uart_port *uport); - -/* Uart driver must call this when the rx is done */ -extern void bcm_bt_rx_done(struct uart_port *uport); - -#endif -- 2.34.1