static inline void w83697hf_lock(void)
{
	outb_p(0xAA, W83697HF_EFER);	/* Leave extended function mode */
}
Example #2
0
/* Probe for the Etherlink II card at I/O port base IOADDR,
   returning non-zero on success.  If found, set the station
   address and memory parameters in DEVICE. */
static int __init
el2_probe1(struct net_device *dev, int ioaddr)
{
    int i, iobase_reg, membase_reg, saved_406, wordlength, retval;
    static unsigned version_printed;
    unsigned long vendor_id;

    if (!request_region(ioaddr, EL2_IO_EXTENT, DRV_NAME))
	return -EBUSY;

    if (!request_region(ioaddr + 0x400, 8, DRV_NAME)) {
	retval = -EBUSY;
	goto out;
    }

    /* Reset and/or avoid any lurking NE2000 */
    if (inb(ioaddr + 0x408) == 0xff) {
    	mdelay(1);
	retval = -ENODEV;
	goto out1;
    }

    /* We verify that it's a 3C503 board by checking the first three octets
       of its ethernet address. */
    iobase_reg = inb(ioaddr+0x403);
    membase_reg = inb(ioaddr+0x404);
    /* ASIC location registers should be 0 or have only a single bit set. */
    if ((iobase_reg  & (iobase_reg - 1)) ||
	(membase_reg & (membase_reg - 1))) {
	retval = -ENODEV;
	goto out1;
    }
    saved_406 = inb_p(ioaddr + 0x406);
    outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406); /* Reset it... */
    outb_p(ECNTRL_THIN, ioaddr + 0x406);
    /* Map the station addr PROM into the lower I/O ports. We now check
       for both the old and new 3Com prefix */
    outb(ECNTRL_SAPROM|ECNTRL_THIN, ioaddr + 0x406);
    vendor_id = inb(ioaddr)*0x10000 + inb(ioaddr + 1)*0x100 + inb(ioaddr + 2);
    if ((vendor_id != OLD_3COM_ID) && (vendor_id != NEW_3COM_ID)) {
	/* Restore the register we frobbed. */
	outb(saved_406, ioaddr + 0x406);
	retval = -ENODEV;
	goto out1;
    }

    if (ei_debug  &&  version_printed++ == 0)
	pr_debug("%s", version);

    dev->base_addr = ioaddr;

    pr_info("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);

    /* Retrieve and print the ethernet address. */
    for (i = 0; i < 6; i++)
	dev->dev_addr[i] = inb(ioaddr + i);
    pr_cont("%pM", dev->dev_addr);

    /* Map the 8390 back into the window. */
    outb(ECNTRL_THIN, ioaddr + 0x406);

    /* Check for EL2/16 as described in tech. man. */
    outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
    outb_p(0, ioaddr + EN0_DCFG);
    outb_p(E8390_PAGE2, ioaddr + E8390_CMD);
    wordlength = inb_p(ioaddr + EN0_DCFG) & ENDCFG_WTS;
    outb_p(E8390_PAGE0, ioaddr + E8390_CMD);

    /* Probe for, turn on and clear the board's shared memory. */
    if (ei_debug > 2)
	pr_cont(" memory jumpers %2.2x ", membase_reg);
    outb(EGACFR_NORM, ioaddr + 0x405);	/* Enable RAM */

    /* This should be probed for (or set via an ioctl()) at run-time.
       Right now we use a sleazy hack to pass in the interface number
       at boot-time via the low bits of the mem_end field.  That value is
       unused, and the low bits would be discarded even if it was used. */
#if defined(EI8390_THICK) || defined(EL2_AUI)
    ei_status.interface_num = 1;
#else
    ei_status.interface_num = dev->mem_end & 0xf;
#endif
    pr_cont(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");

    if ((membase_reg & 0xf0) == 0) {
	dev->mem_start = 0;
	ei_status.name = "3c503-PIO";
	ei_status.mem = NULL;
    } else {
	dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) +
	    ((membase_reg & 0xA0) ? 0x4000 : 0);
#define EL2_MEMSIZE (EL2_MB1_STOP_PG - EL2_MB1_START_PG)*256
	ei_status.mem = ioremap(dev->mem_start, EL2_MEMSIZE);

#ifdef EL2MEMTEST
	/* This has never found an error, but someone might care.
	   Note that it only tests the 2nd 8kB on 16kB 3c503/16
	   cards between card addr. 0x2000 and 0x3fff. */
	{			/* Check the card's memory. */
	    void __iomem *mem_base = ei_status.mem;
	    unsigned int test_val = 0xbbadf00d;
	    writel(0xba5eba5e, mem_base);
	    for (i = sizeof(test_val); i < EL2_MEMSIZE; i+=sizeof(test_val)) {
		writel(test_val, mem_base + i);
		if (readl(mem_base) != 0xba5eba5e ||
		    readl(mem_base + i) != test_val) {
		    pr_warning("3c503: memory failure or memory address conflict.\n");
		    dev->mem_start = 0;
		    ei_status.name = "3c503-PIO";
		    iounmap(mem_base);
		    ei_status.mem = NULL;
		    break;
		}
		test_val += 0x55555555;
		writel(0, mem_base + i);
	    }
	}
#endif  /* EL2MEMTEST */

	if (dev->mem_start)
		dev->mem_end = dev->mem_start + EL2_MEMSIZE;

	if (wordlength) {	/* No Tx pages to skip over to get to Rx */
		ei_status.priv = 0;
		ei_status.name = "3c503/16";
	} else {
		ei_status.priv = TX_PAGES * 256;
		ei_status.name = "3c503";
	}
    }

    /*
	Divide up the memory on the card. This is the same regardless of
	whether shared-mem or PIO is used. For 16 bit cards (16kB RAM),
	we use the entire 8k of bank1 for an Rx ring. We only use 3k
	of the bank0 for 2 full size Tx packet slots. For 8 bit cards,
	(8kB RAM) we use 3kB of bank1 for two Tx slots, and the remaining
	5kB for an Rx ring.  */

    if (wordlength) {
	ei_status.tx_start_page = EL2_MB0_START_PG;
	ei_status.rx_start_page = EL2_MB1_START_PG;
    } else {
	ei_status.tx_start_page = EL2_MB1_START_PG;
	ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
    }

    /* Finish setting the board's parameters. */
    ei_status.stop_page = EL2_MB1_STOP_PG;
    ei_status.word16 = wordlength;
    ei_status.reset_8390 = el2_reset_8390;
    ei_status.get_8390_hdr = el2_get_8390_hdr;
    ei_status.block_input = el2_block_input;
    ei_status.block_output = el2_block_output;

    if (dev->irq == 2)
	dev->irq = 9;
    else if (dev->irq > 5 && dev->irq != 9) {
	pr_warning("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
	       dev->irq);
	dev->irq = 0;
    }

    ei_status.saved_irq = dev->irq;

    dev->netdev_ops = &el2_netdev_ops;
    dev->ethtool_ops = &netdev_ethtool_ops;

    retval = register_netdev(dev);
    if (retval)
	goto out1;

    if (dev->mem_start)
	pr_info("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
		dev->name, ei_status.name, (wordlength+1)<<3,
		dev->mem_start, dev->mem_end-1);

    else
    {
	ei_status.tx_start_page = EL2_MB1_START_PG;
	ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
	pr_info("%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
	       dev->name, ei_status.name, (wordlength+1)<<3);
    }
    release_region(ioaddr + 0x400, 8);
    return 0;
out1:
    release_region(ioaddr + 0x400, 8);
out:
    release_region(ioaddr, EL2_IO_EXTENT);
    return retval;
}
Example #3
0
static void
el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
{
    int boguscount = 0;
    void __iomem *base = ei_status.mem;
    unsigned short int *buf;
    unsigned short word;

    /* Maybe enable shared memory just be to be safe... nahh.*/
    if (base) {	/* Use the shared memory. */
	ring_offset -= (EL2_MB1_START_PG<<8);
	if (ring_offset + count > EL2_MEMSIZE) {
	    /* We must wrap the input move. */
	    int semi_count = EL2_MEMSIZE - ring_offset;
	    memcpy_fromio(skb->data, base + ring_offset, semi_count);
	    count -= semi_count;
	    memcpy_fromio(skb->data + semi_count, base + ei_status.priv, count);
	} else {
		memcpy_fromio(skb->data, base + ring_offset, count);
	}
	return;
    }

/*
 *  No shared memory, use programmed I/O.
 */
    word = (unsigned short) ring_offset;
    outb(word>>8, E33G_DMAAH);
    outb(word&0xFF, E33G_DMAAL);

    outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
	   | ECNTRL_START, E33G_CNTRL);

