mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
modify spi_dpram: success to commicate with BP,and improve spi_uart
This commit is contained in:
@@ -9,9 +9,9 @@ defines of FPGA chip ICE65L08's register
|
||||
#include <linux/miscdevice.h>
|
||||
|
||||
#define SPI_FPGA_INT_PIN RK2818_PIN_PA4
|
||||
#define SPI_DPRAM_BUSY_PIN RK2818_PIN_PA2
|
||||
#define SPI_DPRAM_INT_PIN RK2818_PIN_PA2
|
||||
#define SPI_FPGA_STANDBY_PIN RK2818_PIN_PH7
|
||||
#define SPI_FPGA_RST_PIN RK2818_PIN_PH6
|
||||
#define SPI_FPGA_RST_PIN RK2818_PIN_PF4
|
||||
|
||||
#define SPI_FPGA_TEST_DEBUG 0
|
||||
#if SPI_FPGA_TEST_DEBUG
|
||||
@@ -95,8 +95,8 @@ struct spi_dpram
|
||||
{
|
||||
struct workqueue_struct *spi_dpram_workqueue;
|
||||
struct work_struct spi_dpram_work;
|
||||
struct workqueue_struct *spi_dpram_busy_workqueue;
|
||||
struct work_struct spi_dpram_busy_work;
|
||||
struct workqueue_struct *spi_dpram_irq_workqueue;
|
||||
struct work_struct spi_dpram_irq_work;
|
||||
struct timer_list dpram_timer;
|
||||
unsigned char *prx;
|
||||
unsigned char *ptx;
|
||||
@@ -115,14 +115,17 @@ struct spi_dpram
|
||||
int (*read_dpram)(struct spi_dpram *, unsigned short int addr, unsigned char *buf, unsigned int len);
|
||||
int (*write_ptr)(struct spi_dpram *, unsigned short int addr, unsigned int size);
|
||||
int (*read_ptr)(struct spi_dpram *, unsigned short int addr);
|
||||
int (*write_mailbox)(struct spi_dpram *, unsigned int mailbox);
|
||||
int (*read_mailbox)(struct spi_dpram *);
|
||||
int (*write_irq)(struct spi_dpram *, unsigned int mailbox);
|
||||
int (*read_irq)(struct spi_dpram *);
|
||||
int (*write_ack)(struct spi_dpram *, unsigned int mailbox);
|
||||
int (*read_ack)(struct spi_dpram *);
|
||||
|
||||
};
|
||||
|
||||
struct spi_fpga_port {
|
||||
const char *name;
|
||||
struct spi_device *spi;
|
||||
spinlock_t work_lock;
|
||||
struct mutex spi_lock;
|
||||
struct workqueue_struct *fpga_irq_workqueue;
|
||||
struct work_struct fpga_irq_work;
|
||||
@@ -518,7 +521,7 @@ 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_FPGA_DPRAM)
|
||||
extern int spi_dpram_handle_irq(struct spi_device *spi);
|
||||
extern int spi_dpram_handle_ack(struct spi_device *spi);
|
||||
extern int spi_dpram_register(struct spi_fpga_port *port);
|
||||
extern int spi_dpram_unregister(struct spi_fpga_port *port);
|
||||
#endif
|
||||
|
||||
513
drivers/fpga/spi_dpram.c
Normal file → Executable file
513
drivers/fpga/spi_dpram.c
Normal file → Executable file
@@ -36,6 +36,7 @@
|
||||
#endif
|
||||
|
||||
#define SPI_DPRAM_TEST 0
|
||||
|
||||
/*****RAM0 for bp write and ap read*****/
|
||||
#define SPI_DPRAM_BPWRITE_START 0
|
||||
#define SPI_DPRAM_BPWRITE_END 0x0fff
|
||||
@@ -53,23 +54,6 @@
|
||||
#define SPI_DPRAM_LOG_APWRITE_END 0x33ff
|
||||
#define SPI_DPRAM_LOG_APWRITE_SIZE 0x0400 // 1K*16bits
|
||||
|
||||
/*
|
||||
#define BP_SEND_IN_PTR 0x3FEE
|
||||
#define BP_SEND_OUT_PTR 0x3FF0
|
||||
|
||||
#define BP_READ_IN_PTR 0x3FF2
|
||||
#define BP_READ_OUT_PTR 0x3FF4
|
||||
|
||||
#define BP_SEND_IN_PTR 0x3FF6
|
||||
#define BP_SEND_OUT_PTR 0x3FF8
|
||||
|
||||
#define BP_READ_IN_PTR 0x3FFA
|
||||
#define BP_READ_OUT_PTR 0x3FFC
|
||||
|
||||
#define BP_SEND_AP_Mailbox<6F><78>0x3ffe
|
||||
#define AP_SEND_BP_Mailbox<6F><78>0x3fff
|
||||
|
||||
*/
|
||||
|
||||
#define SPI_DPRAM_PTR0_BPWRITE_APREAD 0X3fee
|
||||
#define SPI_DPRAM_PTR0_APWRITE_BPREAD 0X3ff0
|
||||
@@ -83,15 +67,25 @@
|
||||
#define SPI_DPRAM_PTR3_BPWRITE_APREAD 0x3ffa
|
||||
#define SPI_DPRAM_PTR3_APWRITE_BPREAD 0x3ffc
|
||||
|
||||
#define SPI_DPRAM_MAILBOX_BPWRITE 0x3ffe
|
||||
#define SPI_DPRAM_MAILBOX_APWRITE 0x3fff
|
||||
#define SPI_DPRAM_MAILBOX_BPIRQ 0x3ffe
|
||||
#define SPI_DPRAM_MAILBOX_APIRQ 0x3fff
|
||||
#define SPI_DPRAM_MAILBOX_BPACK 0x3ffb
|
||||
#define SPI_DPRAM_MAILBOX_APACK 0x3ffd
|
||||
|
||||
/*mailbox comminication's definition*/
|
||||
#define MAILBOX_BPWRITE_DATA 0x01
|
||||
#define MAILBOX_BPREAD_DATA 0x02
|
||||
#define MAILBOX_APSEND_IRQ 0x03
|
||||
#define MAILBOX_APSEND_ACK 0x04
|
||||
#define MAILBOX_BPSEND_IRQ (0<<15)
|
||||
#define MAILBOX_BPSEND_ACK (1<<15)
|
||||
#define MAILBOX_APSEND_IRQ (0<<15)
|
||||
#define MAILBOX_APSEND_ACK (1<<15)
|
||||
#define MAILBOX_RAM0 (0<<13)
|
||||
#define MAILBOX_RAM1 (1<<13)
|
||||
#define MAILBOX_RAM2 (2<<13)
|
||||
#define MAILBOX_RAM3 (3<<13)
|
||||
|
||||
#define PIN_BPSEND_ACK RK2818_PIN_PE0
|
||||
#define PIN_APSEND_ACK RK2818_PIN_PF7
|
||||
|
||||
#define MAX_SPI_LEN 768 //the bytes of spi write or read one time
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
@@ -99,17 +93,51 @@ static int spi_dpram_write_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_WRITE);
|
||||
unsigned char *tx_buf = port->dpram.ptx;
|
||||
int ret;
|
||||
*(port->dpram.ptx) = opt;
|
||||
*(port->dpram.ptx+1) = ((addr << 1) >> 8) & 0xff;
|
||||
*(port->dpram.ptx+2) = ((addr << 1) & 0xff);
|
||||
memcpy((port->dpram.ptx + 3), buf, len);
|
||||
unsigned char tx_buf[MAX_SPI_LEN+3];
|
||||
int i,ret,mod,num,count;
|
||||
|
||||
#if 0
|
||||
unsigned char *p = buf;
|
||||
for(i=0;i<len;i++)
|
||||
{
|
||||
printk("%s:buf[%d]=0x%x\n",__FUNCTION__,i,*p);
|
||||
p++;
|
||||
}
|
||||
#endif
|
||||
|
||||
mod = len%MAX_SPI_LEN;
|
||||
if(!mod)
|
||||
num = len/MAX_SPI_LEN;
|
||||
else
|
||||
num = len/MAX_SPI_LEN + 1;
|
||||
|
||||
for(i=0;i<num;i++)
|
||||
{
|
||||
if(i == num -1)
|
||||
{
|
||||
if(!mod)
|
||||
count = MAX_SPI_LEN;
|
||||
else
|
||||
count = mod;
|
||||
memcpy(tx_buf + 3, buf+i*MAX_SPI_LEN, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = MAX_SPI_LEN;
|
||||
memcpy(tx_buf + 3, buf+i*MAX_SPI_LEN, count);
|
||||
}
|
||||
|
||||
tx_buf[0] = opt;
|
||||
tx_buf[1] = (((addr + i*(MAX_SPI_LEN>>1)) << 1) >> 8) & 0xff;
|
||||
tx_buf[2] = (((addr + i*(MAX_SPI_LEN>>1)) << 1) & 0xff);
|
||||
ret = spi_write(port->spi, tx_buf, count+3);
|
||||
if(ret)
|
||||
{
|
||||
printk("%s:spi_write err! i=%d\n",__FUNCTION__,i);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
DBG("%s:tx_buf=0x%x,port->dpram.ptx=0x%x,opt=0x%x,addr=0x%x,len=%d\n",__FUNCTION__,(int)tx_buf, (int)port->dpram.ptx, opt, addr&0xffff, len);
|
||||
ret = spi_write(port->spi, tx_buf, len+3);
|
||||
if(ret)
|
||||
printk("spi_write err!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -119,25 +147,48 @@ static int spi_dpram_read_buf(struct spi_dpram *dpram, unsigned short int addr,
|
||||
unsigned char opt = ((ICE_SEL_DPRAM & ICE_SEL_DPRAM_NOMAL & ICE_SEL_DPRAM_READ));
|
||||
unsigned char tx_buf[4];
|
||||
unsigned char stat;
|
||||
int i,mod,num,count;
|
||||
|
||||
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)
|
||||
mod = len%MAX_SPI_LEN;
|
||||
if(!mod)
|
||||
num = len/MAX_SPI_LEN;
|
||||
else
|
||||
num = len/MAX_SPI_LEN + 1;
|
||||
|
||||
for(i=0;i<num;i++)
|
||||
{
|
||||
printk("%s:spi_write_then_read is error!,err=%d\n\n",__FUNCTION__,stat);
|
||||
return -1;
|
||||
if(i == num -1)
|
||||
{
|
||||
if(!mod)
|
||||
count = MAX_SPI_LEN;
|
||||
else
|
||||
count = mod;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = MAX_SPI_LEN;
|
||||
}
|
||||
|
||||
tx_buf[0] = opt;
|
||||
tx_buf[1] = (((addr + i*(MAX_SPI_LEN>>1)) << 1) >> 8) & 0xff;
|
||||
tx_buf[2] = (((addr + i*(MAX_SPI_LEN>>1)) << 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 + i*MAX_SPI_LEN, count);
|
||||
if(stat)
|
||||
{
|
||||
printk("%s:spi_write_then_read is error!,err=%d\n\n",__FUNCTION__,stat);
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
DBG("%s:opt=0x%x,addr=0x%x,len=%d\n",__FUNCTION__, opt, addr&0xffff, len);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int spi_dpram_write_ptr(struct spi_dpram *dpram, unsigned short int addr, unsigned int size)
|
||||
int spi_dpram_write_word(struct spi_dpram *dpram, unsigned short int addr, unsigned int size)
|
||||
{
|
||||
int ret;
|
||||
//int i;
|
||||
@@ -168,7 +219,7 @@ int spi_dpram_write_ptr(struct spi_dpram *dpram, unsigned short int addr, unsign
|
||||
}
|
||||
|
||||
|
||||
int spi_dpram_read_ptr(struct spi_dpram *dpram, unsigned short int addr)
|
||||
int spi_dpram_read_word(struct spi_dpram *dpram, unsigned short int addr)
|
||||
{
|
||||
int ret;
|
||||
struct spi_fpga_port *port = container_of(dpram, struct spi_fpga_port, dpram);
|
||||
@@ -193,69 +244,105 @@ int spi_dpram_read_ptr(struct spi_dpram *dpram, unsigned short int addr)
|
||||
|
||||
}
|
||||
|
||||
|
||||
int spi_dpram_write_mailbox(struct spi_dpram *dpram, unsigned int mailbox)
|
||||
int spi_dpram_write_ptr(struct spi_dpram *dpram, unsigned short int addr, unsigned int size)
|
||||
{
|
||||
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_WRITE);
|
||||
unsigned char tx_buf[5];
|
||||
|
||||
tx_buf[0] = opt;
|
||||
tx_buf[1] = ((SPI_DPRAM_MAILBOX_APWRITE << 1) >> 8) & 0xff;
|
||||
tx_buf[2] = ((SPI_DPRAM_MAILBOX_APWRITE << 1) & 0xff);
|
||||
tx_buf[3] = mailbox>>8;
|
||||
tx_buf[4] = mailbox&0xff;
|
||||
|
||||
ret = spi_write(port->spi, tx_buf, sizeof(tx_buf));
|
||||
if(ret)
|
||||
{
|
||||
printk("%s:spi_write err!\n",__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return spi_dpram_write_word(dpram, addr, size);
|
||||
}
|
||||
|
||||
|
||||
int spi_dpram_read_mailbox(struct spi_dpram *dpram)
|
||||
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[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)
|
||||
{
|
||||
printk("%s:spi_write_then_read err!\n",__FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ((rx_buf[0]<<8) | rx_buf[1]);
|
||||
return spi_dpram_read_word(dpram, addr);
|
||||
}
|
||||
|
||||
|
||||
static void spi_dpram_handle_busy(struct spi_device *spi)
|
||||
{
|
||||
|
||||
int spi_dpram_write_irq(struct spi_dpram *dpram, unsigned int mailbox)
|
||||
{
|
||||
return spi_dpram_write_word(dpram, SPI_DPRAM_MAILBOX_APIRQ,mailbox);
|
||||
}
|
||||
|
||||
|
||||
static void spi_dpram_busy_work_handler(struct work_struct *work)
|
||||
int spi_dpram_read_irq(struct spi_dpram *dpram)
|
||||
{
|
||||
return spi_dpram_read_word(dpram, SPI_DPRAM_MAILBOX_BPIRQ);
|
||||
}
|
||||
|
||||
int spi_dpram_write_ack(struct spi_dpram *dpram, unsigned int mailbox)
|
||||
{
|
||||
return spi_dpram_write_word(dpram, SPI_DPRAM_MAILBOX_APACK,mailbox);
|
||||
}
|
||||
|
||||
|
||||
int spi_dpram_read_ack(struct spi_dpram *dpram)
|
||||
{
|
||||
return spi_dpram_read_word(dpram, SPI_DPRAM_MAILBOX_BPACK);
|
||||
}
|
||||
|
||||
int gNumSendInt=0,gLastNumSendInt = 0;
|
||||
int gNumSendAck=0,gLastNumSendAck = 0;
|
||||
int gNumRecInt=0,gNumLastRecInt = 0;
|
||||
int gNumCount = 0;
|
||||
unsigned char buf_dpram[SPI_DPRAM_BPWRITE_SIZE<<1];
|
||||
|
||||
|
||||
//really is spi_dpram_irq_work_handler after dpram's pin is exchanged
|
||||
static void spi_dpram_irq_work_handler(struct work_struct *work)
|
||||
{
|
||||
struct spi_fpga_port *port =
|
||||
container_of(work, struct spi_fpga_port, dpram.spi_dpram_busy_work);
|
||||
spi_dpram_handle_busy(port->spi);
|
||||
container_of(work, struct spi_fpga_port, dpram.spi_dpram_irq_work);
|
||||
|
||||
unsigned short int mbox = port->dpram.read_irq(&port->dpram);
|
||||
unsigned int ptr;
|
||||
unsigned int len;
|
||||
//int i,ret;
|
||||
|
||||
//gNumRecInt = mbox & 0x1fff;
|
||||
//if(gNumRecInt - gNumLastRecInt !=1)
|
||||
//if(++gNumLastRecInt > (1<<12))
|
||||
//gNumLastRecInt = 0;
|
||||
//printk("gNumRecInt=%d,gLastNumInt=%d\n",gNumRecInt,gNumLastRecInt);
|
||||
|
||||
if((mbox&MAILBOX_RAM3) == MAILBOX_RAM0)
|
||||
{
|
||||
//RAM0
|
||||
ptr = port->dpram.read_ptr(&port->dpram,SPI_DPRAM_PTR0_BPWRITE_APREAD);
|
||||
len = ptr;
|
||||
port->dpram.read_dpram(&port->dpram, SPI_DPRAM_BPWRITE_START, port->dpram.prx, len);
|
||||
port->dpram.rec_len += len;
|
||||
printk("%s:ram0:len=%d\n",__FUNCTION__,len);
|
||||
//send ack
|
||||
//if(++gNumSendAck > (1<<12))
|
||||
//gNumSendAck = 0;
|
||||
//port->dpram.write_ack(&port->dpram, (MAILBOX_APSEND_ACK | MAILBOX_RAM0 | gNumSendAck));
|
||||
|
||||
//wake up ap to read data
|
||||
wake_up_interruptible(&port->dpram.recq);
|
||||
|
||||
//printk("%s:r_irq=0x%x,s_ack=0x%x\n",__FUNCTION__,mbox, (MAILBOX_APSEND_ACK | MAILBOX_RAM0 | gNumSendAck));
|
||||
}
|
||||
else if((mbox&MAILBOX_RAM3) == MAILBOX_RAM2)
|
||||
{
|
||||
//RAM2
|
||||
ptr = port->dpram.read_ptr(&port->dpram,SPI_DPRAM_PTR2_BPWRITE_APREAD);
|
||||
len = ptr;
|
||||
port->dpram.read_dpram(&port->dpram, SPI_DPRAM_LOG_BPWRITE_START, port->dpram.prx, len);
|
||||
port->dpram.rec_len += len;
|
||||
printk("%s:ram2:len=%d\n",__FUNCTION__,len);
|
||||
//if(++gNumSendAck > (1<<12))
|
||||
//gNumSendAck = 0;
|
||||
//port->dpram.write_ack(&port->dpram, (MAILBOX_APSEND_ACK | MAILBOX_RAM2 | gNumSendAck));
|
||||
|
||||
//wake up ap to read data
|
||||
wake_up_interruptible(&port->dpram.recq);
|
||||
|
||||
//printk("%s:r_irq=0x%x,s_ack=0x%x\n",__FUNCTION__, mbox, (MAILBOX_APSEND_ACK | MAILBOX_RAM2 | gNumSendAck));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
static irqreturn_t spi_dpram_busy_irq(int irq, void *dev_id)
|
||||
static irqreturn_t spi_dpram_irq(int irq, void *dev_id)
|
||||
{
|
||||
struct spi_fpga_port *port = dev_id;
|
||||
|
||||
@@ -268,35 +355,36 @@ static irqreturn_t spi_dpram_busy_irq(int irq, void *dev_id)
|
||||
* via spi_sync() call.
|
||||
*/
|
||||
|
||||
queue_work(port->dpram.spi_dpram_busy_workqueue, &port->dpram.spi_dpram_busy_work);
|
||||
queue_work(port->dpram.spi_dpram_irq_workqueue, &port->dpram.spi_dpram_irq_work);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
||||
#if SPI_DPRAM_TEST
|
||||
#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];
|
||||
#define SEL_RAM SEL_REG
|
||||
|
||||
void spi_dpram_work_handler(struct work_struct *work)
|
||||
{
|
||||
int i,j;
|
||||
int ret;
|
||||
int i;
|
||||
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<SPI_DPRAM_BPWRITE_SIZE;i++)
|
||||
{
|
||||
buf_dpram[2*i] = (0xa000+i)>>8;
|
||||
buf_dpram[2*i+1] = (0xa000+i)&0xff;
|
||||
}
|
||||
|
||||
#if(SEL_RAM == SEL_RAM0)
|
||||
//RAM0
|
||||
for(i=0;i<(SPI_DPRAM_BPWRITE_SIZE/(DPRAM_TEST_LEN>>1));i++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
port->dpram.read_dpram(&port->dpram, SPI_DPRAM_BPWRITE_START, port->dpram.prx, SPI_DPRAM_BPWRITE_SIZE<<1);
|
||||
for(i=0;i<SPI_DPRAM_BPWRITE_SIZE;i++)
|
||||
{
|
||||
ret = (*(port->dpram.prx+2*i)<<8) | (*(port->dpram.prx+2*i+1));
|
||||
@@ -306,86 +394,66 @@ void spi_dpram_work_handler(struct work_struct *work)
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
port->dpram.write_dpram(&port->dpram, SPI_DPRAM_APWRITE_START, buf_dpram, SPI_DPRAM_APWRITE_SIZE<<1);
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR1_APWRITE_BPREAD, SPI_DPRAM_APWRITE_START);
|
||||
port->dpram.write_irq(&port->dpram, MAILBOX_APSEND_IRQ); //send irq to bp after ap write data to dpram
|
||||
|
||||
#elif(SEL_RAM == SEL_RAM2)
|
||||
//RAM2
|
||||
for(i=0;i<(SPI_DPRAM_LOG_BPWRITE_SIZE/(DPRAM_TEST_LEN>>1));i++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
port->dpram.read_dpram(&port->dpram, SPI_DPRAM_LOG_BPWRITE_START, port->dpram.prx, SPI_DPRAM_LOG_BPWRITE_SIZE<<1);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
#elif(SEL_RAM == SEL_RAM3)
|
||||
//RAM3
|
||||
for(i=0;i<(SPI_DPRAM_LOG_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_LOG_APWRITE_START, buf_test_dpram, sizeof(buf_test_dpram));
|
||||
mdelay(1);
|
||||
}
|
||||
port->dpram.write_dpram(&port->dpram, SPI_DPRAM_LOG_APWRITE_START, buf_dpram, SPI_DPRAM_LOG_APWRITE_SIZE<<1);
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR3_APWRITE_BPREAD, SPI_DPRAM_LOG_APWRITE_START);
|
||||
port->dpram.write_irq(&port->dpram, MAILBOX_APSEND_IRQ); //send irq to bp after ap write data to dpram
|
||||
|
||||
#elif(SEL_RAM == SEL_REG)
|
||||
#if 1
|
||||
if(gNumCount++ == 0)
|
||||
{
|
||||
if(++gNumSendAck > (1<<12))
|
||||
gNumSendAck = 0;
|
||||
port->dpram.write_ack(&port->dpram, MAILBOX_APSEND_ACK | MAILBOX_RAM0 | gNumSendAck);
|
||||
printk("%s:line=%d,s_ack=0x%x\n",__FUNCTION__,__LINE__,MAILBOX_APSEND_ACK | MAILBOX_RAM0 | gNumSendAck);
|
||||
|
||||
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);
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR3_APWRITE_BPREAD, SPI_DPRAM_PTR3_APWRITE_BPREAD);
|
||||
port->dpram.write_mailbox(&port->dpram, SPI_DPRAM_MAILBOX_APWRITE);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
ret = port->dpram.read_mailbox(&port->dpram);
|
||||
if(ret != SPI_DPRAM_MAILBOX_BPWRITE)
|
||||
printk("SPI_DPRAM_MAILBOX_BPWRITE(0x%x)=0x%x\n",SPI_DPRAM_MAILBOX_BPWRITE,ret);
|
||||
|
||||
while(port->dpram.apwrite_en != TRUE);
|
||||
port->dpram.apwrite_en = FALSE;
|
||||
if(++gNumSendInt > (1<<12))
|
||||
gNumSendInt = 0;
|
||||
port->dpram.write_dpram(&port->dpram, SPI_DPRAM_APWRITE_START, buf_dpram, SPI_DPRAM_APWRITE_SIZE<<1);
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR1_APWRITE_BPREAD, SPI_DPRAM_APWRITE_SIZE<<1);
|
||||
port->dpram.write_irq(&port->dpram, MAILBOX_APSEND_IRQ | MAILBOX_RAM1 | gNumSendInt);
|
||||
printk("%s:line=%d,s_irq=0x%x\n",__FUNCTION__,__LINE__,MAILBOX_APSEND_IRQ | MAILBOX_RAM1 | gNumSendInt);
|
||||
|
||||
if(gNumCount > (1<<15))
|
||||
gNumCount = 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
while(port->dpram.apwrite_en != TRUE);
|
||||
port->dpram.apwrite_en == FALSE;
|
||||
if(++gNumSendInt > (1<<12))
|
||||
gNumSendInt = 0;
|
||||
port->dpram.write_dpram(&port->dpram, SPI_DPRAM_LOG_APWRITE_START, buf_dpram, SPI_DPRAM_LOG_APWRITE_SIZE<<1);
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR3_APWRITE_BPREAD, SPI_DPRAM_LOG_APWRITE_SIZE<<1);
|
||||
port->dpram.write_irq(&port->dpram, MAILBOX_APSEND_IRQ | MAILBOX_RAM3 | gNumSendInt);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void spi_testdpram_timer(unsigned long data)
|
||||
{
|
||||
struct spi_fpga_port *port = (struct spi_fpga_port *)data;
|
||||
port->dpram.dpram_timer.expires = jiffies + msecs_to_jiffies(1000);
|
||||
port->dpram.dpram_timer.expires = jiffies + msecs_to_jiffies(500);
|
||||
add_timer(&port->dpram.dpram_timer);
|
||||
//schedule_work(&port->gpio.spi_gpio_work);
|
||||
queue_work(port->dpram.spi_dpram_workqueue, &port->dpram.spi_dpram_work);
|
||||
@@ -393,27 +461,27 @@ static void spi_testdpram_timer(unsigned long data)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int spi_dpram_handle_irq(struct spi_device *spi)
|
||||
//really is spi_dpram_handle_ack after dpram's pin is exchanged
|
||||
int spi_dpram_handle_ack(struct spi_device *spi)
|
||||
{
|
||||
struct spi_fpga_port *port = spi_get_drvdata(spi);
|
||||
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:
|
||||
len = port->dpram.read_ptr(&port->dpram,SPI_DPRAM_PTR0_BPWRITE_APREAD);
|
||||
port->dpram.read_dpram(&port->dpram, SPI_DPRAM_BPWRITE_START, port->dpram.prx, len);
|
||||
port->dpram.rec_len += len;
|
||||
break;
|
||||
case MAILBOX_BPREAD_DATA:
|
||||
port->dpram.apwrite_en = TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//clear ack interrupt
|
||||
port->dpram.read_ack(&port->dpram);
|
||||
|
||||
//allow ap to write and wake ap to write data
|
||||
port->dpram.apwrite_en = TRUE;
|
||||
wake_up_interruptible(&port->dpram.sendq);
|
||||
#if 0
|
||||
//while(port->dpram.apwrite_en != TRUE);
|
||||
port->dpram.apwrite_en = FALSE;
|
||||
if(++gNumSendInt > (1<<12))
|
||||
gNumSendInt = 0;
|
||||
port->dpram.write_dpram(&port->dpram, SPI_DPRAM_APWRITE_START, buf_dpram, SPI_DPRAM_APWRITE_SIZE<<1);
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR1_APWRITE_BPREAD, SPI_DPRAM_APWRITE_SIZE<<1);
|
||||
port->dpram.write_irq(&port->dpram, MAILBOX_APSEND_IRQ | MAILBOX_RAM1 | gNumSendInt);
|
||||
printk("%s:r_ack=0x%x,s_irq=0x%x\n",__FUNCTION__,ack, MAILBOX_APSEND_IRQ | MAILBOX_RAM1 | gNumSendInt);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -421,7 +489,7 @@ static int dpr_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct spi_fpga_port *port = pFpgaPort;
|
||||
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
filp->private_data = port;
|
||||
port->dpram.rec_len = 0;
|
||||
port->dpram.send_len = 0;
|
||||
@@ -434,7 +502,7 @@ 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\n",__FUNCTION__,__LINE__);
|
||||
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
filp->private_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
@@ -444,7 +512,7 @@ static ssize_t dpr_read (struct file *filp, char __user *buffer, size_t count, l
|
||||
{
|
||||
//int ret;
|
||||
struct spi_fpga_port *port = filp->private_data;
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
|
||||
while(port->dpram.rec_len == 0)
|
||||
{
|
||||
@@ -468,6 +536,9 @@ static ssize_t dpr_read (struct file *filp, char __user *buffer, size_t count, l
|
||||
count = port->dpram.rec_len;
|
||||
port->dpram.rec_len = 0;
|
||||
|
||||
//allow bp write ram0 again
|
||||
port->dpram.write_ack(&port->dpram, (MAILBOX_APSEND_ACK | MAILBOX_RAM0));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -475,8 +546,9 @@ static ssize_t dpr_read (struct file *filp, char __user *buffer, size_t count, l
|
||||
static ssize_t dpr_write (struct file *filp, const char __user *buffer, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct spi_fpga_port *port = filp->private_data;
|
||||
//int ret;
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
int mod,num;
|
||||
char i,*p,temp;
|
||||
printk("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
|
||||
while(port->dpram.apwrite_en == FALSE)
|
||||
{
|
||||
@@ -497,10 +569,42 @@ static ssize_t dpr_write (struct file *filp, const char __user *buffer, size_t c
|
||||
printk("%s:copy_from_user err!\n",__FUNCTION__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
port->dpram.write_dpram(&port->dpram, SPI_DPRAM_APWRITE_START, port->dpram.ptx, count);
|
||||
mod = count % 2;
|
||||
num = count;
|
||||
if(mod)
|
||||
{
|
||||
*((char *)port->dpram.ptx + count) = 0;
|
||||
num = count + 1;
|
||||
}
|
||||
|
||||
p=port->dpram.ptx;
|
||||
|
||||
/*swap data to suitable bp:p[0]<->p[1]*/
|
||||
for(i=0;i<(num>>1);i++)
|
||||
{
|
||||
temp = *(p+(i<<1));
|
||||
*(p+(i<<1))= *(p+(i<<1)+1);
|
||||
*(p+(i<<1)+1) = temp;
|
||||
p=p+2;
|
||||
}
|
||||
|
||||
#if 1
|
||||
p=port->dpram.ptx;
|
||||
for(i=0;i<num;i++)
|
||||
{
|
||||
printk("%s:ptx[%d]=0x%x\n",__FUNCTION__,i,*p);
|
||||
p++;
|
||||
}
|
||||
#endif
|
||||
|
||||
port->dpram.write_dpram(&port->dpram, SPI_DPRAM_APWRITE_START, port->dpram.ptx, num);
|
||||
port->dpram.apwrite_en = FALSE; //clear apwrite_en after wirte data to dpram
|
||||
port->dpram.write_mailbox(&port->dpram, MAILBOX_APSEND_IRQ); //send irq to bp after ap write data to dpram
|
||||
port->dpram.write_ptr(&port->dpram, SPI_DPRAM_PTR1_APWRITE_BPREAD, count);
|
||||
if(++gNumSendInt > (1<<12))
|
||||
gNumSendInt = 0;
|
||||
|
||||
//send irq to bp after ap write data to dpram
|
||||
port->dpram.write_irq(&port->dpram, MAILBOX_APSEND_IRQ);
|
||||
|
||||
return count;
|
||||
|
||||
@@ -512,7 +616,7 @@ unsigned int dpr_poll(struct file *filp, struct poll_table_struct * wait)
|
||||
unsigned int mask = 0;
|
||||
struct spi_fpga_port *port;
|
||||
port = filp->private_data;
|
||||
DBG("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
printk("%s:line=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
return mask;
|
||||
}
|
||||
@@ -546,13 +650,13 @@ int spi_dpram_register(struct spi_fpga_port *port)
|
||||
return -ENOMEM;
|
||||
}
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
sprintf(b, "spi_dpram_busy_workqueue");
|
||||
port->dpram.spi_dpram_busy_workqueue = create_freezeable_workqueue(b);
|
||||
if (!port->dpram.spi_dpram_busy_workqueue) {
|
||||
sprintf(b, "spi_dpram_irq_workqueue");
|
||||
port->dpram.spi_dpram_irq_workqueue = create_freezeable_workqueue(b);
|
||||
if (!port->dpram.spi_dpram_irq_workqueue) {
|
||||
printk("cannot create workqueue\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
INIT_WORK(&port->dpram.spi_dpram_busy_work, spi_dpram_busy_work_handler);
|
||||
INIT_WORK(&port->dpram.spi_dpram_irq_work, spi_dpram_irq_work_handler);
|
||||
|
||||
#if SPI_DPRAM_TEST
|
||||
sprintf(b, "spi_dpram_workqueue");
|
||||
@@ -585,7 +689,7 @@ int spi_dpram_register(struct spi_fpga_port *port)
|
||||
ret = misc_register(&port->dpram.miscdev);
|
||||
if(ret)
|
||||
{
|
||||
printk("misc_register err!!!\n");
|
||||
printk("%s:misc_register err!!!\n",__FUNCTION__);
|
||||
goto err0;
|
||||
}
|
||||
|
||||
@@ -593,22 +697,25 @@ int spi_dpram_register(struct spi_fpga_port *port)
|
||||
port->dpram.read_dpram = spi_dpram_read_buf;
|
||||
port->dpram.write_ptr = spi_dpram_write_ptr;
|
||||
port->dpram.read_ptr = spi_dpram_read_ptr;
|
||||
port->dpram.write_mailbox = spi_dpram_write_mailbox;
|
||||
port->dpram.read_mailbox = spi_dpram_read_mailbox;
|
||||
port->dpram.write_irq = spi_dpram_write_irq;
|
||||
port->dpram.read_irq = spi_dpram_read_irq;
|
||||
port->dpram.write_ack = spi_dpram_write_ack;
|
||||
port->dpram.read_ack = spi_dpram_read_ack;
|
||||
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
|
||||
ret = gpio_request(SPI_DPRAM_BUSY_PIN, NULL);
|
||||
ret = gpio_request(SPI_DPRAM_INT_PIN, NULL);
|
||||
if (ret) {
|
||||
printk("%s:failed to request fpga busy gpio\n",__FUNCTION__);
|
||||
printk("%s:failed to request dpram irq gpio\n",__FUNCTION__);
|
||||
goto err1;
|
||||
}
|
||||
|
||||
gpio_pull_updown(SPI_DPRAM_BUSY_PIN,GPIOPullUp);
|
||||
ret = request_irq(gpio_to_irq(SPI_DPRAM_BUSY_PIN),spi_dpram_busy_irq,IRQF_TRIGGER_RISING,NULL,port);
|
||||
rk2818_mux_api_set(GPIOA23_UART2_SEL_NAME,0);
|
||||
gpio_pull_updown(SPI_DPRAM_INT_PIN,GPIOPullUp);
|
||||
ret = request_irq(gpio_to_irq(SPI_DPRAM_INT_PIN),spi_dpram_irq,IRQF_TRIGGER_FALLING,NULL,port);
|
||||
if(ret)
|
||||
{
|
||||
printk("unable to request fpga busy_gpio irq\n");
|
||||
printk("%s:unable to request dpram irq_gpio irq\n",__FUNCTION__);
|
||||
goto err2;
|
||||
}
|
||||
DBG("%s:line=%d,port=0x%x\n",__FUNCTION__,__LINE__,(int)port);
|
||||
@@ -616,9 +723,9 @@ int spi_dpram_register(struct spi_fpga_port *port)
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
free_irq(gpio_to_irq(SPI_DPRAM_BUSY_PIN),NULL);
|
||||
free_irq(gpio_to_irq(SPI_DPRAM_INT_PIN),NULL);
|
||||
err1:
|
||||
gpio_free(SPI_DPRAM_BUSY_PIN);
|
||||
gpio_free(SPI_DPRAM_INT_PIN);
|
||||
err0:
|
||||
kfree(port->dpram.prx);
|
||||
kfree(port->dpram.ptx);
|
||||
|
||||
@@ -69,10 +69,10 @@ 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;
|
||||
tx_buf[1] = 1;//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)-1, rx_buf, n_rx);
|
||||
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_UART reg=0x%x,result=0x%x\n",__FUNCTION__,reg&0xff,result&0xff);
|
||||
break;
|
||||
@@ -262,7 +262,7 @@ static void spi_fpga_irq_work_handler(struct work_struct *work)
|
||||
{
|
||||
#if defined(CONFIG_SPI_FPGA_DPRAM)
|
||||
DBG("%s:ICE_INT_TYPE_DPRAM ret=0x%x\n",__FUNCTION__,ret);
|
||||
spi_dpram_handle_irq(spi);
|
||||
spi_dpram_handle_ack(spi);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@@ -308,6 +308,25 @@ static int spi_open_sysclk(int set)
|
||||
}
|
||||
|
||||
|
||||
static int spi_fpga_rst(void)
|
||||
{
|
||||
int ret;
|
||||
ret = gpio_request(SPI_FPGA_RST_PIN, NULL);
|
||||
if (ret) {
|
||||
printk("%s:failed to request fpga rst pin\n",__FUNCTION__);
|
||||
return ret;
|
||||
}
|
||||
rk2818_mux_api_set(GPIOH6_IQ_SEL_NAME,0);
|
||||
gpio_direction_output(SPI_FPGA_RST_PIN,GPIO_HIGH);
|
||||
gpio_direction_output(SPI_FPGA_RST_PIN,GPIO_LOW);
|
||||
mdelay(1);
|
||||
gpio_direction_output(SPI_FPGA_RST_PIN,GPIO_HIGH);
|
||||
|
||||
gpio_direction_input(SPI_FPGA_RST_PIN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit spi_fpga_probe(struct spi_device * spi)
|
||||
{
|
||||
struct spi_fpga_port *port;
|
||||
@@ -329,10 +348,12 @@ static int __devinit spi_fpga_probe(struct spi_device * spi)
|
||||
return -ENOMEM;
|
||||
DBG("port=0x%x\n",(int)port);
|
||||
|
||||
spin_lock_init(&port->work_lock);
|
||||
mutex_init(&port->spi_lock);
|
||||
|
||||
spi_open_sysclk(GPIO_HIGH);
|
||||
|
||||
spi_fpga_rst();
|
||||
sprintf(b, "fpga_irq_workqueue");
|
||||
port->fpga_irq_workqueue = create_freezeable_workqueue(b);
|
||||
if (!port->fpga_irq_workqueue) {
|
||||
@@ -394,8 +415,9 @@ static int __devinit spi_fpga_probe(struct spi_device * spi)
|
||||
goto err1;
|
||||
}
|
||||
|
||||
rk2818_mux_api_set(CXGPIO_HSADC_SEL_NAME,IOMUXB_GPIO2_14_23);
|
||||
gpio_pull_updown(SPI_FPGA_INT_PIN,GPIOPullUp);
|
||||
ret = request_irq(gpio_to_irq(SPI_FPGA_INT_PIN),spi_fpga_irq,IRQF_TRIGGER_RISING,NULL,port);
|
||||
ret = request_irq(gpio_to_irq(SPI_FPGA_INT_PIN),spi_fpga_irq,IRQF_TRIGGER_FALLING,NULL,port);
|
||||
if(ret)
|
||||
{
|
||||
printk("unable to request spi_uart irq\n");
|
||||
|
||||
@@ -659,8 +659,9 @@ int spi_gpio_init_first(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_HIGH); //LCD_RESET output//
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P2_12, SPI_GPIO_LOW); //LCD_RESET output//
|
||||
spi_gpio_set_pindirection(SPI_GPIO_P2_12, SPI_GPIO_OUT);
|
||||
spi_gpio_set_pinlevel(SPI_GPIO_P2_12, SPI_GPIO_HIGH);
|
||||
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
|
||||
@@ -957,10 +958,10 @@ static void spi_gpio_irq_enable(unsigned irq)
|
||||
t->irq = irq;
|
||||
t->id = ID_SPI_GPIO_IRQ_ENABLE;
|
||||
|
||||
spin_lock_irqsave(&port->spi_lock, flags);
|
||||
spin_lock_irqsave(&port->work_lock, flags);
|
||||
list_add_tail(&t->queue, &port->gpio.msg_queue);
|
||||
queue_work(port->gpio.spi_gpio_irq_workqueue, &port->gpio.spi_gpio_irq_work);
|
||||
spin_unlock_irqrestore(&port->spi_lock, flags);
|
||||
spin_unlock_irqrestore(&port->work_lock, flags);
|
||||
}
|
||||
|
||||
static void spi_gpio_irq_disable(unsigned irq)
|
||||
@@ -977,10 +978,10 @@ static void spi_gpio_irq_disable(unsigned irq)
|
||||
t->irq = irq;
|
||||
t->id = ID_SPI_GPIO_IRQ_DISABLE;
|
||||
|
||||
spin_lock_irqsave(&port->spi_lock, flags);
|
||||
spin_lock_irqsave(&port->work_lock, flags);
|
||||
list_add_tail(&t->queue, &port->gpio.msg_queue);
|
||||
queue_work(port->gpio.spi_gpio_irq_workqueue, &port->gpio.spi_gpio_irq_work);
|
||||
spin_unlock_irqrestore(&port->spi_lock, flags);
|
||||
spin_unlock_irqrestore(&port->work_lock, flags);
|
||||
|
||||
|
||||
}
|
||||
@@ -1010,10 +1011,10 @@ static int spi_gpio_irq_set_type(unsigned int irq, unsigned int type)
|
||||
t->id = ID_SPI_GPIO_IRQ_SET_TYPE;
|
||||
t->type = type;
|
||||
|
||||
spin_lock_irqsave(&port->spi_lock, flags);
|
||||
spin_lock_irqsave(&port->work_lock, flags);
|
||||
list_add_tail(&t->queue, &port->gpio.msg_queue);
|
||||
queue_work(port->gpio.spi_gpio_irq_workqueue, &port->gpio.spi_gpio_irq_work);
|
||||
spin_unlock_irqrestore(&port->spi_lock, flags);
|
||||
spin_unlock_irqrestore(&port->work_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1032,10 +1033,10 @@ static int spi_gpio_irq_set_wake(unsigned irq, unsigned state)
|
||||
t->id = ID_SPI_GPIO_IRQ_SET_WAKE;
|
||||
t->state = state;
|
||||
|
||||
spin_lock_irqsave(&port->spi_lock, flags);
|
||||
spin_lock_irqsave(&port->work_lock, flags);
|
||||
list_add_tail(&t->queue, &port->gpio.msg_queue);
|
||||
queue_work(port->gpio.spi_gpio_irq_workqueue, &port->gpio.spi_gpio_irq_work);
|
||||
spin_unlock_irqrestore(&port->spi_lock, flags);
|
||||
spin_unlock_irqrestore(&port->work_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
216
drivers/fpga/spi_uart.c
Normal file → Executable file
216
drivers/fpga/spi_uart.c
Normal file → Executable file
@@ -38,14 +38,14 @@
|
||||
#define SPI_UART_TEST 0
|
||||
|
||||
#define SPI_UART_FIFO_LEN 32
|
||||
#define SPI_UART_TXRX_BUF 0 //send or recieve several bytes one time
|
||||
#define SPI_UART_TXRX_BUF 1 //send or recieve several bytes one time
|
||||
|
||||
static struct tty_driver *spi_uart_tty_driver;
|
||||
/*------------------------<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>spi2uart<72><74><EFBFBD><EFBFBD>-----------------------*/
|
||||
|
||||
#define UART_NR 1 /* Number of UARTs this driver can handle */
|
||||
|
||||
#define UART_XMIT_SIZE PAGE_SIZE
|
||||
#define UART_XMIT_SIZE (PAGE_SIZE<<1)
|
||||
#define WAKEUP_CHARS 1024
|
||||
|
||||
#define circ_empty(circ) ((circ)->head == (circ)->tail)
|
||||
@@ -68,15 +68,19 @@ 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
|
||||
|
||||
int reg = 0, stat = 0;
|
||||
int i;
|
||||
|
||||
for(i=len+2;i>1;i--)
|
||||
buf[i] = buf[i-2];
|
||||
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);
|
||||
buf[0] = reg & 0xff;
|
||||
buf[1] = 0;
|
||||
|
||||
stat = spi_write(port->spi, buf, len+2);
|
||||
if(stat)
|
||||
printk("%s:spi_write err!!!\n\n\n",__FUNCTION__);
|
||||
DBG("%s:reg=0x%x,buf=0x%x,len=0x%x\n",__FUNCTION__,reg&0xff,(int)buf,len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -86,14 +90,21 @@ 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];
|
||||
unsigned char tx_buf[2],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;
|
||||
tx_buf[1] = len;
|
||||
//give fpga 8 clks for reading data
|
||||
stat = spi_write_then_read(port->spi, (const u8 *)&tx_buf, 1, rx_buf, len+1);
|
||||
stat = spi_write_then_read(port->spi, tx_buf, sizeof(tx_buf), rx_buf, len+1);
|
||||
if(stat)
|
||||
{
|
||||
printk("%s:spi_write_then_read is error!,err=%d\n\n",__FUNCTION__,stat);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(buf, rx_buf+1, len);
|
||||
DBG("%s,buf=0x%x,len=0x%x\n",__FUNCTION__,reg&0xff,(int)buf,len);
|
||||
DBG("%s:reg=0x%x,buf=0x%x,len=0x%x\n",__FUNCTION__,reg&0xff,(int)buf,len);
|
||||
return stat;
|
||||
}
|
||||
|
||||
@@ -204,7 +215,7 @@ static unsigned int spi_uart_get_mctrl(struct spi_uart *uart)
|
||||
#endif
|
||||
if (status & UART_MSR_CTS)
|
||||
ret = TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
|
||||
DBG("Enter::%s,LINE=%d,ret=0x%x************************\n",__FUNCTION__,__LINE__,ret);
|
||||
DBG("%s:LINE=%d,ret=0x%x\n",__FUNCTION__,__LINE__,ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -229,7 +240,7 @@ static void spi_uart_write_mctrl(struct spi_uart *uart, unsigned int mctrl)
|
||||
|
||||
#endif
|
||||
|
||||
DBG("Enter::%s,LINE=%d,mcr=0x%x\n",__FUNCTION__,__LINE__,mcr);
|
||||
DBG("%s:LINE=%d,mcr=0x%x\n",__FUNCTION__,__LINE__,mcr);
|
||||
spi_out(port, UART_MCR, mcr, SEL_UART);
|
||||
}
|
||||
|
||||
@@ -237,7 +248,7 @@ static inline void spi_uart_update_mctrl(struct spi_uart *uart,
|
||||
unsigned int set, unsigned int clear)
|
||||
{
|
||||
unsigned int old;
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
old = uart->mctrl;
|
||||
uart->mctrl = (old & ~clear) | set;
|
||||
if (old != uart->mctrl)
|
||||
@@ -349,7 +360,7 @@ static void spi_uart_change_speed(struct spi_uart *uart,
|
||||
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);
|
||||
DBG("Enter::%s,LINE=%d,baud=%d,uart->ier=0x%x,cval=0x%x,fcr=0x%x,quot=0x%x\n",
|
||||
DBG("%s:LINE=%d,baud=%d,uart->ier=0x%x,cval=0x%x,fcr=0x%x,quot=0x%x\n",
|
||||
__FUNCTION__,__LINE__,baud,uart->ier,cval,fcr,quot);
|
||||
spi_uart_write_mctrl(uart, uart->mctrl);
|
||||
}
|
||||
@@ -367,7 +378,7 @@ static void spi_uart_start_tx(struct spi_uart *uart)
|
||||
printk("t,");
|
||||
}
|
||||
|
||||
DBG("Enter::%s,UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -382,7 +393,7 @@ static void spi_uart_stop_tx(struct spi_uart *uart)
|
||||
//spin_unlock_irqrestore(&uart->write_lock, flags);
|
||||
//printk("p");
|
||||
}
|
||||
DBG("Enter::%s,UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
}
|
||||
|
||||
static void spi_uart_stop_rx(struct spi_uart *uart)
|
||||
@@ -403,11 +414,11 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status)
|
||||
#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;
|
||||
count = (ret >> 8) & 0x3f;
|
||||
DBG("%s:count=%d\n",__FUNCTION__,count);
|
||||
if(count == 0)
|
||||
break;
|
||||
buf[0] = ret & 0xff;
|
||||
@@ -423,11 +434,11 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status)
|
||||
flag = TTY_NORMAL;
|
||||
ch = buf[num++];
|
||||
tty_insert_flip_char(tty, ch, flag);
|
||||
//printk("%c,",ch);
|
||||
}
|
||||
|
||||
//printk("\n");
|
||||
tty_flip_buffer_push(tty);
|
||||
}
|
||||
printk("r%d\n",1024-max_count);
|
||||
#else
|
||||
//printk("rx:");
|
||||
while (--max_count >0 )
|
||||
@@ -478,11 +489,11 @@ static void spi_uart_receive_chars(struct spi_uart *uart, unsigned int *status)
|
||||
break;
|
||||
}
|
||||
//printk("\n");
|
||||
DBG("Enter::%s,LINE=%d,rx_count=%d********\n",__FUNCTION__,__LINE__,(1024-max_count));
|
||||
printk("r%d\n",1024-max_count);
|
||||
DBG("%s:LINE=%d,rx_count=%d\n",__FUNCTION__,__LINE__,(1024-max_count));
|
||||
tty_flip_buffer_push(tty);
|
||||
|
||||
#endif
|
||||
printk("r%d\n",1024-max_count);
|
||||
|
||||
}
|
||||
|
||||
@@ -499,12 +510,12 @@ static void spi_uart_transmit_chars(struct spi_uart *uart)
|
||||
spi_out(port, UART_TX, uart->x_char, SEL_UART);
|
||||
uart->icount.tx++;
|
||||
uart->x_char = 0;
|
||||
printk("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
printk("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
return;
|
||||
}
|
||||
if (circ_empty(xmit) || uart->tty->stopped || uart->tty->hw_stopped) {
|
||||
spi_uart_stop_tx(uart);
|
||||
DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
//printk("circ_empty()\n");
|
||||
return;
|
||||
}
|
||||
@@ -512,20 +523,21 @@ static void spi_uart_transmit_chars(struct spi_uart *uart)
|
||||
|
||||
#if SPI_UART_TXRX_BUF
|
||||
//send several bytes one time
|
||||
count = 0;
|
||||
while(count < SPI_UART_FIFO_LEN)
|
||||
count = SPI_UART_FIFO_LEN;
|
||||
while(count > 0)
|
||||
{
|
||||
buf[count] = xmit->buf[xmit->tail];
|
||||
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||
uart->icount.tx++;
|
||||
count++;
|
||||
if (circ_empty(xmit))
|
||||
break;
|
||||
buf[SPI_UART_FIFO_LEN - count] = xmit->buf[xmit->tail];
|
||||
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
|
||||
uart->icount.tx++;
|
||||
--count;
|
||||
}
|
||||
spi_uart_write_buf(uart,buf,count);
|
||||
if(SPI_UART_FIFO_LEN - count > 0)
|
||||
spi_uart_write_buf(uart,buf,SPI_UART_FIFO_LEN - count);
|
||||
#else
|
||||
//send one byte one time
|
||||
count = SPI_UART_FIFO_LEN;//
|
||||
count = SPI_UART_FIFO_LEN;
|
||||
while(count > 0)
|
||||
{
|
||||
spi_out(port, UART_TX, xmit->buf[xmit->tail], SEL_UART);
|
||||
@@ -538,21 +550,21 @@ static void spi_uart_transmit_chars(struct spi_uart *uart)
|
||||
}
|
||||
#endif
|
||||
//printk("\n");
|
||||
DBG("Enter::%s,LINE=%d,tx_count=%d\n",__FUNCTION__,__LINE__,(32-count));
|
||||
DBG("%s:LINE=%d,tx_count=%d\n",__FUNCTION__,__LINE__,(SPI_UART_FIFO_LEN-count));
|
||||
if (circ_chars_pending(xmit) < WAKEUP_CHARS)
|
||||
{
|
||||
tty_wakeup(uart->tty);
|
||||
printk("k,");
|
||||
//printk("k,");
|
||||
}
|
||||
DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
if (circ_empty(xmit))
|
||||
{
|
||||
DBG("circ_empty(xmit)\n");
|
||||
spi_uart_stop_tx(uart);
|
||||
printk("e,");
|
||||
//printk("e,");
|
||||
}
|
||||
|
||||
printk("t%d\n",32-count);
|
||||
printk("t%d\n",SPI_UART_FIFO_LEN-count);
|
||||
|
||||
DBG("uart->tty->hw_stopped = %d\n",uart->tty->hw_stopped);
|
||||
}
|
||||
@@ -564,7 +576,7 @@ static void spi_uart_check_modem_status(struct spi_uart *uart)
|
||||
struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
|
||||
status = spi_in(port, UART_MSR, SEL_UART);//
|
||||
DBG("Enter::%s,LINE=%d,status=0x%x*******\n",__FUNCTION__,__LINE__,status);
|
||||
DBG("%s:LINE=%d,status=0x%x*******\n",__FUNCTION__,__LINE__,status);
|
||||
if ((status & UART_MSR_ANY_DELTA) == 0)
|
||||
return;
|
||||
|
||||
@@ -582,26 +594,26 @@ static void spi_uart_check_modem_status(struct spi_uart *uart)
|
||||
if (cts) {
|
||||
uart->tty->hw_stopped = 0;
|
||||
spi_uart_start_tx(uart);
|
||||
DBG("Enter::%s,UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
tty_wakeup(uart->tty);
|
||||
}
|
||||
} else {
|
||||
if (!cts) {
|
||||
uart->tty->hw_stopped = 1;
|
||||
DBG("Enter::%s,UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
spi_uart_stop_tx(uart);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DBG("Enter::%s,LINE=%d,status=0x%x*******\n",__FUNCTION__,__LINE__,status);
|
||||
DBG("%s:LINE=%d,status=0x%x*******\n",__FUNCTION__,__LINE__,status);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if SPI_UART_TEST
|
||||
#define UART_TEST_LEN 16 //8bit
|
||||
unsigned char buf_test_uart[UART_TEST_LEN];
|
||||
#define UART_TEST_LEN 32 //8bit
|
||||
unsigned char buf_test_uart[UART_TEST_LEN+2];
|
||||
|
||||
void spi_uart_test_init(struct spi_fpga_port *port)
|
||||
{
|
||||
@@ -610,7 +622,7 @@ void spi_uart_test_init(struct spi_fpga_port *port)
|
||||
unsigned char mcr = 0;
|
||||
int ret;
|
||||
|
||||
DBG("Enter::%s,LINE=%d,mcr=0x%x\n",__FUNCTION__,__LINE__,mcr);
|
||||
DBG("%s:LINE=%d,mcr=0x%x\n",__FUNCTION__,__LINE__,mcr);
|
||||
spi_out(port, UART_MCR, mcr, SEL_UART);
|
||||
baud = 1500000;
|
||||
cval = UART_LCR_WLEN8;
|
||||
@@ -627,7 +639,13 @@ void spi_uart_test_init(struct spi_fpga_port *port)
|
||||
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);
|
||||
if(ret != quot)
|
||||
{
|
||||
#if SPI_FPGA_TEST_DEBUG
|
||||
spi_test_wrong_handle();
|
||||
#endif
|
||||
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);
|
||||
@@ -647,14 +665,28 @@ void spi_uart_work_handler(struct work_struct *work)
|
||||
for(i=0;i<UART_TEST_LEN;i++)
|
||||
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);
|
||||
mdelay(5);
|
||||
spi_uart_read_buf(&port->uart, buf_test_uart, count);
|
||||
for(i=0;i<UART_TEST_LEN;i++)
|
||||
{
|
||||
if(buf_test_uart[i] != '0'+i)
|
||||
{
|
||||
#if SPI_FPGA_TEST_DEBUG
|
||||
spi_test_wrong_handle();
|
||||
#endif
|
||||
printk("err:%s:buf_t[%d]=0x%x,buf_r[%d]=0x%x\n",__FUNCTION__,i,'0'+i,i,buf_test_uart[i]);
|
||||
}
|
||||
}
|
||||
#else
|
||||
while(count > 0)
|
||||
{
|
||||
spi_out(port, UART_TX, buf_test_uart[UART_TEST_LEN-count], SEL_UART);
|
||||
--count;
|
||||
}
|
||||
printk("%s,line=%d\n",__FUNCTION__,__LINE__);
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -662,7 +694,7 @@ void spi_uart_work_handler(struct work_struct *work)
|
||||
static void spi_testuart_timer(unsigned long data)
|
||||
{
|
||||
struct spi_fpga_port *port = (struct spi_fpga_port *)data;
|
||||
port->uart.uart_timer.expires = jiffies + msecs_to_jiffies(1000);
|
||||
port->uart.uart_timer.expires = jiffies + msecs_to_jiffies(300);
|
||||
add_timer(&port->uart.uart_timer);
|
||||
//schedule_work(&port->gpio.spi_gpio_work);
|
||||
queue_work(port->uart.spi_uart_workqueue, &port->uart.spi_uart_work);
|
||||
@@ -670,9 +702,6 @@ static void spi_testuart_timer(unsigned long data)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This handles the interrupt from one port.
|
||||
*/
|
||||
@@ -684,7 +713,7 @@ void spi_uart_handle_irq(struct spi_device *spi)
|
||||
|
||||
if (unlikely(uart->in_spi_uart_irq == current))
|
||||
return;
|
||||
DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
/*
|
||||
* In a few places spi_uart_handle_irq() is called directly instead of
|
||||
@@ -696,19 +725,18 @@ void spi_uart_handle_irq(struct spi_device *spi)
|
||||
*/
|
||||
|
||||
uart_iir = spi_in(port, UART_IIR, SEL_UART);//
|
||||
DBG("%s:iir=0x%x\n",__FUNCTION__,uart_iir);
|
||||
if (uart_iir & UART_IIR_NO_INT)
|
||||
return;
|
||||
|
||||
DBG("iir=0x%x\n",uart_iir);
|
||||
|
||||
uart->in_spi_uart_irq = current;
|
||||
lsr = spi_in(port, UART_LSR, SEL_UART);//
|
||||
DBG("lsr=0x%x\n",lsr);
|
||||
DBG("%s:lsr=0x%x\n",__FUNCTION__,lsr);
|
||||
|
||||
if (lsr & UART_LSR_DR)
|
||||
//if (((uart_iir & UART_IIR_RDI) | (uart_iir & UART_IIR_RLSI)) && (lsr & UART_LSR_DR))
|
||||
{
|
||||
DBG("Enter::%s,LINE=%d,lsr & UART_LSR_DR************\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d,start recieve data!\n",__FUNCTION__,__LINE__);
|
||||
spi_uart_receive_chars(uart, &lsr);
|
||||
}
|
||||
|
||||
@@ -718,13 +746,12 @@ void spi_uart_handle_irq(struct spi_device *spi)
|
||||
if (lsr & UART_LSR_THRE)
|
||||
//if ((uart_iir & UART_IIR_THRI)&&(lsr & UART_LSR_THRE))
|
||||
{
|
||||
DBG("Enter::%s,LINE=%d,ICE_STATUS_TXF == 0************\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d,start send data!\n",__FUNCTION__,__LINE__);
|
||||
spi_uart_transmit_chars(uart);
|
||||
}
|
||||
|
||||
uart->in_spi_uart_irq = NULL;
|
||||
|
||||
DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
}
|
||||
|
||||
@@ -733,7 +760,7 @@ static int spi_uart_startup(struct spi_uart *uart)
|
||||
unsigned long page;
|
||||
struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
/*
|
||||
* Set the TTY IO error marker - we will only clear this
|
||||
* once we have successfully opened the port.
|
||||
@@ -786,7 +813,7 @@ static int spi_uart_startup(struct spi_uart *uart)
|
||||
uart->tty->hw_stopped = 1;
|
||||
|
||||
clear_bit(TTY_IO_ERROR, &uart->tty->flags);
|
||||
DBG("Enter::%s,LINE=%d,uart->ier=0x%x\n",__FUNCTION__,__LINE__,uart->ier);
|
||||
DBG("%s:LINE=%d,uart->ier=0x%x\n",__FUNCTION__,__LINE__,uart->ier);
|
||||
/* Kick the IRQ handler once while we're still holding the host lock */
|
||||
//spi_uart_handle_irq(port->spi);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
@@ -800,8 +827,10 @@ static int spi_uart_startup(struct spi_uart *uart)
|
||||
static void spi_uart_shutdown(struct spi_uart *uart)
|
||||
{
|
||||
struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
//mutex_lock(&port->spi_lock);
|
||||
#if 1
|
||||
spi_uart_stop_rx(uart);
|
||||
|
||||
/* TODO: wait here for TX FIFO to drain */
|
||||
@@ -824,7 +853,7 @@ static void spi_uart_shutdown(struct spi_uart *uart)
|
||||
UART_FCR_CLEAR_RCVR |
|
||||
UART_FCR_CLEAR_XMIT, SEL_UART);
|
||||
spi_out(port, UART_FCR, 0, SEL_UART);
|
||||
|
||||
#endif
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
|
||||
//skip:
|
||||
@@ -840,10 +869,10 @@ static int spi_uart_open (struct tty_struct *tty, struct file * filp)
|
||||
uart = spi_uart_port_get(tty->index);
|
||||
if (!uart)
|
||||
{
|
||||
DBG("Enter::%s,LINE=%d,!port\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d,!port\n",__FUNCTION__,__LINE__);
|
||||
return -ENODEV;
|
||||
}
|
||||
DBG("Enter::%s,LINE=%d,tty->index=%d\n",__FUNCTION__,__LINE__,tty->index);
|
||||
DBG("%s:LINE=%d,tty->index=%d\n",__FUNCTION__,__LINE__,tty->index);
|
||||
mutex_lock(&uart->open_lock);
|
||||
|
||||
/*
|
||||
@@ -853,7 +882,7 @@ static int spi_uart_open (struct tty_struct *tty, struct file * filp)
|
||||
if (tty->driver_data && tty->driver_data != uart) {
|
||||
mutex_unlock(&uart->open_lock);
|
||||
spi_uart_port_put(uart);
|
||||
DBG("Enter::%s,LINE=%d,!= uart\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d,!= uart\n",__FUNCTION__,__LINE__);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@@ -866,12 +895,12 @@ static int spi_uart_open (struct tty_struct *tty, struct file * filp)
|
||||
uart->tty = NULL;
|
||||
mutex_unlock(&uart->open_lock);
|
||||
spi_uart_port_put(uart);
|
||||
DBG("Enter::%s,LINE=%d,ret=%d\n",__FUNCTION__,__LINE__,ret);
|
||||
DBG("%s:LINE=%d,ret=%d\n",__FUNCTION__,__LINE__,ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
uart->opened++;
|
||||
DBG("Enter::%s,uart->opened++=%d\n",__FUNCTION__,uart->opened);
|
||||
DBG("%s:uart->opened++=%d\n",__FUNCTION__,uart->opened);
|
||||
mutex_unlock(&uart->open_lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -879,7 +908,7 @@ static int spi_uart_open (struct tty_struct *tty, struct file * filp)
|
||||
static void spi_uart_close(struct tty_struct *tty, struct file * filp)
|
||||
{
|
||||
struct spi_uart *uart = tty->driver_data;
|
||||
printk("Enter::%s,LINE=%d,tty->hw_stopped=%d\n",__FUNCTION__,__LINE__,tty->hw_stopped);
|
||||
printk("%s:LINE=%d,tty->hw_stopped=%d\n",__FUNCTION__,__LINE__,tty->hw_stopped);
|
||||
if (!uart)
|
||||
return;
|
||||
|
||||
@@ -897,7 +926,7 @@ static void spi_uart_close(struct tty_struct *tty, struct file * filp)
|
||||
}
|
||||
|
||||
if (--uart->opened == 0) {
|
||||
DBG("Enter::%s,opened=%d\n",__FUNCTION__,uart->opened);
|
||||
DBG("%s:opened=%d\n",__FUNCTION__,uart->opened);
|
||||
tty->closing = 1;
|
||||
spi_uart_shutdown(uart);
|
||||
tty_ldisc_flush(tty);
|
||||
@@ -945,11 +974,11 @@ static int spi_uart_write(struct tty_struct * tty, const unsigned char *buf,
|
||||
#if 1
|
||||
if ( !(uart->ier & UART_IER_THRI)) {
|
||||
//mutex_lock(&port->spi_lock);
|
||||
DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
/*Note:ICE65L08 output a 'Transmitter holding register interrupt' after 1us*/
|
||||
//printk("s,");
|
||||
printk("s,");
|
||||
spi_uart_start_tx(uart);
|
||||
spi_uart_handle_irq(port->spi);
|
||||
// spi_uart_handle_irq(port->spi);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
}
|
||||
#endif
|
||||
@@ -961,14 +990,14 @@ static int spi_uart_write(struct tty_struct * tty, const unsigned char *buf,
|
||||
static int spi_uart_write_room(struct tty_struct *tty)
|
||||
{
|
||||
struct spi_uart *uart = tty->driver_data;
|
||||
DBG("Enter::%s,LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
return uart ? circ_chars_free(&uart->xmit) : 0;
|
||||
}
|
||||
|
||||
static int spi_uart_chars_in_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct spi_uart *uart = tty->driver_data;
|
||||
printk("Enter::%s,LINE=%d,circ=%ld****\n",__FUNCTION__,__LINE__,circ_chars_pending(&uart->xmit));
|
||||
printk("%s:LINE=%d,circ=%ld\n",__FUNCTION__,__LINE__,circ_chars_pending(&uart->xmit));
|
||||
return uart ? circ_chars_pending(&uart->xmit) : 0;
|
||||
}
|
||||
|
||||
@@ -976,12 +1005,12 @@ static void spi_uart_send_xchar(struct tty_struct *tty, char ch)
|
||||
{
|
||||
struct spi_uart *uart = tty->driver_data;
|
||||
struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
printk("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
printk("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
uart->x_char = ch;
|
||||
if (ch && !(uart->ier & UART_IER_THRI)) {
|
||||
//mutex_lock(&port->spi_lock);
|
||||
spi_uart_start_tx(uart);
|
||||
printk("Enter::%s,UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
printk("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
spi_uart_handle_irq(port->spi);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
}
|
||||
@@ -991,15 +1020,15 @@ static void spi_uart_throttle(struct tty_struct *tty)
|
||||
{
|
||||
struct spi_uart *uart = tty->driver_data;
|
||||
struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
printk("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
printk("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))
|
||||
return;
|
||||
printk("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
printk("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
//mutex_lock(&port->spi_lock);
|
||||
if (I_IXOFF(tty)) {
|
||||
uart->x_char = STOP_CHAR(tty);
|
||||
spi_uart_start_tx(uart);
|
||||
DBG("Enter::%s,UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
}
|
||||
|
||||
if (tty->termios->c_cflag & CRTSCTS)
|
||||
@@ -1013,7 +1042,7 @@ static void spi_uart_unthrottle(struct tty_struct *tty)
|
||||
{
|
||||
struct spi_uart *uart = tty->driver_data;
|
||||
struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
printk("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
printk("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))
|
||||
return;
|
||||
//mutex_lock(&port->spi_lock);
|
||||
@@ -1023,7 +1052,7 @@ static void spi_uart_unthrottle(struct tty_struct *tty)
|
||||
} else {
|
||||
uart->x_char = START_CHAR(tty);
|
||||
spi_uart_start_tx(uart);
|
||||
DBG("Enter::%s,UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1037,9 +1066,10 @@ static void spi_uart_unthrottle(struct tty_struct *tty)
|
||||
static void spi_uart_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
|
||||
{
|
||||
struct spi_uart *uart = tty->driver_data;
|
||||
//struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
unsigned int cflag = tty->termios->c_cflag;
|
||||
unsigned int mask = TIOCM_DTR;
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
|
||||
#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
|
||||
|
||||
@@ -1052,14 +1082,14 @@ static void spi_uart_set_termios(struct tty_struct *tty, struct ktermios *old_te
|
||||
|
||||
/* Handle transition to B0 status */
|
||||
if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)){
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
spi_uart_clear_mctrl(uart, TIOCM_RTS | TIOCM_DTR);
|
||||
//spi_uart_clear_mctrl(uart, TIOCM_RTS);
|
||||
}
|
||||
|
||||
/* Handle transition away from B0 status */
|
||||
if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
if (!(cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags))
|
||||
mask |= TIOCM_RTS;
|
||||
spi_uart_set_mctrl(uart, mask);
|
||||
@@ -1067,18 +1097,16 @@ static void spi_uart_set_termios(struct tty_struct *tty, struct ktermios *old_te
|
||||
|
||||
/* Handle turning off CRTSCTS */
|
||||
if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
tty->hw_stopped = 0;
|
||||
spi_uart_start_tx(uart);
|
||||
DBG("Enter::%s,UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
DBG("%s:UART_IER=0x%x\n",__FUNCTION__,uart->ier);
|
||||
}
|
||||
|
||||
/* Handle turning on CRTSCTS */
|
||||
if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) {
|
||||
DBG("Enter::%s,LINE=%d,status=0x%x,Handle turning on CRTSCTS*****************\n",__FUNCTION__,__LINE__,spi_uart_get_mctrl(uart));
|
||||
//spi_uart_set_mctrl(uart, TIOCM_RTS);
|
||||
if (!(spi_uart_get_mctrl(uart) & TIOCM_CTS)) {
|
||||
DBG("Enter::%s,LINE=%d,tty->hw_stopped = 1********\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d,tty->hw_stopped = 1\n",__FUNCTION__,__LINE__);
|
||||
tty->hw_stopped = 1;
|
||||
spi_uart_stop_tx(uart);
|
||||
}
|
||||
@@ -1091,7 +1119,7 @@ static int spi_uart_break_ctl(struct tty_struct *tty, int break_state)
|
||||
{
|
||||
struct spi_uart *uart = tty->driver_data;
|
||||
struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
//mutex_lock(&port->spi_lock);
|
||||
if (break_state == -1)
|
||||
uart->lcr |= UART_LCR_SBC;
|
||||
@@ -1105,8 +1133,9 @@ static int spi_uart_break_ctl(struct tty_struct *tty, int break_state)
|
||||
static int spi_uart_tiocmget(struct tty_struct *tty, struct file *file)
|
||||
{
|
||||
struct spi_uart *uart = tty->driver_data;
|
||||
//struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
int result;
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
//mutex_lock(&port->spi_lock);
|
||||
result = uart->mctrl | spi_uart_get_mctrl(uart);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
@@ -1117,7 +1146,8 @@ static int spi_uart_tiocmset(struct tty_struct *tty, struct file *file,
|
||||
unsigned int set, unsigned int clear)
|
||||
{
|
||||
struct spi_uart *uart = tty->driver_data;
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
//struct spi_fpga_port *port = container_of(uart, struct spi_fpga_port, uart);
|
||||
DBG("%s:LINE=%d\n",__FUNCTION__,__LINE__);
|
||||
//mutex_lock(&port->spi_lock);
|
||||
spi_uart_update_mctrl(uart, set, clear);
|
||||
//mutex_unlock(&port->spi_lock);
|
||||
@@ -1131,7 +1161,7 @@ static int spi_uart_read_proc(char *page, char **start, off_t off,
|
||||
{
|
||||
int i, len = 0;
|
||||
off_t begin = 0;
|
||||
DBG("Enter::%s,LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
DBG("%s:LINE=%d************************\n",__FUNCTION__,__LINE__);
|
||||
len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n",
|
||||
"", "", "");
|
||||
for (i = 0; i < UART_NR && len < PAGE_SIZE - 96; i++) {
|
||||
|
||||
Reference in New Issue
Block a user