diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index c29f1949..05bbc06e 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -108,6 +108,7 @@ obj-$(CONFIG_MACH_BRAVOC) += board-bravoc-microp.o clock.o obj-$(CONFIG_MACH_HTCLEO) += board-htcleo.o board-htcleo-spi.o board-htcleo-panel.o board-htcleo-keypad.o obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-ts.o board-htcleo-mmc.o ieee754-df.o board-htcleo-power.o obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-battery.o board-htcleo-log.o board-htcleo-acoustic.o board-htcleo-audio.o +obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-bt.o obj-$(CONFIG_MACH_HTCLEO) += clock-wince.o # MSM7x30 boards diff --git a/arch/arm/mach-msm/board-htcleo-bt.c b/arch/arm/mach-msm/board-htcleo-bt.c new file mode 100644 index 00000000..97ac8d4c --- /dev/null +++ b/arch/arm/mach-msm/board-htcleo-bt.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2010 Cotulla + * + * 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. + * + */ +#include +#include + +#include "devices.h" +#include "board-htcleo.h" +#include "dex_comm.h" +#include "gpio_chip.h" + + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "devices.h" +#include "board-htcleo.h" +#include "dex_comm.h" +#include "gpio_chip.h" + + + + + +/////////////////////////////////////////////////////////////////////////////////////// + +static struct rfkill *bt_rfk; +static const char bt_name[] = "bcm4329"; + + +static int bluetooth_set_power(void *data, bool blocked) +{ + printk("set bt power %d\n", blocked); + + if (!blocked) + { + // power on + gpio_set_value(HTCLEO_GPIO_BT_RESET_N, 1); + gpio_set_value(HTCLEO_GPIO_BT_SHUTDOWN_N, 1); + msleep(200); + printk("bt power on\n"); + } + else + { + // power off + gpio_set_value(HTCLEO_GPIO_BT_SHUTDOWN_N, 0); + gpio_set_value(HTCLEO_GPIO_BT_RESET_N, 0); + printk("bt power off\n"); + } + return 0; +} + +static struct rfkill_ops htcleo_rfkill_ops = +{ + .set_block = bluetooth_set_power, +}; + +static int htcleo_rfkill_probe(struct platform_device *pdev) +{ + int rc = 0; + bool default_state = true; /* off */ + + rc = gpio_request(HTCLEO_GPIO_BT_RESET_N, "bt_reset"); + rc = gpio_request(HTCLEO_GPIO_BT_SHUTDOWN_N, "bt_shutdown"); + rc = gpio_request(HTCLEO_GPIO_BT_CHIP_WAKE, "bt_chip_wake"); + + gpio_direction_output(HTCLEO_GPIO_BT_CHIP_WAKE, 0); + gpio_direction_output(HTCLEO_GPIO_BT_RESET_N, 0); + gpio_direction_output(HTCLEO_GPIO_BT_SHUTDOWN_N, 0); + + bluetooth_set_power(NULL, default_state); + + bt_rfk = rfkill_alloc(bt_name, &pdev->dev, RFKILL_TYPE_BLUETOOTH, + &htcleo_rfkill_ops, NULL); + if (!bt_rfk) + { + pr_err("rfkill_alloc failed\n"); + rc = -ENOMEM; + goto err_rfkill_alloc; + } + + rfkill_set_states(bt_rfk, default_state, false); + + /* userspace cannot take exclusive control */ + + rc = rfkill_register(bt_rfk); + if (rc) + { + pr_err("rfkill_register failed\n"); + goto err_rfkill_reg; + } + + return 0; + +err_rfkill_reg: + rfkill_destroy(bt_rfk); +err_rfkill_alloc: + gpio_free(HTCLEO_GPIO_BT_SHUTDOWN_N); + gpio_free(HTCLEO_GPIO_BT_RESET_N); + return rc; +} + +static int htcleo_rfkill_remove(struct platform_device *dev) +{ + rfkill_unregister(bt_rfk); + rfkill_destroy(bt_rfk); + + gpio_free(HTCLEO_GPIO_BT_SHUTDOWN_N); + gpio_free(HTCLEO_GPIO_BT_RESET_N); + + return 0; +} + +static struct platform_driver htcleo_rfkill_driver = +{ + .probe = htcleo_rfkill_probe, + .remove = htcleo_rfkill_remove, + .driver = + { + .name = "htcleo_rfkill", + .owner = THIS_MODULE, + }, +}; + +static int __init htcleo_rfkill_init(void) +{ + if (!machine_is_htcleo()) + return 0; + + return platform_driver_register(&htcleo_rfkill_driver); +} + +static void __exit htcleo_rfkill_exit(void) +{ + platform_driver_unregister(&htcleo_rfkill_driver); +} + +module_init(htcleo_rfkill_init); +module_exit(htcleo_rfkill_exit); +MODULE_DESCRIPTION("htcleo rfkill"); +MODULE_AUTHOR("Cotulla"); +MODULE_LICENSE("GPL"); +// END OF FILE diff --git a/arch/arm/mach-msm/board-htcleo.c b/arch/arm/mach-msm/board-htcleo.c index 8676bd16..6cbf66b3 100644 --- a/arch/arm/mach-msm/board-htcleo.c +++ b/arch/arm/mach-msm/board-htcleo.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "board-htcleo.h" @@ -256,6 +257,44 @@ static struct platform_device htcleo_flashlight_device = }, }; +/////////////////////////////////////////////////////////////////////// +// bluetooth +/////////////////////////////////////////////////////////////////////// + +static uint32_t bt_gpio_table[] = +{ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RTS, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_CTS, 2, GPIO_INPUT, GPIO_PULL_UP, GPIO_8MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RX, 2, GPIO_INPUT, GPIO_PULL_UP, GPIO_8MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_TX, 2, GPIO_OUTPUT,GPIO_PULL_UP, GPIO_8MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_RESET_N, 0, GPIO_OUTPUT,GPIO_PULL_DOWN, GPIO_4MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_SHUTDOWN_N, 0, GPIO_OUTPUT,GPIO_PULL_DOWN, GPIO_4MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_CHIP_WAKE, 0, GPIO_OUTPUT,GPIO_PULL_DOWN, GPIO_4MA), + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_HOST_WAKE, 0, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_4MA), +}; + +#ifdef CONFIG_SERIAL_MSM_HS +static struct msm_serial_hs_platform_data msm_uart_dm1_pdata = +{ + /* Chip to Device */ + .rx_wakeup_irq = MSM_GPIO_TO_INT(HTCLEO_GPIO_BT_HOST_WAKE), + .inject_rx_on_wakeup = 0, + .cpu_lock_supported = 0, + + /* for bcm */ + .bt_wakeup_pin_supported = 1, + .bt_wakeup_pin = HTCLEO_GPIO_BT_CHIP_WAKE, + .host_wakeup_pin = HTCLEO_GPIO_BT_HOST_WAKE, + +}; +#endif + +static void __init htcleo_bt_init(void) +{ + config_gpio_table(bt_gpio_table, ARRAY_SIZE(bt_gpio_table)); +} + + /////////////////////////////////////////////////////////////////////// // KGSL (HW3D support)#include @@ -373,16 +412,23 @@ static struct platform_device htcleo_power = .id = -1, }; +static struct platform_device htcleo_rfkill = +{ + .name = "htcleo_rfkill", + .id = -1, +}; + static struct platform_device *devices[] __initdata = { &ram_console_device, #if !defined(CONFIG_MSM_SERIAL_DEBUGGER) &msm_device_uart1, #endif -// &bcm_bt_lpm_device, -// &msm_device_uart_dm1, +#ifdef CONFIG_SERIAL_MSM_HS + &msm_device_uart_dm1, +#endif &msm_device_smd, -// &htcleo_rfkill, + &htcleo_rfkill, // &msm_audio_device, &android_pmem_device, &android_pmem_adsp_device, @@ -470,6 +516,12 @@ static void __init htcleo_init(void) */ platform_add_devices(devices, ARRAY_SIZE(devices)); +#ifdef CONFIG_SERIAL_MSM_HS + msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata; + msm_device_uart_dm1.name = "msm_serial_hs_bcm"; /* for bcm */ + msm_device_uart_dm1.resource[3].end = 6; +#endif + i2c_register_board_info(0, base_i2c_devices, ARRAY_SIZE(base_i2c_devices)); #ifdef CONFIG_USB_ANDROID @@ -479,6 +531,7 @@ static void __init htcleo_init(void) htcleo_init_mmc(0); platform_device_register(&htcleo_timed_gpios); + htcleo_bt_init(); htcleo_audio_init(); #ifdef CONFIG_USB_ANDROID