/*
 *  Here I also try to get data as fast as possible. I am betting that I
 *  can read one extra byte without clobbering anything in the kernel because
 *  this would only occur on an odd byte-count and allocation of skb->data
 *  is word-aligned. Variable 'count' is NOT checked. Caller must check
 *  for a valid count.
 *  [This is currently quite safe.... but if one day the 3c503 explodes
 *   you know where to come looking ;)]
 */

    buf =  (unsigned short int *) skb->data;
    count =  (count + 1) >> 1;
    for(;;)
    {
        boguscount = 0x1000;
        while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
        {
            if(!boguscount--)
            {
                pr_notice("%s: FIFO blocked in el2_block_input.\n", dev->name);
                el2_reset_8390(dev);
                goto blocked;
            }
        }
        if(count > WRD_COUNT)
        {
            insw(E33G_FIFOH, buf, WRD_COUNT);
            buf   += WRD_COUNT;
            count -= WRD_COUNT;
        }
        else
        {
            insw(E33G_FIFOH, buf, count);
            break;
        }
    }
    blocked:;
    outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
}
Example #4
0
static int __init dtlk_dev_probe(void)
{
    unsigned int testval = 0;
    int i = 0;
    struct dtlk_settings *sp;

    if (dtlk_port_lpc | dtlk_port_tts)
        return -EBUSY;

    for (i = 0; dtlk_portlist[i]; i++) {
#if 0
        printk("DoubleTalk PC - Port %03x = %04x\n",
               dtlk_portlist[i], (testval = inw_p(dtlk_portlist[i])));
#endif

        if (check_region(dtlk_portlist[i], DTLK_IO_EXTENT))
            continue;
        testval = inw_p(dtlk_portlist[i]);
        if ((testval &= 0xfbff) == 0x107f) {
            request_region(dtlk_portlist[i], DTLK_IO_EXTENT,
                           "dtlk");
            dtlk_port_lpc = dtlk_portlist[i];
            dtlk_port_tts = dtlk_port_lpc + 1;

            sp = dtlk_interrogate();
            printk("DoubleTalk PC at %03x-%03x, "
                   "ROM version %s, serial number %u",
                   dtlk_portlist[i], dtlk_portlist[i] +
                   DTLK_IO_EXTENT - 1,
                   sp->rom_version, sp->serial_number);

            /* put LPC port into known state, so
            dtlk_readable() gives valid result */
            outb_p(0xff, dtlk_port_lpc);

            /* INIT string and index marker */
            dtlk_write_bytes("\036\1@\0\0012I\r", 8);
            /* posting an index takes 18 msec.  Here, we
               wait up to 100 msec to see whether it
               appears. */
            dtlk_delay(100);
            dtlk_has_indexing = dtlk_readable();
#ifdef TRACING
            printk(", indexing %d\n", dtlk_has_indexing);
#endif
#ifdef INSCOPE
            {
                /* This macro records ten samples read from the LPC port, for later display */
#define LOOK					\
for (i = 0; i < 10; i++)			\
  {						\
    buffer[b++] = inb_p(dtlk_port_lpc);		\
    __delay(loops_per_jiffy/(1000000/HZ));             \
  }
                char buffer[1000];
                int b = 0, i, j;

                LOOK
                outb_p(0xff, dtlk_port_lpc);
                buffer[b++] = 0;
                LOOK
                dtlk_write_bytes("\0012I\r", 4);
                buffer[b++] = 0;
                __delay(50 * loops_per_jiffy / (1000/HZ));
                outb_p(0xff, dtlk_port_lpc);
                buffer[b++] = 0;
                LOOK

                printk("\n");
                for (j = 0; j < b; j++)
                    printk(" %02x", buffer[j]);
                printk("\n");
            }
#endif				/* INSCOPE */

#ifdef OUTSCOPE
            {
                /* This macro records ten samples read from the TTS port, for later display */
#define LOOK					\
for (i = 0; i < 10; i++)			\
  {						\
    buffer[b++] = inb_p(dtlk_port_tts);		\
    __delay(loops_per_jiffy/(1000000/HZ));  /* 1 us */ \
  }
                char buffer[1000];
                int b = 0, i, j;

                mdelay(10);	/* 10 ms */
                LOOK
                outb_p(0x03, dtlk_port_tts);
                buffer[b++] = 0;
                LOOK
                LOOK

                printk("\n");
                for (j = 0; j < b; j++)
                    printk(" %02x", buffer[j]);
                printk("\n");
            }
#endif				/* OUTSCOPE */

            dtlk_write_bytes("Double Talk found", 18);

            return 0;
        }
    }

    printk(KERN_INFO "\nDoubleTalk PC - not found\n");
    return -ENODEV;
}
Example #5
0
static inline void sci_outp(struct sci_struct *sci, int offset,
			       int value)
{
    	outb_p(value, sci->port+offset);
}
Example #6
0
int
wd8003_start_xmit(struct sk_buff *skb, struct device *dev)
{
  unsigned char cmd;
  int len;

  cli();
  if (dev->tbusy)
    {
       /* put in a time out. */
       if (jiffies - dev->trans_start < 30)
	 {
	   sti();
	   return (1);
	 }

       printk ("wd8003 transmit timed out. \n");
    }
  dev->tbusy = 1;

  if (skb == NULL)
    {
      sti();
      wd_trs(dev);
      return (0);
    }

  /* this should check to see if it's been killed. */
  if (skb->dev != dev)
    {
      sti();
      return (0);
    }


  if (!skb->arp)
    {
      if ( dev->rebuild_header (skb+1, dev)) 
	{
	  cli();
	  if (skb->dev == dev)
	    {
	      arp_queue (skb);
	    }
	   cli (); /* arp_queue turns them back on. */
 	  dev->tbusy = 0;
	   sti();
	   return (0);
	}
    }

  memcpy ((unsigned char *)dev->mem_start, skb+1, skb->len);

  len = skb->len;

  /* now we need to set up the card info. */
  dev->trans_start = jiffies;
  len=max(len, ETHER_MIN_LEN); /* actually we should zero out
				  the extra memory. */
/*  printk ("start_xmit len - %d\n", len);*/

  cmd=inb_p(WD_COMM);
  cmd &= ~CPAGE;
  outb_p(cmd, WD_COMM);

  interrupt_mask |= TRANS_MASK;
  if (!(dev->interrupt))
    outb (interrupt_mask, WD_IMR);

  outb_p(len&0xff,WD_TB0);
  outb_p(len>>8,WD_TB1);
  cmd |= CTRANS;
  outb_p(cmd,WD_COMM);
  sti();
  
  if (skb->free)
    {
	    kfree_skb (skb, FREE_WRITE);
    }

  return (0);
}
Example #7
0
static int wdt977_stop(void)
{
	unsigned long flags;
	spin_lock_irqsave(&spinlock, flags);

	/* unlock the SuperIO chip */
	outb_p(UNLOCK_DATA, IO_INDEX_PORT);
	outb_p(UNLOCK_DATA, IO_INDEX_PORT);

	/* select device Aux2 (device=8) and set watchdog regs F2,F3 and F4
	* F3 is reset to its default state
	* F4 can clear the TIMEOUT'ed state (bit 0) - back to default
	* We can not use GP17 as a PowerLed, as we use its usage as a RedLed
	*/
	outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
	outb_p(0x08, IO_DATA_PORT);
	outb_p(0xF2, IO_INDEX_PORT);
	outb_p(0xFF, IO_DATA_PORT);
	outb_p(0xF3, IO_INDEX_PORT);
	outb_p(0x00, IO_DATA_PORT);
	outb_p(0xF4, IO_INDEX_PORT);
	outb_p(0x00, IO_DATA_PORT);
	outb_p(0xF2, IO_INDEX_PORT);
	outb_p(0x00, IO_DATA_PORT);

	/* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */
	outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
	outb_p(0x07, IO_DATA_PORT);
	outb_p(0xE6, IO_INDEX_PORT);
	outb_p(0x08, IO_DATA_PORT);

	/* lock the SuperIO chip */
	outb_p(LOCK_DATA, IO_INDEX_PORT);

	spin_unlock_irqrestore(&spinlock, flags);
	printk(KERN_INFO PFX "shutdown.\n");

	return 0;
}
Example #8
0
/* Return -1 on error. */
static s32 i801_access(struct i2c_adapter * adap, u16 addr,
		       unsigned short flags, char read_write, u8 command,
		       int size, union i2c_smbus_data * data)
{
	int hwpec = 0;
	int block = 0;
	int ret, xact = 0;

#ifdef HAVE_PEC
	if(isich4)
		hwpec = (flags & I2C_CLIENT_PEC) != 0;
#endif

	switch (size) {
	case I2C_SMBUS_QUICK:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		xact = I801_QUICK;
		break;
	case I2C_SMBUS_BYTE:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		if (read_write == I2C_SMBUS_WRITE)
			outb_p(command, SMBHSTCMD);
		xact = I801_BYTE;
		break;
	case I2C_SMBUS_BYTE_DATA:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		outb_p(command, SMBHSTCMD);
		if (read_write == I2C_SMBUS_WRITE)
			outb_p(data->byte, SMBHSTDAT0);
		xact = I801_BYTE_DATA;
		break;
	case I2C_SMBUS_WORD_DATA:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		outb_p(command, SMBHSTCMD);
		if (read_write == I2C_SMBUS_WRITE) {
			outb_p(data->word & 0xff, SMBHSTDAT0);
			outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
		}
		xact = I801_WORD_DATA;
		break;
	case I2C_SMBUS_BLOCK_DATA:
	case I2C_SMBUS_I2C_BLOCK_DATA:
#ifdef HAVE_PEC
	case I2C_SMBUS_BLOCK_DATA_PEC:
		if(hwpec && size == I2C_SMBUS_BLOCK_DATA)
			size = I2C_SMBUS_BLOCK_DATA_PEC;
#endif
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		outb_p(command, SMBHSTCMD);
		block = 1;
		break;
	case I2C_SMBUS_PROC_CALL:
	default:
		dev_err(&I801_dev->dev, "Unsupported transaction %d\n", size);
		return -1;
	}
Example #9
0
static int wdt_stop(void)
{
	unsigned long flags;

	spin_lock_irqsave(&spinlock, flags);

	/* Unlock the SuperIO chip */
	outb_p(UNLOCK_DATA, IO_INDEX_PORT);
	outb_p(UNLOCK_DATA, IO_INDEX_PORT);

	/*
	 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
	 * F2 is reset to its default value (watchdog timer disabled).
	 * F3 is reset to its default state.
	 * F4 clears the TIMEOUT'ed state (bit 0) - back to default.
	 */
	outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
	outb_p(0x08, IO_DATA_PORT);
	outb_p(0xF2, IO_INDEX_PORT);
	outb_p(0xFF, IO_DATA_PORT);
	outb_p(0xF3, IO_INDEX_PORT);
	outb_p(0x00, IO_DATA_PORT);
	outb_p(0xF4, IO_INDEX_PORT);
	outb_p(0x00, IO_DATA_PORT);
	outb_p(0xF2, IO_INDEX_PORT);
	outb_p(0x00, IO_DATA_PORT);

	/*
	 * Select device Aux1 (dev=7) to set GP16 (in reg E6) and
	 * Gp13 (in reg E3) as inputs.
	 */
	outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
	outb_p(0x07, IO_DATA_PORT);
	if (!testmode) {
		outb_p(0xE6, IO_INDEX_PORT);
		outb_p(0x01, IO_DATA_PORT);
	}
	outb_p(0xE3, IO_INDEX_PORT);
	outb_p(0x01, IO_DATA_PORT);

	/* Lock the SuperIO chip */
	outb_p(LOCK_DATA, IO_INDEX_PORT);

	spin_unlock_irqrestore(&spinlock, flags);

	printk(KERN_INFO PFX "shutdown.\n");

	return 0;
}
Example #10
0
static int i801_transaction(void)
{
	int temp;
	int result = 0;
	int timeout = 0;

	dev_dbg(&I801_dev->dev, "Transaction (pre): CNT=%02x, CMD=%02x,"
		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
		inb_p(SMBHSTDAT1));

	/* Make sure the SMBus host is ready to start transmitting */
	/* 0x1f = Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
	if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
		dev_dbg(&I801_dev->dev, "SMBus busy (%02x). Resetting... \n",
			temp);
		outb_p(temp, SMBHSTSTS);
		if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
			dev_dbg(&I801_dev->dev, "Failed! (%02x)\n", temp);
			return -1;
		} else {
			dev_dbg(&I801_dev->dev, "Successfull!\n");
		}
	}

	outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);

	/* We will always wait for a fraction of a second! */
	do {
		msleep(1);
		temp = inb_p(SMBHSTSTS);
	} while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));

	/* If the SMBus is still busy, we give up */
	if (timeout >= MAX_TIMEOUT) {
		dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
		result = -1;
	}

	if (temp & 0x10) {
		result = -1;
		dev_dbg(&I801_dev->dev, "Error: Failed bus transaction\n");
	}

	if (temp & 0x08) {
		result = -1;
		dev_err(&I801_dev->dev, "Bus collision! SMBus may be locked "
			"until next hard reset. (sorry!)\n");
		/* Clock stops and slave is stuck in mid-transmission */
	}

	if (temp & 0x04) {
		result = -1;
		dev_dbg(&I801_dev->dev, "Error: no response!\n");
	}

	if ((inb_p(SMBHSTSTS) & 0x1f) != 0x00)
		outb_p(inb(SMBHSTSTS), SMBHSTSTS);

	if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) {
		dev_dbg(&I801_dev->dev, "Failed reset at end of transaction"
			"(%02x)\n", temp);
	}
	dev_dbg(&I801_dev->dev, "Transaction (post): CNT=%02x, CMD=%02x, "
		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0),
		inb_p(SMBHSTDAT1));
	return result;
}
Example #11
0
/* All-inclusive block transaction function */
static int i801_block_transaction(union i2c_smbus_data *data, char read_write,
				  int command)
{
	int i, len;
	int smbcmd;
	int temp;
	int result = 0;
	int timeout;
	unsigned char hostc, errmask;

	if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
		if (read_write == I2C_SMBUS_WRITE) {
			/* set I2C_EN bit in configuration register */
			pci_read_config_byte(I801_dev, SMBHSTCFG, &hostc);
			pci_write_config_byte(I801_dev, SMBHSTCFG,
					      hostc | SMBHSTCFG_I2C_EN);
		} else {
			dev_err(&I801_dev->dev,
				"I2C_SMBUS_I2C_BLOCK_READ not DB!\n");
			return -1;
		}
	}

	if (read_write == I2C_SMBUS_WRITE) {
		len = data->block[0];
		if (len < 1)
			len = 1;
		if (len > 32)
			len = 32;
		outb_p(len, SMBHSTDAT0);
		outb_p(data->block[1], SMBBLKDAT);
	} else {
		len = 32;	/* max for reads */
	}

	if(isich4 && command != I2C_SMBUS_I2C_BLOCK_DATA) {
		/* set 32 byte buffer */
	}

	for (i = 1; i <= len; i++) {
		if (i == len && read_write == I2C_SMBUS_READ)
			smbcmd = I801_BLOCK_LAST;
		else
			smbcmd = I801_BLOCK_DATA;
		outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT);

		dev_dbg(&I801_dev->dev, "Block (pre %d): CNT=%02x, CMD=%02x, "
			"ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
			inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
			inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));

		/* Make sure the SMBus host is ready to start transmitting */
		temp = inb_p(SMBHSTSTS);
		if (i == 1) {
			/* Erronenous conditions before transaction: 
			 * Byte_Done, Failed, Bus_Err, Dev_Err, Intr, Host_Busy */
			errmask=0x9f; 
		} else {
			/* Erronenous conditions during transaction: 
			 * Failed, Bus_Err, Dev_Err, Intr */
			errmask=0x1e; 
		}
		if (temp & errmask) {
			dev_dbg(&I801_dev->dev, "SMBus busy (%02x). "
				"Resetting... \n", temp);
			outb_p(temp, SMBHSTSTS);
			if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) {
				dev_err(&I801_dev->dev,
					"Reset failed! (%02x)\n", temp);
				result = -1;
                                goto END;
			}
			if (i != 1) {
				/* if die in middle of block transaction, fail */
				result = -1;
				goto END;
			}
		}

		if (i == 1)
			outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT);

		/* We will always wait for a fraction of a second! */
		timeout = 0;
		do {
			temp = inb_p(SMBHSTSTS);
			msleep(1);
		}
		    while ((!(temp & 0x80))
			   && (timeout++ < MAX_TIMEOUT));

		/* If the SMBus is still busy, we give up */
		if (timeout >= MAX_TIMEOUT) {
			result = -1;
			dev_dbg(&I801_dev->dev, "SMBus Timeout!\n");
		}

		if (temp & 0x10) {
			result = -1;
			dev_dbg(&I801_dev->dev,
				"Error: Failed bus transaction\n");
		} else if (temp & 0x08) {
			result = -1;
			dev_err(&I801_dev->dev, "Bus collision!\n");
		} else if (temp & 0x04) {
			result = -1;
			dev_dbg(&I801_dev->dev, "Error: no response!\n");
		}

		if (i == 1 && read_write == I2C_SMBUS_READ) {
			len = inb_p(SMBHSTDAT0);
			if (len < 1)
				len = 1;
			if (len > 32)
				len = 32;
			data->block[0] = len;
		}

		/* Retrieve/store value in SMBBLKDAT */
		if (read_write == I2C_SMBUS_READ)
			data->block[i] = inb_p(SMBBLKDAT);
		if (read_write == I2C_SMBUS_WRITE && i+1 <= len)
			outb_p(data->block[i+1], SMBBLKDAT);
		if ((temp & 0x9e) != 0x00)
			outb_p(temp, SMBHSTSTS);  /* signals SMBBLKDAT ready */

		if ((temp = (0x1e & inb_p(SMBHSTSTS))) != 0x00) {
			dev_dbg(&I801_dev->dev,
				"Bad status (%02x) at end of transaction\n",
				temp);
		}
		dev_dbg(&I801_dev->dev, "Block (post %d): CNT=%02x, CMD=%02x, "
			"ADD=%02x, DAT0=%02x, BLKDAT=%02x\n", i,
			inb_p(SMBHSTCNT), inb_p(SMBHSTCMD), inb_p(SMBHSTADD),
			inb_p(SMBHSTDAT0), inb_p(SMBBLKDAT));

		if (result < 0)
			goto END;
	}

#ifdef HAVE_PEC
	if(isich4 && command == I2C_SMBUS_BLOCK_DATA_PEC) {
		/* wait for INTR bit as advised by Intel */
		timeout = 0;
		do {
			temp = inb_p(SMBHSTSTS);
			msleep(1);
		} while ((!(temp & 0x02))
			   && (timeout++ < MAX_TIMEOUT));

		if (timeout >= MAX_TIMEOUT) {
			dev_dbg(&I801_dev->dev, "PEC Timeout!\n");
		}
		outb_p(temp, SMBHSTSTS); 
	}
#endif
	result = 0;
END:
	if (command == I2C_SMBUS_I2C_BLOCK_DATA) {
		/* restore saved configuration register value */
		pci_write_config_byte(I801_dev, SMBHSTCFG, hostc);
	}
	return result;
}
Example #12
0
/* Return negative errno on error. */
static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
                          unsigned short flags, char read_write, u8 command,
                          int size, union i2c_smbus_data *data)
{
    int i, len;
    int temp;
    int timeout;
    s32 result = 0;

    /* make sure SMBus is idle */
    temp = inb_p(SMBHSTSTS);
    for (timeout = 0;
            (timeout < MAX_TIMEOUT) && !(temp & ALI1535_STS_IDLE);
            timeout++) {
        msleep(1);
        temp = inb_p(SMBHSTSTS);
    }
    if (timeout >= MAX_TIMEOUT)
        dev_warn(&adap->dev, "Idle wait Timeout! STS=0x%02x\n", temp);

    /* clear status register (clear-on-write) */
    outb_p(0xFF, SMBHSTSTS);

    switch (size) {
    case I2C_SMBUS_QUICK:
        outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
               SMBHSTADD);
        size = ALI1535_QUICK;
        outb_p(size, SMBHSTTYP);	/* output command */
        break;
    case I2C_SMBUS_BYTE:
        outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
               SMBHSTADD);
        size = ALI1535_BYTE;
        outb_p(size, SMBHSTTYP);	/* output command */
        if (read_write == I2C_SMBUS_WRITE)
            outb_p(command, SMBHSTCMD);
        break;
    case I2C_SMBUS_BYTE_DATA:
        outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
               SMBHSTADD);
        size = ALI1535_BYTE_DATA;
        outb_p(size, SMBHSTTYP);	/* output command */
        outb_p(command, SMBHSTCMD);
        if (read_write == I2C_SMBUS_WRITE)
            outb_p(data->byte, SMBHSTDAT0);
        break;
    case I2C_SMBUS_WORD_DATA:
        outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
               SMBHSTADD);
        size = ALI1535_WORD_DATA;
        outb_p(size, SMBHSTTYP);	/* output command */
        outb_p(command, SMBHSTCMD);
        if (read_write == I2C_SMBUS_WRITE) {
            outb_p(data->word & 0xff, SMBHSTDAT0);
            outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
        }
        break;
    case I2C_SMBUS_BLOCK_DATA:
        outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
               SMBHSTADD);
        size = ALI1535_BLOCK_DATA;
        outb_p(size, SMBHSTTYP);	/* output command */
        outb_p(command, SMBHSTCMD);
        if (read_write == I2C_SMBUS_WRITE) {
            len = data->block[0];
            if (len < 0) {
                len = 0;
                data->block[0] = len;
            }
            if (len > 32) {
                len = 32;
                data->block[0] = len;
            }
            outb_p(len, SMBHSTDAT0);
            /* Reset SMBBLKDAT */
            outb_p(inb_p(SMBHSTTYP) | ALI1535_BLOCK_CLR, SMBHSTTYP);
            for (i = 1; i <= len; i++)
                outb_p(data->block[i], SMBBLKDAT);
        }
        break;
    default:
        dev_warn(&adap->dev, "Unsupported transaction %d\n", size);
        result = -EOPNOTSUPP;
        goto EXIT;
    }
