mirror of
https://github.com/torvalds/linux.git
synced 2026-06-10 07:32:29 +02:00
fpga driver update
This commit is contained in:
parent
572cdaccf7
commit
6ccd5e75a3
|
|
@ -287,14 +287,14 @@ struct rk2818_i2c_platform_data default_i2c1_data = {
|
|||
.cfg_gpio = rk2818_i2c1_cfg_gpio,
|
||||
};
|
||||
|
||||
struct rk2818_i2c_platform_data default_i2c2_data = {
|
||||
struct rk2818_i2c_spi_data default_i2c2_data = {
|
||||
.bus_num = 2,
|
||||
.flags = 0,
|
||||
.slave_addr = 0xff,
|
||||
.scl_rate = 400*1000,
|
||||
|
||||
};
|
||||
struct rk2818_i2c_platform_data default_i2c3_data = {
|
||||
struct rk2818_i2c_spi_data default_i2c3_data = {
|
||||
|
||||
.bus_num = 3,
|
||||
.flags = 0,
|
||||
|
|
@ -454,12 +454,6 @@ static struct platform_device *devices[] __initdata = {
|
|||
#ifdef CONFIG_I2C1_RK2818
|
||||
&rk2818_device_i2c1,
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_I2C
|
||||
&rk2818_device_i2c2,
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_I2C
|
||||
&rk2818_device_i2c3,
|
||||
#endif
|
||||
#ifdef CONFIG_SDMMC0_RK2818
|
||||
&rk2818_device_sdmmc0,
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -285,14 +285,14 @@ struct rk2818_i2c_platform_data default_i2c1_data = {
|
|||
.cfg_gpio = rk2818_i2c1_cfg_gpio,
|
||||
};
|
||||
|
||||
struct rk2818_i2c_platform_data default_i2c2_data = {
|
||||
struct rk2818_i2c_spi_data default_i2c2_data = {
|
||||
.bus_num = 2,
|
||||
.flags = 0,
|
||||
.slave_addr = 0xff,
|
||||
.scl_rate = 400*1000,
|
||||
|
||||
};
|
||||
struct rk2818_i2c_platform_data default_i2c3_data = {
|
||||
struct rk2818_i2c_spi_data default_i2c3_data = {
|
||||
|
||||
.bus_num = 3,
|
||||
.flags = 0,
|
||||
|
|
@ -460,12 +460,6 @@ static struct platform_device *devices[] __initdata = {
|
|||
#ifdef CONFIG_I2C1_RK2818
|
||||
&rk2818_device_i2c1,
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_I2C
|
||||
&rk2818_device_i2c2,
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_I2C
|
||||
&rk2818_device_i2c3,
|
||||
#endif
|
||||
#ifdef CONFIG_SDMMC0_RK2818
|
||||
&rk2818_device_sdmmc0,
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -287,14 +287,14 @@ struct rk2818_i2c_platform_data default_i2c1_data = {
|
|||
.cfg_gpio = rk2818_i2c1_cfg_gpio,
|
||||
};
|
||||
|
||||
struct rk2818_i2c_platform_data default_i2c2_data = {
|
||||
struct rk2818_i2c_spi_data default_i2c2_data = {
|
||||
.bus_num = 2,
|
||||
.flags = 0,
|
||||
.slave_addr = 0xff,
|
||||
.scl_rate = 400*1000,
|
||||
|
||||
};
|
||||
struct rk2818_i2c_platform_data default_i2c3_data = {
|
||||
struct rk2818_i2c_spi_data default_i2c3_data = {
|
||||
|
||||
.bus_num = 3,
|
||||
.flags = 0,
|
||||
|
|
@ -463,12 +463,6 @@ static struct platform_device *devices[] __initdata = {
|
|||
#ifdef CONFIG_I2C1_RK2818
|
||||
&rk2818_device_i2c1,
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_I2C
|
||||
&rk2818_device_i2c2,
|
||||
#endif
|
||||
#ifdef CONFIG_SPI_I2C
|
||||
&rk2818_device_i2c3,
|
||||
#endif
|
||||
#ifdef CONFIG_SDMMC0_RK2818
|
||||
&rk2818_device_sdmmc0,
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ extern struct platform_device rk2818_device_i2c2;
|
|||
extern struct platform_device rk2818_device_i2c3;
|
||||
extern struct rk2818_i2c_platform_data default_i2c0_data;
|
||||
extern struct rk2818_i2c_platform_data default_i2c1_data;
|
||||
extern struct rk2818_i2c_platform_data default_i2c2_data;
|
||||
extern struct rk2818_i2c_platform_data default_i2c3_data;
|
||||
extern struct rk2818_i2c_spi_data default_i2c2_data;
|
||||
extern struct rk2818_i2c_spi_data default_i2c3_data;
|
||||
|
||||
extern struct platform_device rk2818_device_sdmmc0;
|
||||
extern struct platform_device rk2818_device_sdmmc1;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,12 @@ struct rk2818_sdmmc_platform_data {
|
|||
void (*cfg_gpio)(struct platform_device *dev);
|
||||
};
|
||||
|
||||
struct rk2818_i2c_spi_data {
|
||||
int bus_num;
|
||||
unsigned int flags;
|
||||
unsigned int slave_addr;
|
||||
unsigned long scl_rate;
|
||||
};
|
||||
struct rk2818_i2c_platform_data {
|
||||
int bus_num;
|
||||
unsigned int flags;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include <linux/i2c.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
|
||||
#include "spi_fpga.h"
|
||||
#include <mach/spi_fpga.h>
|
||||
|
||||
#if defined(CONFIG_SPI_DPRAM_DEBUG)
|
||||
#define DBG(x...) printk(x)
|
||||
|
|
@ -117,12 +117,13 @@ static int spi_dpram_read_buf(struct spi_dpram *dpram, unsigned short int addr,
|
|||
{
|
||||
struct spi_fpga_port *port = container_of(dpram, struct spi_fpga_port, dpram);
|
||||
unsigned char opt = ((ICE_SEL_DPRAM & ICE_SEL_DPRAM_NOMAL & ICE_SEL_DPRAM_READ));
|
||||
unsigned char tx_buf[3];
|
||||
unsigned char tx_buf[4];
|
||||
unsigned char stat;
|
||||
|
||||
tx_buf[0] = opt;
|
||||
tx_buf[1] = ((addr << 1) >> 8) & 0xff;
|
||||
tx_buf[2] = ((addr << 1) & 0xff);
|
||||
tx_buf[3] = 0;//give fpga 8 clks for reading data
|
||||
|
||||
stat = spi_write_then_read(port->spi, tx_buf, sizeof(tx_buf), buf, len);
|
||||
if(stat)
|
||||
|
|
@ -172,11 +173,12 @@ int spi_dpram_read_ptr(struct spi_dpram *dpram, unsigned short int addr)
|
|||
int ret;
|
||||
struct spi_fpga_port *port = container_of(dpram, struct spi_fpga_port, dpram);
|
||||
unsigned char opt = ((ICE_SEL_DPRAM & ICE_SEL_DPRAM_NOMAL & ICE_SEL_DPRAM_READ));
|
||||
unsigned char tx_buf[3],rx_buf[2];
|
||||
unsigned char tx_buf[4],rx_buf[2];
|
||||
|
||||
tx_buf[0] = opt;
|
||||
tx_buf[1] = ((addr << 1) >> 8) & 0xff;
|
||||
tx_buf[2] = ((addr << 1) & 0xff);
|
||||
tx_buf[3] = 0;//give fpga 8 clks for reading data
|
||||
|
||||
ret = spi_write_then_read(port->spi, tx_buf, sizeof(tx_buf), rx_buf, sizeof(rx_buf));
|
||||
if(ret)
|
||||
|
|
@ -221,11 +223,12 @@ int spi_dpram_read_mailbox(struct spi_dpram *dpram)
|
|||
int ret;
|
||||
struct spi_fpga_port *port = container_of(dpram, struct spi_fpga_port, dpram);
|
||||
unsigned char opt = ((ICE_SEL_DPRAM & ICE_SEL_DPRAM_NOMAL & ICE_SEL_DPRAM_READ));
|
||||
unsigned char tx_buf[3],rx_buf[2];
|
||||
unsigned char tx_buf[4],rx_buf[2];
|
||||
|
||||
tx_buf[0] = opt;
|
||||
tx_buf[1] = ((SPI_DPRAM_MAILBOX_BPWRITE << 1) >> 8) & 0xff;
|
||||
tx_buf[2] = ((SPI_DPRAM_MAILBOX_BPWRITE << 1) & 0xff);
|
||||
tx_buf[3] = 0;//give fpga 8 clks for reading data
|
||||
|
||||
ret = spi_write_then_read(port->spi, tx_buf, sizeof(tx_buf), rx_buf, sizeof(rx_buf));
|
||||
if(ret)
|
||||
|
|
@ -271,80 +274,82 @@ static irqreturn_t spi_dpram_busy_irq(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
#if SPI_DPRAM_TEST
|
||||
#define DPRAM_TEST_LEN 512 //8bit
|
||||
#define SEL_RAM0 0
|
||||
#define SEL_RAM1 1
|
||||
#define SEL_RAM2 2
|
||||
#define SEL_RAM3 3
|
||||
#define SEL_REG 4
|
||||
#define SEL_RAM SEL_RAM2
|
||||
#define DPRAM_TEST_LEN 16 //8bit
|
||||
unsigned char buf_test_dpram[DPRAM_TEST_LEN];
|
||||
void spi_dpram_work_handler(struct work_struct *work)
|
||||
{
|
||||
int i;
|
||||
int i,j;
|
||||
int ret;
|
||||
struct spi_fpga_port *port =
|
||||
container_of(work, struct spi_fpga_port, dpram.spi_dpram_work);
|
||||
printk("*************test spi_dpram now***************\n");
|
||||
|
||||
for(i=0; i<(DPRAM_TEST_LEN>>1); i++)
|
||||
{
|
||||
buf_test_dpram[2*i] = (0xa000+i)>>8;
|
||||
buf_test_dpram[2*i+1] = (0xa000+i)&0xff;
|
||||
}
|
||||
#if 0
|
||||
|
||||
#if(SEL_RAM == SEL_RAM0)
|
||||
//RAM0
|
||||
for(i=0;i<(SPI_DPRAM_BPWRITE_SIZE/(DPRAM_TEST_LEN>>1));i++)
|
||||
{
|
||||
spi_dpram_read_buf(&port->dpram, SPI_DPRAM_BPWRITE_START+(i*DPRAM_TEST_LEN>>1), port->dpram.prx, DPRAM_TEST_LEN);
|
||||
port->dpram.read_dpram(&port->dpram, SPI_DPRAM_BPWRITE_START+(i*DPRAM_TEST_LEN>>1), port->dpram.prx+i*DPRAM_TEST_LEN, DPRAM_TEST_LEN);
|
||||
}
|
||||
|
||||
for(i=0;i<DPRAM_TEST_LEN;i++)
|
||||
for(i=0;i<SPI_DPRAM_BPWRITE_SIZE;i++)
|
||||
{
|
||||
ret = (*(port->dpram.prx+2*i)<<8) | (*(port->dpram.prx+2*i+1));
|
||||
if(ret != 0xa000+i)
|
||||
printk("prx[%d]=0x%x ram[%d]=0x%x\n",i,ret&0xffff,i,0xa000+i);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
#elif(SEL_RAM == SEL_RAM1)
|
||||
//RAM1
|
||||
for(i=0;i<(SPI_DPRAM_APWRITE_SIZE/(DPRAM_TEST_LEN>>1));i++)
|
||||
{
|
||||
for(j=(i*(DPRAM_TEST_LEN>>1)); j<((i+1)*(DPRAM_TEST_LEN>>1)); j++)
|
||||
{
|
||||
buf_test_dpram[2*(j-(i*(DPRAM_TEST_LEN>>1)))] = (0xa000+j)>>8;
|
||||
buf_test_dpram[2*(j-(i*(DPRAM_TEST_LEN>>1)))+1] = (0xa000+j)&0xff;
|
||||
printk("buf_test_dpram[%d]=0x%x\n",j,buf_test_dpram[(j-(i*(DPRAM_TEST_LEN>>1)))]);
|
||||
}
|
||||
|
||||
port->dpram.write_dpram(&port->dpram, ((DPRAM_TEST_LEN*i)>>1)+SPI_DPRAM_APWRITE_START, buf_test_dpram, sizeof(buf_test_dpram));
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
for(i=0;i<DPRAM_TEST_LEN;i++)
|
||||
printk("buf_test_dpram[%d]=0x%x\n",i,buf_test_dpram[i]);
|
||||
DBG("\n");
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
#elif(SEL_RAM == SEL_RAM2)
|
||||
//RAM2
|
||||
for(i=0;i<(SPI_DPRAM_LOG_BPWRITE_SIZE/(DPRAM_TEST_LEN>>1));i++)
|
||||
{
|
||||
spi_dpram_read_buf(&port->dpram, SPI_DPRAM_LOG_BPWRITE_START+(i*DPRAM_TEST_LEN>>1), port->dpram.prx, DPRAM_TEST_LEN);
|
||||
port->dpram.read_dpram(&port->dpram, SPI_DPRAM_LOG_BPWRITE_START+(i*DPRAM_TEST_LEN>>1), port->dpram.prx+i*DPRAM_TEST_LEN, DPRAM_TEST_LEN);
|
||||
}
|
||||
|
||||
for(i=0;i<DPRAM_TEST_LEN;i++)
|
||||
{
|
||||
for(i=0;i<SPI_DPRAM_LOG_BPWRITE_SIZE;i++)
|
||||
{
|
||||
ret = (*(port->dpram.prx+2*i)<<8) | (*(port->dpram.prx+2*i+1));
|
||||
if(ret != 0xc000+i)
|
||||
printk("prx[%d]=0x%x ram[%d]=0x%x\n",i,ret&0xffff,i,0xc000+i);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
#elif(SEL_RAM == SEL_RAM3)
|
||||
//RAM3
|
||||
for(i=0;i<(SPI_DPRAM_LOG_APWRITE_SIZE/(DPRAM_TEST_LEN>>1));i++)
|
||||
{
|
||||
spi_dpram_write_buf(&port->dpram, ((DPRAM_TEST_LEN*i)>>1)+SPI_DPRAM_LOG_APWRITE_START, buf_test_dpram, sizeof(buf_test_dpram));
|
||||
for(j=(i*(DPRAM_TEST_LEN>>1)); j<((i+1)*(DPRAM_TEST_LEN>>1)); j++)
|
||||
{
|
||||
buf_test_dpram[2*(j-(i*(DPRAM_TEST_LEN>>1)))] = (0xa000+j)>>8;
|
||||
buf_test_dpram[2*(j-(i*(DPRAM_TEST_LEN>>1)))+1] = (0xa000+j)&0xff;
|
||||
printk("buf_test_dpram[%d]=0x%x\n",j,buf_test_dpram[(j-(i*(DPRAM_TEST_LEN>>1)))]);
|
||||
}
|
||||
|
||||
port->dpram.write_dpram(&port->dpram, ((DPRAM_TEST_LEN*i)>>1)+SPI_DPRAM_LOG_APWRITE_START, buf_test_dpram, sizeof(buf_test_dpram));
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
for(i=0;i<DPRAM_TEST_LEN;i++)
|
||||
printk("buf_test_dpram[%d]=0x%x\n",i,buf_test_dpram[i]);
|
||||
DBG("\n");
|
||||
#endif
|
||||
#elif(SEL_RAM == SEL_REG)
|
||||
|
||||
#if 1
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR0_APWRITE_BPREAD, SPI_DPRAM_PTR0_APWRITE_BPREAD);
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR1_APWRITE_BPREAD, SPI_DPRAM_PTR1_APWRITE_BPREAD);
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR2_APWRITE_BPREAD, SPI_DPRAM_PTR2_APWRITE_BPREAD);
|
||||
|
|
@ -353,46 +358,24 @@ void spi_dpram_work_handler(struct work_struct *work)
|
|||
|
||||
ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR0_BPWRITE_APREAD);
|
||||
if(ret != SPI_DPRAM_PTR0_BPWRITE_APREAD)
|
||||
{
|
||||
//ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR0_BPWRITE_APREAD);
|
||||
//if(ret != SPI_DPRAM_PTR0_BPWRITE_APREAD)
|
||||
printk("SPI_DPRAM_PTR0_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR0_BPWRITE_APREAD,ret);
|
||||
}
|
||||
printk("SPI_DPRAM_PTR0_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR0_BPWRITE_APREAD,ret);
|
||||
|
||||
ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR1_BPWRITE_APREAD);
|
||||
if(ret != SPI_DPRAM_PTR1_BPWRITE_APREAD)
|
||||
{
|
||||
//ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR1_BPWRITE_APREAD);
|
||||
//if(ret != SPI_DPRAM_PTR1_BPWRITE_APREAD)
|
||||
printk("SPI_DPRAM_PTR1_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR1_BPWRITE_APREAD,ret);
|
||||
}
|
||||
|
||||
printk("SPI_DPRAM_PTR1_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR1_BPWRITE_APREAD,ret);
|
||||
|
||||
ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR2_BPWRITE_APREAD);
|
||||
if(ret != SPI_DPRAM_PTR2_BPWRITE_APREAD)
|
||||
{
|
||||
//ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR2_BPWRITE_APREAD);
|
||||
//if(ret != SPI_DPRAM_PTR2_BPWRITE_APREAD)
|
||||
printk("SPI_DPRAM_PTR2_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR2_BPWRITE_APREAD,ret);
|
||||
}
|
||||
|
||||
printk("SPI_DPRAM_PTR2_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR2_BPWRITE_APREAD,ret);
|
||||
|
||||
ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR3_BPWRITE_APREAD);
|
||||
if(ret != SPI_DPRAM_PTR3_BPWRITE_APREAD)
|
||||
{
|
||||
//ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_PTR3_BPWRITE_APREAD);
|
||||
//if(ret != SPI_DPRAM_PTR3_BPWRITE_APREAD)
|
||||
printk("SPI_DPRAM_PTR3_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR3_BPWRITE_APREAD,ret);
|
||||
|
||||
}
|
||||
mdelay(10);
|
||||
printk("SPI_DPRAM_PTR3_BPWRITE_APREAD(0x%x)=0x%x\n",SPI_DPRAM_PTR3_BPWRITE_APREAD,ret);
|
||||
|
||||
ret = port->dpram.read_mailbox(&port->dpram);
|
||||
if(ret != SPI_DPRAM_MAILBOX_BPWRITE)
|
||||
{
|
||||
//ret = port->dpram.read_ptr(&port->dpram, SPI_DPRAM_MAILBOX_BPWRITE);
|
||||
//if(ret != SPI_DPRAM_MAILBOX_BPWRITE)
|
||||
printk("SPI_DPRAM_MAILBOX_BPWRITE(0x%x)=0x%x\n",SPI_DPRAM_MAILBOX_BPWRITE,ret);
|
||||
}
|
||||
printk("SPI_DPRAM_MAILBOX_BPWRITE(0x%x)=0x%x\n",SPI_DPRAM_MAILBOX_BPWRITE,ret);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -414,10 +397,9 @@ static void spi_testdpram_timer(unsigned long data)
|
|||
int spi_dpram_handle_irq(struct spi_device *spi)
|
||||
{
|
||||
struct spi_fpga_port *port = spi_get_drvdata(spi);
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
#if 0
|
||||
unsigned char mbox = port->dpram.read_mailbox(&port->dpram);
|
||||
unsigned int len;
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
switch(mbox)
|
||||
{
|
||||
case MAILBOX_BPWRITE_DATA:
|
||||
|
|
@ -431,7 +413,7 @@ int spi_dpram_handle_irq(struct spi_device *spi)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -451,8 +433,8 @@ static int dpr_open(struct inode *inode, struct file *filp)
|
|||
|
||||
static int dpr_close(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct spi_fpga_port *port = pFpgaPort;
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
//struct spi_fpga_port *port = pFpgaPort;
|
||||
DBG("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
filp->private_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -528,9 +510,9 @@ static ssize_t dpr_write (struct file *filp, const char __user *buffer, size_t c
|
|||
unsigned int dpr_poll(struct file *filp, struct poll_table_struct * wait)
|
||||
{
|
||||
unsigned int mask = 0;
|
||||
struct spi_fpga_port *port = filp->private_data;
|
||||
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
struct spi_fpga_port *port;
|
||||
port = filp->private_data;
|
||||
DBG("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@ defines of FPGA chip ICE65L08's register
|
|||
#define SPI_DPRAM_BUSY_PIN RK2818_PIN_PA2
|
||||
#define SPI_FPGA_STANDBY_PIN RK2818_PIN_PH7
|
||||
|
||||
#define SPI_FPGA_TEST_DEBUG 0
|
||||
#if SPI_FPGA_TEST_DEBUG
|
||||
#define SPI_FPGA_TEST_DEBUG_PIN RK2818_PIN_PE0
|
||||
extern int spi_test_wrong_handle(void);
|
||||
#endif
|
||||
|
||||
struct uart_icount {
|
||||
__u32 cts;
|
||||
__u32 dsr;
|
||||
|
|
@ -132,6 +138,7 @@ struct spi_fpga_port {
|
|||
#define SEL_GPIO 1
|
||||
#define SEL_I2C 2
|
||||
#define SEL_DPRAM 3
|
||||
#define READ_TOP_INT 4
|
||||
|
||||
/* CMD */
|
||||
#define ICE_SEL_UART (SEL_UART<<6)
|
||||
|
|
@ -196,6 +203,17 @@ typedef enum I2C_ch
|
|||
I2C_CH2,
|
||||
I2C_CH3
|
||||
}eI2C_ch_t;
|
||||
typedef enum eI2CReadMode
|
||||
{
|
||||
I2C_NORMAL,
|
||||
I2C_NOREG
|
||||
}eI2ReadMode_t;
|
||||
|
||||
typedef enum eI2RegType
|
||||
{
|
||||
I2C_8_BIT,
|
||||
I2C_16_BIT
|
||||
}eI2RegType_t;
|
||||
|
||||
#define ICE_SEL_I2C_START (0<<0)
|
||||
#define ICE_SEL_I2C_STOP (1<<0)
|
||||
|
|
@ -298,6 +316,7 @@ typedef enum eSpiGpioPinDirection
|
|||
{
|
||||
SPI_GPIO_IN = 0,
|
||||
SPI_GPIO_OUT,
|
||||
SPI_GPIO_DIR_ERR,
|
||||
}eSpiGpioPinDirection_t;
|
||||
|
||||
|
||||
|
|
@ -483,7 +502,7 @@ extern int spi_gpio_unregister(struct spi_fpga_port *port);
|
|||
#endif
|
||||
#if defined(CONFIG_SPI_I2C)
|
||||
extern int spi_i2c_handle_irq(struct spi_fpga_port *port,unsigned char channel);
|
||||
extern int spi_i2c_register(struct spi_fpga_port *port);
|
||||
extern int spi_i2c_register(struct spi_fpga_port *port,int num);
|
||||
extern int spi_i2c_unregister(struct spi_fpga_port *port);
|
||||
#endif
|
||||
#if defined(CONFIG_SPI_DPRAM)
|
||||
|
|
|
|||
|
|
@ -44,20 +44,21 @@
|
|||
#include <linux/i2c.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
|
||||
#include "spi_fpga.h"
|
||||
#include <mach/spi_fpga.h>
|
||||
|
||||
#if defined(CONFIG_SPI_FPGA_INIT_DEBUG)
|
||||
#define DBG(x...) printk(x)
|
||||
#else
|
||||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
struct spi_fpga_port *pFpgaPort;
|
||||
|
||||
/*------------------------spi¶ÁдµÄ»ù±¾º¯Êý-----------------------*/
|
||||
unsigned int spi_in(struct spi_fpga_port *port, int reg, int type)
|
||||
{
|
||||
unsigned char index = 0;
|
||||
unsigned char tx_buf[1], rx_buf[2], n_rx=2, stat=0;
|
||||
unsigned char tx_buf[2], rx_buf[2], n_rx=2, stat=0;
|
||||
unsigned int result=0;
|
||||
//printk("index1=%d\n",index);
|
||||
|
||||
|
|
@ -68,10 +69,11 @@ unsigned int spi_in(struct spi_fpga_port *port, int reg, int type)
|
|||
index = port->uart.index;
|
||||
reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ | ICE_SEL_UART_CH(index));
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = 0;
|
||||
rx_buf[0] = 0;
|
||||
rx_buf[1] = 0;
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);
|
||||
result = rx_buf[1];
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf)-1, rx_buf, n_rx);
|
||||
result = (rx_buf[0] << 8) | rx_buf[1];
|
||||
DBG("%s,SEL_UART reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xff);
|
||||
break;
|
||||
#endif
|
||||
|
|
@ -80,6 +82,7 @@ unsigned int spi_in(struct spi_fpga_port *port, int reg, int type)
|
|||
case SEL_GPIO:
|
||||
reg = (((reg) | ICE_SEL_GPIO) | ICE_SEL_READ );
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = 0;//give fpga 8 clks for reading data
|
||||
rx_buf[0] = 0;
|
||||
rx_buf[1] = 0;
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);
|
||||
|
|
@ -90,13 +93,14 @@ unsigned int spi_in(struct spi_fpga_port *port, int reg, int type)
|
|||
|
||||
#if defined(CONFIG_SPI_I2C)
|
||||
case SEL_I2C:
|
||||
reg = (((reg) | ICE_SEL_I2C) & ICE_SEL_READ );
|
||||
reg = (((reg) | ICE_SEL_I2C) | ICE_SEL_READ );
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = 0;
|
||||
rx_buf[0] = 0;
|
||||
rx_buf[1] = 0;
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);
|
||||
result = (rx_buf[0] << 8) | rx_buf[1];
|
||||
DBG("%s,SEL_I2C reg=0x%x,result=0x%x [0x%x] [0x%x]\n",__FUNCTION__,reg&0xff,result&0xffff,rx_buf[0],rx_buf[1]);
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf)-1, rx_buf, n_rx);
|
||||
result = rx_buf[1];
|
||||
DBG("%s,SEL_I2C reg=0x%x,result=0x%x \n",__FUNCTION__,reg&0xff,result&0xffff);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
|
@ -104,6 +108,7 @@ unsigned int spi_in(struct spi_fpga_port *port, int reg, int type)
|
|||
case SEL_DPRAM:
|
||||
reg = (((reg) | ICE_SEL_DPRAM) & ICE_SEL_DPRAM_READ );
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = 0;//give fpga 8 clks for reading data
|
||||
rx_buf[0] = 0;
|
||||
rx_buf[1] = 0;
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf), rx_buf, n_rx);
|
||||
|
|
@ -111,8 +116,18 @@ unsigned int spi_in(struct spi_fpga_port *port, int reg, int type)
|
|||
DBG("%s,SEL_GPIO reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xffff);
|
||||
break;
|
||||
#endif
|
||||
case READ_TOP_INT:
|
||||
reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ);
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = 0;
|
||||
rx_buf[0] = 0;
|
||||
rx_buf[1] = 0;
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, sizeof(tx_buf)-1, rx_buf, n_rx);
|
||||
result = rx_buf[1];
|
||||
DBG("%s,SEL_INT reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xff);
|
||||
break;
|
||||
default:
|
||||
printk("Can not support this type!\n");
|
||||
printk("%s err: Can not support this type!\n",__FUNCTION__);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +165,6 @@ void spi_out(struct spi_fpga_port *port, int reg, int value, int type)
|
|||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_I2C)
|
||||
|
||||
case SEL_I2C:
|
||||
reg = (((reg) | ICE_SEL_I2C) & ICE_SEL_WRITE);
|
||||
tx_buf[0] = reg & 0xff;
|
||||
|
|
@ -173,61 +187,87 @@ void spi_out(struct spi_fpga_port *port, int reg, int value, int type)
|
|||
#endif
|
||||
|
||||
default:
|
||||
printk("Can not support this type!\n");
|
||||
printk("%s err: Can not support this type!\n",__FUNCTION__);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if SPI_FPGA_TEST_DEBUG
|
||||
int spi_test_wrong_handle(void)
|
||||
{
|
||||
gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,0);
|
||||
udelay(2);
|
||||
gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,1);
|
||||
printk("%s:give one trailing edge!\n",__FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_test_request_gpio(int set)
|
||||
{
|
||||
int ret;
|
||||
rk2818_mux_api_set(GPIOE0_VIPDATA0_SEL_NAME,0);
|
||||
ret = gpio_request(SPI_FPGA_TEST_DEBUG_PIN, NULL);
|
||||
if (ret) {
|
||||
printk("%s:failed to request SPI_FPGA_TEST_DEBUG_PIN pin\n",__FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
gpio_direction_output(SPI_FPGA_TEST_DEBUG_PIN,set);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void spi_fpga_irq_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct spi_fpga_port *port =
|
||||
container_of(work, struct spi_fpga_port, fpga_irq_work);
|
||||
struct spi_device *spi = port->spi;
|
||||
int ret,uart_ch,gpio_ch;
|
||||
int ret,uart_ch=0;
|
||||
|
||||
DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
ret = spi_in(port, ICE_SEL_READ_INT_TYPE, SEL_UART);
|
||||
ret = spi_in(port, ICE_SEL_READ_INT_TYPE, READ_TOP_INT);
|
||||
if((ret | ICE_INT_TYPE_UART0) == ICE_INT_TYPE_UART0)
|
||||
{
|
||||
#if defined(CONFIG_SPI_UART)
|
||||
uart_ch = 0;
|
||||
printk("Enter::%s,LINE=%d,uart_ch=%d,uart.index=%d\n",__FUNCTION__,__LINE__,uart_ch,port->uart.index);
|
||||
DBG("%s:ICE_INT_TYPE_UART0 ret=0x%x\n",__FUNCTION__,ret);
|
||||
port->uart.index = uart_ch;
|
||||
spi_uart_handle_irq(spi);
|
||||
#endif
|
||||
}
|
||||
else if((ret | ICE_INT_TYPE_GPIO) == ICE_INT_TYPE_GPIO)
|
||||
{
|
||||
gpio_ch = 0;
|
||||
printk("Enter::%s,LINE=%d,gpio_ch=%d\n",__FUNCTION__,__LINE__,gpio_ch);
|
||||
#if defined(CONFIG_SPI_GPIO)
|
||||
printk("%s:ICE_INT_TYPE_GPIO ret=0x%x\n",__FUNCTION__,ret);
|
||||
spi_gpio_handle_irq(spi);
|
||||
#endif
|
||||
}
|
||||
else if((ret | ICE_INT_TYPE_I2C2) == ICE_INT_TYPE_I2C2)
|
||||
{
|
||||
#if defined(CONFIG_SPI_I2C)
|
||||
spi_i2c_handle_irq(port,0);
|
||||
DBG("%s:ICE_INT_TYPE_I2C2 ret=0x%x\n",__FUNCTION__,ret);
|
||||
spi_i2c_handle_irq(port,I2C_CH2);
|
||||
#endif
|
||||
}
|
||||
else if((ret | ICE_INT_TYPE_I2C3) == ICE_INT_TYPE_I2C3)
|
||||
{
|
||||
#if defined(CONFIG_SPI_I2C)
|
||||
spi_i2c_handle_irq(port,1);
|
||||
DBG("%s:ICE_INT_TYPE_I2C3 ret=0x%x\n",__FUNCTION__,ret);
|
||||
spi_i2c_handle_irq(port,I2C_CH3);
|
||||
#endif
|
||||
}
|
||||
else if((ret | ICE_INT_TYPE_DPRAM) == ICE_INT_TYPE_DPRAM)
|
||||
{
|
||||
#if defined(CONFIG_SPI_DPRAM)
|
||||
DBG("%s:ICE_INT_TYPE_DPRAM ret=0x%x\n",__FUNCTION__,ret);
|
||||
spi_dpram_handle_irq(spi);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("%s:NO such INT TYPE\n",__FUNCTION__);
|
||||
printk("%s:NO such INT TYPE,ret=0x%x\n",__FUNCTION__,ret);
|
||||
}
|
||||
|
||||
DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
|
|
@ -267,12 +307,13 @@ static int spi_open_sysclk(int set)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern int spi_i2c_set_bt_power(void);
|
||||
static int __devinit spi_fpga_probe(struct spi_device * spi)
|
||||
{
|
||||
struct spi_fpga_port *port;
|
||||
int ret;
|
||||
char b[12];
|
||||
int num;
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
/*
|
||||
* bits_per_word cannot be configured in platform data
|
||||
|
|
@ -318,18 +359,23 @@ static int __devinit spi_fpga_probe(struct spi_device * spi)
|
|||
return ret;
|
||||
}
|
||||
#endif
|
||||
#if 0 //defined(CONFIG_SPI_I2C)
|
||||
#if defined(CONFIG_SPI_I2C)
|
||||
|
||||
printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
ret = spi_i2c_register(port);
|
||||
printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
if(ret)
|
||||
spin_lock_init(&port->i2c.i2c_lock);
|
||||
for (num= 2;num<4;num++)
|
||||
{
|
||||
spi_i2c_unregister(port);
|
||||
printk("%s:ret=%d,fail to spi_i2c_register\n",__FUNCTION__,ret);
|
||||
return ret;
|
||||
ret = spi_i2c_register(port,num);
|
||||
printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
if(ret)
|
||||
{
|
||||
spi_i2c_unregister(port);
|
||||
printk("%s:ret=%d,fail to spi_i2c_register\n",__FUNCTION__,ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPI_DPRAM)
|
||||
ret = spi_dpram_register(port);
|
||||
if(ret)
|
||||
|
|
@ -362,6 +408,10 @@ static int __devinit spi_fpga_probe(struct spi_device * spi)
|
|||
spi_gpio_init();
|
||||
#endif
|
||||
|
||||
#if SPI_FPGA_TEST_DEBUG
|
||||
spi_test_request_gpio(GPIO_HIGH);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include <linux/i2c.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
|
||||
#include "spi_fpga.h"
|
||||
#include <mach/spi_fpga.h>
|
||||
|
||||
#if defined(CONFIG_SPI_GPIO_DEBUG)
|
||||
#define DBG(x...) printk(x)
|
||||
|
|
@ -52,15 +52,14 @@ static void spi_gpio_write_reg(int reg, int PinNum, int set)
|
|||
unsigned int new_set;
|
||||
struct spi_fpga_port *port = pFpgaPort;
|
||||
PinNum = PinNum % 16;
|
||||
//mutex_lock(&port->spi_lock);
|
||||
|
||||
old_set= spi_in(port, reg, SEL_GPIO);
|
||||
|
||||
if(1 == set)
|
||||
new_set = old_set | (1 << PinNum );
|
||||
else
|
||||
new_set = old_set & (~(1 << PinNum ));
|
||||
spi_out(port, reg, new_set, SEL_GPIO);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
|
||||
spi_out(port, reg, new_set, SEL_GPIO);
|
||||
}
|
||||
|
||||
static int spi_gpio_read_reg(int reg)
|
||||
|
|
@ -68,9 +67,7 @@ static int spi_gpio_read_reg(int reg)
|
|||
int ret = 0;
|
||||
struct spi_fpga_port *port = pFpgaPort;
|
||||
|
||||
//mutex_lock(&port->spi_lock);
|
||||
ret = spi_in(port, reg, SEL_GPIO);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -125,10 +122,8 @@ int spi_gpio_int_sel(eSpiGpioPinNum_t PinNum,eSpiGpioTypeSel_t type)
|
|||
gGpio0State &= (~(1 << PinNum ));
|
||||
spin_unlock(&gpio_state_lock);
|
||||
DBG("%s,PinNum=%d,GPIO[%d]:type=%d\n",__FUNCTION__,PinNum,PinNum/16,type);
|
||||
//mutex_lock(&port->spi_lock);
|
||||
spi_gpio_write_reg(reg, PinNum, type);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
|
||||
spi_gpio_write_reg(reg, PinNum, type);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
|
@ -144,6 +139,10 @@ int spi_gpio_set_pindirection(eSpiGpioPinNum_t PinNum,eSpiGpioPinDirection_t dir
|
|||
{
|
||||
int reg = get_gpio_addr(PinNum);
|
||||
//struct spi_fpga_port *port = pFpgaPort;
|
||||
int state;
|
||||
spin_lock(&gpio_state_lock);
|
||||
state = gGpio0State;
|
||||
spin_unlock(&gpio_state_lock);
|
||||
|
||||
if(reg == -1)
|
||||
{
|
||||
|
|
@ -154,34 +153,76 @@ int spi_gpio_set_pindirection(eSpiGpioPinNum_t PinNum,eSpiGpioPinDirection_t dir
|
|||
if(ICE_SEL_GPIO0 == reg)
|
||||
{
|
||||
reg |= ICE_SEL_GPIO0_DIR;
|
||||
spin_lock(&gpio_state_lock);
|
||||
if((gGpio0State & (1 << PinNum )) != 0)
|
||||
if((state & (1 << PinNum )) != 0)
|
||||
{
|
||||
printk("Fail to set direction because it is int pin!\n");
|
||||
return -1;
|
||||
}
|
||||
spin_unlock(&gpio_state_lock);
|
||||
DBG("%s,PinNum=%d,direction=%d,GPIO[%d]:PinNum/16=%d\n",__FUNCTION__,PinNum,direction,PinNum/16,PinNum%16);
|
||||
//mutex_lock(&port->spi_lock);
|
||||
spi_gpio_write_reg(reg, PinNum, direction);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
DBG("%s,PinNum=%d,direction=%d,GPIO[%d]:PinNum/16=%d\n",__FUNCTION__,PinNum,direction,PinNum/16,PinNum%16);
|
||||
spi_gpio_write_reg(reg, PinNum, direction);
|
||||
}
|
||||
else
|
||||
{
|
||||
reg |= ICE_SEL_GPIO_DIR;
|
||||
DBG("%s,PinNum=%d,direction=%d,GPIO[%d]:PinNum/16=%d\n",__FUNCTION__,PinNum,direction,PinNum/16,PinNum%16);
|
||||
//mutex_lock(&port->spi_lock);
|
||||
spi_gpio_write_reg(reg, PinNum, direction);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
DBG("%s,PinNum=%d,direction=%d,GPIO[%d]:PinNum/16=%d\n",__FUNCTION__,PinNum,direction,PinNum/16,PinNum%16);
|
||||
spi_gpio_write_reg(reg, PinNum, direction);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
eSpiGpioPinDirection_t spi_gpio_get_pindirection(eSpiGpioPinNum_t PinNum)
|
||||
{
|
||||
int ret = 0;
|
||||
int reg = get_gpio_addr(PinNum);
|
||||
int dir = 0;
|
||||
//struct spi_fpga_port *port = pFpgaPort;
|
||||
int state;
|
||||
spin_lock(&gpio_state_lock);
|
||||
state = gGpio0State;
|
||||
spin_unlock(&gpio_state_lock);
|
||||
|
||||
if(reg == -1)
|
||||
{
|
||||
printk("%s:error\n",__FUNCTION__);
|
||||
return SPI_GPIO_DIR_ERR;
|
||||
}
|
||||
|
||||
if(ICE_SEL_GPIO0 == reg)
|
||||
{
|
||||
reg |= ICE_SEL_GPIO0_DIR;
|
||||
if((state & (1 << PinNum )) != 0)
|
||||
{
|
||||
printk("Fail to get pindirection because it is int pin!\n");
|
||||
return SPI_GPIO_DIR_ERR;
|
||||
}
|
||||
ret = spi_gpio_read_reg(reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
reg |= ICE_SEL_GPIO_DIR;
|
||||
ret = spi_gpio_read_reg(reg);
|
||||
}
|
||||
|
||||
if((ret & (1 << (PinNum%16) )) == 0)
|
||||
dir = SPI_GPIO_IN;
|
||||
else
|
||||
dir = SPI_GPIO_OUT;
|
||||
|
||||
DBG("%s,PinNum=%d,ret=0x%x,GPIO[%d]:PinNum/16=%d,pindirection=%d\n\n",__FUNCTION__,PinNum,ret,PinNum/16,PinNum%16,dir);
|
||||
|
||||
return dir;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int spi_gpio_set_pinlevel(eSpiGpioPinNum_t PinNum, eSpiGpioPinLevel_t PinLevel)
|
||||
{
|
||||
int reg = get_gpio_addr(PinNum);
|
||||
//struct spi_fpga_port *port = pFpgaPort;
|
||||
int state;
|
||||
spin_lock(&gpio_state_lock);
|
||||
state = gGpio0State;
|
||||
spin_unlock(&gpio_state_lock);
|
||||
|
||||
if(reg == -1)
|
||||
{
|
||||
|
|
@ -192,26 +233,20 @@ int spi_gpio_set_pinlevel(eSpiGpioPinNum_t PinNum, eSpiGpioPinLevel_t PinLevel)
|
|||
if(ICE_SEL_GPIO0 == reg)
|
||||
{
|
||||
reg |= ICE_SEL_GPIO0_DATA;
|
||||
spin_lock(&gpio_state_lock);
|
||||
if((gGpio0State & (1 << PinNum )) != 0)
|
||||
if((state & (1 << PinNum )) != 0)
|
||||
{
|
||||
printk("Fail to set PinLevel because PinNum=%d is int pin!\n",PinNum);
|
||||
return -1;
|
||||
}
|
||||
spin_unlock(&gpio_state_lock);
|
||||
DBG("%s,PinNum=%d,GPIO[%d]:PinNum/16=%d,PinLevel=%d\n",__FUNCTION__,PinNum,PinNum/16,PinNum%16,PinLevel);
|
||||
//mutex_lock(&port->spi_lock);
|
||||
spi_gpio_write_reg(reg, PinNum, PinLevel);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
DBG("%s,PinNum=%d,GPIO[%d]:PinNum/16=%d,PinLevel=%d\n",__FUNCTION__,PinNum,PinNum/16,PinNum%16,PinLevel);
|
||||
spi_gpio_write_reg(reg, PinNum, PinLevel);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
reg |= ICE_SEL_GPIO_DATA;
|
||||
DBG("%s,PinNum=%d,GPIO[%d]:PinNum/16=%d,PinLevel=%d\n",__FUNCTION__,PinNum,PinNum/16,PinNum%16,PinLevel);
|
||||
//mutex_lock(&port->spi_lock);
|
||||
spi_gpio_write_reg(reg, PinNum, PinLevel);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
DBG("%s,PinNum=%d,GPIO[%d]:PinNum/16=%d,PinLevel=%d\n",__FUNCTION__,PinNum,PinNum/16,PinNum%16,PinLevel);
|
||||
spi_gpio_write_reg(reg, PinNum, PinLevel);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -225,6 +260,10 @@ eSpiGpioPinLevel_t spi_gpio_get_pinlevel(eSpiGpioPinNum_t PinNum)
|
|||
int reg = get_gpio_addr(PinNum);
|
||||
int level = 0;
|
||||
//struct spi_fpga_port *port = pFpgaPort;
|
||||
int state;
|
||||
spin_lock(&gpio_state_lock);
|
||||
state = gGpio0State;
|
||||
spin_unlock(&gpio_state_lock);
|
||||
|
||||
if(reg == -1)
|
||||
{
|
||||
|
|
@ -235,25 +274,19 @@ eSpiGpioPinLevel_t spi_gpio_get_pinlevel(eSpiGpioPinNum_t PinNum)
|
|||
if(ICE_SEL_GPIO0 == reg)
|
||||
{
|
||||
reg |= ICE_SEL_GPIO0_DATA;
|
||||
spin_lock(&gpio_state_lock);
|
||||
if((gGpio0State & (1 << PinNum )) != 0)
|
||||
if((state & (1 << PinNum )) != 0)
|
||||
{
|
||||
printk("Fail to get PinLevel because it is int pin!\n");
|
||||
return SPI_GPIO_LEVEL_ERR;
|
||||
}
|
||||
spin_unlock(&gpio_state_lock);
|
||||
//mutex_lock(&port->spi_lock);
|
||||
ret = spi_gpio_read_reg(reg);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
}
|
||||
ret = spi_gpio_read_reg(reg);
|
||||
}
|
||||
else
|
||||
{
|
||||
reg |= ICE_SEL_GPIO_DATA;
|
||||
//mutex_lock(&port->spi_lock);
|
||||
ret = spi_gpio_read_reg(reg);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
reg |= ICE_SEL_GPIO_DATA;
|
||||
ret = spi_gpio_read_reg(reg);
|
||||
}
|
||||
|
||||
|
||||
if((ret & (1 << (PinNum%16) )) == 0)
|
||||
level = SPI_GPIO_LOW;
|
||||
else
|
||||
|
|
@ -270,21 +303,21 @@ int spi_gpio_enable_int(eSpiGpioPinNum_t PinNum)
|
|||
{
|
||||
int reg = get_gpio_addr(PinNum);
|
||||
//struct spi_fpga_port *port = pFpgaPort;
|
||||
int state;
|
||||
spin_lock(&gpio_state_lock);
|
||||
state = gGpio0State;
|
||||
spin_unlock(&gpio_state_lock);
|
||||
|
||||
if(ICE_SEL_GPIO0 == reg)
|
||||
{
|
||||
reg |= ICE_SEL_GPIO0_INT_EN;
|
||||
spin_lock(&gpio_state_lock);
|
||||
if((gGpio0State & (1 << PinNum )) == 0)
|
||||
if((state & (1 << PinNum )) == 0)
|
||||
{
|
||||
printk("Fail to enable int because it is gpio pin!\n");
|
||||
return -1;
|
||||
}
|
||||
spin_unlock(&gpio_state_lock);
|
||||
DBG("%s,PinNum=%d,IntEn=%d\n",__FUNCTION__,PinNum,SPI_GPIO_INT_ENABLE);
|
||||
//mutex_lock(&port->spi_lock);
|
||||
spi_gpio_write_reg(reg, PinNum, SPI_GPIO_INT_ENABLE);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
DBG("%s,PinNum=%d,IntEn=%d\n",__FUNCTION__,PinNum,SPI_GPIO_INT_ENABLE);
|
||||
spi_gpio_write_reg(reg, PinNum, SPI_GPIO_INT_ENABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -300,21 +333,23 @@ int spi_gpio_disable_int(eSpiGpioPinNum_t PinNum)
|
|||
{
|
||||
int reg = get_gpio_addr(PinNum);
|
||||
//struct spi_fpga_port *port = pFpgaPort;
|
||||
int state;
|
||||
spin_lock(&gpio_state_lock);
|
||||
state = gGpio0State;
|
||||
spin_unlock(&gpio_state_lock);
|
||||
|
||||
if(ICE_SEL_GPIO0 == reg)
|
||||
{
|
||||
reg |= ICE_SEL_GPIO0_INT_EN;
|
||||
spin_lock(&gpio_state_lock);
|
||||
if((gGpio0State & (1 << PinNum )) == 0)
|
||||
|
||||
if((state & (1 << PinNum )) == 0)
|
||||
{
|
||||
printk("Fail to enable int because it is gpio pin!\n");
|
||||
return -1;
|
||||
}
|
||||
spin_unlock(&gpio_state_lock);
|
||||
DBG("%s,PinNum=%d,IntEn=%d\n",__FUNCTION__,PinNum,SPI_GPIO_INT_DISABLE);
|
||||
//mutex_lock(&port->spi_lock);
|
||||
spi_gpio_write_reg(reg, PinNum, SPI_GPIO_INT_DISABLE);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
|
||||
DBG("%s,PinNum=%d,IntEn=%d\n",__FUNCTION__,PinNum,SPI_GPIO_INT_DISABLE);
|
||||
spi_gpio_write_reg(reg, PinNum, SPI_GPIO_INT_DISABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -330,21 +365,25 @@ int spi_gpio_set_int_trigger(eSpiGpioPinNum_t PinNum,eSpiGpioIntType_t IntType)
|
|||
{
|
||||
int reg = get_gpio_addr(PinNum);
|
||||
//struct spi_fpga_port *port = pFpgaPort;
|
||||
int state;
|
||||
spin_lock(&gpio_state_lock);
|
||||
state = gGpio0State;
|
||||
spin_unlock(&gpio_state_lock);
|
||||
|
||||
if(ICE_SEL_GPIO0 == reg)
|
||||
{
|
||||
reg |= ICE_SEL_GPIO0_INT_TRI;
|
||||
spin_lock(&gpio_state_lock);
|
||||
if((gGpio0State & (1 << PinNum )) == 0)
|
||||
|
||||
if((state & (1 << PinNum )) == 0)
|
||||
{
|
||||
printk("Fail to enable int because it is gpio pin!\n");
|
||||
return -1;
|
||||
}
|
||||
spin_unlock(&gpio_state_lock);
|
||||
|
||||
DBG("%s,PinNum=%d,IntType=%d\n",__FUNCTION__,PinNum,IntType);
|
||||
//mutex_lock(&port->spi_lock);
|
||||
|
||||
spi_gpio_write_reg(reg, PinNum, IntType);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -372,17 +411,30 @@ int spi_request_gpio_irq(eSpiGpioPinNum_t PinNum, pSpiFunc Routine, eSpiGpioIntT
|
|||
return -1;
|
||||
DBG("Enter::%s,LINE=%d,PinNum=%d\n",__FUNCTION__,__LINE__,PinNum);
|
||||
if(spi_gpio_int_sel(PinNum,SPI_GPIO0_IS_INT))
|
||||
{
|
||||
printk("%s err:fail to enable select intterupt when PinNum=%d\n",__FUNCTION__,PinNum);
|
||||
return -1;
|
||||
}
|
||||
if(spi_gpio_set_int_trigger(PinNum,IntType))
|
||||
{
|
||||
printk("%s err:fail to enable set intterrupt trigger when PinNum=%d\n",__FUNCTION__,PinNum);
|
||||
return -1;
|
||||
spin_lock(&gpio_irq_lock);
|
||||
}
|
||||
|
||||
if(g_spiGpioVectorTable[PinNum].gpio_vector)
|
||||
return -1;
|
||||
{
|
||||
printk("%s err:fail to enable g_spiGpioVectorTable[%d] have been used\n",__FUNCTION__,PinNum);
|
||||
return -1;
|
||||
}
|
||||
spin_lock(&gpio_irq_lock);
|
||||
g_spiGpioVectorTable[PinNum].gpio_vector = (pSpiFuncIntr)Routine;
|
||||
g_spiGpioVectorTable[PinNum].gpio_devid= dev_id;
|
||||
spin_unlock(&gpio_irq_lock);
|
||||
if(spi_gpio_enable_int(PinNum))
|
||||
{
|
||||
printk("%s err:fail to enable gpio intterupt when PinNum=%d\n",__FUNCTION__,PinNum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -402,31 +454,117 @@ int spi_free_gpio_irq(eSpiGpioPinNum_t PinNum)
|
|||
int spi_gpio_handle_irq(struct spi_device *spi)
|
||||
{
|
||||
int gpio_iir, i;
|
||||
int state;
|
||||
spin_lock(&gpio_state_lock);
|
||||
state = gGpio0State;
|
||||
spin_unlock(&gpio_state_lock);
|
||||
|
||||
#if 1
|
||||
gpio_iir = spi_gpio_read_iir() & 0xffff;
|
||||
if(gpio_iir == 0xffff)
|
||||
return -1;
|
||||
//spin_lock(&gpio_state_lock);
|
||||
|
||||
DBG("gpio_iir=0x%x\n",gpio_iir);
|
||||
for(i=0; i<SPI_GPIO_IRQ_NUM; i++)
|
||||
{
|
||||
if(((gpio_iir & (1 << i)) == 0) && ((gGpio0State & (1 << i)) != 0))
|
||||
if(((gpio_iir & (1 << i)) == 0) && ((state & (1 << i)) != 0))
|
||||
{
|
||||
if(g_spiGpioVectorTable[i].gpio_vector)
|
||||
{
|
||||
g_spiGpioVectorTable[i].gpio_vector(i,g_spiGpioVectorTable[i].gpio_devid);
|
||||
DBG("spi_gpio_irq=%d\n",i);
|
||||
spin_lock(&gpio_irq_lock);
|
||||
g_spiGpioVectorTable[i].gpio_vector(i,g_spiGpioVectorTable[i].gpio_devid);
|
||||
spin_unlock(&gpio_irq_lock);
|
||||
DBG("%s:spi_gpio_irq=%d\n",__FUNCTION__,i);
|
||||
}
|
||||
}
|
||||
}
|
||||
//spin_unlock(&gpio_state_lock);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#if SPI_GPIO_TEST
|
||||
static irqreturn_t spi_gpio_int_test_0(int irq, void *dev)
|
||||
{
|
||||
printk("%s:LINE=%d,dev=0x%x\n",__FUNCTION__,__LINE__,(int)dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t spi_gpio_int_test_1(int irq, void *dev)
|
||||
{
|
||||
printk("%s:LINE=%d,dev=0x%x\n",__FUNCTION__,__LINE__,(int)dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t spi_gpio_int_test_2(int irq, void *dev)
|
||||
{
|
||||
printk("%s:LINE=%d,dev=0x%x\n",__FUNCTION__,__LINE__,(int)dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static irqreturn_t spi_gpio_int_test_3(int irq, void *dev)
|
||||
{
|
||||
printk("%s:LINE=%d,dev=0x%x\n",__FUNCTION__,__LINE__,(int)dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
volatile int TestGpioPinLevel = 0;
|
||||
void spi_gpio_work_handler(struct work_struct *work)
|
||||
{
|
||||
//struct spi_fpga_port *port =
|
||||
//container_of(work, struct spi_fpga_port, gpio.spi_gpio_work);
|
||||
int i,ret;
|
||||
printk("*************test spi_gpio now***************\n");
|
||||
|
||||
if(TestGpioPinLevel == 0)
|
||||
TestGpioPinLevel = 1;
|
||||
else
|
||||
TestGpioPinLevel = 0;
|
||||
|
||||
#if (FPGA_TYPE == ICE_CC72)
|
||||
for(i=0;i<32;i++)
|
||||
{
|
||||
spi_gpio_set_pinlevel(i, TestGpioPinLevel);
|
||||
ret = spi_gpio_get_pinlevel(i);
|
||||
if(ret != TestGpioPinLevel)
|
||||
DBG("PinNum=%d,set_pinlevel=%d,get_pinlevel=%d\n",i,TestGpioPinLevel,ret);
|
||||
//spi_gpio_set_pindirection(i, SPI_GPIO_OUT);
|
||||
}
|
||||
|
||||
#elif (FPGA_TYPE == ICE_CC196)
|
||||
|
||||
for(i=16;i<81;i++)
|
||||
{
|
||||
spi_gpio_set_pinlevel(i, TestGpioPinLevel);
|
||||
ret = spi_gpio_get_pinlevel(i);
|
||||
if(ret != TestGpioPinLevel)
|
||||
{
|
||||
#if SPI_FPGA_TEST_DEBUG
|
||||
spi_test_wrong_handle();
|
||||
#endif
|
||||
printk("err:PinNum=%d,set_pinlevel=%d but get_pinlevel=%d\n",i,TestGpioPinLevel,ret);
|
||||
ret = spi_gpio_get_pindirection(i);
|
||||
printk("spi_gpio_get_pindirection=%d\n\n",ret);
|
||||
}
|
||||
}
|
||||
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void spi_testgpio_timer(unsigned long data)
|
||||
{
|
||||
struct spi_fpga_port *port = (struct spi_fpga_port *)data;
|
||||
port->gpio.gpio_timer.expires = jiffies + msecs_to_jiffies(2000);
|
||||
add_timer(&port->gpio.gpio_timer);
|
||||
//schedule_work(&port->gpio.spi_gpio_work);
|
||||
queue_work(port->gpio.spi_gpio_workqueue, &port->gpio.spi_gpio_work);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int spi_gpio_init(void)
|
||||
{
|
||||
int i,ret;
|
||||
|
|
@ -443,6 +581,7 @@ int spi_gpio_init(void)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if (FPGA_TYPE == ICE_CC72)
|
||||
for(i=0; i<16; i++)
|
||||
{
|
||||
|
|
@ -471,34 +610,6 @@ int spi_gpio_init(void)
|
|||
|
||||
#elif (FPGA_TYPE == ICE_CC196)
|
||||
|
||||
#if 0
|
||||
for(i=0;i<82;i++)
|
||||
{
|
||||
if(i<16)
|
||||
spi_gpio_int_sel(i,SPI_GPIO0_IS_GPIO);
|
||||
spi_gpio_set_pindirection(i, SPI_GPIO_OUT);
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
if(TestGpioPinLevel == 0)
|
||||
TestGpioPinLevel = 1;
|
||||
else
|
||||
TestGpioPinLevel = 0;
|
||||
for(i=0;i<82;i++)
|
||||
{
|
||||
spi_gpio_set_pinlevel(i, TestGpioPinLevel);
|
||||
ret = spi_gpio_get_pinlevel(i);
|
||||
if(ret != TestGpioPinLevel)
|
||||
DBG("PinNum=%d,set_pinlevel=%d,get_pinlevel=%d\n\n",i,TestGpioPinLevel,ret);
|
||||
}
|
||||
mdelay(10);
|
||||
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
spi_out(port, (ICE_SEL_GPIO0 | ICE_SEL_GPIO0_TYPE), 0x0000, SEL_GPIO);
|
||||
|
|
@ -565,12 +676,11 @@ int spi_gpio_init(void)
|
|||
ret = spi_in(port, (ICE_SEL_GPIO5 | ICE_SEL_GPIO_DIR), SEL_GPIO) & 0xffff;
|
||||
if(ret != 0xffff)
|
||||
DBG("%s:Line=%d,set=0xffff,ret=0x%x\n",__FUNCTION__,__LINE__,ret);
|
||||
|
||||
|
||||
|
||||
#else
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P1_00, SPI_GPIO_LOW); //LCD_ON output
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P1_00, SPI_GPIO_HIGH); //LCD_ON output//
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P1_00, SPI_GPIO_OUT);
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P1_01, SPI_GPIO_LOW); //LCD_PWR_CTRL output
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P1_01, SPI_GPIO_HIGH); //LCD_PWR_CTRL output
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P1_01, SPI_GPIO_OUT);
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P1_02, SPI_GPIO_HIGH); //SD_POW_ON output
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P1_02, SPI_GPIO_OUT);
|
||||
|
|
@ -587,7 +697,7 @@ int spi_gpio_init(void)
|
|||
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P1_08, SPI_GPIO_LOW); //BT_WAKE_B output
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P1_08, SPI_GPIO_OUT);
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P1_09, SPI_GPIO_HIGH); //LCD_DISP_ON output
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P1_09, SPI_GPIO_LOW); //LCD_DISP_ON output
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P1_09, SPI_GPIO_OUT);
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P1_10, SPI_GPIO_LOW); //WM_PWR_EN output
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P1_10, SPI_GPIO_OUT);
|
||||
|
|
@ -623,88 +733,74 @@ int spi_gpio_init(void)
|
|||
spi_gpio_set_pindirection(SPI_GPIO_P2_10, SPI_GPIO_IN); //X-XL input
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P2_11, SPI_GPIO_IN); //X+XR input
|
||||
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P2_12, SPI_GPIO_LOW); //LCD_RESET output
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P2_12, SPI_GPIO_HIGH); //LCD_RESET output//
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P2_12, SPI_GPIO_OUT);
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P2_13, SPI_GPIO_HIGH); //USB_PWR_EN output
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P2_13, SPI_GPIO_OUT);
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P2_14, SPI_GPIO_LOW); //WL_HOST_WAKE_B output
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P2_14, SPI_GPIO_OUT);
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P2_15, SPI_GPIO_LOW); //TOUCH_SCREEN_RST output
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P2_15, SPI_GPIO_HIGH); //TOUCH_SCREEN_RST output//
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P2_15, SPI_GPIO_OUT);
|
||||
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P4_06, SPI_GPIO_IN); //CHARGER_INT_END input
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P4_07, SPI_GPIO_LOW); //TOUCH_SCREEN_RST output
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P4_07, SPI_GPIO_LOW); //CM3605_PWD output
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P4_07, SPI_GPIO_OUT);
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P4_08, SPI_GPIO_LOW); //CM3605_PS_SHUTDOWN
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P4_08, SPI_GPIO_OUT);
|
||||
|
||||
#endif
|
||||
|
||||
#if SPI_GPIO_TEST
|
||||
|
||||
for(i=0;i<81;i++)
|
||||
{
|
||||
if(i<4)
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
case 0:
|
||||
spi_request_gpio_irq(i, (pSpiFunc)spi_gpio_int_test_0, SPI_GPIO_EDGE_FALLING, port);
|
||||
break;
|
||||
case 1:
|
||||
spi_request_gpio_irq(i, (pSpiFunc)spi_gpio_int_test_1, SPI_GPIO_EDGE_FALLING, port);
|
||||
break;
|
||||
case 2:
|
||||
spi_request_gpio_irq(i, (pSpiFunc)spi_gpio_int_test_2, SPI_GPIO_EDGE_FALLING, port);
|
||||
break;
|
||||
case 3:
|
||||
spi_request_gpio_irq(i, (pSpiFunc)spi_gpio_int_test_3, SPI_GPIO_EDGE_FALLING, port);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//if(i<16)
|
||||
//spi_gpio_int_sel(i,SPI_GPIO0_IS_GPIO);
|
||||
spi_gpio_set_pindirection(i, SPI_GPIO_OUT);
|
||||
ret = spi_gpio_get_pindirection(i);
|
||||
if(ret != SPI_GPIO_OUT)
|
||||
{
|
||||
#if SPI_FPGA_TEST_DEBUG
|
||||
spi_test_wrong_handle();
|
||||
#endif
|
||||
printk("err:PinNum=%d,set_pindirection=%d but get_pindirection=%d\n",i,SPI_GPIO_OUT,ret);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if SPI_GPIO_TEST
|
||||
volatile int TestGpioPinLevel = 0;
|
||||
void spi_gpio_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct spi_fpga_port *port =
|
||||
container_of(work, struct spi_fpga_port, gpio.spi_gpio_work);
|
||||
int i,ret;
|
||||
printk("*************test spi_gpio now***************\n");
|
||||
|
||||
if(TestGpioPinLevel == 0)
|
||||
TestGpioPinLevel = 1;
|
||||
else
|
||||
TestGpioPinLevel = 0;
|
||||
|
||||
#if (FPGA_TYPE == ICE_CC72)
|
||||
for(i=0;i<32;i++)
|
||||
{
|
||||
spi_gpio_set_pinlevel(i, TestGpioPinLevel);
|
||||
ret = spi_gpio_get_pinlevel(i);
|
||||
if(ret != TestGpioPinLevel)
|
||||
DBG("PinNum=%d,set_pinlevel=%d,get_pinlevel=%d\n",i,TestGpioPinLevel,ret);
|
||||
//spi_gpio_set_pindirection(i, SPI_GPIO_OUT);
|
||||
}
|
||||
|
||||
#elif (FPGA_TYPE == ICE_CC196)
|
||||
for(i=0;i<16;i++)
|
||||
{
|
||||
if(i<16)
|
||||
spi_gpio_int_sel(i,SPI_GPIO0_IS_GPIO);
|
||||
spi_gpio_set_pindirection(i, SPI_GPIO_OUT);
|
||||
}
|
||||
|
||||
for(i=0;i<81;i++)
|
||||
{
|
||||
spi_gpio_set_pinlevel(i, TestGpioPinLevel);
|
||||
ret = spi_gpio_get_pinlevel(i);
|
||||
if(ret != TestGpioPinLevel)
|
||||
printk("err:PinNum=%d,set_pinlevel=%d but get_pinlevel=%d\n\n",i,TestGpioPinLevel,ret);
|
||||
}
|
||||
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void spi_testgpio_timer(unsigned long data)
|
||||
{
|
||||
struct spi_fpga_port *port = (struct spi_fpga_port *)data;
|
||||
port->gpio.gpio_timer.expires = jiffies + msecs_to_jiffies(1000);
|
||||
add_timer(&port->gpio.gpio_timer);
|
||||
//schedule_work(&port->gpio.spi_gpio_work);
|
||||
queue_work(port->gpio.spi_gpio_workqueue, &port->gpio.spi_gpio_work);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int spi_gpio_register(struct spi_fpga_port *port)
|
||||
{
|
||||
#if SPI_GPIO_TEST
|
||||
|
|
@ -728,6 +824,7 @@ int spi_gpio_register(struct spi_fpga_port *port)
|
|||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spi_gpio_unregister(struct spi_fpga_port *port)
|
||||
{
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include <mach/board.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
|
||||
#include "spi_fpga.h"
|
||||
#include <mach/spi_fpga.h>
|
||||
|
||||
#if defined(CONFIG_SPI_I2C_DEBUG)
|
||||
#define DBG(x...) printk(x)
|
||||
|
|
@ -35,12 +35,9 @@
|
|||
#define DBG(x...)
|
||||
#endif
|
||||
|
||||
#define SPI_I2C_TEST 0
|
||||
|
||||
#define MAXMSGLEN 16
|
||||
#define MAXMSGLEN 8
|
||||
#define DRV_NAME "fpga_i2c"
|
||||
|
||||
|
||||
#define SPI_I2C_TEST 0
|
||||
struct spi_i2c_data {
|
||||
struct device *dev;
|
||||
struct i2c_adapter adapter;
|
||||
|
|
@ -53,28 +50,29 @@ int spi_i2c_handle_irq(struct spi_fpga_port *port,unsigned char channel)
|
|||
{
|
||||
int reg;
|
||||
int ret;
|
||||
|
||||
if(channel == 0)
|
||||
|
||||
if(channel == I2C_CH2)
|
||||
reg = ICE_SEL_I2C_INT|ICE_SEL_I2C_CH2;
|
||||
else
|
||||
reg = ICE_SEL_I2C_INT|ICE_SEL_I2C_CH3;
|
||||
|
||||
port->i2c.interrupt = 0;
|
||||
ret = spi_in(port,reg,SEL_I2C);
|
||||
if(ret == INT_I2C_READ_ACK)
|
||||
DBG("Enter::%s,LINE=%d ret = [%d]\n",__FUNCTION__,__LINE__,ret);
|
||||
if(INT_I2C_READ_ACK == (ret & 0x07))
|
||||
port->i2c.interrupt = INT_I2C_READ_ACK;
|
||||
else if(ret == INT_I2C_READ_NACK)
|
||||
else if(INT_I2C_READ_NACK ==(ret & 0x07))
|
||||
{
|
||||
printk("Error::read no ack!!check the I2C slave device \n");
|
||||
printk("Error::read no ack!!check the I2C slave device ret=%d \n",ret);
|
||||
}
|
||||
else if(ret == INT_I2C_WRITE_ACK)
|
||||
else if(INT_I2C_WRITE_ACK == (ret & 0x07))
|
||||
port->i2c.interrupt = INT_I2C_WRITE_ACK;
|
||||
else if(ret == INT_I2C_WRITE_NACK)
|
||||
else if(INT_I2C_WRITE_NACK == (ret & 0x07))
|
||||
{
|
||||
printk("Error::write no ack!!check the I2C slave device \n");
|
||||
printk("Error::write no ack!!check the I2C slave device ret=%d \n",ret);
|
||||
}
|
||||
else
|
||||
printk("Error:ack value error!!check the I2C slave device \n");
|
||||
printk("Error:ack value error!!check the I2C slave device ret=%d \n",ret);
|
||||
return port->i2c.interrupt;
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +102,7 @@ int spi_i2c_select_speed(int speed)
|
|||
return result;
|
||||
}
|
||||
|
||||
int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg)
|
||||
int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
|
||||
{
|
||||
|
||||
unsigned int reg ;
|
||||
|
|
@ -118,17 +116,19 @@ int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg)
|
|||
len = pmsg->len;
|
||||
speed = spi_i2c_select_speed(pmsg->scl_rate);
|
||||
|
||||
if(pmsg->channel == I2C_CH2)
|
||||
if(ch == I2C_CH2)
|
||||
channel = ICE_SEL_I2C_CH2;
|
||||
else if(pmsg->channel == I2C_CH3)
|
||||
else if(ch == I2C_CH3)
|
||||
channel = ICE_SEL_I2C_CH3;
|
||||
else
|
||||
{
|
||||
printk("Error:try to read form error i2c channel\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//printk("len = %d chan = %d read=%d,reg=%d\n",pmsg->len,ch,pmsg->read_type,pmsg->reg_type);
|
||||
|
||||
if(pmsg->read_type == 0)
|
||||
if(pmsg->read_type == I2C_NORMAL)
|
||||
{
|
||||
//slaveaddr ;
|
||||
slaveaddr = slaveaddr<<1;
|
||||
|
|
@ -137,19 +137,30 @@ int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg)
|
|||
//speed;
|
||||
reg = channel |ICE_SEL_I2C_SPEED|ICE_SEL_I2C_TRANS;
|
||||
spi_out(port,reg,speed,SEL_I2C);
|
||||
//len;
|
||||
//len;&&data
|
||||
reg = channel |ICE_SEL_I2C_FIFO |ICE_SEL_I2C_TRANS;
|
||||
spi_out(port,reg,len,SEL_I2C);
|
||||
reg = channel |ICE_SEL_I2C_TRANS;
|
||||
//data;
|
||||
for(i = 0 ;i < len;i++)
|
||||
if(pmsg->reg_type == I2C_8_BIT)
|
||||
{
|
||||
spi_out(port,reg,1,SEL_I2C);
|
||||
reg = channel |ICE_SEL_I2C_TRANS;
|
||||
spi_out(port,reg,pmsg->buf[0],SEL_I2C);
|
||||
}
|
||||
else if(pmsg->reg_type == I2C_16_BIT)
|
||||
{
|
||||
if(i == len-1)
|
||||
reg = channel |ICE_SEL_I2C_STOP;
|
||||
spi_out(port,reg,pmsg->buf[i],SEL_I2C);
|
||||
}
|
||||
|
||||
spi_out(port,reg,2,SEL_I2C);
|
||||
reg = channel |ICE_SEL_I2C_TRANS;
|
||||
spi_out(port,reg,pmsg->buf[0],SEL_I2C);
|
||||
spi_out(port,reg,pmsg->buf[1],SEL_I2C);
|
||||
}
|
||||
}
|
||||
|
||||
//handle irq after send stop cmd
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//slaveaddr
|
||||
slaveaddr = slaveaddr|ICE_I2C_SLAVE_READ;
|
||||
if(pmsg->read_type == 0)
|
||||
|
|
@ -161,30 +172,30 @@ int spi_i2c_readbuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg)
|
|||
reg = channel |ICE_SEL_I2C_SPEED|ICE_SEL_I2C_TRANS;
|
||||
spi_out(port,reg,speed,SEL_I2C);
|
||||
//len;
|
||||
reg = channel |ICE_SEL_I2C_FIFO |ICE_SEL_I2C_TRANS;
|
||||
reg = channel |ICE_SEL_I2C_FIFO |ICE_SEL_I2C_STOP;
|
||||
spi_out(port,reg,len,SEL_I2C);
|
||||
|
||||
i=50;
|
||||
while(i--)
|
||||
{
|
||||
if(port->i2c.interrupt == INT_I2C_READ_ACK)
|
||||
msleep(100);
|
||||
if(port->i2c.interrupt == INT_I2C_READ_ACK)
|
||||
{
|
||||
//printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
for(i = 0;i<len;i++)
|
||||
{
|
||||
result = spi_in(port,reg,SEL_I2C);
|
||||
pmsg->buf[i] = result & 0xFF;
|
||||
result = spi_in(port,channel,SEL_I2C);
|
||||
pmsg->buf[i] = 0;
|
||||
pmsg->buf[i] = result & 0xff ;
|
||||
}
|
||||
spin_lock(&port->i2c.i2c_lock);
|
||||
port->i2c.interrupt &= INT_I2C_READ_MASK;
|
||||
spin_unlock(&port->i2c.i2c_lock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(i = 0;i<len;i++)
|
||||
DBG("pmsg->buf[%d] = 0x%x \n",i,pmsg->buf[i]);
|
||||
}
|
||||
//for(i = 0;i<len;i++)
|
||||
//printk("pmsg->buf[%d] = 0x%x \n",i,pmsg->buf[i]);
|
||||
return pmsg->len;
|
||||
|
||||
}
|
||||
int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg)
|
||||
|
||||
int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg,int ch)
|
||||
{
|
||||
|
||||
unsigned int reg ;
|
||||
|
|
@ -197,16 +208,16 @@ int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg)
|
|||
len = pmsg->len;
|
||||
speed = spi_i2c_select_speed(pmsg->scl_rate);
|
||||
|
||||
if(pmsg->channel == I2C_CH2)
|
||||
if(ch == I2C_CH2)
|
||||
channel = ICE_SEL_I2C_CH2;
|
||||
else if(pmsg->channel == I2C_CH3)
|
||||
else if(ch == I2C_CH3)
|
||||
channel = ICE_SEL_I2C_CH3;
|
||||
else
|
||||
{
|
||||
printk("Error: try to write the error i2c channel\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DBG("len = %d ch = %d\n",pmsg->len,ch);
|
||||
//slaveaddr ;
|
||||
slaveaddr = slaveaddr<<1;
|
||||
reg = channel |ICE_SEL_I2C_START;
|
||||
|
|
@ -225,24 +236,27 @@ int spi_i2c_writebuf(struct spi_fpga_port *port ,struct i2c_msg *pmsg)
|
|||
reg = channel|ICE_SEL_I2C_STOP;
|
||||
spi_out(port,reg,pmsg->buf[i],SEL_I2C);
|
||||
}
|
||||
|
||||
msleep(25);
|
||||
i = 50;
|
||||
while(i--)
|
||||
{
|
||||
if(port->i2c.interrupt == INT_I2C_WRITE_ACK)
|
||||
{
|
||||
//printk("wait num= %d,port->i2c.interrupt = 0x%x\n",i,port->i2c.interrupt);
|
||||
spin_lock(&port->i2c.i2c_lock);
|
||||
port->i2c.interrupt &= INT_I2C_WRITE_MASK;
|
||||
spin_unlock(&port->i2c.i2c_lock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
DBG("wait num= %d,port->i2c.interrupt = 0x%x\n",i,port->i2c.interrupt);
|
||||
|
||||
return pmsg->len;
|
||||
|
||||
|
||||
}
|
||||
#if defined(CONFIG_SPI_I2C_DEBUG)
|
||||
|
||||
|
||||
#if SPI_I2C_TEST
|
||||
unsigned short rda5400[][2] =
|
||||
{
|
||||
{0x3f,0x0000},//page 0
|
||||
|
|
@ -288,18 +302,22 @@ int spi_i2c_16bit_test(struct spi_fpga_port *port)
|
|||
int i ;
|
||||
struct i2c_msg msg[1] =
|
||||
{
|
||||
{0x16,0,len+2,i2c_buf,200,3,0}
|
||||
{0x16,0,len+2,i2c_buf,200,0,0}
|
||||
};
|
||||
|
||||
for(i = 0;i < (sizeof(rda5400)/sizeof(rda5400[0]));i++)
|
||||
{
|
||||
i2c_buf[0] = 0x22;
|
||||
i2c_buf[1] = rda5400[i][0];
|
||||
i2c_buf[1] = rda5400[i][1]>>8;
|
||||
i2c_buf[2] = rda5400[i][1]&0xFF;
|
||||
spi_i2c_writebuf(port, msg);
|
||||
i2c_buf[2] = rda5400[i][1]>>8;
|
||||
i2c_buf[3] = rda5400[i][1]&0xFF;
|
||||
printk("i = %d\n",i);
|
||||
spi_i2c_writebuf(port, msg,3);
|
||||
msg[0].len = 2;
|
||||
spi_i2c_readbuf(port, msg);
|
||||
|
||||
spi_i2c_readbuf(port, msg,3);
|
||||
if(msg->buf[0] != i2c_buf[2] ||msg->buf[1] != i2c_buf[3] )
|
||||
printk("i=%d,msg[0]=%d,msg[1]=%d\n",i,msg->buf[0],msg->buf[1]);
|
||||
}
|
||||
return 0;
|
||||
|
||||
|
|
@ -312,48 +330,110 @@ int spi_i2c_8bit_test(struct spi_fpga_port *port)
|
|||
int i ;
|
||||
struct i2c_msg msg[1] =
|
||||
{
|
||||
{0x16,0,len+1,i2c_buf,200,2,0}
|
||||
{0x16,0,len+1,i2c_buf,200,0,0}
|
||||
};
|
||||
|
||||
for(i = 0;i < (sizeof(rda5400)/sizeof(rda5400[0]));i++)
|
||||
{
|
||||
printk("i=%d\n",i);
|
||||
msg[0].len = 3;
|
||||
i2c_buf[0] = rda5400[i][0];
|
||||
i2c_buf[1] = rda5400[i][1]>>8;
|
||||
i2c_buf[2] = rda5400[i][1]&0xFF;
|
||||
spi_i2c_writebuf(port, msg);
|
||||
msg[0].len = 1;
|
||||
spi_i2c_readbuf(port, msg);
|
||||
spi_i2c_writebuf(port, msg,3);
|
||||
msg[0].len = 2;
|
||||
i2c_buf[1] = 0;
|
||||
i2c_buf[2] = 0;
|
||||
spi_i2c_readbuf(port, msg,3);
|
||||
if(msg->buf[0] != (rda5400[i][1]>>8) ||msg->buf[1] != (rda5400[i][1]&0xff) )
|
||||
printk("i=%d,msg[0]=0x%x,msg[1]=0x%x\n",i,msg->buf[0],msg->buf[1]);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
int spi_i2c_test(void )
|
||||
|
||||
int spi_i2c_test(void)
|
||||
{
|
||||
struct spi_fpga_port *port = pFpgaPort;
|
||||
printk("IN::************spi_i2c_test********\r\n");
|
||||
spi_i2c_8bit_test(port);
|
||||
spi_i2c_16bit_test(port);
|
||||
|
||||
printk("OUT::************spi_i2c_test********\r\n");
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
//EXPORT_SYMBOL(spi_i2c_test);
|
||||
void spi_i2c_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct spi_fpga_port *port =
|
||||
container_of(work, struct spi_fpga_port, i2c.spi_i2c_work);
|
||||
|
||||
printk("*************test spi_i2c now***************\n");
|
||||
spi_i2c_8bit_test(port);
|
||||
|
||||
}
|
||||
|
||||
static void spi_testi2c_timer(unsigned long data)
|
||||
{
|
||||
struct spi_fpga_port *port = (struct spi_fpga_port *)data;
|
||||
port->i2c.i2c_timer.expires = jiffies + msecs_to_jiffies(2000);
|
||||
add_timer(&port->i2c.i2c_timer);
|
||||
queue_work(port->i2c.spi_i2c_workqueue, &port->i2c.spi_i2c_work);
|
||||
}
|
||||
#define BT_RST_PIN SPI_GPIO_P1_07
|
||||
#define BT_PWR_PIN SPI_GPIO_P1_06
|
||||
int spi_i2c_set_bt_power(void)
|
||||
{
|
||||
#if 1
|
||||
|
||||
spi_gpio_set_pinlevel(BT_RST_PIN, SPI_GPIO_HIGH);
|
||||
spi_gpio_set_pindirection(BT_RST_PIN, SPI_GPIO_OUT);
|
||||
spi_gpio_set_pinlevel(BT_PWR_PIN, SPI_GPIO_HIGH);
|
||||
spi_gpio_set_pindirection(BT_PWR_PIN, SPI_GPIO_OUT);
|
||||
|
||||
#else
|
||||
spi_gpio_set_pinlevel(BT_PWR_PIN, SPI_GPIO_LOW);
|
||||
spi_gpio_set_pindirection(BT_PWR_PIN, SPI_GPIO_OUT);
|
||||
mdelay(2);
|
||||
spi_gpio_set_pinlevel(BT_PWR_PIN, SPI_GPIO_HIGH);
|
||||
spi_gpio_set_pindirection(BT_PWR_PIN, SPI_GPIO_OUT);
|
||||
|
||||
mdelay(2);
|
||||
spi_gpio_set_pinlevel(BT_RST_PIN, SPI_GPIO_LOW);
|
||||
spi_gpio_set_pindirection(BT_RST_PIN, SPI_GPIO_OUT);
|
||||
mdelay(20);
|
||||
/*等待10ms以上,等待26M XTAL稳定,然后拉高RESETN*/
|
||||
spi_gpio_set_pinlevel(BT_RST_PIN, SPI_GPIO_HIGH);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
int spi_i2c_register(struct spi_fpga_port *port,int num)
|
||||
{
|
||||
|
||||
spin_lock_init(&port->i2c.i2c_lock);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int spi_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *pmsg, int num)
|
||||
int spi_i2c_unregister(struct spi_fpga_port *port)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spi_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *pmsg, int num)
|
||||
{
|
||||
//struct spi_fpga_port *port1 = pFpgaPort;
|
||||
struct spi_fpga_port *port = adapter->algo_data;
|
||||
|
||||
struct spi_fpga_port *port = pFpgaPort;
|
||||
|
||||
printk("%s:line=%d,channel = %d\n",__FUNCTION__,__LINE__,adapter->nr);
|
||||
DBG("%s:line=%d,channel = %d\n",__FUNCTION__,__LINE__,adapter->nr);
|
||||
if(pmsg->len > MAXMSGLEN)
|
||||
return 0;
|
||||
if(adapter->nr != I2C_CH2 && adapter->nr != I2C_CH3)
|
||||
return 0;
|
||||
if(pmsg->flags)
|
||||
spi_i2c_readbuf(port,pmsg);
|
||||
spi_i2c_readbuf(port,pmsg,adapter->nr);
|
||||
//spi_i2c_readbuf(port,pmsg,adapter->nr,num);
|
||||
else
|
||||
spi_i2c_writebuf(port,pmsg);
|
||||
spi_i2c_writebuf(port,pmsg,adapter->nr);
|
||||
|
||||
return pmsg->len;
|
||||
|
||||
|
|
@ -369,74 +449,59 @@ static const struct i2c_algorithm spi_i2c_algorithm = {
|
|||
.master_xfer = spi_i2c_xfer,
|
||||
.functionality = spi_i2c_func,
|
||||
};
|
||||
|
||||
static int spi_i2c_probe(struct platform_device *pdev)
|
||||
#if 1
|
||||
int spi_i2c_register(struct spi_fpga_port *port,int num)
|
||||
{
|
||||
int ret;
|
||||
struct spi_i2c_data *i2c;
|
||||
struct rk2818_i2c_platform_data *pdata;
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
pdata = pdev->dev.platform_data;
|
||||
if(!pdata)
|
||||
struct i2c_adapter *adapter;
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
//spi_i2c_add_bus(port);
|
||||
adapter = kzalloc(sizeof(struct i2c_adapter),GFP_KERNEL);
|
||||
if(adapter == NULL)
|
||||
return -ENOMEM;
|
||||
sprintf(adapter->name,"spi_i2c");
|
||||
adapter->algo = &spi_i2c_algorithm;
|
||||
adapter->class = I2C_CLASS_HWMON;
|
||||
adapter->nr = num;
|
||||
adapter->algo_data = port;
|
||||
ret = i2c_add_numbered_adapter(adapter);
|
||||
if(ret)
|
||||
{
|
||||
dev_err(&pdev->dev,"no platform data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
i2c = kzalloc(sizeof(struct spi_i2c_data),GFP_KERNEL);
|
||||
if(!i2c)
|
||||
{
|
||||
dev_err(&pdev->dev,"no memory for state\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
strlcpy(i2c->adapter.name,DRV_NAME,sizeof(i2c->adapter.name));
|
||||
i2c->adapter.owner = THIS_MODULE;
|
||||
i2c->adapter.algo = &spi_i2c_algorithm;
|
||||
i2c->adapter.class = I2C_CLASS_HWMON;
|
||||
|
||||
i2c->dev = &pdev->dev;
|
||||
i2c->adapter.algo_data = i2c;
|
||||
i2c->adapter.dev.parent = &pdev->dev;
|
||||
i2c->adapter.nr = pdata->bus_num;
|
||||
ret = i2c_add_numbered_adapter(&i2c->adapter);
|
||||
if(ret < 0){
|
||||
dev_err(&pdev->dev,"fail to add bus to i2c core fpga\n");
|
||||
kfree(i2c);
|
||||
printk(KERN_INFO "SPI2I2C: Failed to add bus\n");
|
||||
kfree(adapter);
|
||||
|
||||
return ret;
|
||||
}
|
||||
platform_set_drvdata(pdev,i2c);
|
||||
printk("Enter::%s,LINE=%d i2c->adap.nr = %d ************************\n",__FUNCTION__,__LINE__,i2c->adapter.nr);
|
||||
#if defined(CONFIG_SPI_I2C_DEBUG)
|
||||
|
||||
#if SPI_I2C_TEST
|
||||
char b[20];
|
||||
if(num != 3)
|
||||
return 0;
|
||||
sprintf(b, "spi_i2c_workqueue");
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
port->i2c.spi_i2c_workqueue = create_freezeable_workqueue(b);
|
||||
if (!port->i2c.spi_i2c_workqueue) {
|
||||
printk("cannot create workqueue\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
INIT_WORK(&port->i2c.spi_i2c_work, spi_i2c_work_handler);
|
||||
|
||||
setup_timer(&port->i2c.i2c_timer, spi_testi2c_timer, (unsigned long)port);
|
||||
port->i2c.i2c_timer.expires = jiffies+2000;//>1000ms
|
||||
add_timer(&port->i2c.i2c_timer);
|
||||
printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_i2c_remove(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static struct platform_driver spi_i2c_driver = {
|
||||
.probe = spi_i2c_probe,
|
||||
.remove = spi_i2c_remove,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = DRV_NAME,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init spi_i2c_adap_init(void)
|
||||
{
|
||||
printk(" *************Enter::%s,LINE=%d ************\n",__FUNCTION__,__LINE__);
|
||||
return platform_driver_register(&spi_i2c_driver);
|
||||
}
|
||||
static void __exit spi_i2c_adap_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&spi_i2c_driver);
|
||||
}
|
||||
|
||||
subsys_initcall(spi_i2c_adap_init);
|
||||
module_exit(spi_i2c_adap_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Driver for spi2i2c.");
|
||||
MODULE_AUTHOR("swj <swj@rock-chips.com>");
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
#include <linux/i2c.h>
|
||||
#include <mach/rk2818_iomap.h>
|
||||
|
||||
#include "spi_fpga.h"
|
||||
#include <mach/spi_fpga.h>
|
||||
|
||||
#if defined(CONFIG_SPI_UART_DEBUG)
|
||||
#define DBG(x...) printk(x)
|
||||
|
|
@ -37,6 +37,9 @@
|
|||
|
||||
#define SPI_UART_TEST 0
|
||||
|
||||
#define SPI_UART_FIFO_LEN 32
|
||||
#define SPI_UART_TXRX_BUF 0 //send or recieve several bytes one time
|
||||
|
||||
static struct tty_driver *spi_uart_tty_driver;
|
||||
/*------------------------ÒÔÏÂÊÇspi2uart±äÁ¿-----------------------*/
|
||||
|
||||
|
|
@ -60,6 +63,41 @@ static struct tty_driver *spi_uart_tty_driver;
|
|||
static struct spi_uart *spi_uart_table[UART_NR];
|
||||
static DEFINE_SPINLOCK(spi_uart_table_lock);
|
||||
|
||||
#if SPI_UART_TXRX_BUF
|
||||
static int spi_uart_write_buf(struct spi_uart *uart, unsigned char *buf, int len)
|
||||
{
|
||||
struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
int index = port->uart.index;
|
||||
int reg = 0;
|
||||
unsigned char tx_buf[SPI_UART_TXRX_BUF+2];//uart's tx fifo max lenth + 1
|
||||
|
||||
reg = ((((reg) | ICE_SEL_UART) & ICE_SEL_WRITE) | ICE_SEL_UART_CH(index));
|
||||
tx_buf[0] = reg & 0xff;
|
||||
tx_buf[1] = 0;
|
||||
memcpy(tx_buf+2, buf, len);
|
||||
spi_write(port->spi, (const u8 *)&tx_buf, len+2);
|
||||
DBG("%s,buf=0x%x,len=0x%x\n",__FUNCTION__,reg&0xff,(int)tx_buf,len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int spi_uart_read_buf(struct spi_uart *uart, unsigned char *buf, int len)
|
||||
{
|
||||
struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
int index = port->uart.index;
|
||||
int reg = 0,stat = 0;
|
||||
unsigned char tx_buf[1],rx_buf[SPI_UART_FIFO_LEN+1];
|
||||
|
||||
reg = (((reg) | ICE_SEL_UART) | ICE_SEL_READ | ICE_SEL_UART_CH(index));
|
||||
tx_buf[0] = reg & 0xff;
|
||||
//give fpga 8 clks for reading data
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, 1, rx_buf, len+1);
|
||||
memcpy(buf, rx_buf+1, len);
|
||||
DBG("%s,buf=0x%x,len=0x%x\n",__FUNCTION__,reg&0xff,(int)buf,len);
|
||||
return stat;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int spi_uart_add_port(struct spi_uart *uart)
|
||||
{
|
||||
|
|
@ -359,9 +397,38 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status)
|
|||
{
|
||||
struct tty_struct *tty = uart->tty;
|
||||
struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
|
||||
unsigned int ch, flag;
|
||||
int max_count = 1024;
|
||||
int max_count = 1024;
|
||||
|
||||
#if SPI_UART_TXRX_BUF
|
||||
int ret,count,stat = 0,num = 0;
|
||||
unsigned char buf[SPI_UART_FIFO_LEN];
|
||||
max_count = 512;
|
||||
while (max_count >0 )
|
||||
{
|
||||
ret = spi_in(port, UART_RX, SEL_UART);
|
||||
count = (ret >> 8) & 0xff;
|
||||
if(count == 0)
|
||||
break;
|
||||
buf[0] = ret & 0xff;
|
||||
if(count > 1)
|
||||
{
|
||||
stat = spi_uart_read_buf(uart,buf+1,count-1);
|
||||
if(stat)
|
||||
printk("err:%s:stat=%d,fail to read uart data because of spi bus error!\n",__FUNCTION__,stat);
|
||||
}
|
||||
max_count -= count;
|
||||
while (count-- >0 )
|
||||
{
|
||||
flag = TTY_NORMAL;
|
||||
ch = buf[num++];
|
||||
tty_insert_flip_char(tty, ch, flag);
|
||||
}
|
||||
|
||||
tty_flip_buffer_push(tty);
|
||||
}
|
||||
printk("r%d\n",1024-max_count);
|
||||
#else
|
||||
//printk("rx:");
|
||||
while (--max_count >0 )
|
||||
{
|
||||
|
|
@ -370,7 +437,6 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status)
|
|||
flag = TTY_NORMAL;
|
||||
uart->icount.rx++;
|
||||
//--max_count;
|
||||
#if 1
|
||||
if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE |
|
||||
UART_LSR_FE | UART_LSR_OE))) {
|
||||
/*
|
||||
|
|
@ -397,7 +463,7 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status)
|
|||
else if (*status & UART_LSR_FE)
|
||||
flag = TTY_FRAME;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((*status & uart->ignore_status_mask & ~UART_LSR_OE) == 0)
|
||||
tty_insert_flip_char(tty, ch, flag);
|
||||
|
||||
|
|
@ -415,6 +481,8 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status)
|
|||
DBG("Enter::%s,LINE=%d,rx_count=%d********\n",__FUNCTION__,__LINE__,(1024-max_count));
|
||||
printk("r%d\n",1024-max_count);
|
||||
tty_flip_buffer_push(tty);
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -422,6 +490,9 @@ static void spi_uart_transmit_chars(struct spi_uart *uart)
|
|||
{
|
||||
struct circ_buf *xmit = &uart->xmit;
|
||||
int count;
|
||||
#if SPI_UART_TXRX_BUF
|
||||
unsigned char buf[SPI_UART_FIFO_LEN];
|
||||
#endif
|
||||
struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
|
||||
if (uart->x_char) {
|
||||
|
|
@ -438,7 +509,23 @@ static void spi_uart_transmit_chars(struct spi_uart *uart)
|
|||
return;
|
||||
}
|
||||
//printk("tx:");
|
||||
count = 32;//
|
||||
|
||||
#if SPI_UART_TXRX_BUF
|
||||
//send several bytes one time
|
||||
count = 0;
|
||||
while(count < SPI_UART_FIFO_LEN)
|
||||
{
|
||||
buf[count] = xmit->buf[xmit->tail];
|
||||
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||
uart->icount.tx++;
|
||||
count++;
|
||||
if (circ_empty(xmit))
|
||||
break;
|
||||
}
|
||||
spi_uart_write_buf(uart,buf,count);
|
||||
#else
|
||||
//send one byte one time
|
||||
count = SPI_UART_FIFO_LEN;//
|
||||
while(count > 0)
|
||||
{
|
||||
spi_out(port, UART_TX, xmit->buf[xmit->tail], SEL_UART);
|
||||
|
|
@ -449,7 +536,7 @@ static void spi_uart_transmit_chars(struct spi_uart *uart)
|
|||
if (circ_empty(xmit))
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
//printk("\n");
|
||||
DBG("Enter::%s,LINE=%d,tx_count=%d\n",__FUNCTION__,__LINE__,(32-count));
|
||||
if (circ_chars_pending(xmit) < WAKEUP_CHARS)
|
||||
|
|
@ -515,41 +602,61 @@ static void spi_uart_check_modem_status(struct spi_uart *uart)
|
|||
#if SPI_UART_TEST
|
||||
#define UART_TEST_LEN 16 //8bit
|
||||
unsigned char buf_test_uart[UART_TEST_LEN];
|
||||
unsigned int ice65l08_init_para[]=
|
||||
|
||||
void spi_uart_test_init(struct spi_fpga_port *port)
|
||||
{
|
||||
0x030083,
|
||||
0x010000,
|
||||
0x000034, // (0100XYH) 设置分频系数:XY = MCLK / (4*波特率);
|
||||
0x030003, // 设置字节有效长度: 8 bits;
|
||||
0x01000f, // TX RX 中断
|
||||
0x020080, // 设置触发等级 接受FIFO为 16bytes 产生中断;
|
||||
};
|
||||
unsigned char cval, fcr = 0;
|
||||
unsigned int baud, quot;
|
||||
unsigned char mcr = 0;
|
||||
int ret;
|
||||
|
||||
DBG("Enter::%s,LINE=%d,mcr=0x%x\n",__FUNCTION__,__LINE__,mcr);
|
||||
spi_out(port, UART_MCR, mcr, SEL_UART);
|
||||
baud = 1500000;
|
||||
cval = UART_LCR_WLEN8;
|
||||
fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10;
|
||||
quot = 6000000 / baud;
|
||||
mcr |= UART_MCR_RTS;
|
||||
mcr |= UART_MCR_AFE;
|
||||
|
||||
spi_out(port, UART_FCR, UART_FCR_ENABLE_FIFO, SEL_UART);
|
||||
spi_out(port, UART_FCR, UART_FCR_ENABLE_FIFO |
|
||||
UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, SEL_UART);
|
||||
spi_out(port, UART_FCR, 0, SEL_UART);
|
||||
spi_out(port, UART_LCR, UART_LCR_WLEN8, SEL_UART);
|
||||
spi_out(port, UART_LCR, cval | UART_LCR_DLAB, SEL_UART);
|
||||
spi_out(port, UART_DLL, quot & 0xff, SEL_UART);
|
||||
ret = spi_in(port, UART_DLL, SEL_UART)&0xff;
|
||||
printk("%s:quot=0x%x,UART_DLL=0x%x\n",__FUNCTION__,quot,ret);
|
||||
spi_out(port, UART_DLM, quot >> 8, SEL_UART);
|
||||
spi_out(port, UART_LCR, cval, SEL_UART);
|
||||
spi_out(port, UART_FCR, fcr, SEL_UART);
|
||||
spi_out(port, UART_MCR, mcr, SEL_UART);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void spi_uart_work_handler(struct work_struct *work)
|
||||
{
|
||||
int i;
|
||||
int ret,count;
|
||||
int offset,value;
|
||||
int count;
|
||||
struct spi_fpga_port *port =
|
||||
container_of(work, struct spi_fpga_port, uart.spi_uart_work);
|
||||
printk("*************test spi_uart now***************\n");
|
||||
|
||||
spi_uart_test_init(port);
|
||||
for(i=0;i<UART_TEST_LEN;i++)
|
||||
buf_test_uart[i] = '0'+i;
|
||||
|
||||
for(i =0; i<sizeof(ice65l08_init_para)/sizeof(ice65l08_init_para[0]); i++)
|
||||
{
|
||||
offset = (ice65l08_init_para[i] >> 16) & 0xff;
|
||||
value = ice65l08_init_para[i] & 0xffff;
|
||||
spi_out(port, offset, value, SEL_UART);
|
||||
}
|
||||
|
||||
buf_test_uart[i] = '0'+i;
|
||||
count = UART_TEST_LEN;
|
||||
#if SPI_UART_TXRX_BUF
|
||||
spi_uart_write_buf(&port->uart, buf_test_uart, count);
|
||||
#else
|
||||
while(count > 0)
|
||||
{
|
||||
spi_out(port, UART_TX, buf_test_uart[UART_TEST_LEN-count], SEL_UART);
|
||||
--count;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void spi_testuart_timer(unsigned long data)
|
||||
|
|
|
|||
|
|
@ -514,6 +514,7 @@ struct i2c_msg {
|
|||
__u32 scl_rate;
|
||||
__u16 channel;
|
||||
__u16 read_type;
|
||||
__u16 reg_type;
|
||||
};
|
||||
|
||||
/* To determine what functionality is present */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user