From: root <root@roger-desktop.(none)>
Date: Mon, 9 Aug 2010 02:57:41 +0000 (+0800)
Subject: add bcm432x drivers
X-Git-Tag: firefly_0821_release~11293
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=35fbfafbeec7ffd799ff88a07f561aba7515b66b;p=firefly-linux-kernel-4.4.55.git

add bcm432x drivers
---

diff --git a/arch/arm/mach-rk2818/board-raho.c b/arch/arm/mach-rk2818/board-raho.c
index fc4b4281815a..d1aa810bb6cd 100755
--- a/arch/arm/mach-rk2818/board-raho.c
+++ b/arch/arm/mach-rk2818/board-raho.c
@@ -722,6 +722,10 @@ struct dm9000_plat_data dm9k_platdata = {
 #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,
diff --git a/arch/arm/mach-rk2818/devices.c b/arch/arm/mach-rk2818/devices.c
index 3e76ca5c11f1..c0885e341e0f 100755
--- a/arch/arm/mach-rk2818/devices.c
+++ b/arch/arm/mach-rk2818/devices.c
@@ -450,7 +450,12 @@ struct platform_device rk2818_device_dsp = {
         }
 };
 
-
+#ifdef CONFIG_BT
+struct platform_device rk2818_device_rfkill = {
+	.name = "rkbt_rfkill",
+	.id = -1,
+};
+#endif
 
 #if defined(CONFIG_ANDROID_PMEM)
 
diff --git a/arch/arm/mach-rk2818/devices.h b/arch/arm/mach-rk2818/devices.h
index 85cc7dc5833a..45a78afc5f0c 100755
--- a/arch/arm/mach-rk2818/devices.h
+++ b/arch/arm/mach-rk2818/devices.h
@@ -50,6 +50,7 @@ extern struct platform_device rk2818_device_backlight;
 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;
diff --git a/arch/arm/mach-rk2818/include/mach/spi_fpga.h b/arch/arm/mach-rk2818/include/mach/spi_fpga.h
index 51a402bd0b33..bb58ed2ff63f 100755
--- a/arch/arm/mach-rk2818/include/mach/spi_fpga.h
+++ b/arch/arm/mach-rk2818/include/mach/spi_fpga.h
@@ -4,6 +4,8 @@ defines of FPGA chip ICE65L08's register
 
 #ifndef SPI_UART_H
 #define SPI_UART_H
+#include <linux/circ_buf.h>
+#include <linux/miscdevice.h>
 
 #define SPI_FPGA_INT_PIN RK2818_PIN_PA4
 #define SPI_DPRAM_BUSY_PIN RK2818_PIN_PA2
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig
old mode 100644
new mode 100755
index 652367aa6546..92234c562e9f
--- a/drivers/bluetooth/Kconfig
+++ b/drivers/bluetooth/Kconfig
@@ -195,5 +195,17 @@ config BT_MRVL_SDIO
 	  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
 
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
old mode 100644
new mode 100755
index b3f57d2d4eb0..64a470eae09f
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -2,6 +2,7 @@
 # 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
