static u16 sonypi_ecrget(u16 addr) { wait_on_command(1, inw_p(SONYPI_CST_IOPORT) & 3); outw_p(0x80, SONYPI_CST_IOPORT); wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2); outw_p(addr, SONYPI_DATA_IOPORT); wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2); return inw_p(SONYPI_DATA_IOPORT); }
static void sonypi_ecrset(u16 addr, u16 value) { wait_on_command(1, inw_p(SONYPI_CST_IOPORT) & 3); outw_p(0x81, SONYPI_CST_IOPORT); wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2); outw_p(addr, SONYPI_DATA_IOPORT); wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2); outw_p(value, SONYPI_DATA_IOPORT); wait_on_command(0, inw_p(SONYPI_CST_IOPORT) & 2); }
static PyObject * chwtest_inw(PyObject *self, PyObject *args) { unsigned long int address; unsigned short int value; if (!PyArg_ParseTuple(args, "l", &address)) return NULL; value = inw_p(address); return Py_BuildValue("h", value); }
/**************************************************************** * Name: Command :LOCAL * * Description: Issue queued command to the PCI-2000. * * Parameters: padapter - Pointer to adapter information structure. * cmd - PCI-2000 command byte. * * Returns: Non-zero command tag if operation is accepted. * ****************************************************************/ static UCHAR Command (PADAPTER2000 padapter, UCHAR cmd) { outb_p (cmd, padapter->cmd); if ( WaitReady (padapter) ) return 0; if ( inw_p (padapter->mb0) ) return 0; return inb_p (padapter->mb1); }
static int dyna_pci10xx_ai_eoc(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned long context) { unsigned int status; status = inw_p(dev->iobase); if (status & (1 << 15)) return 0; return -EBUSY; }
static int synth_probe(struct spk_synth *synth) { unsigned int port_val = 0; int i = 0; struct synth_settings *sp; pr_info("Probing for DoubleTalk.\n"); if (port_forced) { speakup_info.port_tts = port_forced; pr_info("probe forced to %x by kernel command line\n", speakup_info.port_tts); if ((port_forced & 0xf) != 0xf) pr_info("warning: port base should probably end with f\n"); if (synth_request_region(speakup_info.port_tts-1, SYNTH_IO_EXTENT)) { pr_warn("sorry, port already reserved\n"); return -EBUSY; } port_val = inw(speakup_info.port_tts-1); synth_lpc = speakup_info.port_tts-1; } else { for (i = 0; synth_portlist[i]; i++) { if (synth_request_region(synth_portlist[i], SYNTH_IO_EXTENT)) continue; port_val = inw(synth_portlist[i]) & 0xfbff; if (port_val == 0x107f) { synth_lpc = synth_portlist[i]; speakup_info.port_tts = synth_lpc+1; break; } synth_release_region(synth_portlist[i], SYNTH_IO_EXTENT); } } port_val &= 0xfbff; if (port_val != 0x107f) { pr_info("DoubleTalk PC: not found\n"); synth_release_region(synth_lpc, SYNTH_IO_EXTENT); return -ENODEV; } while (inw_p(synth_lpc) != 0x147f) cpu_relax(); /* wait until it's ready */ sp = synth_interrogate(synth); pr_info("%s: %03x-%03x, ROM ver %s, s/n %u, driver: %s\n", synth->long_name, synth_lpc, synth_lpc+SYNTH_IO_EXTENT - 1, sp->rom_version, sp->serial_number, synth->version); synth->alive = 1; return 0; }
/* digital input bit interface */ static int dyna_pci10xx_di_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { struct dyna_pci10xx_private *devpriv = dev->private; u16 d = 0; mutex_lock(&devpriv->mutex); smp_mb(); d = inw_p(devpriv->BADR3); udelay(10); /* on return the data[0] contains output and data[1] contains input */ data[1] = d; data[0] = s->state; mutex_unlock(&devpriv->mutex); return insn->n; }
static int dyna_pci10xx_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { struct dyna_pci10xx_private *devpriv = dev->private; int n; u16 d = 0; int ret = 0; unsigned int chan, range; /* get the channel number and range */ chan = CR_CHAN(insn->chanspec); range = range_codes_pci1050_ai[CR_RANGE((insn->chanspec))]; mutex_lock(&devpriv->mutex); /* convert n samples */ for (n = 0; n < insn->n; n++) { /* trigger conversion */ smp_mb(); outw_p(0x0000 + range + chan, dev->iobase + 2); udelay(10); ret = comedi_timeout(dev, s, insn, dyna_pci10xx_ai_eoc, 0); if (ret) break; /* read data */ d = inw_p(dev->iobase); /* mask the first 4 bits - EOC bits */ d &= 0x0FFF; data[n] = d; } mutex_unlock(&devpriv->mutex); /* return the number of samples read/written */ return ret ? ret : n; }
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 = -ENXIO; dev_dbg(&adap->dev, "SMBus Protocol error (no response)!\n"); } if (temp & GS_COL_STS) { result = -EIO; dev_warn(&adap->dev, "SMBus collision!\n"); } if (temp & GS_TO_STS) { result = -ETIMEDOUT; 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 -EIO; }
/* Return negative errno 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; int status; switch (size) { 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; default: dev_warn(&adap->dev, "Unsupported transaction %d\n", size); return -EOPNOTSUPP; } /* How about enabling interrupts... */ outw_p(size & GE_CYC_TYPE_MASK, SMB_GLOBAL_ENABLE); status = amd756_transaction(adap); if (status) return status; 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; }
/* 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 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 (!request_region(dtlk_portlist[i], DTLK_IO_EXTENT, "dtlk")) continue; testval = inw_p(dtlk_portlist[i]); if ((testval &= 0xfbff) == 0x107f) { 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. */ msleep_interruptible(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; } release_region(dtlk_portlist[i], DTLK_IO_EXTENT); } printk(KERN_INFO "DoubleTalk PC - not found\n"); return -ENODEV; }