[PATCH] IrDA support for au1000/au1100

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello.

Here a patch for IrDA support on au1000 and au1100 CPUs in order to
work with linux 2.6.x.

I tested the software with an au1100 based board.

Ciao,

Rodolfo

-- 

GNU/Linux Solutions                  e-mail:    giometti@xxxxxxxxxxxx
Linux Device Driver                             giometti@xxxxxxxxx
Embedded Systems                     		giometti@xxxxxxxx
UNIX programming                     phone:     +39 349 2432127
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index d54156f..190138e 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -342,8 +342,8 @@ config TOSHIBA_FIR
 	  donauboe.
 
 config AU1000_FIR
-	tristate "Alchemy Au1000 SIR/FIR"
-	depends on MIPS_AU1000 && IRDA
+	tristate "Alchemy Au1000/Au1100 SIR/FIR"
+	depends on ( SOC_AU1000 || SOC_AU1100 ) && IRDA
 
 config SMC_IRCC_FIR
 	tristate "SMSC IrCC (EXPERIMENTAL)"
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c
index e6b1985..34071f3 100644
--- a/drivers/net/irda/au1k_ir.c
+++ b/drivers/net/irda/au1k_ir.c
@@ -5,6 +5,8 @@
  * Author: MontaVista Software, Inc.
  *         	ppopov@xxxxxxxxxx or source@xxxxxxxxxx
  *
+ * Driver ported to Linux 2.6.x by Rodolfo Giometti <giometti@xxxxxxxx>
+ *
  *  This program is free software; you can distribute it and/or modify it
  *  under the terms of the GNU General Public License (Version 2) as
  *  published by the Free Software Foundation.
@@ -32,19 +34,13 @@
 
 #include <asm/irq.h>
 #include <asm/io.h>
-#include <asm/au1000.h>
-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100)
-#include <asm/pb1000.h>
-#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
-#include <asm/db1x00.h>
-#else 
-#error au1k_ir: unsupported board
-#endif
 
 #include <net/irda/irda.h>
 #include <net/irda/irmod.h>
 #include <net/irda/wrapper.h>
 #include <net/irda/irda_device.h>
+
+#include <au1xxx.h>
 #include "au1000_ircc.h"
 
 static int au1k_irda_net_init(struct net_device *);
