newton:add irda MIR mode

Now irda can work under MIR mode, FIR mode is still terrible.
This commit is contained in:
lyx
2011-07-05 03:05:25 -07:00
parent 97e1ade85d
commit 42df56ac6d
3 changed files with 95 additions and 38 deletions

View File

@@ -51,7 +51,7 @@
*/
static u32 curTrans_mode; /* SIR, MIR, FIR */
static u32 curTrans_speed; /* 2.4kbps, 9.6kbps,..., 4Mbps */
static u32 curTrans_way; /* idle, send, receive, auto-multi-receive, multi-receive, multi-send */
static u32 curTrans_way; /* idle, send, receive, mir-receive, mir-send, fir-receive, fir-send, auto-multi-receive, multi-receive, multi-send */
static u16 curFIT; /* FIT2,1,0 in PWR/FIT register */
/*---------------------------------------------------------------------------
@@ -189,25 +189,49 @@ int irda_hw_set_speed(u32 speed)
case BU92725GUW_IDLE:
break;
case BU92725GUW_REV:
if (mode != BU92725GUW_SIR)
curTrans_way = BU92725GUW_AUTO_MULTI_REV;
if (mode == BU92725GUW_MIR)
curTrans_way = BU92725GUW_MIR_REV;
else if (mode == BU92725GUW_FIR)
//curTrans_way = BU92725GUW_AUTO_MULTI_REV;
//curTrans_way = BU92725GUW_MULTI_REV;
curTrans_way = BU92725GUW_FIR_REV;
break;
case BU92725GUW_SEND:
if (mode != BU92725GUW_SIR)
curTrans_way = BU92725GUW_MULTI_SEND;
if (mode == BU92725GUW_MIR)
curTrans_way = BU92725GUW_MIR_SEND;
else if (mode == BU92725GUW_FIR)
//curTrans_way = BU92725GUW_MULTI_SEND;
curTrans_way = BU92725GUW_FIR_SEND;
break;
case BU92725GUW_MIR_REV:
if (mode == BU92725GUW_SIR)
curTrans_way = BU92725GUW_REV;
else if (mode == BU92725GUW_FIR)
//curTrans_way = BU92725GUW_AUTO_MULTI_REV;
//curTrans_way = BU92725GUW_MULTI_REV;
curTrans_way = BU92725GUW_FIR_REV;
break;
case BU92725GUW_MIR_SEND:
if (mode == BU92725GUW_SIR)
curTrans_way = BU92725GUW_SEND;
else if (mode == BU92725GUW_FIR)
//curTrans_way = BU92725GUW_MULTI_SEND;
curTrans_way = BU92725GUW_FIR_SEND;
break;
case BU92725GUW_FIR_REV:
case BU92725GUW_AUTO_MULTI_REV:
case BU92725GUW_MULTI_REV:
if (mode == BU92725GUW_SIR)
curTrans_way = BU92725GUW_REV;
else if (mode == BU92725GUW_MIR)
curTrans_way = BU92725GUW_MIR_REV;
break;
case BU92725GUW_MULTI_REV: //not used now
if (mode == BU92725GUW_SIR)
curTrans_way = BU92725GUW_REV;
break;
case BU92725GUW_FIR_SEND:
case BU92725GUW_MULTI_SEND:
if (mode == BU92725GUW_SIR)
curTrans_way = BU92725GUW_SEND;
else if (mode == BU92725GUW_MIR)
curTrans_way = BU92725GUW_MIR_SEND;
break;
}
@@ -233,9 +257,11 @@ int irda_hw_tx_enable_irq(enum eTrans_Mode mode)
*/
if (mode == BU92725GUW_SIR)
BU92725GUW_set_trans_way(BU92725GUW_SEND);
else if (mode == BU92725GUW_MIR)
BU92725GUW_set_trans_way(BU92725GUW_MIR_SEND);
else
BU92725GUW_set_trans_way(BU92725GUW_MULTI_SEND);
//BU92725GUW_set_trans_way(BU92725GUW_MULTI_SEND);
BU92725GUW_set_trans_way(BU92725GUW_FIR_SEND);
//BU92725GUW_clr_fifo();
return 0;
@@ -289,20 +315,24 @@ void irda_hw_set_moderx(void)
if (curTrans_mode == BU92725GUW_SIR)
BU92725GUW_set_trans_way(BU92725GUW_REV);
else if (curTrans_mode == BU92725GUW_MIR)
BU92725GUW_set_trans_way(BU92725GUW_MIR_REV);
else
BU92725GUW_set_trans_way(BU92725GUW_AUTO_MULTI_REV);
//BU92725GUW_set_trans_way(BU92725GUW_AUTO_MULTI_REV);
//BU92725GUW_set_trans_way(BU92725GUW_MULTI_REV);
BU92725GUW_set_trans_way(BU92725GUW_FIR_REV);
}
int irda_hw_get_mode(void)
{
return curTrans_way;
#if 0
u16 val = 0;
val = BU92725GUW_READ_REG(REG_TRCR_ADDR);
RK29IR_DBG("line %d: enter %s, REG_TRCR_ADDR = 0x%x\n", __LINE__, __FUNCTION__, val);
return (val& (REG_TRCR_TX_EN | REG_TRCR_RX_EN));
#endif
}
/*
@@ -363,7 +393,8 @@ u16 BU92725GUW_get_data(u8 *buf)
RK29IR_DBG("line %d: enter %s\n", __LINE__, __FUNCTION__);
/* get data count from FLV or FLVII */
if (curTrans_way == BU92725GUW_REV)
if ((curTrans_way == BU92725GUW_REV) || (curTrans_way == BU92725GUW_MIR_REV)
|| (curTrans_way == BU92725GUW_FIR_REV))
len = BU92725GUW_READ_REG(REG_FLV_ADDR);
else
len = BU92725GUW_READ_REG(REG_FLVII_ADDR);
@@ -378,7 +409,8 @@ u16 BU92725GUW_get_data(u8 *buf)
}
/* restart receive mode under SIR */
if (curTrans_way == BU92725GUW_REV) {
if ((curTrans_way == BU92725GUW_REV) || (curTrans_way == BU92725GUW_MIR_REV)
|| (curTrans_way == BU92725GUW_FIR_REV)){
BU92725GUW_WRITE_REG(REG_TRCR_ADDR, 0x0000);
BU92725GUW_WRITE_REG(REG_TRCR_ADDR, REG_TRCR_RX_EN);
}
@@ -414,7 +446,8 @@ u16 BU92725GUW_get_data(u8 *buf)
BU92725GUW_WRITE_REG(REG_FTLV_ADDR, len);
/* set TRCR:TX_EN under normal send mode */
if (curTrans_way == BU92725GUW_SEND) {//SIR
if ((curTrans_way == BU92725GUW_SEND) || (curTrans_way == BU92725GUW_MIR_SEND)
|| (curTrans_way == BU92725GUW_FIR_SEND)) {
BU92725GUW_WRITE_REG(REG_TRCR_ADDR, REG_TRCR_TX_EN);
}
@@ -633,17 +666,21 @@ static void internal_set(u8 modeChg)
val = 0x0000;
break;
case BU92725GUW_REV:
case BU92725GUW_MIR_REV:
case BU92725GUW_FIR_REV:
val = REG_TRCR_RX_EN;
break;
case BU92725GUW_SEND:
val = 0x0000;
break;
case BU92725GUW_AUTO_MULTI_REV:
val = REG_TRCR_RX_EN | REG_TRCR_AUTO_FLV_CP;
break;
case BU92725GUW_MULTI_REV: //not used
val = REG_TRCR_RX_EN | REG_TRCR_RX_CON;
case BU92725GUW_MULTI_REV:
val = REG_TRCR_RX_EN | REG_TRCR_RX_CON;//FIR
break;
case BU92725GUW_SEND:
case BU92725GUW_MIR_SEND:
case BU92725GUW_FIR_SEND:
val = 0x0000;
break;
case BU92725GUW_MULTI_SEND:
val = REG_TRCR_TX_CON;
break;
@@ -660,20 +697,35 @@ static void internal_set(u8 modeChg)
case BU92725GUW_REV: /* SIR use */
val = REG_INT_EOFRX | REG_INT_TO | REG_INT_OE | REG_INT_FE; //IER1, 2, 5, 7
break;
case BU92725GUW_SEND: /* SIR use */
val = REG_INT_TXE; //IER3
case BU92725GUW_MIR_REV: /* MIR use */
val = REG_INT_STFRX | REG_INT_TO | REG_INT_OE | REG_INT_EOF
| REG_INT_AC | REG_INT_DECE; //IER1,2, 5, 6, 7
break;
case BU92725GUW_FIR_REV: /* FIR use */
val = REG_INT_STFRX | REG_INT_TO | REG_INT_CRC | REG_INT_OE | REG_INT_EOF
| REG_INT_AC | REG_INT_DECE; //IER1,2, 4, 5, 6, 7
break;
case BU92725GUW_MULTI_REV: /* not used */
val = REG_INT_STFRX | REG_INT_TO | REG_INT_CRC | REG_INT_OE | REG_INT_EOF | REG_INT_AC | REG_INT_DECE |
REG_INT_RDOE | REG_INT_DEX | REG_INT_RDUE; //IER1,2, 4, 5, 6, 7, 8, 9, 10
break;
case BU92725GUW_AUTO_MULTI_REV: /* M/FIR use */
val = REG_INT_TO | REG_INT_CRC | REG_INT_OE | REG_INT_EOF | REG_INT_AC | REG_INT_DECE |
REG_INT_RDOE | REG_INT_DEX | REG_INT_RDE; //IER2, 4, 5, 6, 7, 8, 9, 12
break;
case BU92725GUW_SEND: /* SIR use */
val = REG_INT_TXE; //IER3
break;
case BU92725GUW_MIR_SEND:
case BU92725GUW_FIR_SEND:
val = REG_INT_TXE | REG_INT_TO; //IER2, 3
break;
case BU92725GUW_MULTI_SEND: /* M/FIR use */
val = REG_INT_TO | REG_INT_TXE | REG_INT_WRE; //IER2, 3, 11
@@ -681,6 +733,7 @@ static void internal_set(u8 modeChg)
}
BU92725GUW_WRITE_REG(REG_IER_ADDR, val);
RK29IR_DBG("REG_IER_ADDR: 0x%x\n", val);
}

