mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
add bcm432x drivers
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
12
drivers/bluetooth/Kconfig
Normal file → Executable 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
2
drivers/bluetooth/Makefile
Normal file → Executable 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
177
drivers/bluetooth/bcm4325.c
Executable 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
12
drivers/bluetooth/hci_h4.c
Normal file → Executable 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
9
drivers/bluetooth/hci_ldisc.c
Normal file → Executable 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
139
drivers/bluetooth/vflash.c
Executable 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
62
drivers/serial/rk2818_serial.c
Normal file → Executable 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/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);
|
||||
|
||||
Reference in New Issue
Block a user