Example #13
0
static int ali1535_transaction(struct i2c_adapter *adap)
{
    int temp;
    int result = 0;
    int timeout = 0;

    dev_dbg(&adap->dev, "Transaction (pre): STS=%02x, TYP=%02x, "
            "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
            inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
            inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));

    /* get status */
    temp = inb_p(SMBHSTSTS);

    /* Make sure the SMBus host is ready to start transmitting */
    /* Check the busy bit first */
    if (temp & ALI1535_STS_BUSY) {
        /* If the host controller is still busy, it may have timed out
         * in the previous transaction, resulting in a "SMBus Timeout"
         * printk.  I've tried the following to reset a stuck busy bit.
         *   1. Reset the controller with an KILL command. (this
         *      doesn't seem to clear the controller if an external
         *      device is hung)
         *   2. Reset the controller and the other SMBus devices with a
         *      T_OUT command. (this clears the host busy bit if an
         *      external device is hung, but it comes back upon a new
         *      access to a device)
         *   3. Disable and reenable the controller in SMBHSTCFG. Worst
         *      case, nothing seems to work except power reset.
         */

        /* Try resetting entire SMB bus, including other devices - This
         * may not work either - it clears the BUSY bit but then the
         * BUSY bit may come back on when you try and use the chip
         * again.  If that's the case you are stuck.
         */
        dev_info(&adap->dev,
                 "Resetting entire SMB Bus to clear busy condition (%02x)\n",
                 temp);
        outb_p(ALI1535_T_OUT, SMBHSTTYP);
        temp = inb_p(SMBHSTSTS);
    }

    /* now check the error bits and the busy bit */
    if (temp & (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
        /* do a clear-on-write */
        outb_p(0xFF, SMBHSTSTS);
        if ((temp = inb_p(SMBHSTSTS)) &
                (ALI1535_STS_ERR | ALI1535_STS_BUSY)) {
            /* This is probably going to be correctable only by a
             * power reset as one of the bits now appears to be
             * stuck */
            /* This may be a bus or device with electrical problems. */
            dev_err(&adap->dev,
                    "SMBus reset failed! (0x%02x) - controller or "
                    "device on bus is probably hung\n", temp);
            return -EBUSY;
        }
    } else {
        /* check and clear done bit */
        if (temp & ALI1535_STS_DONE) {
            outb_p(temp, SMBHSTSTS);
        }
    }

    /* start the transaction by writing anything to the start register */
    outb_p(0xFF, SMBHSTPORT);

    /* We will always wait for a fraction of a second! */
    timeout = 0;
    do {
        msleep(1);
        temp = inb_p(SMBHSTSTS);
    } while (((temp & ALI1535_STS_BUSY) && !(temp & ALI1535_STS_IDLE))
             && (timeout++ < MAX_TIMEOUT));

    /* If the SMBus is still busy, we give up */
    if (timeout >= MAX_TIMEOUT) {
        result = -ETIMEDOUT;
        dev_err(&adap->dev, "SMBus Timeout!\n");
    }

    if (temp & ALI1535_STS_FAIL) {
        result = -EIO;
        dev_dbg(&adap->dev, "Error: Failed bus transaction\n");
    }

    /* Unfortunately the ALI SMB controller maps "no response" and "bus
     * collision" into a single bit. No reponse is the usual case so don't
     * do a printk.  This means that bus collisions go unreported.
     */
    if (temp & ALI1535_STS_BUSERR) {
        result = -ENXIO;
        dev_dbg(&adap->dev,
                "Error: no response or bus collision ADD=%02x\n",
                inb_p(SMBHSTADD));
    }

    /* haven't ever seen this */
    if (temp & ALI1535_STS_DEV) {
        result = -EIO;
        dev_err(&adap->dev, "Error: device error\n");
    }

    /* check to see if the "command complete" indication is set */
    if (!(temp & ALI1535_STS_DONE)) {
        result = -ETIMEDOUT;
        dev_err(&adap->dev, "Error: command never completed\n");
    }

    dev_dbg(&adap->dev, "Transaction (post): STS=%02x, TYP=%02x, "
            "CMD=%02x, ADD=%02x, DAT0=%02x, DAT1=%02x\n",
            inb_p(SMBHSTSTS), inb_p(SMBHSTTYP), inb_p(SMBHSTCMD),
            inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), inb_p(SMBHSTDAT1));

    /* take consequent actions for error conditions */
    if (!(temp & ALI1535_STS_DONE)) {
        /* issue "kill" to reset host controller */
        outb_p(ALI1535_KILL,SMBHSTTYP);
        outb_p(0xFF,SMBHSTSTS);
    } else if (temp & ALI1535_STS_ERR) {
        /* issue "timeout" to reset all devices on bus */
        outb_p(ALI1535_T_OUT,SMBHSTTYP);
        outb_p(0xFF,SMBHSTSTS);
    }

    return result;
}
static void dt_sendcmd(u_int cmd)
{
	outb_p(cmd & 0xFF, speakup_info.port_tts);
	outb_p((cmd >> 8) & 0xFF, speakup_info.port_tts+1);
}
Example #15
0
static void bluecard_write_wakeup(bluecard_info_t *info)
{
	if (!info) {
		BT_ERR("Unknown device");
		return;
	}

	if (!test_bit(XMIT_SENDING_READY, &(info->tx_state)))
		return;

	if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
		set_bit(XMIT_WAKEUP, &(info->tx_state));
		return;
	}

	do {
		register unsigned int iobase = info->p_dev->resource[0]->start;
		register unsigned int offset;
		register unsigned char command;
		register unsigned long ready_bit;
		register struct sk_buff *skb;
		register int len;

		clear_bit(XMIT_WAKEUP, &(info->tx_state));

		if (!pcmcia_dev_present(info->p_dev))
			return;

		if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
			if (!test_bit(XMIT_BUF_TWO_READY, &(info->tx_state)))
				break;
			offset = 0x10;
			command = REG_COMMAND_TX_BUF_TWO;
			ready_bit = XMIT_BUF_TWO_READY;
		} else {
			if (!test_bit(XMIT_BUF_ONE_READY, &(info->tx_state)))
				break;
			offset = 0x00;
			command = REG_COMMAND_TX_BUF_ONE;
			ready_bit = XMIT_BUF_ONE_READY;
		}

		if (!(skb = skb_dequeue(&(info->txq))))
			break;

		if (bt_cb(skb)->pkt_type & 0x80) {
			/* Disable RTS */
			info->ctrl_reg |= REG_CONTROL_RTS;
			outb(info->ctrl_reg, iobase + REG_CONTROL);
		}

		/* Activate LED */
		bluecard_enable_activity_led(info);

		/* Send frame */
		len = bluecard_write(iobase, offset, skb->data, skb->len);

		/* Tell the FPGA to send the data */
		outb_p(command, iobase + REG_COMMAND);

		/* Mark the buffer as dirty */
		clear_bit(ready_bit, &(info->tx_state));

		if (bt_cb(skb)->pkt_type & 0x80) {
			DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
			DEFINE_WAIT(wait);

			unsigned char baud_reg;

			switch (bt_cb(skb)->pkt_type) {
			case PKT_BAUD_RATE_460800:
				baud_reg = REG_CONTROL_BAUD_RATE_460800;
				break;
			case PKT_BAUD_RATE_230400:
				baud_reg = REG_CONTROL_BAUD_RATE_230400;
				break;
			case PKT_BAUD_RATE_115200:
				baud_reg = REG_CONTROL_BAUD_RATE_115200;
				break;
			case PKT_BAUD_RATE_57600:
				/* Fall through... */
			default:
				baud_reg = REG_CONTROL_BAUD_RATE_57600;
				break;
			}

			/* Wait until the command reaches the baseband */
			prepare_to_wait(&wq, &wait, TASK_INTERRUPTIBLE);
			schedule_timeout(HZ/10);
			finish_wait(&wq, &wait);

			/* Set baud on baseband */
			info->ctrl_reg &= ~0x03;
			info->ctrl_reg |= baud_reg;
			outb(info->ctrl_reg, iobase + REG_CONTROL);

			/* Enable RTS */
			info->ctrl_reg &= ~REG_CONTROL_RTS;
			outb(info->ctrl_reg, iobase + REG_CONTROL);

			/* Wait before the next HCI packet can be send */
			prepare_to_wait(&wq, &wait, TASK_INTERRUPTIBLE);
			schedule_timeout(HZ);
			finish_wait(&wq, &wait);
		}

		if (len == skb->len) {
			kfree_skb(skb);
		} else {
			skb_pull(skb, len);
			skb_queue_head(&(info->txq), skb);
		}

		info->hdev->stat.byte_tx += len;

		/* Change buffer */
		change_bit(XMIT_BUFFER_NUMBER, &(info->tx_state));

	} while (test_bit(XMIT_WAKEUP, &(info->tx_state)));

	clear_bit(XMIT_SENDING, &(info->tx_state));
}
Example #16
0
static int wdt_start(void)
{
	unsigned long flags;

	spin_lock_irqsave(&spinlock, flags);

	/* Unlock the SuperIO chip */
	outb_p(UNLOCK_DATA, IO_INDEX_PORT);
	outb_p(UNLOCK_DATA, IO_INDEX_PORT);

	/*
	 * Select device Aux2 (device=8) to set watchdog regs F2, F3 and F4.
	 * F2 has the timeout in watchdog counter units.
	 * F3 is set to enable watchdog LED blink at timeout.
	 * F4 is used to just clear the TIMEOUT'ed state (bit 0).
	 */
	outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
	outb_p(0x08, IO_DATA_PORT);
	outb_p(0xF2, IO_INDEX_PORT);
	outb_p(timeoutW, IO_DATA_PORT);
	outb_p(0xF3, IO_INDEX_PORT);
	outb_p(0x08, IO_DATA_PORT);
	outb_p(0xF4, IO_INDEX_PORT);
	outb_p(0x00, IO_DATA_PORT);

	/* Set device Aux2 active */
	outb_p(0x30, IO_INDEX_PORT);
	outb_p(0x01, IO_DATA_PORT);

	/*
	 * Select device Aux1 (dev=7) to set GP16 as the watchdog output
	 * (in reg E6) and GP13 as the watchdog LED output (in reg E3).
	 * Map GP16 at pin 119.
	 * In test mode watch the bit 0 on F4 to indicate "triggered" or
	 * check watchdog LED on SBC.
	 */
	outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
	outb_p(0x07, IO_DATA_PORT);
	if (!testmode) {
		unsigned pin_map;

		outb_p(0xE6, IO_INDEX_PORT);
		outb_p(0x0A, IO_DATA_PORT);
		outb_p(0x2C, IO_INDEX_PORT);
		pin_map = inb_p(IO_DATA_PORT);
		pin_map |= 0x10;
		pin_map &= ~(0x20);
		outb_p(0x2C, IO_INDEX_PORT);
		outb_p(pin_map, IO_DATA_PORT);
	}
	outb_p(0xE3, IO_INDEX_PORT);
	outb_p(0x08, IO_DATA_PORT);

	/* Set device Aux1 active */
	outb_p(0x30, IO_INDEX_PORT);
	outb_p(0x01, IO_DATA_PORT);

	/* Lock the SuperIO chip */
	outb_p(LOCK_DATA, IO_INDEX_PORT);

	spin_unlock_irqrestore(&spinlock, flags);

	printk(KERN_INFO PFX "activated.\n");

	return 0;
}
Example #17
0
int
wd8003_open(struct device *dev)
{
  unsigned char cmd;
  int i;
  /* we probably don't want to be interrupted here. */
  cli();
  /* This section of code is mostly copied from the bsd driver which is
     mostly copied from somewhere else. */
  /* The somewhere else is probably the cmwymr(sp?) dos packet driver */

  cmd=inb_p(WD_COMM);
  cmd|=CSTOP;
  cmd &= ~(CSTART|CPAGE);
  outb_p(cmd, WD_COMM);
  outb_p(0, WD_IMR);
  sti();
  outb_p( dconfig,WD_DCR);
  /*Zero the remote byte count. */
  outb_p(0, WD_RBY0);
  outb_p(0, WD_RBY1);
  outb_p(WD_MCONFIG,WD_RCC);
  outb_p(WD_TCONFIG,WD_TRC);
  outb_p(0,WD_TRPG);		 /* Set the transmit page start = 0 */
  outb_p( max_pages,WD_PSTOP); /* (read) page stop = top of board memory */
  outb_p(WD_TXBS,WD_PSTRT);	/* (read) page start = cur = bnd = top of tx memory */
  outb_p(WD_TXBS,WD_BNDR);
  /* clear interrupt status. */
  outb_p(0xff,WD_ISR);
  /* we don't want no stinking interrupts. */
  outb_p(0 ,WD_IMR);
  cmd|=1<<CPAGE_SHIFT;
  outb_p(cmd,WD_COMM);
  /* set the ether address. */
  for (i=0; i < ETHER_ADDR_LEN; i++)
    {
      outb_p(dev->dev_addr[i],WD_PAR0+i);
    }
  /* National recommends setting the boundry < current page register */
  outb_p(WD_TXBS+1,WD_CUR);	/* Set the current page = page start + 1 */
  /* set the multicast address. */
  for (i=0; i < ETHER_ADDR_LEN; i++)
    {
      outb_p(dev->broadcast[i],WD_MAR0+i);
    }

  cmd&=~(CPAGE|CRDMA);
  cmd|= 4<<CRDMA_SHIFT;
  outb_p(cmd, WD_COMM);
  outb_p(WD_RCONFIG,WD_RCC);
  wd_start(dev); 
  return (0);
}
Example #18
0
/* Another internally used function */
static int vt596_transaction(void)
{
	int temp;
	int result = 0;
	int timeout = 0;

	dev_dbg(&vt596_adapter.dev, "Transaction (pre): CNT=%02x, CMD=%02x, "
		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT), 
		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), 
		inb_p(SMBHSTDAT1));

	/* Make sure the SMBus host is ready to start transmitting */
	if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
		dev_dbg(&vt596_adapter.dev, "SMBus busy (0x%02x). "
				"Resetting...\n", temp);
		
		outb_p(temp, SMBHSTSTS);
		if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
			dev_dbg(&vt596_adapter.dev, "Failed! (0x%02x)\n", temp);
			
			return -1;
		} else {
			dev_dbg(&vt596_adapter.dev, "Successfull!\n");
		}
	}

	/* start the transaction by setting bit 6 */
	outb_p(inb(SMBHSTCNT) | 0x040, SMBHSTCNT);

	/* We will always wait for a fraction of a second! 
	   I don't know if VIA needs this, Intel did  */
	do {
		msleep(1);
		temp = inb_p(SMBHSTSTS);
	} while ((temp & 0x01) && (timeout++ < MAX_TIMEOUT));

	/* If the SMBus is still busy, we give up */
	if (timeout >= MAX_TIMEOUT) {
		result = -1;
		dev_dbg(&vt596_adapter.dev, "SMBus Timeout!\n");
	}

	if (temp & 0x10) {
		result = -1;
		dev_dbg(&vt596_adapter.dev, "Error: Failed bus transaction\n");
	}

	if (temp & 0x08) {
		result = -1;
		dev_info(&vt596_adapter.dev, "Bus collision! SMBus may be "
			"locked until next hard\nreset. (sorry!)\n");
		/* Clock stops and slave is stuck in mid-transmission */
	}

	if (temp & 0x04) {
		result = -1;
		dev_dbg(&vt596_adapter.dev, "Error: no response!\n");
	}

	if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
		outb_p(temp, SMBHSTSTS);
		if ((temp = inb_p(SMBHSTSTS)) & 0x1F) {
			dev_warn(&vt596_adapter.dev, "Failed reset at end "
				 "of transaction (%02x)\n", temp);
		}
	}

	dev_dbg(&vt596_adapter.dev, "Transaction (post): CNT=%02x, CMD=%02x, "
		"ADD=%02x, DAT0=%02x, DAT1=%02x\n", inb_p(SMBHSTCNT),
		inb_p(SMBHSTCMD), inb_p(SMBHSTADD), inb_p(SMBHSTDAT0), 
		inb_p(SMBHSTDAT1));
	
	return result;
}
Example #19
0
static  void
wd_rcv( struct device *dev )
{
   
   unsigned char   pkt;	/* Next packet page start */
   unsigned char   bnd;	/* Last packet page end */
   unsigned char   cur;	/* Future packet page start */
   unsigned char   cmd;	/* Command register save */
   volatile struct wd_ring *ring;
   int		   done=0;
   
   /* Calculate next packet location */
   cur = wd_get_cur( dev );
   bnd = wd_get_bnd( dev );
   if( (pkt = bnd + 1) == max_pages )
     pkt = WD_TXBS;
   
   while( done != 1)
     {
	if (pkt != cur)
	  {

	     /* Position pointer to packet in card ring buffer */
	     ring = (volatile struct wd_ring *) (dev->mem_start + (pkt << 8));
	     
	     /* Ensure a valid packet */
	     if( ring->status & 1 )
	       { 
		  /* Too small and too big packets are
		     filtered by the board */
		  if( wd_debug )
		    printk("\nwd8013 - wdget: bnd = %d, pkt = %d, "
			   "cur = %d, status = %d, len = %d, next = %d",
			   bnd, pkt, cur, ring->status, ring->count,
			   ring->next);
		  
		  stats.rx_packets++; /* count all receives */
		  done = wdget( ring, dev ); /* get the packet */
		  
		  /* Calculate next packet location */
		  pkt = ring->next;
		  
		  /* Compute new boundry - tell the chip */
		  if( (bnd = pkt - 1) < WD_TXBS )
		    bnd = max_pages - 1;
		  wd_put_bnd(bnd, dev);
		  
		  /* update our copy of cur. */
		  cur = wd_get_cur(dev);
	       }
	     else 
	       {	/* Bad packet in ring buffer -
			   should not happen due to hardware filtering */
		  printk("wd8013 - bad packet: len = %d, status = x%x, "
			 "bnd = %d, pkt = %d, cur = %d\n"
			 "trashing receive buffer!",
			 ring->count, ring->status, bnd, pkt,
			 cur);
		  /* Reset bnd = cur-1 */
		  if( ( bnd = wd_get_cur( dev ) - 1 ) < WD_TXBS )
		    bnd = max_pages - 1;
		  wd_put_bnd( bnd, dev );
		  break; /* return */
	       }
	     
	  }
	else
	  {
	     done = dev_rint(NULL, 0,0, dev);
	  }
     }
   
   /* reset to page 0 */
   cmd = inb_p(WD_COMM);
   if (cmd & 0x40)
     {
	outb_p(cmd & ~(CPAGE1), WD_COMM);	/* select page 0 */
     }
}
Example #20
0
/* Return -1 on error. */
static s32 vt596_access(struct i2c_adapter *adap, u16 addr,
		unsigned short flags,  char read_write, u8 command,
		int size,  union i2c_smbus_data *data)
{
	int i, len;

	switch (size) {
	case I2C_SMBUS_PROC_CALL:
		dev_info(&vt596_adapter.dev,
			 "I2C_SMBUS_PROC_CALL not supported!\n");
		return -1;
	case I2C_SMBUS_QUICK:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		size = VT596_QUICK;
		break;
	case I2C_SMBUS_BYTE:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		if (read_write == I2C_SMBUS_WRITE)
			outb_p(command, SMBHSTCMD);
		size = VT596_BYTE;
		break;
	case I2C_SMBUS_BYTE_DATA:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		outb_p(command, SMBHSTCMD);
		if (read_write == I2C_SMBUS_WRITE)
			outb_p(data->byte, SMBHSTDAT0);
		size = VT596_BYTE_DATA;
		break;
	case I2C_SMBUS_WORD_DATA:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		outb_p(command, SMBHSTCMD);
		if (read_write == I2C_SMBUS_WRITE) {
			outb_p(data->word & 0xff, SMBHSTDAT0);
			outb_p((data->word & 0xff00) >> 8, SMBHSTDAT1);
		}
		size = VT596_WORD_DATA;
		break;
	case I2C_SMBUS_BLOCK_DATA:
		outb_p(((addr & 0x7f) << 1) | (read_write & 0x01),
		       SMBHSTADD);
		outb_p(command, SMBHSTCMD);
		if (read_write == I2C_SMBUS_WRITE) {
			len = data->block[0];
			if (len < 0)
				len = 0;
			if (len > I2C_SMBUS_BLOCK_MAX)
				len = I2C_SMBUS_BLOCK_MAX;
			outb_p(len, SMBHSTDAT0);
			i = inb_p(SMBHSTCNT);	/* Reset SMBBLKDAT */
			for (i = 1; i <= len; i++)
				outb_p(data->block[i], SMBBLKDAT);
		}
		size = VT596_BLOCK_DATA;
		break;
	}
Example #21
0
static int wdt977_start(void)
{
	unsigned long flags;

	spin_lock_irqsave(&spinlock, flags);

	/* unlock the SuperIO chip */
	outb_p(UNLOCK_DATA, IO_INDEX_PORT);
	outb_p(UNLOCK_DATA, IO_INDEX_PORT);

	/* select device Aux2 (device=8) and set watchdog regs F2, F3 and F4
	 * F2 has the timeout in minutes
	 * F3 could be set to the POWER LED blink (with GP17 set to PowerLed)
	 *   at timeout, and to reset timer on kbd/mouse activity (not impl.)
	 * F4 is used to just clear the TIMEOUT'ed state (bit 0)
	 */
	outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
	outb_p(0x08, IO_DATA_PORT);
	outb_p(0xF2, IO_INDEX_PORT);
	outb_p(timeoutM, IO_DATA_PORT);
	outb_p(0xF3, IO_INDEX_PORT);
	outb_p(0x00, IO_DATA_PORT);	/* another setting is 0E for kbd/mouse/LED */
	outb_p(0xF4, IO_INDEX_PORT);
	outb_p(0x00, IO_DATA_PORT);

	/* at last select device Aux1 (dev=7) and set GP16 as a watchdog output */
	/* in test mode watch the bit 1 on F4 to indicate "triggered" */
	if (!testmode)
	{
		outb_p(DEVICE_REGISTER, IO_INDEX_PORT);
		outb_p(0x07, IO_DATA_PORT);
		outb_p(0xE6, IO_INDEX_PORT);
		outb_p(0x08, IO_DATA_PORT);
	}

	/* lock the SuperIO chip */
	outb_p(LOCK_DATA, IO_INDEX_PORT);

	spin_unlock_irqrestore(&spinlock, flags);
	printk(KERN_INFO PFX "activated.\n");

	return 0;
}
static void send_1_byte(struct aztech *az)
{
	udelay(radio_wait_time);
	outb_p(128 + 2 + az->curvol, az->isa.io);
	outb_p(128 + 64 + 2 + az->curvol, az->isa.io);
}
Example #23
0
static void WriteByteToHwPort(unsigned long addr, u8 val)
{
	outb_p(val, addr);
}
Example #24
0
static inline void superio_outb(int addr, int val)
{
	outb_p(addr, superio_cmd);
	outb_p(val, superio_cmd + 1);
}
Example #25
0
static int serial8250_startup(struct uart_port *port)
{
    struct uart_8250_port *up = (struct uart_8250_port *)port;
    unsigned long flags;
    int retval;

    /*
     * Clear the FIFO buffers and disable them.
     * (they will be reeanbled in set_termios())
     */
    if (uart_config[up->port.type].flags & UART_CLEAR_FIFO) {
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
                    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
        serial_outp(up, UART_FCR, 0);
    }

    /*
     * Clear the interrupt registers.
     */
    (void) serial_inp(up, UART_LSR);
    (void) serial_inp(up, UART_RX);
    (void) serial_inp(up, UART_IIR);
    (void) serial_inp(up, UART_MSR);

    /*
     * At this point, there's no way the LSR could still be 0xff;
     * if it is, then bail out, because there's likely no UART
     * here.
     */
    if (!(up->port.flags & UPF_BUGGY_UART) &&
            (serial_inp(up, UART_LSR) == 0xff)) {
        printk("ttyS%d: LSR safety check engaged!\n", up->port.line);
        return -ENODEV;
    }

    retval = serial_link_irq_chain(up);
    if (retval)
        return retval;

    /*
     * Now, initialize the UART
     */
    serial_outp(up, UART_LCR, UART_LCR_WLEN8);

    spin_lock_irqsave(&up->port.lock, flags);
    if (up->port.flags & UPF_FOURPORT) {
        if (!is_real_interrupt(up->port.irq))
            up->port.mctrl |= TIOCM_OUT1;
    } else
        /*
         * Most PC uarts need OUT2 raised to enable interrupts.
         */
        if (is_real_interrupt(up->port.irq))
            up->port.mctrl |= TIOCM_OUT2;

    serial8250_set_mctrl(&up->port, up->port.mctrl);
    spin_unlock_irqrestore(&up->port.lock, flags);

    /*
     * Finally, enable interrupts.  Note: Modem status interrupts
     * are set via set_termios(), which will be occurring imminently
     * anyway, so we don't enable them here.
     */
    up->ier = UART_IER_RLSI | UART_IER_RDI;
    serial_outp(up, UART_IER, up->ier);

    if (up->port.flags & UPF_FOURPORT) {
        unsigned int icp;
        /*
         * Enable interrupts on the AST Fourport board
         */
        icp = (up->port.iobase & 0xfe0) | 0x01f;
        outb_p(0x80, icp);
        (void) inb_p(icp);
    }

    /*
     * And clear the interrupt registers again for luck.
     */
    (void) serial_inp(up, UART_LSR);
    (void) serial_inp(up, UART_RX);
    (void) serial_inp(up, UART_IIR);
    (void) serial_inp(up, UART_MSR);

    return 0;
}
Example #26
0
static inline int superio_inb(int addr)
{
	outb_p(addr, superio_cmd);
	return inb_p(superio_cmd + 1);
}
Example #27
0
/*
 * Either use the shared memory (if enabled on the board) or put the packet
 * out through the ASIC FIFO.
 */
static void
el2_block_output(struct net_device *dev, int count,
		 const unsigned char *buf, int start_page)
{
    unsigned short int *wrd;
    int boguscount;		/* timeout counter */
    unsigned short word;	/* temporary for better machine code */
    void __iomem *base = ei_status.mem;

    if (ei_status.word16)      /* Tx packets go into bank 0 on EL2/16 card */
	outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR);
    else
	outb(EGACFR_NORM, E33G_GACFR);

    if (base) {	/* Shared memory transfer */
	memcpy_toio(base + ((start_page - ei_status.tx_start_page) << 8),
			buf, count);
	outb(EGACFR_NORM, E33G_GACFR);	/* Back to bank1 in case on bank0 */
	return;
    }

/*
 *  No shared memory, put the packet out the other way.
 *  Set up then start the internal memory transfer to Tx Start Page
 */

    word = (unsigned short)start_page;
    outb(word&0xFF, E33G_DMAAH);
    outb(word>>8, E33G_DMAAL);

    outb_p((ei_status.interface_num ? ECNTRL_AUI : ECNTRL_THIN ) | ECNTRL_OUTPUT
	   | ECNTRL_START, E33G_CNTRL);

/*
 *  Here I am going to write data to the FIFO as quickly as possible.
 *  Note that E33G_FIFOH is defined incorrectly. It is really
 *  E33G_FIFOL, the lowest port address for both the byte and
 *  word write. Variable 'count' is NOT checked. Caller must supply a
 *  valid count. Note that I may write a harmless extra byte to the
 *  8390 if the byte-count was not even.
 */
    wrd = (unsigned short int *) buf;
    count  = (count + 1) >> 1;
    for(;;)
    {
        boguscount = 0x1000;
        while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
        {
            if(!boguscount--)
            {
                pr_notice("%s: FIFO blocked in el2_block_output.\n", dev->name);
                el2_reset_8390(dev);
                goto blocked;
            }
        }
        if(count > WRD_COUNT)
        {
            outsw(E33G_FIFOH, wrd, WRD_COUNT);
            wrd   += WRD_COUNT;
            count -= WRD_COUNT;
        }
        else
        {
            outsw(E33G_FIFOH, wrd, count);
            break;
        }
    }
    blocked:;
    outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
}
static void w83697ug_unselect_wd_register(void)
{
	outb_p(0xAA, WDT_EFER); /* Leave extended function mode */
}
Example #29
0
static void wdt_ctr_load(int ctr, int val)
{
	outb_p(val&0xFF, WDT_COUNT0+ctr);
	outb_p(val>>8, WDT_COUNT0+ctr);
}
static inline void w83697hf_unlock(void)
{
	outb_p(0x87, W83697HF_EFER);	/* Enter extended function mode */
	outb_p(0x87, W83697HF_EFER);	/* Again according to manual */
}