예제 #1
0
static int au1k_irda_stop(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);

	au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);

	/* disable interrupts */
	irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) & ~IR_IEN);
	irda_write(aup, IR_CONFIG_1, 0);
	irda_write(aup, IR_ENABLE, 0); /* disable clock */

	if (aup->irlap) {
		irlap_close(aup->irlap);
		aup->irlap = NULL;
	}

	netif_stop_queue(dev);
	del_timer(&aup->timer);

	/* disable the interrupt */
	free_irq(aup->irq_tx, dev);
	free_irq(aup->irq_rx, dev);

	return 0;
}
예제 #2
0
static void au1k_tx_ack(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	volatile struct ring_dest *ptxd;

	ptxd = aup->tx_ring[aup->tx_tail];
	while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) {
		update_tx_stats(dev, ptxd->flags,
				(ptxd->count_1 << 8) | ptxd->count_0);
		ptxd->count_0 = 0;
		ptxd->count_1 = 0;
		wmb();
		aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1);
		ptxd = aup->tx_ring[aup->tx_tail];

		if (aup->tx_full) {
			aup->tx_full = 0;
			netif_wake_queue(dev);
		}
	}

	if (aup->tx_tail == aup->tx_head) {
		if (aup->newspeed) {
			au1k_irda_set_speed(dev, aup->newspeed);
			aup->newspeed = 0;
		} else {
			irda_write(aup, IR_CONFIG_1,
			    irda_read(aup, IR_CONFIG_1) & ~IR_TX_ENABLE);
			irda_write(aup, IR_CONFIG_1,
			    irda_read(aup, IR_CONFIG_1) | IR_RX_ENABLE);
			irda_write(aup, IR_RING_PROMPT, 0);
		}
	}
}
예제 #3
0
static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id)
{
	struct net_device *dev = dev_id;
	struct au1k_private *aup = netdev_priv(dev);

	irda_write(aup, IR_INT_CLEAR, 0); /* ack irda interrupts */

	au1k_irda_rx(dev);
	au1k_tx_ack(dev);

	return IRQ_HANDLED;
}
예제 #4
0
static int au1k_irda_rx(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	volatile struct ring_dest *prxd;
	struct sk_buff *skb;
	struct db_dest *pDB;
	u32 flags, count;

	prxd = aup->rx_ring[aup->rx_head];
	flags = prxd->flags;

	while (!(flags & AU_OWN))  {
		pDB = aup->rx_db_inuse[aup->rx_head];
		count = (prxd->count_1 << 8) | prxd->count_0;
		if (!(flags & IR_RX_ERROR)) {
			/* good frame */
			update_rx_stats(dev, flags, count);
			skb = alloc_skb(count + 1, GFP_ATOMIC);
			if (skb == NULL) {
				dev->stats.rx_dropped++;
				continue;
			}
			skb_reserve(skb, 1);
			if (aup->speed == 4000000)
				skb_put(skb, count);
			else
				skb_put(skb, count - 2);
			skb_copy_to_linear_data(skb, (void *)pDB->vaddr,
						count - 2);
			skb->dev = dev;
			skb_reset_mac_header(skb);
			skb->protocol = htons(ETH_P_IRDA);
			netif_rx(skb);
			prxd->count_0 = 0;
			prxd->count_1 = 0;
		}
		prxd->flags |= AU_OWN;
		aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1);
		irda_write(aup, IR_RING_PROMPT, 0);

		/* next descriptor */
		prxd = aup->rx_ring[aup->rx_head];
		flags = prxd->flags;

	}
	return 0;
}
예제 #5
0
static int au1k_irda_start(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	char hwname[32];
	int retval;

	retval = au1k_init(dev);
	if (retval) {
		printk(KERN_ERR "%s: error in au1k_init\n", dev->name);
		return retval;
	}

	retval = request_irq(aup->irq_tx, &au1k_irda_interrupt, 0,
			     dev->name, dev);
	if (retval) {
		printk(KERN_ERR "%s: unable to get IRQ %d\n",
				dev->name, dev->irq);
		return retval;
	}
	retval = request_irq(aup->irq_rx, &au1k_irda_interrupt, 0,
			     dev->name, dev);
	if (retval) {
		free_irq(aup->irq_tx, dev);
		printk(KERN_ERR "%s: unable to get IRQ %d\n",
				dev->name, dev->irq);
		return retval;
	}

	/* Give self a hardware name */
	sprintf(hwname, "Au1000 SIR/FIR");
	aup->irlap = irlap_open(dev, &aup->qos, hwname);
	netif_start_queue(dev);

	/* int enable */
	irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) | IR_IEN);

	/* power up */
	au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR);

	aup->timer.expires = RUN_AT((3 * HZ));
	aup->timer.data = (unsigned long)dev;
	return 0;
}
예제 #6
0
파일: device.c 프로젝트: ihipop/I-GNOKII
size_t device_write(const __ptr_t buf, size_t n, struct gn_statemachine *state)
{
	switch (state->device.type) {
	case GN_CT_DKU2:
	case GN_CT_Serial:
	case GN_CT_Infrared:
		return serial_write(state->device.fd, buf, n, state);
	case GN_CT_Irda:
		return irda_write(state->device.fd, buf, n, state);
	case GN_CT_Bluetooth:
		return bluetooth_write(state->device.fd, buf, n, state);
	case GN_CT_Tekram:
		return tekram_write(state->device.fd, buf, n, state);
	case GN_CT_TCP:
		return tcp_write(state->device.fd, buf, n, state);
	case GN_CT_DKU2LIBUSB:
		return fbusdku2usb_write(buf, n, state);
	case GN_CT_SOCKETPHONET:
		return socketphonet_write(state->device.fd, buf, n, state);
	default:
		break;
	}
	return 0;
}
예제 #7
0
static int au1k_init(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	u32 enable, ring_address;
	int i;

	enable = IR_HC | IR_CE | IR_C;
#ifndef CONFIG_CPU_LITTLE_ENDIAN
	enable |= IR_BE;
#endif
	aup->tx_head = 0;
	aup->tx_tail = 0;
	aup->rx_head = 0;

	for (i = 0; i < NUM_IR_DESC; i++)
		aup->rx_ring[i]->flags = AU_OWN;

	irda_write(aup, IR_ENABLE, enable);
	msleep(20);

	/* disable PHY */
	au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
	irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN);
	msleep(20);

	irda_write(aup, IR_MAX_PKT_LEN, MAX_BUF_SIZE);

	ring_address = (u32)virt_to_phys((void *)aup->rx_ring[0]);
	irda_write(aup, IR_RING_BASE_ADDR_H, ring_address >> 26);
	irda_write(aup, IR_RING_BASE_ADDR_L, (ring_address >> 10) & 0xffff);

	irda_write(aup, IR_RING_SIZE,
				(RING_SIZE_64 << 8) | (RING_SIZE_64 << 12));

	irda_write(aup, IR_CONFIG_2, IR_PHYCLK_48MHZ | IR_ONE_PIN);
	irda_write(aup, IR_RING_ADDR_CMPR, 0);

	au1k_irda_set_speed(dev, 9600);
	return 0;
}
예제 #8
0
/*
 * Set the IrDA communications speed.
 */