View File

@@ -162,6 +162,10 @@ enum eThrans_Way {
BU92725GUW_IDLE = 0,
BU92725GUW_REV, /* SIR use */
BU92725GUW_SEND, /* SIR use */
BU92725GUW_MIR_REV, /* MIR use */
BU92725GUW_MIR_SEND, /* MIR use */
BU92725GUW_FIR_REV, /* FIR use */
BU92725GUW_FIR_SEND, /* FIR use */
BU92725GUW_AUTO_MULTI_REV, /* M/FIR use */
BU92725GUW_MULTI_REV, /* not used */
BU92725GUW_MULTI_SEND, /* M/FIR use */

View File

@@ -59,7 +59,7 @@ struct irda_driver {
};
#define IS_FIR(si) ((si)->speed >= 4000000)
static int max_rate = 115200;
static int max_rate = 4000000;
#define IRDA_FRAME_SIZE_LIMIT BU92725GUW_FIFO_SIZE
#define RK29_MAX_RXLEN 2047
@@ -123,8 +123,8 @@ static int rk29_irda_set_speed(struct rk29_irda *si, int speed)
si->speed = speed;
irda_hw_set_speed(speed);
//irda_hw_set_speed(speed);
irda_hw_set_speed(1152000);//MIR
rk29_irda_rx_alloc(si);
local_irq_restore(flags);
@@ -154,10 +154,11 @@ static irqreturn_t rk29_irda_irq(int irq, void *dev_id)
//disable_irq(dev->irq);
/* EIR 1, 3, 11, 12 */
/* EIR 1, 3, 11, 12
irda_setptn |= irq_src & (REG_INT_EOFRX | REG_INT_TXE | REG_INT_WRE | REG_INT_RDE |
REG_INT_CRC | REG_INT_OE | REG_INT_FE | REG_INT_AC |
REG_INT_DECE | REG_INT_RDOE | REG_INT_DEX) ;
REG_INT_DECE | REG_INT_RDOE | REG_INT_DEX) ;*/
irda_setptn = irq_src;
/* error */
if (irq_src & (REG_INT_TO| REG_INT_CRC | REG_INT_OE | REG_INT_FE |
@@ -170,7 +171,7 @@ static irqreturn_t rk29_irda_irq(int irq, void *dev_id)
if (IS_FIR(si)) //FIR
{
RK29IR_DBG("[%s][%d]: FIR\n",__FUNCTION__,__LINE__);
if(irda_hw_get_mode() == BU92725GUW_AUTO_MULTI_REV) {//rx
if(irda_hw_get_mode() == BU92725GUW_MIR_REV) {//rx
struct sk_buff *skb = si->rxskb;
RK29IR_DBG("[%s][%d]: rx\n",__FUNCTION__,__LINE__);
if (irda_setptn & (REG_INT_FE | REG_INT_OE | REG_INT_CRC | REG_INT_DECE)) {
@@ -182,11 +183,11 @@ static irqreturn_t rk29_irda_irq(int irq, void *dev_id)
dev->stats.rx_errors++;
}
}
if ((irda_setptn & (FRM_EVT_RX_EOFRX | FRM_EVT_RX_RDE | REG_INT_EOF))) {
if (irda_setptn & FRM_EVT_RX_EOFRX) {
tmp_len = BU92725GUW_get_data(skb->data+skb->len);
skb->len += tmp_len;
}
if (irda_setptn & (REG_INT_EOF | FRM_EVT_RX_EOFRX)) {
if (irda_setptn & REG_INT_EOF) {
RK29IR_DBG("[%s][%d]: report data:\n",__FUNCTION__,__LINE__);
si->rxskb = NULL;
RK29IR_DATA_DBG("[%s][%d]: fir report data:\n",__FUNCTION__,__LINE__);
@@ -212,11 +213,11 @@ static irqreturn_t rk29_irda_irq(int irq, void *dev_id)
netif_rx(skb);
}
}
else if (irda_hw_get_mode() == BU92725GUW_MULTI_SEND) {//tx
else if (irda_hw_get_mode() == BU92725GUW_MIR_SEND) {//tx
struct sk_buff *skb = si->txskb;
si->txskb = NULL;
RK29IR_DBG("[%s][%d]: tx\n",__FUNCTION__,__LINE__);
if (irda_setptn & (FRM_EVT_TX_TXE | FRM_EVT_TX_WRE)) {
if (irda_setptn & FRM_EVT_TX_TXE) {
/*
* Do we need to change speed? Note that we're lazy
* here - we don't free the old rxskb. We don't need
@@ -471,13 +472,12 @@ static int rk29_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
dev->trans_start = jiffies;
BU92725GUW_send_data(si->tx_buff.data, si->tx_buff.len, NULL, 0);
si->tx_buff.len = 0;
}
else {
unsigned long mtt = irda_get_mtt(skb);
si->txskb = skb;
irda_hw_tx_enable_irq(BU92725GUW_FIR);
irda_hw_tx_enable_irq(BU92725GUW_MIR);
RK29IR_DATA_DBG("[%d][%s], fir transmit data:\n", __LINE__, __FUNCTION__);
for (i=0;i<skb->len;i++) {