@@ -52,7 +48,7 @@ static int au1k_irda_start(struct net_de
 static int au1k_irda_stop(struct net_device *dev);
 static int au1k_irda_hard_xmit(struct sk_buff *, struct net_device *);
 static int au1k_irda_rx(struct net_device *);
-static void au1k_irda_interrupt(int, void *, struct pt_regs *);
+static irqreturn_t au1k_irda_interrupt(int, void *, struct pt_regs *);
 static void au1k_tx_timeout(struct net_device *);
 static struct net_device_stats *au1k_irda_stats(struct net_device *);
 static int au1k_irda_ioctl(struct net_device *, struct ifreq *, int);
@@ -78,12 +74,16 @@ static DEFINE_SPINLOCK(ir_lock);
  * IrDA peripheral bug. You have to read the register
  * twice to get the right value.
  */
-u32 read_ir_reg(u32 addr) 
+static inline u32 read_ir_reg(unsigned long addr) 
 { 
-	readl(addr);
-	return readl(addr);
+	au_readl(addr);
+	return au_readl(addr);
 }
 
+static inline void write_ir_reg(u32 data, unsigned long addr) 
+{ 
+	au_writel(data, addr);
+}
 
 /*
  * Buffer allocation/deallocation routines. The buffer descriptor returned
@@ -259,7 +259,7 @@ static int au1k_irda_net_init(struct net
 	/* attach a data buffer to each descriptor */
 	for (i=0; i<NUM_IR_DESC; i++) {
 		pDB = GetFreeDB(aup);
-		if (!pDB) goto out;
+		if (!pDB) goto out3;
 		aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
 		aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
 		aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
@@ -268,7 +268,7 @@ static int au1k_irda_net_init(struct net
 	}
 	for (i=0; i<NUM_IR_DESC; i++) {
 		pDB = GetFreeDB(aup);
-		if (!pDB) goto out;
+		if (!pDB) goto out4;
 		aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
 		aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
 		aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
@@ -288,6 +288,9 @@ static int au1k_irda_net_init(struct net
 
 	return 0;
 
+out4:
+	ReleaseDB(aup, pDB);
+
 out3:
 	dma_free((void *)aup->rx_ring[0],
 		2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
@@ -320,22 +323,22 @@ static int au1k_init(struct net_device *
 		aup->rx_ring[i]->flags = AU_OWN;
 	}
 
-	writel(control, IR_INTERFACE_CONFIG);
+	write_ir_reg(control, IR_INTERFACE_CONFIG);
 	au_sync_delay(10);
 
-	writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); /* disable PHY */
+	write_ir_reg(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); /* disable PHY */
 	au_sync_delay(1);
 
-	writel(MAX_BUF_SIZE, IR_MAX_PKT_LEN);
+	write_ir_reg(MAX_BUF_SIZE, IR_MAX_PKT_LEN);
 
 	ring_address = (u32)virt_to_phys((void *)aup->rx_ring[0]);
-	writel(ring_address >> 26, IR_RING_BASE_ADDR_H);
-	writel((ring_address >> 10) & 0xffff, IR_RING_BASE_ADDR_L);
+	write_ir_reg(ring_address >> 26, IR_RING_BASE_ADDR_H);
+	write_ir_reg((ring_address >> 10) & 0xffff, IR_RING_BASE_ADDR_L);
 
-	writel(RING_SIZE_64<<8 | RING_SIZE_64<<12, IR_RING_SIZE);
+	write_ir_reg(RING_SIZE_64<<8 | RING_SIZE_64<<12, IR_RING_SIZE);
 
-	writel(1<<2 | IR_ONE_PIN, IR_CONFIG_2); /* 48MHz */
-	writel(0, IR_RING_ADDR_CMPR);
+	write_ir_reg(1<<2 | IR_ONE_PIN, IR_CONFIG_2); /* 48MHz */
+	write_ir_reg(0, IR_RING_ADDR_CMPR);
 
 	au1k_irda_set_speed(dev, 9600);
 	return 0;
@@ -352,13 +355,13 @@ static int au1k_irda_start(struct net_de
 		return retval;
 	}
 
-	if ((retval = request_irq(AU1000_IRDA_TX_INT, &au1k_irda_interrupt, 
+	if ((retval = request_irq(AU1000_IRDA_TX_INT, au1k_irda_interrupt, 
 					0, dev->name, dev))) {
 		printk(KERN_ERR "%s: unable to get IRQ %d\n", 
 				dev->name, dev->irq);
 		return retval;
 	}
-	if ((retval = request_irq(AU1000_IRDA_RX_INT, &au1k_irda_interrupt, 
+	if ((retval = request_irq(AU1000_IRDA_RX_INT, au1k_irda_interrupt, 
 					0, dev->name, dev))) {
 		free_irq(AU1000_IRDA_TX_INT, dev);
 		printk(KERN_ERR "%s: unable to get IRQ %d\n", 
@@ -371,7 +374,7 @@ static int au1k_irda_start(struct net_de
 	aup->irlap = irlap_open(dev, &aup->qos, hwname);
 	netif_start_queue(dev);
 
-	writel(read_ir_reg(IR_CONFIG_2) | 1<<8, IR_CONFIG_2); /* int enable */
+	write_ir_reg(read_ir_reg(IR_CONFIG_2) | 1<<8, IR_CONFIG_2); /* int enable */
 
 	aup->timer.expires = RUN_AT((3*HZ)); 
 	aup->timer.data = (unsigned long)dev;
@@ -383,9 +386,9 @@ static int au1k_irda_stop(struct net_dev
 	struct au1k_private *aup = netdev_priv(dev);
 
 	/* disable interrupts */
-	writel(read_ir_reg(IR_CONFIG_2) & ~(1<<8), IR_CONFIG_2);
-	writel(0, IR_CONFIG_1); 
-	writel(0, IR_INTERFACE_CONFIG); /* disable clock */
+	write_ir_reg(read_ir_reg(IR_CONFIG_2) & ~(1<<8), IR_CONFIG_2);
+	write_ir_reg(0, IR_CONFIG_1); 
+	write_ir_reg(0, IR_INTERFACE_CONFIG); /* disable clock */
 	au_sync();
 
 	if (aup->irlap) {
@@ -462,12 +465,12 @@ static void au1k_tx_ack(struct net_devic
 			aup->newspeed = 0;
 		}
 		else {
-			writel(read_ir_reg(IR_CONFIG_1) & ~IR_TX_ENABLE, 
+			write_ir_reg(read_ir_reg(IR_CONFIG_1) & ~IR_TX_ENABLE, 
 					IR_CONFIG_1); 
 			au_sync();
-			writel(read_ir_reg(IR_CONFIG_1) | IR_RX_ENABLE, 
+			write_ir_reg(read_ir_reg(IR_CONFIG_1) | IR_RX_ENABLE, 
 					IR_CONFIG_1); 
-			writel(0, IR_RING_PROMPT);
+			write_ir_reg(0, IR_RING_PROMPT);
 			au_sync();
 		}
 	}
@@ -543,8 +546,8 @@ static int au1k_irda_hard_xmit(struct sk
 	ptxd->flags |= AU_OWN;
 	au_sync();
 
-	writel(read_ir_reg(IR_CONFIG_1) | IR_TX_ENABLE, IR_CONFIG_1); 
-	writel(0, IR_RING_PROMPT);
+	write_ir_reg(read_ir_reg(IR_CONFIG_1) | IR_TX_ENABLE, IR_CONFIG_1); 
+	write_ir_reg(0, IR_RING_PROMPT);
 	au_sync();
 
 	dev_kfree_skb(skb);
@@ -615,7 +618,7 @@ static int au1k_irda_rx(struct net_devic
 		}
 		prxd->flags |= AU_OWN;
 		aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1);
-		writel(0, IR_RING_PROMPT);
+		write_ir_reg(0, IR_RING_PROMPT);
 		au_sync();
 
 		/* next descriptor */
@@ -628,19 +631,21 @@ static int au1k_irda_rx(struct net_devic
 }
 
 
-void au1k_irda_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t au1k_irda_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
 
 	if (dev == NULL) {
 		printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name);
-		return;
+		return IRQ_NONE;
 	}
 
-	writel(0, IR_INT_CLEAR); /* ack irda interrupts */
+	write_ir_reg(0, IR_INT_CLEAR); /* ack irda interrupts */
 
 	au1k_irda_rx(dev);
 	au1k_tx_ack(dev);
+
+	return IRQ_HANDLED;
 }
 
 
@@ -683,10 +688,10 @@ au1k_irda_set_speed(struct net_device *d
 	spin_lock_irqsave(&ir_lock, flags);
 
 	/* disable PHY first */
-	writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE);
+	write_ir_reg(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE);
 
 	/* disable RX/TX */
-	writel(read_ir_reg(IR_CONFIG_1) & ~(IR_RX_ENABLE|IR_TX_ENABLE), 
+	write_ir_reg(read_ir_reg(IR_CONFIG_1) & ~(IR_RX_ENABLE|IR_TX_ENABLE), 
 			IR_CONFIG_1);
 	au_sync_delay(1);
 	while (read_ir_reg(IR_ENABLE) & (IR_RX_STATUS | IR_TX_STATUS)) {
@@ -699,7 +704,7 @@ au1k_irda_set_speed(struct net_device *d
 	}
 
 	/* disable DMA */
-	writel(read_ir_reg(IR_CONFIG_1) & ~IR_DMA_ENABLE, IR_CONFIG_1);
+	write_ir_reg(read_ir_reg(IR_CONFIG_1) & ~IR_DMA_ENABLE, IR_CONFIG_1);
 	au_sync_delay(1);
 
 	/* 
@@ -724,42 +729,42 @@ au1k_irda_set_speed(struct net_device *d
 	if (speed == 4000000) {
 #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
 		bcsr->resets |= BCSR_RESETS_FIR_SEL;
-#else /* Pb1000 and Pb1100 */
-		writel(1<<13, CPLD_AUX1);
+#elif defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100)
+		write_ir_reg(1<<13, CPLD_AUX1);
 #endif
 	}
 	else {
 #if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
 		bcsr->resets &= ~BCSR_RESETS_FIR_SEL;
-#else /* Pb1000 and Pb1100 */
-		writel(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1);
+#elif defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100)
+		write_ir_reg(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1);
 #endif
 	}
 
 	switch (speed) {
 	case 9600:	
-		writel(11<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
-		writel(IR_SIR_MODE, IR_CONFIG_1); 
+		write_ir_reg(11<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
+		write_ir_reg(IR_SIR_MODE, IR_CONFIG_1); 
 		break;
 	case 19200:	
-		writel(5<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
-		writel(IR_SIR_MODE, IR_CONFIG_1); 
+		write_ir_reg(5<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
+		write_ir_reg(IR_SIR_MODE, IR_CONFIG_1); 
 		break;
 	case 38400:
-		writel(2<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
-		writel(IR_SIR_MODE, IR_CONFIG_1); 
+		write_ir_reg(2<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
+		write_ir_reg(IR_SIR_MODE, IR_CONFIG_1); 
 		break;
 	case 57600:	
-		writel(1<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
-		writel(IR_SIR_MODE, IR_CONFIG_1); 
+		write_ir_reg(1<<10 | 12<<5, IR_WRITE_PHY_CONFIG); 
+		write_ir_reg(IR_SIR_MODE, IR_CONFIG_1); 
 		break;
 	case 115200: 
-		writel(12<<5, IR_WRITE_PHY_CONFIG); 
-		writel(IR_SIR_MODE, IR_CONFIG_1); 
+		write_ir_reg(12<<5, IR_WRITE_PHY_CONFIG); 
+		write_ir_reg(IR_SIR_MODE, IR_CONFIG_1); 
 		break;
 	case 4000000:
-		writel(0xF, IR_WRITE_PHY_CONFIG);
-		writel(IR_FIR|IR_DMA_ENABLE|IR_RX_ENABLE, IR_CONFIG_1); 
+		write_ir_reg(0xF, IR_WRITE_PHY_CONFIG);
+		write_ir_reg(IR_FIR|IR_DMA_ENABLE|IR_RX_ENABLE, IR_CONFIG_1); 
 		break;
 	default:
 		printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed);
@@ -768,11 +773,11 @@ au1k_irda_set_speed(struct net_device *d
 	}
 
 	aup->speed = speed;
-	writel(read_ir_reg(IR_ENABLE) | 0x8000, IR_ENABLE);
+	write_ir_reg(read_ir_reg(IR_ENABLE) | 0x8000, IR_ENABLE);
 	au_sync();
 
 	control = read_ir_reg(IR_ENABLE);
-	writel(0, IR_RING_PROMPT);
+	write_ir_reg(0, IR_RING_PROMPT);
 	au_sync();
 
 	if (control & (1<<14)) {

[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux