static int i801_block_transaction_byte_by_byte(struct i801_priv *priv, union i2c_smbus_data *data, char read_write, int command, int hwpec) { int i, len; int smbcmd; int status; int result; int timeout; result = i801_check_pre(priv); if (result < 0) return result; len = data->block[0]; if (read_write == I2C_SMBUS_WRITE) { outb_p(len, SMBHSTDAT0(priv)); outb_p(data->block[1], SMBBLKDAT(priv)); } for (i = 1; i <= len; i++) { if (i == len && read_write == I2C_SMBUS_READ) { if (command == I2C_SMBUS_I2C_BLOCK_DATA) smbcmd = I801_I2C_BLOCK_LAST; else smbcmd = I801_BLOCK_LAST; } else { if (command == I2C_SMBUS_I2C_BLOCK_DATA && read_write == I2C_SMBUS_READ) smbcmd = I801_I2C_BLOCK_DATA; else smbcmd = I801_BLOCK_DATA; } outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT(priv)); if (i == 1) outb_p(inb(SMBHSTCNT(priv)) | I801_START, SMBHSTCNT(priv)); /* We will always wait for a fraction of a second! */ timeout = 0; do { msleep(1); status = inb_p(SMBHSTSTS(priv)); } while ((!(status & SMBHSTSTS_BYTE_DONE)) && (timeout++ < MAX_TIMEOUT)); result = i801_check_post(priv, status, timeout > MAX_TIMEOUT); if (result < 0) return result; if (i == 1 && read_write == I2C_SMBUS_READ && command != I2C_SMBUS_I2C_BLOCK_DATA) { len = inb_p(SMBHSTDAT0(priv)); if (len < 1 || len > I2C_SMBUS_BLOCK_MAX) { dev_err(&priv->pci_dev->dev, "Illegal SMBus block read size %d\n", len); /* Recover */ while (inb_p(SMBHSTSTS(priv)) & SMBHSTSTS_HOST_BUSY) outb_p(SMBHSTSTS_BYTE_DONE, SMBHSTSTS(priv)); outb_p(SMBHSTSTS_INTR, SMBHSTSTS(priv)); return -EPROTO; } data->block[0] = len; } /* Retrieve/store value in SMBBLKDAT */ if (read_write == I2C_SMBUS_READ) data->block[i] = inb_p(SMBBLKDAT(priv)); if (read_write == I2C_SMBUS_WRITE && i+1 <= len) outb_p(data->block[i+1], SMBBLKDAT(priv)); /* signals SMBBLKDAT ready */ outb_p(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INTR, SMBHSTSTS(priv)); } return 0; }
void do_hd_request(void) { int i, r = 0; unsigned int start_sector, dev, partition; unsigned int start_sec, head, cyl; unsigned int nsect; CHECK_REQUEST; partition = MINOR(CURRENT_REQ->dev); /* get partition */ start_sector = CURRENT_REQ->start_sector; nsect = CURRENT_REQ->nr_sectors; /* need to check if nsect is exceed the partition limit or not */ if (partition >= 5 * NR_HD || nsect > hd[partition].nr_sects) { end_request(0); goto repeat; /* repeat defined in blk.h */ } start_sector += hd[partition].start_sect; dev = partition / 5; /* get cyl, head, start_sec number according start_sector */ /* div result: EAX = Quotient, EDX = Remainder */ /* * start_sector / sect nrs per track = total track number(start_sector) * ... remainder sector number(start_sec) */ __asm__("divl %4" :"=a" (start_sector), "=d" (start_sec) :"0" (start_sector), "1" (0), "r" (hd_info[dev].sect)); /* totoal track number / total head nrs = cylinder number(cyl) * ... head nr(head) */ __asm__("divl %4" :"=a" (cyl), "=d" (head) :"0" (start_sector), "1" (0), "r" (hd_info[dev].head)); start_sec++; if (reset) { reset = 0; recalibrate = 1; reset_hd(CURRENT_DEV); return; } if (recalibrate) { recalibrate = 0; hd_out(dev, hd_info[CURRENT_DEV].sect, 0, 0, 0, WIN_RESTORE, recal_intr); return; } if (CURRENT_REQ->cmd == WRITE) { hd_out(dev, nsect, start_sec, head, cyl, WIN_WRITE, write_intr); /* wait DRQ_STAT signal */ for(i = 0; i < 3000 && !(r = inb_p(HD_STATUS) & DRQ_STAT); i++) /* nothing */ ; if (!r) { bad_rw_intr(); goto repeat; } /* write 512 byte (1 sector) to HD */ port_write(HD_DATA, CURRENT_REQ->buffer, 256); } else if (CURRENT_REQ->cmd == READ) { hd_out(dev, nsect, start_sec, head, cyl, WIN_READ, read_intr); } else { panic("unknown hd-command"); } }
static u8 get_cmd640_reg_pci1(u16 reg) { outl_p((reg & 0xfc) | cmd640_key, 0xcf8); return inb_p((reg & 3) | 0xcfc); }
/* This initializes the NE2000 card. If it turns out the card is not // really a NE2000 after all then it will return ERRNOTFOUND, else NOERR // It also dumps the prom into buffer prom for the upper layers.. // Pass it a nic with a null iobase and it will initialize the structure for // you, otherwise it will just reinitialize it. */ int nic_init(snic* nic, int addr, unsigned char *prom, unsigned char *manual) { uint f; kprintf("NE2000: reseting NIC card..."); if(!nic->iobase) { nic->iobase=addr; nic_stat_clear(&nic->stat); nic->pstart=0; nic->pstop=0; nic->wordlength=0; nic->current_page=0; nic->notify=NULL; for(f=0;f<MAX_TX;f++) { nic->tx_packet[f]= NULL; /* nic->tx_packet[f].count=0; nic->tx_packet[f].buf=NULL; nic->tx_packet[f].page=0; */ } nic->last_tx=NULL; nic->busy=0; nic->sending=0; } else { if(!nic->iobase || nic->iobase!=addr) return ERR; } outb(inb(addr + NE_RESET), addr + NE_RESET); /* reset the NE2000*/ while(!(inb_p(addr+INTERRUPTSTATUS) & ISR_RST)) { /* TODO insert timeout code here.*/ } kprintf("done.\n"); outb_p(0xff,addr + INTERRUPTSTATUS); /* clear all pending ints*/ // Initialize registers outb_p(NIC_DMA_DISABLE | NIC_PAGE0 | NIC_STOP, addr); /* enter page 0*/ outb_p(DCR_DEFAULT, addr + DATACONFIGURATION); outb_p(0x00, addr + REMOTEBYTECOUNT0); outb_p(0x00, addr + REMOTEBYTECOUNT1); outb_p(0x00, addr + INTERRUPTMASK); /* mask off all irq's*/ outb_p(0xff, addr + INTERRUPTSTATUS); /* clear pending ints*/ outb_p(RCR_MON, RECEIVECONFIGURATION); /* enter monitor mode*/ outb_p(TCR_INTERNAL_LOOPBACK, TRANSMITCONFIGURATION); /* internal loopback*/ nic->wordlength=nic_dump_prom(nic,prom); if(prom[14]!=0x57 || prom[15]!=0x57) { kprintf("NE2000: PROM signature does not match NE2000 0x57.\n"); return ERRNOTFOUND; } kprintf("NE2000: PROM signature matches NE2000 0x57.\n"); /* if the wordlength for the NE2000 card is 2 bytes, then // we have to setup the DP8390 chipset to be the same or // else all hell will break loose.*/ if(nic->wordlength==2) { outb_p(DCR_DEFAULT_WORD, addr + DATACONFIGURATION); } nic->pstart=(nic->wordlength==2) ? PSTARTW : PSTART; nic->pstop=(nic->wordlength==2) ? PSTOPW : PSTOP; outb_p(NIC_DMA_DISABLE | NIC_PAGE0 | NIC_STOP, addr); outb_p(nic->pstart, addr + TRANSMITPAGE); /* setup local buffer*/ outb_p(nic->pstart + TXPAGES, addr + PAGESTART); outb_p(nic->pstop - 1, addr + BOUNDARY); outb_p(nic->pstop, addr + PAGESTOP); outb_p(0x00, addr + INTERRUPTMASK); /* mask off all irq's*/ outb_p(0xff, addr + INTERRUPTSTATUS); /* clear pending ints*/ nic->current_page=nic->pstart + TXPAGES; /* put physical address in the registers */ outb_p(NIC_DMA_DISABLE | NIC_PAGE1 | NIC_STOP, addr); /* switch to page 1 */ if(manual) for(f=0;f<6;f++) outb_p(manual[f], addr + PHYSICAL + f); else for(f=0;f<LEN_ADDR;f++) outb_p(prom[f], addr + PHYSICAL + f); kprintf("NE2000: Physical Address- "); kprintf("%X:%X:%X:%X:%X:%X\n", inb(addr+PAR0),inb(addr+PAR1),inb(addr+PAR2), inb(addr+PAR3),inb(addr+PAR4),inb(addr+PAR5)); /* setup multicast filter to accept all packets*/ for(f=0;f<8;f++) outb_p(0xFF, addr + MULTICAST + f); outb_p(nic->pstart+TXPAGES, addr + CURRENT); outb_p(NIC_DMA_DISABLE | NIC_PAGE0 | NIC_STOP, addr); /* switch to page 0 */ return NOERR; }
/* Access routines for accessing mc146818 type chips via addr/data regs */ u_char todc_mc146818_read_val(int addr) { outb_p(addr, todc_info->nvram_as0); return inb_p(todc_info->nvram_data); }
static int i801_transaction(void) { int temp; int result = 0; int timeout = 0; dev_dbg(I801_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, "SMBus busy (%02x). Resetting...\n", temp); outb_p(temp, SMBHSTSTS); if ((temp = (0x1f & inb_p(SMBHSTSTS))) != 0x00) { dev_dbg(I801_dev, "Failed! (%02x)\n", temp); return -1; } else { dev_dbg(I801_dev, "Successfull!\n"); } } outb_p(inb(SMBHSTCNT) | I801_START, SMBHSTCNT); /* We will always wait for a fraction of a second! */ do { i2c_delay(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, "SMBus Timeout!\n"); result = -1; } if (temp & 0x10) { result = -1; dev_dbg(I801_dev, "Error: Failed bus transaction\n"); } if (temp & 0x08) { result = -1; dev_err(I801_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, "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, "Failed reset at end of transaction " "(%02x)\n", temp); } dev_dbg(I801_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; }
static inline bool synth_writable(void) { return inb_p(synth_port_control) & SYNTH_WRITABLE; }
static inline void pcipcwd_check_temperature_support(void) { if (inb_p(pcipcwd_private.io_addr) != 0xF0) pcipcwd_private.supports_temp = 1; }
static int s3lfb_set_mode(video_adapter_t *adp, int mode) { device_t dev = s3pci_dev; /* XXX */ struct s3pci_softc *sc = (struct s3pci_softc *)device_get_softc(dev); #if 0 unsigned char tmp; #endif int error; /* First, set the mode as if it was a classic VESA card */ if ((error = (*prevvidsw->set_mode)(adp, mode))) return error; /* If not in a linear mode (according to s3lfb_get_info() called * by vesa_set_mode in the (*vidsw[adp->va_index]->get_info)... * sequence, return with no error */ #if 0 if (!(adp->va_info.vi_flags & V_INFO_LINEAR)) return 0; #endif if ((mode <= M_VESA_BASE) || !(adp->va_info.vi_flags & V_INFO_GRAPHICS) || (adp->va_info.vi_flags & V_INFO_LINEAR)) return 0; /* Ok, now apply the configuration to the card */ outb_p(0x38, S3_CRTC_ADDR); outb_p(0x48, S3_CRTC_VALUE); outb_p(0x39, S3_CRTC_ADDR); outb_p(0xa5, S3_CRTC_VALUE); /* check that CR47 is read/write */ #if 0 outb_p(0x47, S3_CRTC_ADDR); outb_p(0xff, S3_CRTC_VALUE); tmp = inb_p(S3_CRTC_VALUE); outb_p(0x00, S3_CRTC_VALUE); if ((tmp != 0xff) || (inb_p(S3_CRTC_VALUE))) { /* lock S3 registers */ outb_p(0x39, S3_CRTC_ADDR); outb_p(0x5a, S3_CRTC_VALUE); outb_p(0x38, S3_CRTC_ADDR); outb_p(0x00, S3_CRTC_VALUE); return ENXIO; } #endif /* enable enhanced register access */ outb_p(0x40, S3_CRTC_ADDR); outb_p(inb_p(S3_CRTC_VALUE) | 1, S3_CRTC_VALUE); /* enable enhanced functions */ outb_enh(inb_enh(0) | 1, 0x0); /* enable enhanced mode memory mapping */ outb_p(0x31, S3_CRTC_ADDR); outb_p(inb_p(S3_CRTC_VALUE) | 8, S3_CRTC_VALUE); /* enable linear frame buffer and set address window to max */ outb_p(0x58, S3_CRTC_ADDR); outb_p(inb_p(S3_CRTC_VALUE) | 0x13, S3_CRTC_VALUE); /* disabled enhanced register access */ outb_p(0x40, S3_CRTC_ADDR); outb_p(inb_p(S3_CRTC_VALUE) & ~1, S3_CRTC_VALUE); /* lock S3 registers */ outb_p(0x39, S3_CRTC_ADDR); outb_p(0x5a, S3_CRTC_VALUE); outb_p(0x38, S3_CRTC_ADDR); outb_p(0x00, S3_CRTC_VALUE); adp->va_info.vi_flags |= V_INFO_LINEAR; adp->va_info.vi_buffer = sc->mem_base; adp->va_buffer = s3lfb_map_buffer(adp->va_info.vi_buffer, adp->va_info.vi_buffer_size); adp->va_buffer_size = adp->va_info.vi_buffer_size; adp->va_window = adp->va_buffer; adp->va_window_size = adp->va_info.vi_buffer_size/adp->va_info.vi_planes; adp->va_window_gran = adp->va_info.vi_buffer_size/adp->va_info.vi_planes; return 0; }
static void acq_keepalive(void) { /* Write a watchdog value */ inb_p(wdt_start); }
static void acq_stop(void) { /* Turn the card off */ inb_p(wdt_stop); }
static void piix4_poll(struct i2c_adapter *piix4_adapter, struct i2c_op_q_entry *e, unsigned int ns_since_last_poll) { struct i2c_piix4_adapdata *adapdata = i2c_get_adapdata(piix4_adapter); unsigned short piix4_smba = adapdata->smba; int temp; int i; temp = inb_p(SMBHSTSTS); if (temp & 0x01) { e->time_left -= ns_since_last_poll; if (e->time_left <= 0) { dev_err(&piix4_adapter->dev, "SMBus Timeout!\n"); e->result = -EBUSY; goto out_done; } else { /* Not done, return to restart the timer */ e->call_again_ns = RETRY_TIME_NS; } return; } if (temp & 0x10) { e->result = -EIO; dev_err(&piix4_adapter->dev, "Error: Failed bus transaction\n"); goto out_done; } if (temp & 0x08) { e->result = -EIO; dev_dbg(&piix4_adapter->dev, "Bus collision! SMBus may be " "locked until next hard reset. (sorry!)\n"); /* Clock stops and slave is stuck in mid-transmission */ goto out_done; } if (temp & 0x04) { e->result = -ENODEV; dev_dbg(&piix4_adapter->dev, "Error: no response!\n"); goto out_done; } if (inb_p(SMBHSTSTS) != 0x00) outb_p(inb(SMBHSTSTS), SMBHSTSTS); if ((temp = inb_p(SMBHSTSTS)) != 0x00) { dev_err(&piix4_adapter->dev, "Failed reset at end of " "transaction (%02x)\n", temp); } dev_dbg(&piix4_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)); if ((e->smbus.read_write == I2C_SMBUS_WRITE) || (e->smbus.size == PIIX4_QUICK)) goto out_done; switch (e->smbus.size) { case PIIX4_BYTE: case PIIX4_BYTE_DATA: e->smbus.data->byte = inb_p(SMBHSTDAT0); break; case PIIX4_WORD_DATA: e->smbus.data->word = (inb_p(SMBHSTDAT0) + (inb_p(SMBHSTDAT1) << 8)); break; case PIIX4_BLOCK_DATA: e->smbus.data->block[0] = inb_p(SMBHSTDAT0); if (e->smbus.data->block[0] == 0 || e->smbus.data->block[0] > I2C_SMBUS_BLOCK_MAX) { e->result = -EPROTO; goto out_done; } i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ for (i = 1; i <= e->smbus.data->block[0]; i++) e->smbus.data->block[i] = inb_p(SMBBLKDAT); break; } out_done: i2c_op_done(piix4_adapter, e); }
static int piix4_setup_sb800(struct pci_dev *PIIX4_dev, const struct pci_device_id *id) { unsigned short piix4_smba; unsigned short smba_idx = 0xcd6; u8 smba_en_lo, smba_en_hi, i2ccfg, i2ccfg_offset = 0x10, smb_en = 0x2c; /* SB800 and later SMBus does not support forcing address */ if (force || force_addr) { dev_err(&PIIX4_dev->dev, "SMBus does not support " "forcing address!\n"); return -EINVAL; } /* Determine the address of the SMBus areas */ if (!request_region(smba_idx, 2, "smba_idx")) { dev_err(&PIIX4_dev->dev, "SMBus base address index region " "0x%x already in use!\n", smba_idx); return -EBUSY; } outb_p(smb_en, smba_idx); smba_en_lo = inb_p(smba_idx + 1); outb_p(smb_en + 1, smba_idx); smba_en_hi = inb_p(smba_idx + 1); release_region(smba_idx, 2); if ((smba_en_lo & 1) == 0) { dev_err(&PIIX4_dev->dev, "Host SMBus controller not enabled!\n"); return -ENODEV; } piix4_smba = ((smba_en_hi << 8) | smba_en_lo) & 0xffe0; if (acpi_check_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) return -ENODEV; if (!request_region(piix4_smba, SMBIOSIZE, piix4_driver.name)) { dev_err(&PIIX4_dev->dev, "SMBus region 0x%x already in use!\n", piix4_smba); return -EBUSY; } /* Request the SMBus I2C bus config region */ if (!request_region(piix4_smba + i2ccfg_offset, 1, "i2ccfg")) { dev_err(&PIIX4_dev->dev, "SMBus I2C bus config region " "0x%x already in use!\n", piix4_smba + i2ccfg_offset); release_region(piix4_smba, SMBIOSIZE); return -EBUSY; } i2ccfg = inb_p(piix4_smba + i2ccfg_offset); release_region(piix4_smba + i2ccfg_offset, 1); if (i2ccfg & 1) dev_dbg(&PIIX4_dev->dev, "Using IRQ for SMBus.\n"); else dev_dbg(&PIIX4_dev->dev, "Using SMI# for SMBus.\n"); dev_info(&PIIX4_dev->dev, "SMBus Host Controller at 0x%x, revision %d\n", piix4_smba, i2ccfg >> 4); return piix4_smba; }
i = inb_p(SMBHSTCNT); /* Reset SMBBLKDAT */ for (i = 1; i <= len; i++) outb_p(e->smbus.data->block[i], SMBBLKDAT); } e->smbus.size = PIIX4_BLOCK_DATA; break; default: dev_warn(&piix4_adapter->dev, "Unsupported transaction %d\n", e->smbus.size); return -EOPNOTSUPP; } outb_p((e->smbus.size & 0x1C) + (ENABLE_INT9 & 1), SMBHSTCNT); dev_dbg(&piix4_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 */ temp = inb_p(SMBHSTSTS); if (temp != 0x00) { dev_dbg(&piix4_adapter->dev, "SMBus busy (%02x). " "Resetting...\n", temp); outb_p(temp, SMBHSTSTS); temp = inb_p(SMBHSTSTS); if (temp != 0x00) { dev_err(&piix4_adapter->dev, "Failed! (%02x)\n", temp); return -EBUSY; } else { dev_dbg(&piix4_adapter->dev, "Successfull!\n");
static unsigned char ddb_rtc_read_data(unsigned long addr) { outb_p(addr, RTC_PORT(0)); return inb_p(RTC_PORT(1)); }
static int dt_getstatus(void) { dt_stat = inb_p(speakup_info.port_tts) | (inb_p(speakup_info.port_tts + 1) << 8); return dt_stat; }
static int el_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_local *lp = (struct net_local *)dev->priv; int ioaddr = dev->base_addr; unsigned long flags; /* * Avoid incoming interrupts between us flipping txing and flipping * mode as the driver assumes txing is a faithful indicator of card * state */ spin_lock_irqsave(&lp->lock, flags); /* * Avoid timer-based retransmission conflicts. */ netif_stop_queue(dev); do { int gp_start = 0x800 - (ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN); unsigned char *buf = skb->data; lp->tx_pkt_start = gp_start; lp->collisions = 0; lp->stats.tx_bytes += skb->len; /* * Command mode with status cleared should [in theory] * mean no more interrupts can be pending on the card. */ outb_p(AX_SYS, AX_CMD); inb_p(RX_STATUS); inb_p(TX_STATUS); lp->loading = 1; lp->txing = 1; /* * Turn interrupts back on while we spend a pleasant afternoon * loading bytes into the board */ spin_unlock_irqrestore(&lp->lock, flags); outw(0x00, RX_BUF_CLR); /* Set rx packet area to 0. */ outw(gp_start, GP_LOW); /* aim - packet will be loaded into buffer start */ outsb(DATAPORT,buf,skb->len); /* load buffer (usual thing each byte increments the pointer) */ outw(gp_start, GP_LOW); /* the board reuses the same register */ if(lp->loading != 2) { outb(AX_XMIT, AX_CMD); /* fire ... Trigger xmit. */ lp->loading=0; dev->trans_start = jiffies; if (el_debug > 2) printk(" queued xmit.\n"); dev_kfree_skb (skb); return 0; } /* A receive upset our load, despite our best efforts */ if(el_debug>2) printk("%s: burped during tx load.\n", dev->name); spin_lock_irqsave(&lp->lock, flags); } while(1); }
static inline bool synth_writable(void) { return (inb_p(synth_port + UART_RX) & 0x10) != 0; }
/* All-inclusive block transaction function */ static int i801_block_transaction(union i2c_smbus_data *data, char read_write, int command, int hwpec) { 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 if (!isich5) { dev_err(I801_dev, "I2C_SMBUS_I2C_BLOCK_READ unsupported!\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 if (command == I2C_SMBUS_I2C_BLOCK_DATA && read_write == I2C_SMBUS_READ) smbcmd = I801_I2C_BLOCK_DATA; else smbcmd = I801_BLOCK_DATA; outb_p(smbcmd | ENABLE_INT9, SMBHSTCNT); dev_dbg(I801_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, "SMBus busy (%02x). " "Resetting...\n", temp); outb_p(temp, SMBHSTSTS); if (((temp = inb_p(SMBHSTSTS)) & errmask) != 0x00) { dev_err(I801_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); i2c_delay(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, "SMBus Timeout!\n"); } if (temp & 0x10) { result = -1; dev_dbg(I801_dev, "Error: Failed bus transaction\n"); } else if (temp & 0x08) { result = -1; dev_err(I801_dev, "Bus collision!\n"); } else if (temp & 0x04) { result = -1; dev_dbg(I801_dev, "Error: no response!\n"); } if (i == 1 && read_write == I2C_SMBUS_READ) { if (command != I2C_SMBUS_I2C_BLOCK_DATA) { len = inb_p(SMBHSTDAT0); if (len < 1) len = 1; if (len > 32) len = 32; data->block[0] = len; } else { /* if slave returns < 32 bytes transaction will fail */ data->block[0] = 32; } } /* 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, "Bad status (%02x) at end of transaction\n", temp); } dev_dbg(I801_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; } if (hwpec) { /* wait for INTR bit as advised by Intel */ timeout = 0; do { temp = inb_p(SMBHSTSTS); i2c_delay(1); } while ((!(temp & 0x02)) && (timeout++ < MAX_TIMEOUT)); if (timeout >= MAX_TIMEOUT) { dev_dbg(I801_dev, "PEC Timeout!\n"); } outb_p(temp, SMBHSTSTS); } result = 0; END: if (command == I2C_SMBUS_I2C_BLOCK_DATA && read_write == I2C_SMBUS_WRITE) { /* restore saved configuration register value */ pci_write_config_byte(I801_dev, SMBHSTCFG, hostc); } return result; }
static inline bool synth_full(void) { return (inb_p(synth_port + UART_RX) & 0x80) == 0; }
static inline bool synth_full(void) { return inb_p(speakup_info.port_tts + UART_RX) == 'F'; }
void setup_APIC_timer(void * data) { unsigned int clocks = (unsigned long) data, slice, t0, t1; int delta; /* * ok, Intel has some smart code in their APIC that knows * if a CPU was in 'hlt' lowpower mode, and this increases * its APIC arbitration priority. To avoid the external timer * IRQ APIC event being in synchron with the APIC clock we * introduce an interrupt skew to spread out timer events. * * The number of slices within a 'big' timeslice is smp_num_cpus+1 */ slice = clocks / (smp_num_cpus+1); printk(KERN_INFO "cpu: %d, clocks: %d, slice: %d\n", smp_processor_id(), clocks, slice); /* * Wait for timer IRQ slice: */ if (hpet.address) { int trigger = hpet_readl(HPET_T0_CMP); while (hpet_readl(HPET_COUNTER) >= trigger); while (hpet_readl(HPET_COUNTER) < trigger); } else { int c1, c2; outb_p(0x00, 0x43); c2 = inb_p(0x40); c2 |= inb_p(0x40) << 8; do { c1 = c2; outb_p(0x00, 0x43); c2 = inb_p(0x40); c2 |= inb_p(0x40) << 8; } while (c2 - c1 < 300); } __setup_APIC_LVTT(clocks); t0 = apic_read(APIC_TMICT)*APIC_DIVISOR; /* Wait till TMCCT gets reloaded from TMICT... */ do { t1 = apic_read(APIC_TMCCT)*APIC_DIVISOR; delta = (int)(t0 - t1 - slice*(smp_processor_id()+1)); } while (delta >= 0); /* Now wait for our slice for real. */ do { t1 = apic_read(APIC_TMCCT)*APIC_DIVISOR; delta = (int)(t0 - t1 - slice*(smp_processor_id()+1)); } while (delta < 0); __setup_APIC_LVTT(clocks); printk(KERN_INFO "CPU%d<T0:%u,T1:%u,D:%d,S:%u,C:%u>\n", smp_processor_id(), t0, t1, delta, slice, clocks); }
/* You should call this before you just read the stats directlly from the // snic struct. This procedure updates the counters */ nic_stat nic_get_stats(snic *nic) { nic->stat.errors.frame_alignment+=inb_p(nic->iobase + FAE_TALLY); nic->stat.errors.crc+=inb_p(nic->iobase + CRC_TALLY); nic->stat.errors.missed_packets+=inb_p(nic->iobase + MISS_PKT_TALLY); return nic->stat; }
/* 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) printk(version); dev->base_addr = ioaddr; printk("%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); printk("%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) printk(" 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 printk(", 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) { printk("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) { printk("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; #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = eip_poll; #endif retval = register_netdev(dev); if (retval) goto out1; if (dev->mem_start) printk("%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; printk("\n%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; }
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; }
static int amd756_transaction(struct i2c_adapter *adap) { int temp; int result = 0; int timeout = 0; dev_dbg(&adap->dev, "Transaction (pre): GS=%04x, GE=%04x, ADD=%04x, " "DAT=%04x\n", inw_p(SMB_GLOBAL_STATUS), inw_p(SMB_GLOBAL_ENABLE), inw_p(SMB_HOST_ADDRESS), inb_p(SMB_HOST_DATA)); /* Make sure the SMBus host is ready to start transmitting */ if ((temp = inw_p(SMB_GLOBAL_STATUS)) & (GS_HST_STS | GS_SMB_STS)) { dev_dbg(&adap->dev, "SMBus busy (%04x). Waiting...\n", temp); do { msleep(1); temp = inw_p(SMB_GLOBAL_STATUS); } while ((temp & (GS_HST_STS | GS_SMB_STS)) && (timeout++ < MAX_TIMEOUT)); /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { dev_dbg(&adap->dev, "Busy wait timeout (%04x)\n", temp); goto abort; } timeout = 0; } /* start the transaction by setting the start bit */ outw_p(inw(SMB_GLOBAL_ENABLE) | GE_HOST_STC, SMB_GLOBAL_ENABLE); /* We will always wait for a fraction of a second! */ do { msleep(1); temp = inw_p(SMB_GLOBAL_STATUS); } while ((temp & GS_HST_STS) && (timeout++ < MAX_TIMEOUT)); /* If the SMBus is still busy, we give up */ if (timeout >= MAX_TIMEOUT) { dev_dbg(&adap->dev, "Completion timeout!\n"); goto abort; } if (temp & GS_PRERR_STS) { result = -1; dev_dbg(&adap->dev, "SMBus Protocol error (no response)!\n"); } if (temp & GS_COL_STS) { result = -1; dev_warn(&adap->dev, "SMBus collision!\n"); } if (temp & GS_TO_STS) { result = -1; dev_dbg(&adap->dev, "SMBus protocol timeout!\n"); } if (temp & GS_HCYC_STS) dev_dbg(&adap->dev, "SMBus protocol success!\n"); outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS); #ifdef DEBUG if (((temp = inw_p(SMB_GLOBAL_STATUS)) & GS_CLEAR_STS) != 0x00) { dev_dbg(&adap->dev, "Failed reset at end of transaction (%04x)\n", temp); } #endif dev_dbg(&adap->dev, "Transaction (post): GS=%04x, GE=%04x, ADD=%04x, DAT=%04x\n", inw_p(SMB_GLOBAL_STATUS), inw_p(SMB_GLOBAL_ENABLE), inw_p(SMB_HOST_ADDRESS), inb_p(SMB_HOST_DATA)); return result; abort: dev_warn(&adap->dev, "Sending abort\n"); outw_p(inw(SMB_GLOBAL_ENABLE) | GE_ABORT, SMB_GLOBAL_ENABLE); msleep(100); outw_p(GS_CLEAR_STS, SMB_GLOBAL_STATUS); return -1; }
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; }
/* Return -1 on error. */ static s32 amd756_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; /** TODO: Should I supporte the 10-bit transfers? */ switch (size) { case I2C_SMBUS_PROC_CALL: dev_dbg(&adap->dev, "I2C_SMBUS_PROC_CALL not supported!\n"); /* TODO: Well... It is supported, I'm just not sure what to do here... */ return -1; case I2C_SMBUS_QUICK: outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMB_HOST_ADDRESS); size = AMD756_QUICK; break; case I2C_SMBUS_BYTE: outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMB_HOST_ADDRESS); if (read_write == I2C_SMBUS_WRITE) outb_p(command, SMB_HOST_DATA); size = AMD756_BYTE; break; case I2C_SMBUS_BYTE_DATA: outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMB_HOST_ADDRESS); outb_p(command, SMB_HOST_COMMAND); if (read_write == I2C_SMBUS_WRITE) outw_p(data->byte, SMB_HOST_DATA); size = AMD756_BYTE_DATA; break; case I2C_SMBUS_WORD_DATA: outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMB_HOST_ADDRESS); outb_p(command, SMB_HOST_COMMAND); if (read_write == I2C_SMBUS_WRITE) outw_p(data->word, SMB_HOST_DATA); /* TODO: endian???? */ size = AMD756_WORD_DATA; break; case I2C_SMBUS_BLOCK_DATA: outw_p(((addr & 0x7f) << 1) | (read_write & 0x01), SMB_HOST_ADDRESS); outb_p(command, SMB_HOST_COMMAND); if (read_write == I2C_SMBUS_WRITE) { len = data->block[0]; if (len < 0) len = 0; if (len > 32) len = 32; outw_p(len, SMB_HOST_DATA); /* i = inw_p(SMBHSTCNT); Reset SMBBLKDAT */ for (i = 1; i <= len; i++) outb_p(data->block[i], SMB_HOST_BLOCK_DATA); } size = AMD756_BLOCK_DATA; break; } /* How about enabling interrupts... */ outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE); if (amd756_transaction(adap)) /* Error in transaction */ return -1; if ((read_write == I2C_SMBUS_WRITE) || (size == AMD756_QUICK)) return 0; switch (size) { case AMD756_BYTE: data->byte = inw_p(SMB_HOST_DATA); break; case AMD756_BYTE_DATA: data->byte = inw_p(SMB_HOST_DATA); break; case AMD756_WORD_DATA: data->word = inw_p(SMB_HOST_DATA); /* TODO: endian???? */ break; case AMD756_BLOCK_DATA: data->block[0] = inw_p(SMB_HOST_DATA) & 0x3f; if(data->block[0] > 32) data->block[0] = 32; /* i = inw_p(SMBHSTCNT); Reset SMBBLKDAT */ for (i = 1; i <= data->block[0]; i++) data->block[i] = inb_p(SMB_HOST_BLOCK_DATA); break; } return 0; }
static u8 get_cmd640_reg_vlb(u16 reg) { outb_p(reg, cmd640_key); return inb_p(cmd640_key + 4); }
/* 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++) { usleep_range(1000, 2000); 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; }