fpga driver update

This commit is contained in:
root 2010-07-26 16:46:48 +08:00
parent 572cdaccf7
commit 6ccd5e75a3
12 changed files with 761 additions and 452 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -514,6 +514,7 @@ struct i2c_msg {
__u32 scl_rate;
__u16 channel;
__u16 read_type;
__u16 reg_type;
};
/* To determine what functionality is present */