add bcm432x drivers

This commit is contained in:
root
2010-08-09 10:57:41 +08:00
parent b6826b0ff4
commit 35fbfafbee
11 changed files with 422 additions and 5 deletions

View File

@@ -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,

View File

@@ -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)

View File

@@ -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;

View File

@@ -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

12
drivers/bluetooth/Kconfig Normal file → Executable file
View File

@@ -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

2
drivers/bluetooth/Makefile Normal file → Executable file
View File

@@ -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

177
drivers/bluetooth/bcm4325.c Executable file
View File

@@ -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");

12
drivers/bluetooth/hci_h4.c Normal file → Executable file
View File

@@ -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;

9
drivers/bluetooth/hci_ldisc.c Normal file → Executable file
View File

@@ -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;

139
drivers/bluetooth/vflash.c Executable file
View File

@@ -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");

62
drivers/serial/rk2818_serial.c Normal file → Executable file
View File

@@ -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/TXHIGH
//CTS/RTSLOW
//注意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);