@@ -11,6 +12,7 @@ obj-$(CONFIG_BT_HCIDTL1)	+= dtl1_cs.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
diff --git a/drivers/bluetooth/bcm4325.c b/drivers/bluetooth/bcm4325.c
new file mode 100755
index 000000000000..b8dff1bd1967
--- /dev/null
+++ b/drivers/bluetooth/bcm4325.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2010 ROCKCHIP, Inc.
+ * Author: roger_chen <cz@rock-chips.com>
+ *
+ * This program is the bluetooth device bcm4325's driver,
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/rfkill.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+//#include <asm/gpio.h>
+//#include <asm/arch/gpio.h>
+//#include <asm/arch/iomux.h>
+//#include <asm/arch/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/wakelock.h>
+#include <mach/spi_fpga.h>
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+
+#define BT_PWR_ON		{spi_gpio_set_pinlevel(SPI_GPIO_P1_06, SPI_GPIO_HIGH);	\
+            			    spi_gpio_set_pindirection(SPI_GPIO_P1_06, SPI_GPIO_OUT);}
+#define BT_PWR_OFF		{spi_gpio_set_pinlevel(SPI_GPIO_P1_06, SPI_GPIO_LOW);	\
+            				spi_gpio_set_pindirection(SPI_GPIO_P1_06, SPI_GPIO_OUT);}
+
+#define BT_RESET_HIGH	{spi_gpio_set_pinlevel(SPI_GPIO_P1_07, SPI_GPIO_HIGH);	\
+            				spi_gpio_set_pindirection(SPI_GPIO_P1_07, SPI_GPIO_OUT);}
+#define BT_RESET_LOW	{spi_gpio_set_pinlevel(SPI_GPIO_P1_07, SPI_GPIO_LOW);	\
+            				spi_gpio_set_pindirection(SPI_GPIO_P1_07, SPI_GPIO_OUT);}
+
+#define BT_SLEEP_GPIO_IOMUX		    
+#define BT_SLEEP_GPIO_SET_OUT		spi_gpio_set_pindirection(SPI_GPIO_P1_08, SPI_GPIO_OUT);
+#define BT_WAKEUP					//spi_gpio_set_pinlevel(SPI_GPIO_P1_08, SPI_GPIO_HIGH);
+#define BT_SLEEP					//spi_gpio_set_pinlevel(SPI_GPIO_P1_08, SPI_GPIO_LOW);
+
+#if 1
+#define DBG(x...)   printk(KERN_INFO x)
+#else
+#define DBG(x...)
+#endif
+
+static struct rfkill *bt_rfk;
+static const char bt_name[] = "bcm4325";
+//extern void rfkill_switch_all(enum rfkill_type type, bool blocked);
+
+  
+/*
+bSleep:
+0: wakeup
+1: sleep
+*/
+int bcm4325_sleep(int bSleep)
+{
+	if(0 == bSleep)	/*wake up*/
+	{
+		BT_WAKEUP;
+	}
+	else		/*sleep*/
+	{
+		BT_SLEEP;
+	}
+    
+    return 0;
+}
+
+static int bcm4325_set_block(void *data, bool blocked)
+{
+    DBG("%s---blocked :%d\n", __FUNCTION__, blocked);
+
+    if (false == blocked) {          
+        BT_SLEEP_GPIO_IOMUX;
+        BT_SLEEP_GPIO_SET_OUT;
+        BT_PWR_ON;
+        mdelay(2);
+        BT_RESET_LOW;       
+        mdelay(40);
+        BT_RESET_HIGH;
+        mdelay(10);
+        BT_WAKEUP;
+        printk("Enter::%s,bluetooth is power on!\n",__FUNCTION__);
+    }
+    else {
+        BT_SLEEP; 
+//        BT_PWR_OFF;
+        printk("Enter::%s,bluetooth is power off!\n",__FUNCTION__);
+    }
+
+    return 0;
+}
+
+
+static const struct rfkill_ops bcm4325_rfk_ops = {
+	.set_block = bcm4325_set_block,
+};
+
+static int __init bcm4325_rfkill_probe(struct platform_device *pdev)
+{
+	int rc = 0;
+	
+	DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
+	
+	/* default to bluetooth off */
+//	rfkill_switch_all(RFKILL_TYPE_BLUETOOTH, true);
+    
+    bt_rfk = rfkill_alloc(bt_name, 
+                    NULL, 
+                    RFKILL_TYPE_BLUETOOTH, 
+                    &bcm4325_rfk_ops, 
+                    NULL);
+
+	if (!bt_rfk)
+	{
+		printk("fail to rfkill_allocate************\n");
+		return -ENOMEM;
+	}
+
+	
+	rc = rfkill_register(bt_rfk);
+	if (rc)
+		rfkill_destroy(bt_rfk);
+
+    printk("rc=0x%x\n", rc);
+    
+	return rc;
+}
+
+
+static int __devexit bcm4325_rfkill_remove(struct platform_device *pdev)
+{
+	if (bt_rfk)
+		rfkill_unregister(bt_rfk);
+	bt_rfk = NULL;
+
+	platform_set_drvdata(pdev, NULL);
+	DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
+	return 0;
+}
+
+static struct platform_driver bcm4325_rfkill_driver = {
+	.probe = bcm4325_rfkill_probe,
+	.remove = __devexit_p(bcm4325_rfkill_remove),
+	.driver = {
+		.name = "rkbt_rfkill",  //"bcm4325_rfkill",
+		.owner = THIS_MODULE,
+	},
+};
+
+/*
+ * Module initialization
+ */
+static int __init bcm4325_mod_init(void)
+{
+	int ret;
+	DBG("Enter::%s,line=%d\n",__FUNCTION__,__LINE__);
+	ret = platform_driver_register(&bcm4325_rfkill_driver);
+    printk("ret=0x%x\n", ret);
+	return ret;
+}
+
+static void __exit bcm4325_mod_exit(void)
+{
+	platform_driver_unregister(&bcm4325_rfkill_driver);
+}
+
+module_init(bcm4325_mod_init);
+module_exit(bcm4325_mod_exit);
+MODULE_DESCRIPTION("bcm4325 Bluetooth driver");
+MODULE_AUTHOR("roger_chen cz@rock-chips.com");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
old mode 100644
new mode 100755
index c0ce8134814e..50c943d2cce3
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -62,6 +62,10 @@ struct h4_struct {
 #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)
 {
@@ -140,7 +144,9 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
 		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;
@@ -176,7 +182,9 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
 				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;
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
old mode 100644
new mode 100755
index 4895f0e05322..51ff3ef58ec7
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -46,6 +46,10 @@
 
 #include "hci_uart.h"
 
+#ifdef CONFIG_BT_HCIBCM4325  
+extern int bcm4325_sleep(int bSleep);
+#endif
+
 #define VERSION "2.2"
 
 static int reset = 0;
@@ -133,7 +137,10 @@ int hci_uart_tx_wakeup(struct hci_uart *hu)
 
 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;
 
diff --git a/drivers/bluetooth/vflash.c b/drivers/bluetooth/vflash.c
new file mode 100755
index 000000000000..8be5c1bfa600
--- /dev/null
+++ b/drivers/bluetooth/vflash.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2010 ROCKCHIP, Inc.
+ * Author: roger_chen <cz@rock-chips.com>
+ *
+ * This program is the virtual flash device 
+ * used to store bd_addr or MAC
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+#include <asm/uaccess.h>
+
+#if 0
+#define DBG(x...)   printk("vFlash:" x)
+#else
+#define DBG(x...)
+#endif
+
+#define VERSION "0.1"
+
+static int minor = MISC_DYNAMIC_MINOR;
+
+static struct miscdevice vflash_miscdev;
+
+#define READ_BDADDR_FROM_FLASH  0x01
+
+extern char GetSNSectorInfo(char * pbuf);
+
+static int vflash_ioctl(struct inode *inode, struct file *file,
+					unsigned int cmd, unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+    unsigned long n = 0;
+    
+    DBG("%s---cmd=0x%x---arg=0x%x\n", __FUNCTION__, cmd, arg);
+
+    if(NULL == argp)
+        return -EFAULT;
+        
+    switch(cmd)
+    {
+        case READ_BDADDR_FROM_FLASH:
+        {   
+            char *tempBuf = (char *)kmalloc(512, GFP_KERNEL);
+            int i;
+            #if 0
+            GetSNSectorInfo(tempBuf);
+            #else
+            tempBuf[498] = 0x00;
+            tempBuf[499] = 0x11;
+            tempBuf[500] = 0x22;
+            tempBuf[501] = 0x33;
+            tempBuf[502] = 0x44;
+            tempBuf[503] = 0x55;
+            tempBuf[504] = 0x66;
+            #endif
+            for(i=498; i<=504; i++)
+            {
+                DBG("tempBuf[%d]=%x\n", i, tempBuf[i]);
+            }
+            
+			if(copy_to_user(argp, &(tempBuf[499]), 6))
+			{
+			    printk("ERROR: copy_to_user---%s\n", __FUNCTION__);
+                kfree(tempBuf);
+			    return -EFAULT;
+            }
+            
+            kfree(tempBuf);
+        }
+        break;
+        default:
+        break;
+    }
+    
+	return 0;
+}
+
+static int vflash_open(struct inode *inode, struct file *file)
+{
+    DBG("%s\n", __FUNCTION__);
+	return 0;
+}
+
+static int vflash_release(struct inode *inode, struct file *file)
+{
+    DBG("%s\n", __FUNCTION__);
+	return 0;
+}
+
+
+static const struct file_operations vflash_fops = {
+	.owner		= THIS_MODULE,
+	.ioctl		= vflash_ioctl,
+	.open		= vflash_open,
+	.release	= vflash_release,
+};
+
+static struct miscdevice vflash_miscdev= {
+	.name		= "vflash",
+	.fops		= &vflash_fops,
+};
+
+
+static int vflash_init(void)
+{
+	vflash_miscdev.minor = minor;
+
+	if (misc_register(&vflash_miscdev) < 0) {
+		printk(KERN_ERR"Can't register misc device with minor %d", minor);
+		return -EIO;
+	}
+	return 0;
+}
+
+static void vflash_exit(void)
+{
+	if (misc_deregister(&vflash_miscdev) < 0)
+		printk(KERN_ERR"Can't unregister misc device with minor %d", minor);
+}
+
+
+module_init(vflash_init);
+module_exit(vflash_exit);
+
+module_param(minor, int, 0444);
+MODULE_PARM_DESC(minor, "Miscellaneous minor device number");
+
+MODULE_AUTHOR("roger_chen <cz@rock-chips.com>");
+MODULE_DESCRIPTION("Bluetooth virtual flash driver ver " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/serial/rk2818_serial.c b/drivers/serial/rk2818_serial.c
old mode 100644
new mode 100755
index 0c4e4c0e26ef..9d3d06ca05bb
--- a/drivers/serial/rk2818_serial.c
+++ b/drivers/serial/rk2818_serial.c
@@ -32,6 +32,7 @@
 #include <linux/clk.h>
 #include <linux/platform_device.h>
 #include <mach/iomux.h>
+#include <mach/gpio.h>
 
 #include "rk2818_serial.h"
 
@@ -622,12 +623,71 @@ static int __devinit rk2818_serial_probe(struct platform_device *pdev)
 	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);