static int au1k_irda_set_speed(struct net_device *dev, int speed)
{
	struct au1k_private *aup = netdev_priv(dev);
	volatile struct ring_dest *ptxd;
	unsigned long control;
	int ret = 0, timeout = 10, i;

	if (speed == aup->speed)
		return ret;

	/* disable PHY first */
	au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
	irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN);

	/* disable RX/TX */
	irda_write(aup, IR_CONFIG_1,
	    irda_read(aup, IR_CONFIG_1) & ~(IR_RX_ENABLE | IR_TX_ENABLE));
	msleep(20);
	while (irda_read(aup, IR_STATUS) & (IR_RX_STATUS | IR_TX_STATUS)) {
		msleep(20);
		if (!timeout--) {
			printk(KERN_ERR "%s: rx/tx disable timeout\n",
					dev->name);
			break;
		}
	}

	/* disable DMA */
	irda_write(aup, IR_CONFIG_1,
		   irda_read(aup, IR_CONFIG_1) & ~IR_DMA_ENABLE);
	msleep(20);

	/* After we disable tx/rx. the index pointers go back to zero. */
	aup->tx_head = aup->tx_tail = aup->rx_head = 0;
	for (i = 0; i < NUM_IR_DESC; i++) {
		ptxd = aup->tx_ring[i];
		ptxd->flags = 0;
		ptxd->count_0 = 0;
		ptxd->count_1 = 0;
	}

	for (i = 0; i < NUM_IR_DESC; i++) {
		ptxd = aup->rx_ring[i];
		ptxd->count_0 = 0;
		ptxd->count_1 = 0;
		ptxd->flags = AU_OWN;
	}

	if (speed == 4000000)
		au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_FIR);
	else
		au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR);

	switch (speed) {
	case 9600:
		irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(11) | IR_PW(12));
		irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
		break;
	case 19200:
		irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(5) | IR_PW(12));
		irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
		break;
	case 38400:
		irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(2) | IR_PW(12));
		irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
		break;
	case 57600:
		irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(1) | IR_PW(12));
		irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
		break;
	case 115200:
		irda_write(aup, IR_WRITE_PHY_CONFIG, IR_PW(12));
		irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
		break;
	case 4000000:
		irda_write(aup, IR_WRITE_PHY_CONFIG, IR_P(15));
		irda_write(aup, IR_CONFIG_1, IR_FIR | IR_DMA_ENABLE |
				IR_RX_ENABLE);
		break;
	default:
		printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed);
		ret = -EINVAL;
		break;
	}

	aup->speed = speed;
	irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) | IR_PHYEN);

	control = irda_read(aup, IR_STATUS);
	irda_write(aup, IR_RING_PROMPT, 0);

	if (control & (1 << 14)) {
		printk(KERN_ERR "%s: configuration error\n", dev->name);
	} else {
		if (control & (1 << 11))
			printk(KERN_DEBUG "%s Valid SIR config\n", dev->name);
		if (control & (1 << 12))
			printk(KERN_DEBUG "%s Valid MIR config\n", dev->name);
		if (control & (1 << 13))
			printk(KERN_DEBUG "%s Valid FIR config\n", dev->name);
		if (control & (1 << 10))
			printk(KERN_DEBUG "%s TX enabled\n", dev->name);
		if (control & (1 << 9))
			printk(KERN_DEBUG "%s RX enabled\n", dev->name);
	}

	return ret;
}