From 35fbfafbeec7ffd799ff88a07f561aba7515b66b Mon Sep 17 00:00:00 2001 From: root Date: Mon, 9 Aug 2010 10:57:41 +0800 Subject: [PATCH] add bcm432x drivers --- arch/arm/mach-rk2818/board-raho.c | 4 + arch/arm/mach-rk2818/devices.c | 7 +- arch/arm/mach-rk2818/devices.h | 1 + arch/arm/mach-rk2818/include/mach/spi_fpga.h | 2 + drivers/bluetooth/Kconfig | 12 ++ drivers/bluetooth/Makefile | 2 + drivers/bluetooth/bcm4325.c | 177 +++++++++++++++++++ drivers/bluetooth/hci_h4.c | 12 +- drivers/bluetooth/hci_ldisc.c | 9 +- drivers/bluetooth/vflash.c | 139 +++++++++++++++ drivers/serial/rk2818_serial.c | 62 ++++++- 11 files changed, 422 insertions(+), 5 deletions(-) mode change 100644 => 100755 drivers/bluetooth/Kconfig mode change 100644 => 100755 drivers/bluetooth/Makefile create mode 100755 drivers/bluetooth/bcm4325.c mode change 100644 => 100755 drivers/bluetooth/hci_h4.c mode change 100644 => 100755 drivers/bluetooth/hci_ldisc.c create mode 100755 drivers/bluetooth/vflash.c mode change 100644 => 100755 drivers/serial/rk2818_serial.c 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 +#include #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 + * + * This program is the bluetooth device bcm4325's driver, + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +//#include +//#include +//#include +#include +#include +#include +#include +#include + +#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 + * + * This program is the virtual flash device + * used to store bd_addr or MAC + * + */ + + +#include +#include +#include +#include +#include +#include +#include + +#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 "); +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 #include #include +#include #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); -- 2.34.1