diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile index 9669f390..093106e0 100644 --- a/arch/arm/mach-msm/Makefile +++ b/arch/arm/mach-msm/Makefile @@ -118,7 +118,7 @@ obj-$(CONFIG_MACH_HTCLEO) += board-htcleo.o board-htcleo-spi.o board-htcleo-pane 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-audio.o board-htcleo-acoustic.o -obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-bt.o board-htcleo-wifi.o board-htcleo-microp.o +obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-rfkill.o board-htcleo-wifi.o board-htcleo-microp.o obj-$(CONFIG_MACH_HTCLEO) += board-htcleo-proximity.o board-htcleo-leds.o board-htcleo-ls.o obj-$(CONFIG_MACH_HTCLEO) += clock-wince.o obj-$(CONFIG_HTCLEO_BACKLIGHT) += board-htcleo-bl.o diff --git a/arch/arm/mach-msm/board-htcleo-rfkill.c b/arch/arm/mach-msm/board-htcleo-rfkill.c new file mode 100644 index 00000000..df0bbefc --- /dev/null +++ b/arch/arm/mach-msm/board-htcleo-rfkill.c @@ -0,0 +1,357 @@ +/* + * Copyright (C) 2009 Google, Inc. + * Copyright (C) 2009 HTC Corporation. + * + * 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. + * + */ + +/* Control bluetooth power for htcleo platform */ + +#include +#include +#include +#include +#include +#include +#include + +#include "gpio_chip.h" +#include "proc_comm.h" +#include "board-htcleo.h" + +#define HTC_RFKILL_DBG + +static struct rfkill *bt_rfk; +static const char bt_name[] = "bcm4329"; +static int pre_state; + +static uint32_t htcleo_bt_init_table[] = { + /* BT_RTS */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RTS, + 0, + GPIO_OUTPUT, + GPIO_NO_PULL, + GPIO_8MA), + /* BT_CTS */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_CTS, + 0, + GPIO_INPUT, + GPIO_PULL_UP, + GPIO_8MA), + /* BT_RX */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RX, + 0, + GPIO_INPUT, + GPIO_PULL_UP, + GPIO_8MA), + /* BT_TX */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_TX, + 0, + GPIO_OUTPUT, + GPIO_NO_PULL, + GPIO_8MA), + + /* BT_SHUTDOWN_N */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_SHUTDOWN_N, + 0, + GPIO_OUTPUT, + GPIO_NO_PULL, + GPIO_4MA), + /* BT_RESET_N */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_RESET_N, + 0, + GPIO_OUTPUT, + GPIO_NO_PULL, + GPIO_4MA), + + /* BT_HOST_WAKE */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_HOST_WAKE, + 0, + GPIO_INPUT, + GPIO_PULL_UP, + GPIO_4MA), + /* BT_CHIP_WAKE */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_CHIP_WAKE, + 0, + GPIO_OUTPUT, + GPIO_NO_PULL, + GPIO_4MA), +}; + +static uint32_t htcleo_bt_on_table[] = { + /* BT_RTS */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RTS, + 2, + GPIO_OUTPUT, + GPIO_PULL_UP, + GPIO_8MA), + /* BT_CTS */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_CTS, + 2, + GPIO_INPUT, + GPIO_PULL_UP, + GPIO_8MA), + /* BT_RX */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RX, + 2, + GPIO_INPUT, + GPIO_PULL_UP, + GPIO_8MA), + /* BT_TX */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_TX, + 2, + GPIO_OUTPUT, + GPIO_PULL_UP, + GPIO_8MA), + + /* BT_HOST_WAKE */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_HOST_WAKE, + 0, + GPIO_INPUT, + GPIO_NO_PULL, + GPIO_4MA), + /* BT_CHIP_WAKE */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_CHIP_WAKE, + 0, + GPIO_OUTPUT, + GPIO_NO_PULL, + GPIO_4MA), +}; + +static uint32_t htcleo_bt_off_table[] = { + /* BT_RTS */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RTS, + 0, + GPIO_OUTPUT, + GPIO_NO_PULL, + GPIO_8MA), + /* BT_CTS */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_CTS, + 0, + GPIO_INPUT, + GPIO_PULL_UP, + GPIO_8MA), + /* BT_RX */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_RX, + 0, + GPIO_INPUT, + GPIO_PULL_UP, + GPIO_8MA), + /* BT_TX */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_UART1_TX, + 0, + GPIO_OUTPUT, + GPIO_NO_PULL, + GPIO_8MA), + + /* BT_HOST_WAKE */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_HOST_WAKE, + 0, + GPIO_INPUT, + GPIO_PULL_UP, + GPIO_4MA), + /* BT_CHIP_WAKE */ + PCOM_GPIO_CFG(HTCLEO_GPIO_BT_CHIP_WAKE, + 0, + GPIO_OUTPUT, + GPIO_NO_PULL, + GPIO_4MA), +}; + +static void config_bt_table(uint32_t *table, int len) +{ + int n; + unsigned id; + for (n = 0; n < len; n++) { + id = table[n]; + msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &id, 0); + } +} + +static void htcleo_config_bt_init(void) +{ + /* set bt initial configuration*/ + config_bt_table(htcleo_bt_init_table, + ARRAY_SIZE(htcleo_bt_init_table)); + /* BT_RESET_N */ + gpio_configure(HTCLEO_GPIO_BT_RESET_N, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); + mdelay(5); + + /* BT_SHUTDOWN_N */ + gpio_configure(HTCLEO_GPIO_BT_SHUTDOWN_N, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_HIGH); + /* BT_RESET_N */ + gpio_configure(HTCLEO_GPIO_BT_RESET_N, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_HIGH); + mdelay(15); + + /* BT_RESET_N */ + gpio_configure(HTCLEO_GPIO_BT_RESET_N, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); + /* BT_SHUTDOWN_N */ + gpio_configure(HTCLEO_GPIO_BT_SHUTDOWN_N, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); + + /* BT_RTS */ + gpio_configure(HTCLEO_GPIO_BT_UART1_RTS, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); + /* BT_TX */ + gpio_configure(HTCLEO_GPIO_BT_UART1_TX, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); + + /* BT_CHIP_WAKE */ + gpio_configure(HTCLEO_GPIO_BT_CHIP_WAKE, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); +} + +static void htcleo_config_bt_on(void) +{ + + #ifdef HTC_RFKILL_DBG + printk(KERN_INFO "-- RK ON --\n"); + #endif + + /* set bt on configuration*/ + config_bt_table(htcleo_bt_on_table, + ARRAY_SIZE(htcleo_bt_on_table)); + mdelay(5); + /* BT_SHUTDOWN_N */ + gpio_configure(HTCLEO_GPIO_BT_SHUTDOWN_N, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_HIGH); + /* BT_RESET_N */ + gpio_configure(HTCLEO_GPIO_BT_RESET_N, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_HIGH); + mdelay(5); + + /* BT_CHIP_WAKE */ + gpio_configure(HTCLEO_GPIO_BT_CHIP_WAKE, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_HIGH); +} + +static void htcleo_config_bt_off(void) +{ + #ifdef HTC_RFKILL_DBG + printk(KERN_INFO "-- RK OFF --\n"); + #endif + + /* BT_RESET_N */ + gpio_configure(HTCLEO_GPIO_BT_RESET_N, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); + /* BT_SHUTDOWN_N */ + gpio_configure(HTCLEO_GPIO_BT_SHUTDOWN_N, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); + + config_bt_table(htcleo_bt_off_table, + ARRAY_SIZE(htcleo_bt_off_table)); + mdelay(5); + + /* BT_RTS */ + gpio_configure(HTCLEO_GPIO_BT_UART1_RTS, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); + /* BT_TX */ + gpio_configure(HTCLEO_GPIO_BT_UART1_TX, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); + + /* BT_CHIP_WAKE */ + gpio_configure(HTCLEO_GPIO_BT_CHIP_WAKE, + GPIOF_DRIVE_OUTPUT | GPIOF_OUTPUT_LOW); +} + +static int bluetooth_set_power(void *data, bool blocked) +{ + if (pre_state == blocked) { + #ifdef HTC_RFKILL_DBG + printk(KERN_INFO "-- SAME ST --\n"); + #endif + return 0; + } else + pre_state = blocked; + + if (!blocked) + htcleo_config_bt_on(); + else + htcleo_config_bt_off(); + + 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 */ + + htcleo_config_bt_init(); /* bt gpio initial config */ + + bluetooth_set_power(NULL, default_state); + + bt_rfk = rfkill_alloc(bt_name, &pdev->dev, RFKILL_TYPE_BLUETOOTH, + &htcleo_rfkill_ops, NULL); + if (!bt_rfk) { + rc = -ENOMEM; + goto err_rfkill_reset; + } + + rfkill_set_states(bt_rfk, default_state, false); + + /* userspace cannot take exclusive control */ + rc = rfkill_register(bt_rfk); + if (rc) + goto err_rfkill_reg; + + return 0; + +err_rfkill_reg: + rfkill_destroy(bt_rfk); +err_rfkill_reset: + return rc; +} + +static int htcleo_rfkill_remove(struct platform_device *dev) +{ + rfkill_unregister(bt_rfk); + rfkill_destroy(bt_rfk); + + 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) +{ + pre_state = -1; + 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("Nick Pelly "); +MODULE_LICENSE("GPL"); diff --git a/arch/arm/mach-msm/board-htcleo.c b/arch/arm/mach-msm/board-htcleo.c index b6522715..17c144a7 100644 --- a/arch/arm/mach-msm/board-htcleo.c +++ b/arch/arm/mach-msm/board-htcleo.c @@ -333,6 +333,14 @@ unsigned htcleo_get_vbus_state(void) #endif +static struct platform_device htcleo_rfkill = { + .name = "htcleo_rfkill", + .id = -1, +}; + + + + /////////////////////////////////////////////////////////////////////// // Flashlight /////////////////////////////////////////////////////////////////////// @@ -476,61 +484,6 @@ static struct platform_device msm_camera_sensor_s5k3e2fx = }, }; -/////////////////////////////////////////////////////////////////////// -// bluetooth -/////////////////////////////////////////////////////////////////////// -static char bdaddress[20]; -static void bt_export_bd_address(void) - { - unsigned char cTemp[6]; - - memcpy(cTemp, get_bt_bd_ram(), 6); - sprintf(bdaddress, "%02x:%02x:%02x:%02x:%02x:%02x", cTemp[0], cTemp[1], cTemp[2], cTemp[3], cTemp[4], cTemp[5]); - pr_info("BD_ADDRESS=%s\n", bdaddress); -} - -module_param_string(bdaddress, bdaddress, sizeof(bdaddress), S_IWUSR | S_IRUGO); -MODULE_PARM_DESC(bdaddress, "BT MAC ADDRESS"); - -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)); -} - - -static struct platform_device htcleo_rfkill = -{ - .name = "htcleo_rfkill", - .id = -1, -}; /////////////////////////////////////////////////////////////////////// // KGSL (HW3D support)#include @@ -693,6 +646,9 @@ static struct platform_device *devices[] __initdata = &htc_headset_mgr, &htc_headset_gpio, }; + + + /////////////////////////////////////////////////////////////////////// // Vibrator /////////////////////////////////////////////////////////////////////// @@ -811,14 +767,29 @@ 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; +static struct msm_serial_hs_platform_data msm_uart_dm1_pdata = { + .rx_wakeup_irq = MSM_GPIO_TO_INT(HTCLEO_GPIO_BT_HOST_WAKE), /*Chip to Device*/ + .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 + +#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 htcleo_add_usb_devices(); #endif @@ -826,8 +797,6 @@ static void __init htcleo_init(void) htcleo_init_mmc(0); platform_device_register(&htcleo_timed_gpios); - bt_export_bd_address(); - htcleo_bt_init(); htcleo_audio_init(); #ifdef CONFIG_USB_ANDROID