#endif
static struct platform_device *devices[] __initdata = {
+#ifdef CONFIG_BT
+ &rk2818_device_rfkill,
+#endif
+ &rk2818_device_uart0,
&rk2818_device_uart1,
#ifdef CONFIG_I2C0_RK2818
&rk2818_device_i2c0,
}
};
-
+#ifdef CONFIG_BT
+struct platform_device rk2818_device_rfkill = {
+ .name = "rkbt_rfkill",
+ .id = -1,
+};
+#endif
#if defined(CONFIG_ANDROID_PMEM)
extern struct platform_device rk2818_device_camera; /* ddl@rock-chips.com : camera support */
extern struct platform_device rk2818_soc_camera_pdrv;
extern struct platform_device rk2818_device_dsp;
+extern struct platform_device rk2818_device_rfkill;
extern struct platform_device rk2818_nand_device;
extern struct platform_device rk2818_device_dwc_otg;
extern struct platform_device rk2818_device_host11;
\r
#ifndef SPI_UART_H\r
#define SPI_UART_H\r
+#include <linux/circ_buf.h>\r
+#include <linux/miscdevice.h>\r
\r
#define SPI_FPGA_INT_PIN RK2818_PIN_PA4\r
#define SPI_DPRAM_BUSY_PIN RK2818_PIN_PA2\r
Say Y here to compile support for Marvell BT-over-SDIO driver
into the kernel or say M to compile it as module.
+config BT_HCIBCM4325
+ tristate "HCI BCM4325 UART driver"
+ depends on BT_HCIUART
+ help
+ Bluetooth HCI BCM4325 UART driver.
+ This driver provides the firmware loading mechanism for the Broadcom
+ Blutonium based devices.
+
+ Say Y here to compile support for HCI BCM4325 devices into the
+ kernel or say M to compile it as module (bcm4325).
+
+
endmenu
# Makefile for the Linux Bluetooth HCI device drivers.
#
+obj-$(CONFIG_BT) += vflash.o
obj-$(CONFIG_BT_HCIVHCI) += hci_vhci.o
obj-$(CONFIG_BT_HCIUART) += hci_uart.o
obj-$(CONFIG_BT_HCIBCM203X) += bcm203x.o
obj-$(CONFIG_BT_HCIBT3C) += bt3c_cs.o
obj-$(CONFIG_BT_HCIBLUECARD) += bluecard_cs.o
obj-$(CONFIG_BT_HCIBTUART) += btuart_cs.o
+obj-$(CONFIG_BT_HCIBCM4325) += bcm4325.o
obj-$(CONFIG_BT_HCIBTUSB) += btusb.o
obj-$(CONFIG_BT_HCIBTSDIO) += btsdio.o
--- /dev/null
+/*\r
+ * Copyright (C) 2010 ROCKCHIP, Inc.\r
+ * Author: roger_chen <cz@rock-chips.com>\r
+ *\r
+ * This program is the bluetooth device bcm4325's driver,\r
+ *\r
+ */\r
+\r
+#include <linux/kernel.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/module.h>\r
+#include <linux/device.h>\r
+#include <linux/rfkill.h>\r
+#include <linux/delay.h>\r
+#include <linux/i2c.h>\r
+#include <linux/init.h>\r
+#include <linux/slab.h>\r
+//#include <asm/gpio.h>\r
+//#include <asm/arch/gpio.h>\r
+//#include <asm/arch/iomux.h>\r
+//#include <asm/arch/gpio.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/wakelock.h>\r
+#include <mach/spi_fpga.h>\r
+#include <linux/fs.h>\r
+#include <asm/uaccess.h>\r
+\r
+#define BT_PWR_ON {spi_gpio_set_pinlevel(SPI_GPIO_P1_06, SPI_GPIO_HIGH); \\r
+ spi_gpio_set_pindirection(SPI_GPIO_P1_06, SPI_GPIO_OUT);}\r
+#define BT_PWR_OFF {spi_gpio_set_pinlevel(SPI_GPIO_P1_06, SPI_GPIO_LOW); \\r
+ spi_gpio_set_pindirection(SPI_GPIO_P1_06, SPI_GPIO_OUT);}\r
+\r
+#define BT_RESET_HIGH {spi_gpio_set_pinlevel(SPI_GPIO_P1_07, SPI_GPIO_HIGH); \\r
+ spi_gpio_set_pindirection(SPI_GPIO_P1_07, SPI_GPIO_OUT);}\r
+#define BT_RESET_LOW {spi_gpio_set_pinlevel(SPI_GPIO_P1_07, SPI_GPIO_LOW); \\r
+ spi_gpio_set_pindirection(SPI_GPIO_P1_07, SPI_GPIO_OUT);}\r
+\r
+#define BT_SLEEP_GPIO_IOMUX \r
+#define BT_SLEEP_GPIO_SET_OUT spi_gpio_set_pindirection(SPI_GPIO_P1_08, SPI_GPIO_OUT);\r
+#define BT_WAKEUP //spi_gpio_set_pinlevel(SPI_GPIO_P1_08, SPI_GPIO_HIGH);\r
+#define BT_SLEEP //spi_gpio_set_pinlevel(SPI_GPIO_P1_08, SPI_GPIO_LOW);\r
+\r
+#if 1\r
+#define DBG(x...) printk(KERN_INFO x)\r
+#else\r
+#define DBG(x...)\r
+#endif\r
+\r
+static struct rfkill *bt_rfk;\r
+static const char bt_name[] = "bcm4325";\r
+//extern void rfkill_switch_all(enum rfkill_type type, bool blocked);\r
+\r
+ \r
+/*\r
+bSleep:\r
+0: wakeup\r
+1: sleep\r
+*/\r
+int bcm4325_sleep(int bSleep)\r
+{\r
+ if(0 == bSleep) /*wake up*/\r
+ {\r
+ BT_WAKEUP;\r
+ }\r
+ else /*sleep*/\r
+ {\r
+ BT_SLEEP;\r
+ }\r
+ \r
+ return 0;\r
+}\r
+\r
+static int bcm4325_set_block(void *data, bool blocked)\r
+{\r
+ DBG("%s---blocked :%d\n", __FUNCTION__, blocked);\r
+\r
+ if (false == blocked) { \r
+ BT_SLEEP_GPIO_IOMUX;\r
+ BT_SLEEP_GPIO_SET_OUT;\r
+ BT_PWR_ON;\r
+ mdelay(2);\r
+ BT_RESET_LOW; \r
+ mdelay(40);\r
+ BT_RESET_HIGH;\r
+ mdelay(10);\r
+ BT_WAKEUP;\r
+ printk("Enter::%s,bluetooth is power on!\n",__FUNCTION__);\r
+ }\r
+ else {\r
+ BT_SLEEP; \r
+// BT_PWR_OFF;\r
+ printk("Enter::%s,bluetooth is power off!\n",__FUNCTION__);\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+static const struct rfkill_ops bcm4325_rfk_ops = {\r
+ .set_block = bcm4325_set_block,\r
+};\r
+\r
+static int __init bcm4325_rfkill_probe(struct platform_device *pdev)\r
+{\r
+ int rc = 0;\r
+ \r
+ DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);\r
+ \r
+ /* default to bluetooth off */\r
+// rfkill_switch_all(RFKILL_TYPE_BLUETOOTH, true);\r
+ \r
+ bt_rfk = rfkill_alloc(bt_name, \r
+ NULL, \r
+ RFKILL_TYPE_BLUETOOTH, \r
+ &bcm4325_rfk_ops, \r
+ NULL);\r
+\r
+ if (!bt_rfk)\r
+ {\r
+ printk("fail to rfkill_allocate************\n");\r
+ return -ENOMEM;\r
+ }\r
+\r
+ \r
+ rc = rfkill_register(bt_rfk);\r
+ if (rc)\r
+ rfkill_destroy(bt_rfk);\r
+\r
+ printk("rc=0x%x\n", rc);\r
+ \r
+ return rc;\r
+}\r
+\r
+\r
+static int __devexit bcm4325_rfkill_remove(struct platform_device *pdev)\r
+{\r
+ if (bt_rfk)\r
+ rfkill_unregister(bt_rfk);\r
+ bt_rfk = NULL;\r
+\r
+ platform_set_drvdata(pdev, NULL);\r
+ DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);\r
+ return 0;\r
+}\r
+\r
+static struct platform_driver bcm4325_rfkill_driver = {\r
+ .probe = bcm4325_rfkill_probe,\r
+ .remove = __devexit_p(bcm4325_rfkill_remove),\r
+ .driver = {\r
+ .name = "rkbt_rfkill", //"bcm4325_rfkill",\r
+ .owner = THIS_MODULE,\r
+ },\r
+};\r
+\r
+/*\r
+ * Module initialization\r
+ */\r
+static int __init bcm4325_mod_init(void)\r
+{\r
+ int ret;\r
+ DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);\r
+ ret = platform_driver_register(&bcm4325_rfkill_driver);\r
+ printk("ret=0x%x\n", ret);\r
+ return ret;\r
+}\r
+\r
+static void __exit bcm4325_mod_exit(void)\r
+{\r
+ platform_driver_unregister(&bcm4325_rfkill_driver);\r
+}\r
+\r
+module_init(bcm4325_mod_init);\r
+module_exit(bcm4325_mod_exit);\r
+MODULE_DESCRIPTION("bcm4325 Bluetooth driver");\r
+MODULE_AUTHOR("roger_chen cz@rock-chips.com");\r
+MODULE_LICENSE("GPL");\r
+\r
#define H4_W4_SCO_HDR 3
#define H4_W4_DATA 4
+#ifdef CONFIG_BT_HCIBCM4325
+extern int bcm4325_sleep(int bSleep);
+#endif
+
/* Initialize protocol */
static int h4_open(struct hci_uart *hu)
{
h4->rx_count = len;
return len;
}
-
+#ifdef CONFIG_BT_HCIBCM4325
+ bcm4325_sleep(1);
+#endif;
h4->rx_state = H4_W4_PACKET_TYPE;
h4->rx_skb = NULL;
h4->rx_count = 0;
BT_DBG("Complete data");
hci_recv_frame(h4->rx_skb);
-
+#ifdef CONFIG_BT_HCIBCM4325
+ bcm4325_sleep(1);
+#endif;
h4->rx_state = H4_W4_PACKET_TYPE;
h4->rx_skb = NULL;
continue;
#include "hci_uart.h"
+#ifdef CONFIG_BT_HCIBCM4325
+extern int bcm4325_sleep(int bSleep);
+#endif
+
#define VERSION "2.2"
static int reset = 0;
restart:
clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
-
+/*added by Barry,for broadcom 4325*/
+#ifdef CONFIG_BT_HCIBCM4325
+ bcm4325_sleep(0);
+#endif;
while ((skb = hci_uart_dequeue(hu))) {
int len;
--- /dev/null
+/*\r
+ * Copyright (C) 2010 ROCKCHIP, Inc.\r
+ * Author: roger_chen <cz@rock-chips.com>\r
+ *\r
+ * This program is the virtual flash device \r
+ * used to store bd_addr or MAC\r
+ *\r
+ */\r
+\r
+\r
+#include <linux/module.h>\r
+#include <linux/kernel.h>\r
+#include <linux/errno.h>\r
+#include <linux/miscdevice.h>\r
+#include <linux/fs.h>\r
+#include <linux/platform_device.h>\r
+#include <asm/uaccess.h>\r
+\r
+#if 0\r
+#define DBG(x...) printk("vFlash:" x)\r
+#else\r
+#define DBG(x...)\r
+#endif\r
+\r
+#define VERSION "0.1"\r
+\r
+static int minor = MISC_DYNAMIC_MINOR;\r
+\r
+static struct miscdevice vflash_miscdev;\r
+\r
+#define READ_BDADDR_FROM_FLASH 0x01\r
+\r
+extern char GetSNSectorInfo(char * pbuf);\r
+\r
+static int vflash_ioctl(struct inode *inode, struct file *file,\r
+ unsigned int cmd, unsigned long arg)\r
+{\r
+ void __user *argp = (void __user *)arg;\r
+ unsigned long n = 0;\r
+ \r
+ DBG("%s---cmd=0x%x---arg=0x%x\n", __FUNCTION__, cmd, arg);\r
+\r
+ if(NULL == argp)\r
+ return -EFAULT;\r
+ \r
+ switch(cmd)\r
+ {\r
+ case READ_BDADDR_FROM_FLASH:\r
+ { \r
+ char *tempBuf = (char *)kmalloc(512, GFP_KERNEL);\r
+ int i;\r
+ #if 0\r
+ GetSNSectorInfo(tempBuf);\r
+ #else\r
+ tempBuf[498] = 0x00;\r
+ tempBuf[499] = 0x11;\r
+ tempBuf[500] = 0x22;\r
+ tempBuf[501] = 0x33;\r
+ tempBuf[502] = 0x44;\r
+ tempBuf[503] = 0x55;\r
+ tempBuf[504] = 0x66;\r
+ #endif\r
+ for(i=498; i<=504; i++)\r
+ {\r
+ DBG("tempBuf[%d]=%x\n", i, tempBuf[i]);\r
+ }\r
+ \r
+ if(copy_to_user(argp, &(tempBuf[499]), 6))\r
+ {\r
+ printk("ERROR: copy_to_user---%s\n", __FUNCTION__);\r
+ kfree(tempBuf);\r
+ return -EFAULT;\r
+ }\r
+ \r
+ kfree(tempBuf);\r
+ }\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ \r
+ return 0;\r
+}\r
+\r
+static int vflash_open(struct inode *inode, struct file *file)\r
+{\r
+ DBG("%s\n", __FUNCTION__);\r
+ return 0;\r
+}\r
+\r
+static int vflash_release(struct inode *inode, struct file *file)\r
+{\r
+ DBG("%s\n", __FUNCTION__);\r
+ return 0;\r
+}\r
+\r
+\r
+static const struct file_operations vflash_fops = {\r
+ .owner = THIS_MODULE,\r
+ .ioctl = vflash_ioctl,\r
+ .open = vflash_open,\r
+ .release = vflash_release,\r
+};\r
+\r
+static struct miscdevice vflash_miscdev= {\r
+ .name = "vflash",\r
+ .fops = &vflash_fops,\r
+};\r
+\r
+\r
+static int vflash_init(void)\r
+{\r
+ vflash_miscdev.minor = minor;\r
+\r
+ if (misc_register(&vflash_miscdev) < 0) {\r
+ printk(KERN_ERR"Can't register misc device with minor %d", minor);\r
+ return -EIO;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static void vflash_exit(void)\r
+{\r
+ if (misc_deregister(&vflash_miscdev) < 0)\r
+ printk(KERN_ERR"Can't unregister misc device with minor %d", minor);\r
+}\r
+\r
+\r
+module_init(vflash_init);\r
+module_exit(vflash_exit);\r
+\r
+module_param(minor, int, 0444);\r
+MODULE_PARM_DESC(minor, "Miscellaneous minor device number");\r
+\r
+MODULE_AUTHOR("roger_chen <cz@rock-chips.com>");\r
+MODULE_DESCRIPTION("Bluetooth virtual flash driver ver " VERSION);\r
+MODULE_VERSION(VERSION);\r
+MODULE_LICENSE("GPL");\r
+\r
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <mach/iomux.h>
+#include <mach/gpio.h>
#include "rk2818_serial.h"
struct rk2818_port *rk2818_port;
struct resource *resource;
struct uart_port *port;
-
+ int ret = 0;
+
if (unlikely(pdev->id < 0 || pdev->id >= UART_NR))
return -ENXIO;
printk(KERN_INFO "rk2818_serial: detected port %d\n", pdev->id);
+
+#if 1
+//cz@rock-chips.com
+//20100808
+//UART0µÄËĸö¹Ü½ÅÏÈIOMUX³ÉGPIO
+//È»ºó·Ö±ðÉèÖÃÊäÈëÊä³ö/À¸ßÀµÍ´¦Àí
+//×îºóÔÙIOMUX³ÉUART
+//·ÀÖ¹Ö±½ÓIOMUX³ÉUARTºóËĸö¹Ü½ÅµÄ״̬²»¶Ôʱ
+//²Ù×÷UARTµ¼ÖÂUART_USR_BUSYʼÖÕΪ1Ôì³ÉÈçÏÂËÀÑ»·
+//while(rk2818_uart_read(port,UART_USR)&UART_USR_BUSY)
+//UARTËĸö¹Ü½ÅÔÚδ´«ÊäʱÕý³£×´Ì¬Ó¦¸ÃΪ£º
+//RX/TX£ºHIGH
+//CTS/RTS£ºLOW
+//×¢Ò⣺CTS/RTSΪµÍÓÐЧ£¬Ó²¼þÉϲ»Ó¦¸ÃÇ¿ÐÐ×öÉÏÀ
+ rk2818_mux_api_set(GPIOG1_UART0_MMC1WPT_NAME, IOMUXA_GPIO1_C1 /*IOMUXA_UART0_SOUT*/);
+ rk2818_mux_api_set(GPIOG0_UART0_MMC1DET_NAME, IOMUXA_GPIO1_C0 /*IOMUXA_UART0_SIN*/);
+
+ ret = gpio_request(RK2818_PIN_PG0, NULL);
+ if(ret != 0)
+ {
+ gpio_free(RK2818_PIN_PG0);
+ }
+ gpio_direction_output(RK2818_PIN_PG0,GPIO_HIGH);
+
+
+ ret = gpio_request(RK2818_PIN_PG1, NULL);
+ if(ret != 0)
+ {
+ gpio_free(RK2818_PIN_PG1);
+ }
+ gpio_direction_output(RK2818_PIN_PG1,GPIO_HIGH);
+
+ gpio_pull_updown(RK2818_PIN_PG1,GPIOPullUp);
+ gpio_pull_updown(RK2818_PIN_PG0,GPIOPullUp);
+
+ rk2818_mux_api_set(GPIOG1_UART0_MMC1WPT_NAME, IOMUXA_UART0_SOUT);
+ rk2818_mux_api_set(GPIOG0_UART0_MMC1DET_NAME, IOMUXA_UART0_SIN);
+
+ rk2818_mux_api_set(GPIOB2_U0CTSN_SEL_NAME, IOMUXB_GPIO0_B2/*IOMUXB_UART0_CTS_N*/);
+ rk2818_mux_api_set(GPIOB3_U0RTSN_SEL_NAME, IOMUXB_GPIO0_B3/*IOMUXB_UART0_RTS_N*/);
+
+ ret = gpio_request(RK2818_PIN_PB2, NULL);
+ if(ret != 0)
+ {
+ gpio_free(RK2818_PIN_PB2);
+ }
+ gpio_direction_input(RK2818_PIN_PB2);
+// gpio_direction_output(RK2818_PIN_PB2,GPIO_LOW);
+
+ ret = gpio_request(RK2818_PIN_PB3, NULL);
+ if(ret != 0)
+ {
+ gpio_free(RK2818_PIN_PB3);
+ }
+ gpio_direction_output(RK2818_PIN_PB3,GPIO_LOW);
+#endif
+
+
port = get_port_from_line(pdev->id);
port->dev = &pdev->dev;
rk2818_port = UART_TO_RK2818(port);