|
@@ -164,151 +164,6 @@ static int sa1100_irda_sir_tx_start(struct sk_buff *skb, struct net_device *dev,
|
|
|
return NETDEV_TX_OK;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * FIR format support.
|
|
|
- */
|
|
|
-static int sa1100_irda_fir_tx_start(struct sk_buff *skb, struct net_device *dev,
|
|
|
- struct sa1100_irda *si)
|
|
|
-{
|
|
|
- int mtt = irda_get_mtt(skb);
|
|
|
-
|
|
|
- si->dma_tx.skb = skb;
|
|
|
- si->dma_tx.dma = dma_map_single(si->dev, skb->data, skb->len,
|
|
|
- DMA_TO_DEVICE);
|
|
|
- if (dma_mapping_error(si->dev, si->dma_tx.dma)) {
|
|
|
- si->dma_tx.skb = NULL;
|
|
|
- netif_wake_queue(dev);
|
|
|
- dev->stats.tx_dropped++;
|
|
|
- dev_kfree_skb(skb);
|
|
|
- return NETDEV_TX_OK;
|
|
|
- }
|
|
|
-
|
|
|
- sa1100_start_dma(si->dma_tx.regs, si->dma_tx.dma, skb->len);
|
|
|
-
|
|
|
- /*
|
|
|
- * If we have a mean turn-around time, impose the specified
|
|
|
- * specified delay. We could shorten this by timing from
|
|
|
- * the point we received the packet.
|
|
|
- */
|
|
|
- if (mtt)
|
|
|
- udelay(mtt);
|
|
|
-
|
|
|
- Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_TXE;
|
|
|
-
|
|
|
- return NETDEV_TX_OK;
|
|
|
-}
|
|
|
-
|
|
|
-static irqreturn_t sa1100_irda_sir_irq(struct net_device *, struct sa1100_irda *);
|
|
|
-static irqreturn_t sa1100_irda_fir_irq(struct net_device *, struct sa1100_irda *);
|
|
|
-
|
|
|
-/*
|
|
|
- * Set the IrDA communications speed.
|
|
|
- */
|
|
|
-static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
|
|
|
-{
|
|
|
- unsigned long flags;
|
|
|
- int brd, ret = -EINVAL;
|
|
|
-
|
|
|
- switch (speed) {
|
|
|
- case 9600: case 19200: case 38400:
|
|
|
- case 57600: case 115200:
|
|
|
- brd = 3686400 / (16 * speed) - 1;
|
|
|
-
|
|
|
- /*
|
|
|
- * Stop the receive DMA.
|
|
|
- */
|
|
|
- if (IS_FIR(si))
|
|
|
- sa1100_stop_dma(si->dma_rx.regs);
|
|
|
-
|
|
|
- local_irq_save(flags);
|
|
|
-
|
|
|
- Ser2UTCR3 = 0;
|
|
|
- Ser2HSCR0 = HSCR0_UART;
|
|
|
-
|
|
|
- Ser2UTCR1 = brd >> 8;
|
|
|
- Ser2UTCR2 = brd;
|
|
|
-
|
|
|
- /*
|
|
|
- * Clear status register
|
|
|
- */
|
|
|
- Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
|
|
|
- Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
|
|
|
-
|
|
|
- if (si->pdata->set_speed)
|
|
|
- si->pdata->set_speed(si->dev, speed);
|
|
|
-
|
|
|
- si->speed = speed;
|
|
|
- si->tx_start = sa1100_irda_sir_tx_start;
|
|
|
- si->irq = sa1100_irda_sir_irq;
|
|
|
-
|
|
|
- local_irq_restore(flags);
|
|
|
- ret = 0;
|
|
|
- break;
|
|
|
-
|
|
|
- case 4000000:
|
|
|
- local_irq_save(flags);
|
|
|
-
|
|
|
- si->hscr0 = 0;
|
|
|
-
|
|
|
- Ser2HSSR0 = 0xff;
|
|
|
- Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;
|
|
|
- Ser2UTCR3 = 0;
|
|
|
-
|
|
|
- si->speed = speed;
|
|
|
- si->tx_start = sa1100_irda_fir_tx_start;
|
|
|
- si->irq = sa1100_irda_fir_irq;
|
|
|
-
|
|
|
- if (si->pdata->set_speed)
|
|
|
- si->pdata->set_speed(si->dev, speed);
|
|
|
-
|
|
|
- sa1100_irda_rx_alloc(si);
|
|
|
- sa1100_irda_rx_dma_start(si);
|
|
|
-
|
|
|
- local_irq_restore(flags);
|
|
|
-
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * Control the power state of the IrDA transmitter.
|
|
|
- * State:
|
|
|
- * 0 - off
|
|
|
- * 1 - short range, lowest power
|
|
|
- * 2 - medium range, medium power
|
|
|
- * 3 - maximum range, high power
|
|
|
- *
|
|
|
- * Currently, only assabet is known to support this.
|
|
|
- */
|
|
|
-static int
|
|
|
-__sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state)
|
|
|
-{
|
|
|
- int ret = 0;
|
|
|
- if (si->pdata->set_power)
|
|
|
- ret = si->pdata->set_power(si->dev, state);
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-static inline int
|
|
|
-sa1100_set_power(struct sa1100_irda *si, unsigned int state)
|
|
|
-{
|
|
|
- int ret;
|
|
|
-
|
|
|
- ret = __sa1100_irda_set_power(si, state);
|
|
|
- if (ret == 0)
|
|
|
- si->power = state;
|
|
|
-
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
- * HP-SIR format interrupt service routines.
|
|
|
- */
|
|
|
static irqreturn_t sa1100_irda_sir_irq(struct net_device *dev, struct sa1100_irda *si)
|
|
|
{
|
|
|
int status;
|
|
@@ -403,6 +258,40 @@ static irqreturn_t sa1100_irda_sir_irq(struct net_device *dev, struct sa1100_ird
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * FIR format support.
|
|
|
+ */
|
|
|
+static int sa1100_irda_fir_tx_start(struct sk_buff *skb, struct net_device *dev,
|
|
|
+ struct sa1100_irda *si)
|
|
|
+{
|
|
|
+ int mtt = irda_get_mtt(skb);
|
|
|
+
|
|
|
+ si->dma_tx.skb = skb;
|
|
|
+ si->dma_tx.dma = dma_map_single(si->dev, skb->data, skb->len,
|
|
|
+ DMA_TO_DEVICE);
|
|
|
+ if (dma_mapping_error(si->dev, si->dma_tx.dma)) {
|
|
|
+ si->dma_tx.skb = NULL;
|
|
|
+ netif_wake_queue(dev);
|
|
|
+ dev->stats.tx_dropped++;
|
|
|
+ dev_kfree_skb(skb);
|
|
|
+ return NETDEV_TX_OK;
|
|
|
+ }
|
|
|
+
|
|
|
+ sa1100_start_dma(si->dma_tx.regs, si->dma_tx.dma, skb->len);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * If we have a mean turn-around time, impose the specified
|
|
|
+ * specified delay. We could shorten this by timing from
|
|
|
+ * the point we received the packet.
|
|
|
+ */
|
|
|
+ if (mtt)
|
|
|
+ udelay(mtt);
|
|
|
+
|
|
|
+ Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_TXE;
|
|
|
+
|
|
|
+ return NETDEV_TX_OK;
|
|
|
+}
|
|
|
+
|
|
|
static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev)
|
|
|
{
|
|
|
struct sk_buff *skb = si->dma_rx.skb;
|
|
@@ -476,10 +365,8 @@ static void sa1100_irda_fir_error(struct sa1100_irda *si, struct net_device *dev
|
|
|
}
|
|
|
|
|
|
/*
|
|
|
- * FIR format interrupt service routine. We only have to
|
|
|
- * handle RX events; transmit events go via the TX DMA handler.
|
|
|
- *
|
|
|
- * No matter what, we disable RX, process, and the restart RX.
|
|
|
+ * We only have to handle RX events here; transmit events go via the TX
|
|
|
+ * DMA handler. We disable RX, process, and the restart RX.
|
|
|
*/
|
|
|
static irqreturn_t sa1100_irda_fir_irq(struct net_device *dev, struct sa1100_irda *si)
|
|
|
{
|
|
@@ -528,6 +415,111 @@ static irqreturn_t sa1100_irda_fir_irq(struct net_device *dev, struct sa1100_ird
|
|
|
return IRQ_HANDLED;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Set the IrDA communications speed.
|
|
|
+ */
|
|
|
+static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
|
|
|
+{
|
|
|
+ unsigned long flags;
|
|
|
+ int brd, ret = -EINVAL;
|
|
|
+
|
|
|
+ switch (speed) {
|
|
|
+ case 9600: case 19200: case 38400:
|
|
|
+ case 57600: case 115200:
|
|
|
+ brd = 3686400 / (16 * speed) - 1;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Stop the receive DMA.
|
|
|
+ */
|
|
|
+ if (IS_FIR(si))
|
|
|
+ sa1100_stop_dma(si->dma_rx.regs);
|
|
|
+
|
|
|
+ local_irq_save(flags);
|
|
|
+
|
|
|
+ Ser2UTCR3 = 0;
|
|
|
+ Ser2HSCR0 = HSCR0_UART;
|
|
|
+
|
|
|
+ Ser2UTCR1 = brd >> 8;
|
|
|
+ Ser2UTCR2 = brd;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Clear status register
|
|
|
+ */
|
|
|
+ Ser2UTSR0 = UTSR0_REB | UTSR0_RBB | UTSR0_RID;
|
|
|
+ Ser2UTCR3 = UTCR3_RIE | UTCR3_RXE | UTCR3_TXE;
|
|
|
+
|
|
|
+ if (si->pdata->set_speed)
|
|
|
+ si->pdata->set_speed(si->dev, speed);
|
|
|
+
|
|
|
+ si->speed = speed;
|
|
|
+ si->tx_start = sa1100_irda_sir_tx_start;
|
|
|
+ si->irq = sa1100_irda_sir_irq;
|
|
|
+
|
|
|
+ local_irq_restore(flags);
|
|
|
+ ret = 0;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 4000000:
|
|
|
+ local_irq_save(flags);
|
|
|
+
|
|
|
+ si->hscr0 = 0;
|
|
|
+
|
|
|
+ Ser2HSSR0 = 0xff;
|
|
|
+ Ser2HSCR0 = si->hscr0 | HSCR0_HSSP;
|
|
|
+ Ser2UTCR3 = 0;
|
|
|
+
|
|
|
+ si->speed = speed;
|
|
|
+ si->tx_start = sa1100_irda_fir_tx_start;
|
|
|
+ si->irq = sa1100_irda_fir_irq;
|
|
|
+
|
|
|
+ if (si->pdata->set_speed)
|
|
|
+ si->pdata->set_speed(si->dev, speed);
|
|
|
+
|
|
|
+ sa1100_irda_rx_alloc(si);
|
|
|
+ sa1100_irda_rx_dma_start(si);
|
|
|
+
|
|
|
+ local_irq_restore(flags);
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Control the power state of the IrDA transmitter.
|
|
|
+ * State:
|
|
|
+ * 0 - off
|
|
|
+ * 1 - short range, lowest power
|
|
|
+ * 2 - medium range, medium power
|
|
|
+ * 3 - maximum range, high power
|
|
|
+ *
|
|
|
+ * Currently, only assabet is known to support this.
|
|
|
+ */
|
|
|
+static int
|
|
|
+__sa1100_irda_set_power(struct sa1100_irda *si, unsigned int state)
|
|
|
+{
|
|
|
+ int ret = 0;
|
|
|
+ if (si->pdata->set_power)
|
|
|
+ ret = si->pdata->set_power(si->dev, state);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+static inline int
|
|
|
+sa1100_set_power(struct sa1100_irda *si, unsigned int state)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ret = __sa1100_irda_set_power(si, state);
|
|
|
+ if (ret == 0)
|
|
|
+ si->power = state;
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static irqreturn_t sa1100_irda_irq(int irq, void *dev_id)
|
|
|
{
|
|
|
struct net_device *dev = dev_id;
|