diff options
Diffstat (limited to 'drivers/staging/comedi/drivers/s626.c')
-rw-r--r-- | drivers/staging/comedi/drivers/s626.c | 1211 |
1 files changed, 565 insertions, 646 deletions
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c index 81a1fe66157..0cf4b3d1279 100644 --- a/drivers/staging/comedi/drivers/s626.c +++ b/drivers/staging/comedi/drivers/s626.c @@ -80,7 +80,7 @@ INSN_CONFIG instructions: #define PCI_SUBDEVICE_ID_S626 0x0272 struct s626_private { - void __iomem *base_addr; + void __iomem *mmio; uint8_t ai_cmd_running; /* ai_cmd is running */ uint8_t ai_continous; /* continous acquisition */ int ai_sample_count; /* number of samples to acquire */ @@ -106,64 +106,6 @@ struct s626_private { unsigned int ao_readback[S626_DAC_CHANNELS]; }; -struct dio_private { - uint16_t RDDIn; - uint16_t WRDOut; - uint16_t RDEdgSel; - uint16_t WREdgSel; - uint16_t RDCapSel; - uint16_t WRCapSel; - uint16_t RDCapFlg; - uint16_t RDIntSel; - uint16_t WRIntSel; -}; - -static struct dio_private dio_private_A = { - .RDDIn = LP_RDDINA, - .WRDOut = LP_WRDOUTA, - .RDEdgSel = LP_RDEDGSELA, - .WREdgSel = LP_WREDGSELA, - .RDCapSel = LP_RDCAPSELA, - .WRCapSel = LP_WRCAPSELA, - .RDCapFlg = LP_RDCAPFLGA, - .RDIntSel = LP_RDINTSELA, - .WRIntSel = LP_WRINTSELA, -}; - -static struct dio_private dio_private_B = { - .RDDIn = LP_RDDINB, - .WRDOut = LP_WRDOUTB, - .RDEdgSel = LP_RDEDGSELB, - .WREdgSel = LP_WREDGSELB, - .RDCapSel = LP_RDCAPSELB, - .WRCapSel = LP_WRCAPSELB, - .RDCapFlg = LP_RDCAPFLGB, - .RDIntSel = LP_RDINTSELB, - .WRIntSel = LP_WRINTSELB, -}; - -static struct dio_private dio_private_C = { - .RDDIn = LP_RDDINC, - .WRDOut = LP_WRDOUTC, - .RDEdgSel = LP_RDEDGSELC, - .WREdgSel = LP_WREDGSELC, - .RDCapSel = LP_RDCAPSELC, - .WRCapSel = LP_WRCAPSELC, - .RDCapFlg = LP_RDCAPFLGC, - .RDIntSel = LP_RDINTSELC, - .WRIntSel = LP_WRINTSELC, -}; - -/* to group dio devices (48 bits mask and data are not allowed ???) -static struct dio_private *dio_private_word[]={ - &dio_private_A, - &dio_private_B, - &dio_private_C, -}; -*/ - -#define diopriv ((struct dio_private *)s->private) - /* COUNTER OBJECT ------------------------------------------------ */ struct enc_private { /* Pointers to functions that differ for A and B counters: */ @@ -195,37 +137,53 @@ struct enc_private { /* Translation table to map IntSrc into equivalent RDMISC2 event flag bits. */ /* static const uint16_t EventBits[][4] = { EVBITS(0), EVBITS(1), EVBITS(2), EVBITS(3), EVBITS(4), EVBITS(5) }; */ -/* enab/disable a function or test status bit(s) that are accessed */ -/* through Main Control Registers 1 or 2. */ -#define MC_ENABLE(REGADRS, CTRLWORD) writel(((uint32_t)(CTRLWORD) << 16) | (uint32_t)(CTRLWORD), devpriv->base_addr+(REGADRS)) +/* + * Enable/disable a function or test status bit(s) that are accessed + * through Main Control Registers 1 or 2. + */ +static void s626_mc_enable(struct comedi_device *dev, + unsigned int cmd, unsigned int reg) +{ + struct s626_private *devpriv = dev->private; + unsigned int val = (cmd << 16) | cmd; -#define MC_DISABLE(REGADRS, CTRLWORD) writel((uint32_t)(CTRLWORD) << 16 , devpriv->base_addr+(REGADRS)) + writel(val, devpriv->mmio + reg); +} -#define MC_TEST(REGADRS, CTRLWORD) ((readl(devpriv->base_addr+(REGADRS)) & CTRLWORD) != 0) +static void s626_mc_disable(struct comedi_device *dev, + unsigned int cmd, unsigned int reg) +{ + struct s626_private *devpriv = dev->private; -/* #define WR7146(REGARDS,CTRLWORD) - writel(CTRLWORD,(uint32_t)(devpriv->base_addr+(REGARDS))) */ -#define WR7146(REGARDS, CTRLWORD) writel(CTRLWORD, devpriv->base_addr+(REGARDS)) + writel(cmd << 16 , devpriv->mmio + reg); +} -/* #define RR7146(REGARDS) - readl((uint32_t)(devpriv->base_addr+(REGARDS))) */ -#define RR7146(REGARDS) readl(devpriv->base_addr+(REGARDS)) +static bool s626_mc_test(struct comedi_device *dev, + unsigned int cmd, unsigned int reg) +{ + struct s626_private *devpriv = dev->private; + unsigned int val; + + val = readl(devpriv->mmio + reg); + + return (val & cmd) ? true : false; +} #define BUGFIX_STREG(REGADRS) (REGADRS - 4) /* Write a time slot control record to TSL2. */ #define VECTPORT(VECTNUM) (P_TSL2 + ((VECTNUM) << 2)) -#define SETVECT(VECTNUM, VECTVAL) WR7146(VECTPORT(VECTNUM), (VECTVAL)) /* Code macros used for constructing I2C command bytes. */ #define I2C_B2(ATTR, VAL) (((ATTR) << 6) | ((VAL) << 24)) #define I2C_B1(ATTR, VAL) (((ATTR) << 4) | ((VAL) << 16)) #define I2C_B0(ATTR, VAL) (((ATTR) << 2) | ((VAL) << 8)) -static const struct comedi_lrange s626_range_table = { 2, { - RANGE(-5, 5), - RANGE(-10, 10), - } +static const struct comedi_lrange s626_range_table = { + 2, { + BIP_RANGE(5), + BIP_RANGE(10), + } }; /* Execute a DEBI transfer. This must be called from within a */ @@ -234,16 +192,18 @@ static void DEBItransfer(struct comedi_device *dev) { struct s626_private *devpriv = dev->private; - /* Initiate upload of shadow RAM to DEBI control register. */ - MC_ENABLE(P_MC2, MC2_UPLD_DEBI); + /* Initiate upload of shadow RAM to DEBI control register */ + s626_mc_enable(dev, MC2_UPLD_DEBI, P_MC2); - /* Wait for completion of upload from shadow RAM to DEBI control */ - /* register. */ - while (!MC_TEST(P_MC2, MC2_UPLD_DEBI)) + /* + * Wait for completion of upload from shadow RAM to + * DEBI control register. + */ + while (!s626_mc_test(dev, MC2_UPLD_DEBI, P_MC2)) ; - /* Wait until DEBI transfer is done. */ - while (RR7146(P_PSR) & PSR_DEBI_S) + /* Wait until DEBI transfer is done */ + while (readl(devpriv->mmio + P_PSR) & PSR_DEBI_S) ; } @@ -252,19 +212,14 @@ static void DEBItransfer(struct comedi_device *dev) static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr) { struct s626_private *devpriv = dev->private; - uint16_t retval; - /* Set up DEBI control register value in shadow RAM. */ - WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); + /* Set up DEBI control register value in shadow RAM */ + writel(DEBI_CMD_RDWORD | addr, devpriv->mmio + P_DEBICMD); /* Execute the DEBI transfer. */ DEBItransfer(dev); - /* Fetch target register value. */ - retval = (uint16_t) RR7146(P_DEBIAD); - - /* Return register value. */ - return retval; + return readl(devpriv->mmio + P_DEBIAD); } /* Write a value to a gate array register. */ @@ -272,9 +227,9 @@ static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata) { struct s626_private *devpriv = dev->private; - /* Set up DEBI control register value in shadow RAM. */ - WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); - WR7146(P_DEBIAD, wdata); + /* Set up DEBI control register value in shadow RAM */ + writel(DEBI_CMD_WRWORD | addr, devpriv->mmio + P_DEBICMD); + writel(wdata, devpriv->mmio + P_DEBIAD); /* Execute the DEBI transfer. */ DEBItransfer(dev); @@ -284,23 +239,22 @@ static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata) * specifies bits that are to be preserved, wdata is new value to be * or'd with the masked original. */ -static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask, - uint16_t wdata) +static void DEBIreplace(struct comedi_device *dev, unsigned int addr, + unsigned int mask, unsigned int wdata) { struct s626_private *devpriv = dev->private; + unsigned int val; - /* Copy target gate array register into P_DEBIAD register. */ - WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); - /* Set up DEBI control reg value in shadow RAM. */ - DEBItransfer(dev); /* Execute the DEBI Read transfer. */ - - /* Write back the modified image. */ - WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); - /* Set up DEBI control reg value in shadow RAM. */ + addr &= 0xffff; + writel(DEBI_CMD_RDWORD | addr, devpriv->mmio + P_DEBICMD); + DEBItransfer(dev); - WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask)); - /* Modify the register image. */ - DEBItransfer(dev); /* Execute the DEBI Write transfer. */ + writel(DEBI_CMD_WRWORD | addr, devpriv->mmio + P_DEBICMD); + val = readl(devpriv->mmio + P_DEBIAD); + val &= mask; + val |= wdata; + writel(val & 0xffff, devpriv->mmio + P_DEBIAD); + DEBItransfer(dev); } /* ************** EEPROM ACCESS FUNCTIONS ************** */ @@ -308,31 +262,32 @@ static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask, static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val) { struct s626_private *devpriv = dev->private; + unsigned int ctrl; - /* Write I2C command to I2C Transfer Control shadow register. */ - WR7146(P_I2CCTRL, val); - - /* Upload I2C shadow registers into working registers and wait for */ - /* upload confirmation. */ - - MC_ENABLE(P_MC2, MC2_UPLD_IIC); - while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) - ; + /* Write I2C command to I2C Transfer Control shadow register */ + writel(val, devpriv->mmio + P_I2CCTRL); - /* Wait until I2C bus transfer is finished or an error occurs. */ - while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY) + /* + * Upload I2C shadow registers into working registers and + * wait for upload confirmation. + */ + s626_mc_enable(dev, MC2_UPLD_IIC, P_MC2); + while (!s626_mc_test(dev, MC2_UPLD_IIC, P_MC2)) ; - /* Return non-zero if I2C error occurred. */ - return RR7146(P_I2CCTRL) & I2C_ERR; + /* Wait until I2C bus transfer is finished or an error occurs */ + do { + ctrl = readl(devpriv->mmio + P_I2CCTRL); + } while ((ctrl & (I2C_BUSY | I2C_ERR)) == I2C_BUSY); + /* Return non-zero if I2C error occurred */ + return ctrl & I2C_ERR; } /* Read uint8_t from EEPROM. */ static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr) { struct s626_private *devpriv = dev->private; - uint8_t rtnval; /* Send EEPROM target address. */ if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW) @@ -360,9 +315,8 @@ static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr) /* Abort function and declare error if handshake failed. */ return 0; } - /* Return copy of EEPROM value. */ - rtnval = (uint8_t) (RR7146(P_I2CCTRL) >> 16); - return rtnval; + + return (readl(devpriv->mmio + P_I2CCTRL) >> 16) & 0xff; } /* *********** DAC FUNCTIONS *********** */ @@ -402,23 +356,25 @@ static void SendDAC(struct comedi_device *dev, uint32_t val) /* Copy DAC setpoint value to DAC's output DMA buffer. */ - /* WR7146( (uint32_t)devpriv->pDacWBuf, val ); */ + /* writel(val, devpriv->mmio + (uint32_t)devpriv->pDacWBuf); */ *devpriv->pDacWBuf = val; - /* enab the output DMA transfer. This will cause the DMAC to copy - * the DAC's data value to A2's output FIFO. The DMA transfer will + /* + * Enable the output DMA transfer. This will cause the DMAC to copy + * the DAC's data value to A2's output FIFO. The DMA transfer will * then immediately terminate because the protection address is * reached upon transfer of the first DWORD value. */ - MC_ENABLE(P_MC1, MC1_A2OUT); + s626_mc_enable(dev, MC1_A2OUT, P_MC1); /* While the DMA transfer is executing ... */ - /* Reset Audio2 output FIFO's underflow flag (along with any other - * FIFO underflow/overflow flags). When set, this flag will - * indicate that we have emerged from slot 0. + /* + * Reset Audio2 output FIFO's underflow flag (along with any + * other FIFO underflow/overflow flags). When set, this flag + * will indicate that we have emerged from slot 0. */ - WR7146(P_ISR, ISR_AFOU); + writel(ISR_AFOU, devpriv->mmio + P_ISR); /* Wait for the DMA transfer to finish so that there will be data * available in the FIFO when time slot 1 tries to transfer a DWORD @@ -426,7 +382,7 @@ static void SendDAC(struct comedi_device *dev, uint32_t val) * Done by polling the DMAC enable flag; this flag is automatically * cleared when the transfer has finished. */ - while ((RR7146(P_MC1) & MC1_A2OUT) != 0) + while (readl(devpriv->mmio + P_MC1) & MC1_A2OUT) ; /* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */ @@ -436,7 +392,7 @@ static void SendDAC(struct comedi_device *dev, uint32_t val) * will be shifted in and stored in FB_BUFFER2 for end-of-slot-list * detection. */ - SETVECT(0, XSD2 | RSD3 | SIB_A2); + writel(XSD2 | RSD3 | SIB_A2, devpriv->mmio + VECTPORT(0)); /* Wait for slot 1 to execute to ensure that the Packet will be * transmitted. This is detected by polling the Audio2 output FIFO @@ -444,7 +400,7 @@ static void SendDAC(struct comedi_device *dev, uint32_t val) * finished transferring the DAC's data DWORD from the output FIFO * to the output buffer register. */ - while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0) + while (!(readl(devpriv->mmio + P_SSR) & SSR_AF2_OUT)) ; /* Set up to trap execution at slot 0 when the TSL sequencer cycles @@ -453,7 +409,8 @@ static void SendDAC(struct comedi_device *dev, uint32_t val) * stored in the last byte to be shifted out of the FIFO's DWORD * buffer register. */ - SETVECT(0, XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS); + writel(XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS, + devpriv->mmio + VECTPORT(0)); /* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */ @@ -474,14 +431,14 @@ static void SendDAC(struct comedi_device *dev, uint32_t val) * we test for the FB_BUFFER2 MSB contents to be equal to 0xFF. If * the TSL has not yet finished executing slot 5 ... */ - if ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) { + if (readl(devpriv->mmio + P_FB_BUFFER2) & 0xff000000) { /* The trap was set on time and we are still executing somewhere * in slots 2-5, so we now wait for slot 0 to execute and trap * TSL execution. This is detected when FB_BUFFER2 MSB changes * from 0xFF to 0x00, which slot 0 causes to happen by shifting * out/in on SD2 the 0x00 that is always referenced by slot 5. */ - while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) + while (readl(devpriv->mmio + P_FB_BUFFER2) & 0xff000000) ; } /* Either (1) we were too late setting the slot 0 trap; the TSL @@ -492,13 +449,13 @@ static void SendDAC(struct comedi_device *dev, uint32_t val) * In order to do this, we reprogram slot 0 so that it will shift in * SD3, which is driven only by a pull-up resistor. */ - SETVECT(0, RSD3 | SIB_A2 | EOS); + writel(RSD3 | SIB_A2 | EOS, devpriv->mmio + VECTPORT(0)); /* Wait for slot 0 to execute, at which time the TSL is setup for * the next DAC write. This is detected when FB_BUFFER2 MSB changes * from 0x00 to 0xFF. */ - while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0) + while (!(readl(devpriv->mmio + P_FB_BUFFER2) & 0xff000000)) ; } @@ -532,16 +489,16 @@ static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata) * disables gating for the DAC clock and all DAC chip selects. */ + /* Choose DAC chip select to be asserted */ WSImage = (chan & 2) ? WS1 : WS2; - /* Choose DAC chip select to be asserted. */ - SETVECT(2, XSD2 | XFIFO_1 | WSImage); - /* Slot 2: Transmit high data byte to target DAC. */ - SETVECT(3, XSD2 | XFIFO_0 | WSImage); - /* Slot 3: Transmit low data byte to target DAC. */ - SETVECT(4, XSD2 | XFIFO_3 | WS3); + /* Slot 2: Transmit high data byte to target DAC */ + writel(XSD2 | XFIFO_1 | WSImage, devpriv->mmio + VECTPORT(2)); + /* Slot 3: Transmit low data byte to target DAC */ + writel(XSD2 | XFIFO_0 | WSImage, devpriv->mmio + VECTPORT(3)); /* Slot 4: Transmit to non-existent TrimDac channel to keep clock */ - SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS); - /* Slot 5: running after writing target DAC's low data byte. */ + writel(XSD2 | XFIFO_3 | WS3, devpriv->mmio + VECTPORT(4)); + /* Slot 5: running after writing target DAC's low data byte */ + writel(XSD2 | XFIFO_2 | WS3 | EOS, devpriv->mmio + VECTPORT(5)); /* Construct and transmit target DAC's serial packet: * ( A10D DDDD ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>, @@ -577,14 +534,14 @@ static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan, * can be detected. */ - SETVECT(2, XSD2 | XFIFO_1 | WS3); - /* Slot 2: Send high uint8_t to target TrimDac. */ - SETVECT(3, XSD2 | XFIFO_0 | WS3); - /* Slot 3: Send low uint8_t to target TrimDac. */ - SETVECT(4, XSD2 | XFIFO_3 | WS1); - /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running. */ - SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS); - /* Slot 5: Send NOP low uint8_t to DAC0. */ + /* Slot 2: Send high uint8_t to target TrimDac */ + writel(XSD2 | XFIFO_1 | WS3, devpriv->mmio + VECTPORT(2)); + /* Slot 3: Send low uint8_t to target TrimDac */ + writel(XSD2 | XFIFO_0 | WS3, devpriv->mmio + VECTPORT(3)); + /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running */ + writel(XSD2 | XFIFO_3 | WS1, devpriv->mmio + VECTPORT(4)); + /* Slot 5: Send NOP low uint8_t to DAC0 */ + writel(XSD2 | XFIFO_2 | WS1 | EOS, devpriv->mmio + VECTPORT(5)); /* Construct and transmit target DAC's serial packet: * ( 0000 AAAA ), ( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the @@ -638,8 +595,8 @@ static void SetLatchSource(struct comedi_device *dev, struct enc_private *k, uint16_t value) { DEBIreplace(dev, k->MyCRB, - (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC)), - (uint16_t) (value << CRBBIT_LATCHSRC)); + ~(CRBMSK_INTCTRL | CRBMSK_LATCHSRC), + value << CRBBIT_LATCHSRC); } /* Write value into counter preload register. */ @@ -670,43 +627,24 @@ static unsigned int s626_ai_reg_to_uint(int data) static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan) { - unsigned int group; - unsigned int bitmask; + unsigned int group = chan / 16; + unsigned int mask = 1 << (chan - (16 * group)); unsigned int status; - /* select dio bank */ - group = chan / 16; - bitmask = 1 << (chan - (16 * group)); - /* set channel to capture positive edge */ - status = DEBIread(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->RDEdgSel); - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WREdgSel, - bitmask | status); + status = DEBIread(dev, LP_RDEDGSEL(group)); + DEBIwrite(dev, LP_WREDGSEL(group), mask | status); /* enable interrupt on selected channel */ - status = DEBIread(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->RDIntSel); - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRIntSel, - bitmask | status); + status = DEBIread(dev, LP_RDINTSEL(group)); + DEBIwrite(dev, LP_WRINTSEL(group), mask | status); /* enable edge capture write command */ DEBIwrite(dev, LP_MISC1, MISC1_EDCAP); /* enable edge capture on selected channel */ - status = DEBIread(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->RDCapSel); - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRCapSel, - bitmask | status); + status = DEBIread(dev, LP_RDCAPSEL(group)); + DEBIwrite(dev, LP_WRCAPSEL(group), mask | status); return 0; } @@ -718,9 +656,7 @@ static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group, DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); /* enable edge capture on selected channel */ - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRCapSel, mask); + DEBIwrite(dev, LP_WRCAPSEL(group), mask); return 0; } @@ -732,244 +668,249 @@ static int s626_dio_clear_irq(struct comedi_device *dev) /* disable edge capture write command */ DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); - for (group = 0; group < S626_DIO_BANKS; group++) { - /* clear pending events and interrupt */ - DEBIwrite(dev, - ((struct dio_private *)(dev->subdevices + 2 + - group)->private)->WRCapSel, - 0xffff); - } + /* clear all dio pending events and interrupt */ + for (group = 0; group < S626_DIO_BANKS; group++) + DEBIwrite(dev, LP_WRCAPSEL(group), 0xffff); return 0; } -static irqreturn_t s626_irq_handler(int irq, void *d) +static void handle_dio_interrupt(struct comedi_device *dev, + uint16_t irqbit, uint8_t group) { - struct comedi_device *dev = d; struct s626_private *devpriv = dev->private; - struct comedi_subdevice *s; - struct comedi_cmd *cmd; - struct enc_private *k; - unsigned long flags; - int32_t *readaddr; - uint32_t irqtype, irqstatus; - int i = 0; - short tempdata; - uint8_t group; - uint16_t irqbit; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_cmd *cmd = &s->async->cmd; - if (dev->attached == 0) - return IRQ_NONE; - /* lock to avoid race with comedi_poll */ - spin_lock_irqsave(&dev->spinlock, flags); + s626_dio_reset_irq(dev, group, irqbit); - /* save interrupt enable register state */ - irqstatus = readl(devpriv->base_addr + P_IER); + if (devpriv->ai_cmd_running) { + /* check if interrupt is an ai acquisition start trigger */ + if ((irqbit >> (cmd->start_arg - (16 * group))) == 1 && + cmd->start_src == TRIG_EXT) { + /* Start executing the RPS program */ + s626_mc_enable(dev, MC1_ERPS1, P_MC1); + + if (cmd->scan_begin_src == TRIG_EXT) + s626_dio_set_irq(dev, cmd->scan_begin_arg); + } + if ((irqbit >> (cmd->scan_begin_arg - (16 * group))) == 1 && + cmd->scan_begin_src == TRIG_EXT) { + /* Trigger ADC scan loop start */ + s626_mc_enable(dev, MC2_ADC_RPS, P_MC2); - /* read interrupt type */ - irqtype = readl(devpriv->base_addr + P_ISR); + if (cmd->convert_src == TRIG_EXT) { + devpriv->ai_convert_count = cmd->chanlist_len; - /* disable master interrupt */ - writel(0, devpriv->base_addr + P_IER); + s626_dio_set_irq(dev, cmd->convert_arg); + } - /* clear interrupt */ - writel(irqtype, devpriv->base_addr + P_ISR); + if (cmd->convert_src == TRIG_TIMER) { + struct enc_private *k = &encpriv[5]; - switch (irqtype) { - case IRQ_RPS1: /* end_of_scan occurs */ - /* manage ai subdevice */ - s = dev->subdevices; - cmd = &(s->async->cmd); + devpriv->ai_convert_count = cmd->chanlist_len; + k->SetEnable(dev, k, CLKENAB_ALWAYS); + } + } + if ((irqbit >> (cmd->convert_arg - (16 * group))) == 1 && + cmd->convert_src == TRIG_EXT) { + /* Trigger ADC scan loop start */ + s626_mc_enable(dev, MC2_ADC_RPS, P_MC2); + + devpriv->ai_convert_count--; + if (devpriv->ai_convert_count > 0) + s626_dio_set_irq(dev, cmd->convert_arg); + } + } +} - /* Init ptr to DMA buffer that holds new ADC data. We skip the - * first uint16_t in the buffer because it contains junk data from - * the final ADC of the previous poll list scan. - */ - readaddr = (int32_t *) devpriv->ANABuf.LogicalBase + 1; - - /* get the data and hand it over to comedi */ - for (i = 0; i < (s->async->cmd.chanlist_len); i++) { - /* Convert ADC data to 16-bit integer values and copy to application */ - /* buffer. */ - tempdata = s626_ai_reg_to_uint((int)*readaddr); - readaddr++; - - /* put data into read buffer */ - /* comedi_buf_put(s->async, tempdata); */ - if (cfc_write_to_buffer(s, tempdata) == 0) - printk - ("s626_irq_handler: cfc_write_to_buffer error!\n"); +static void check_dio_interrupts(struct comedi_device *dev) +{ + uint16_t irqbit; + uint8_t group; + + for (group = 0; group < S626_DIO_BANKS; group++) { + irqbit = 0; + /* read interrupt type */ + irqbit = DEBIread(dev, LP_RDCAPFLG(group)); + + /* check if interrupt is generated from dio channels */ + if (irqbit) { + handle_dio_interrupt(dev, irqbit, group); + return; } + } +} - /* end of scan occurs */ - s->async->events |= COMEDI_CB_EOS; +static void check_counter_interrupts(struct comedi_device *dev) +{ + struct s626_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + struct enc_private *k; + uint16_t irqbit; - if (!(devpriv->ai_continous)) - devpriv->ai_sample_count--; - if (devpriv->ai_sample_count <= 0) { - devpriv->ai_cmd_running = 0; + /* read interrupt type */ + irqbit = DEBIread(dev, LP_RDMISC2); - /* Stop RPS program. */ - MC_DISABLE(P_MC1, MC1_ERPS1); + /* check interrupt on counters */ + if (irqbit & IRQ_COINT1A) { + k = &encpriv[0]; - /* send end of acquisition */ - s->async->events |= COMEDI_CB_EOA; + /* clear interrupt capture flag */ + k->ResetCapFlags(dev, k); + } + if (irqbit & IRQ_COINT2A) { + k = &encpriv[1]; - /* disable master interrupt */ - irqstatus = 0; - } + /* clear interrupt capture flag */ + k->ResetCapFlags(dev, k); + } + if (irqbit & IRQ_COINT3A) { + k = &encpriv[2]; - if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT) - s626_dio_set_irq(dev, cmd->scan_begin_arg); - /* tell comedi that data is there */ - comedi_event(dev, s); - break; - case IRQ_GPIO3: /* check dio and conter interrupt */ - /* manage ai subdevice */ - s = dev->subdevices; - cmd = &(s->async->cmd); + /* clear interrupt capture flag */ + k->ResetCapFlags(dev, k); + } + if (irqbit & IRQ_COINT1B) { + k = &encpriv[3]; - /* s626_dio_clear_irq(dev); */ + /* clear interrupt capture flag */ + k->ResetCapFlags(dev, k); + } + if (irqbit & IRQ_COINT2B) { + k = &encpriv[4]; + + /* clear interrupt capture flag */ + k->ResetCapFlags(dev, k); + + if (devpriv->ai_convert_count > 0) { + devpriv->ai_convert_count--; + if (devpriv->ai_convert_count == 0) + k->SetEnable(dev, k, CLKENAB_INDEX); - for (group = 0; group < S626_DIO_BANKS; group++) { - irqbit = 0; - /* read interrupt type */ - irqbit = DEBIread(dev, - ((struct dio_private *)(dev-> - subdevices + - 2 + - group)-> - private)->RDCapFlg); - - /* check if interrupt is generated from dio channels */ - if (irqbit) { - s626_dio_reset_irq(dev, group, irqbit); - if (devpriv->ai_cmd_running) { - /* check if interrupt is an ai acquisition start trigger */ - if ((irqbit >> (cmd->start_arg - - (16 * group))) - == 1 && cmd->start_src == TRIG_EXT) { - /* Start executing the RPS program. */ - MC_ENABLE(P_MC1, MC1_ERPS1); - - if (cmd->scan_begin_src == - TRIG_EXT) { - s626_dio_set_irq(dev, - cmd->scan_begin_arg); - } - } - if ((irqbit >> (cmd->scan_begin_arg - - (16 * group))) - == 1 - && cmd->scan_begin_src == - TRIG_EXT) { - /* Trigger ADC scan loop start by setting RPS Signal 0. */ - MC_ENABLE(P_MC2, MC2_ADC_RPS); - - if (cmd->convert_src == - TRIG_EXT) { - devpriv->ai_convert_count - = cmd->chanlist_len; - - s626_dio_set_irq(dev, - cmd->convert_arg); - } - - if (cmd->convert_src == - TRIG_TIMER) { - k = &encpriv[5]; - devpriv->ai_convert_count - = cmd->chanlist_len; - k->SetEnable(dev, k, - CLKENAB_ALWAYS); - } - } - if ((irqbit >> (cmd->convert_arg - - (16 * group))) - == 1 - && cmd->convert_src == TRIG_EXT) { - /* Trigger ADC scan loop start by setting RPS Signal 0. */ - MC_ENABLE(P_MC2, MC2_ADC_RPS); - - devpriv->ai_convert_count--; - - if (devpriv->ai_convert_count > - 0) { - s626_dio_set_irq(dev, - cmd->convert_arg); - } - } - } - break; + if (cmd->convert_src == TRIG_TIMER) { + /* Trigger ADC scan loop start */ + s626_mc_enable(dev, MC2_ADC_RPS, P_MC2); } } + } + if (irqbit & IRQ_COINT3B) { + k = &encpriv[5]; - /* read interrupt type */ - irqbit = DEBIread(dev, LP_RDMISC2); - - /* check interrupt on counters */ - if (irqbit & IRQ_COINT1A) { - k = &encpriv[0]; + /* clear interrupt capture flag */ + k->ResetCapFlags(dev, k); - /* clear interrupt capture flag */ - k->ResetCapFlags(dev, k); + if (cmd->scan_begin_src == TRIG_TIMER) { + /* Trigger ADC scan loop start */ + s626_mc_enable(dev, MC2_ADC_RPS, P_MC2); } - if (irqbit & IRQ_COINT2A) { - k = &encpriv[1]; - /* clear interrupt capture flag */ - k->ResetCapFlags(dev, k); + if (cmd->convert_src == TRIG_TIMER) { + k = &encpriv[4]; + devpriv->ai_convert_count = cmd->chanlist_len; + k->SetEnable(dev, k, CLKENAB_ALWAYS); } - if (irqbit & IRQ_COINT3A) { - k = &encpriv[2]; + } +} - /* clear interrupt capture flag */ - k->ResetCapFlags(dev, k); - } - if (irqbit & IRQ_COINT1B) { - k = &encpriv[3]; +static bool handle_eos_interrupt(struct comedi_device *dev) +{ + struct s626_private *devpriv = dev->private; + struct comedi_subdevice *s = dev->read_subdev; + struct comedi_async *async = s->async; + struct comedi_cmd *cmd = &async->cmd; + /* + * Init ptr to DMA buffer that holds new ADC data. We skip the + * first uint16_t in the buffer because it contains junk data + * from the final ADC of the previous poll list scan. + */ + int32_t *readaddr = (int32_t *)devpriv->ANABuf.LogicalBase + 1; + bool finished = false; + int i; - /* clear interrupt capture flag */ - k->ResetCapFlags(dev, k); - } - if (irqbit & IRQ_COINT2B) { - k = &encpriv[4]; + /* get the data and hand it over to comedi */ + for (i = 0; i < cmd->chanlist_len; i++) { + short tempdata; - /* clear interrupt capture flag */ - k->ResetCapFlags(dev, k); + /* + * Convert ADC data to 16-bit integer values and copy + * to application buffer. + */ + tempdata = s626_ai_reg_to_uint((int)*readaddr); + readaddr++; - if (devpriv->ai_convert_count > 0) { - devpriv->ai_convert_count--; - if (devpriv->ai_convert_count == 0) - k->SetEnable(dev, k, CLKENAB_INDEX); + /* put data into read buffer */ + /* comedi_buf_put(async, tempdata); */ + cfc_write_to_buffer(s, tempdata); + } - if (cmd->convert_src == TRIG_TIMER) { - /* Trigger ADC scan loop start by setting RPS Signal 0. */ - MC_ENABLE(P_MC2, MC2_ADC_RPS); - } - } - } - if (irqbit & IRQ_COINT3B) { - k = &encpriv[5]; + /* end of scan occurs */ + async->events |= COMEDI_CB_EOS; - /* clear interrupt capture flag */ - k->ResetCapFlags(dev, k); + if (!devpriv->ai_continous) + devpriv->ai_sample_count--; + if (devpriv->ai_sample_count <= 0) { + devpriv->ai_cmd_running = 0; - if (cmd->scan_begin_src == TRIG_TIMER) { - /* Trigger ADC scan loop start by setting RPS Signal 0. */ - MC_ENABLE(P_MC2, MC2_ADC_RPS); - } + /* Stop RPS program */ + s626_mc_disable(dev, MC1_ERPS1, P_MC1); - if (cmd->convert_src == TRIG_TIMER) { - k = &encpriv[4]; - devpriv->ai_convert_count = cmd->chanlist_len; - k->SetEnable(dev, k, CLKENAB_ALWAYS); - } - } + /* send end of acquisition */ + async->events |= COMEDI_CB_EOA; + + /* disable master interrupt */ + finished = true; + } + + if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT) + s626_dio_set_irq(dev, cmd->scan_begin_arg); + + /* tell comedi that data is there */ + comedi_event(dev, s); + + return finished; +} + +static irqreturn_t s626_irq_handler(int irq, void *d) +{ + struct comedi_device *dev = d; + struct s626_private *devpriv = dev->private; + unsigned long flags; + uint32_t irqtype, irqstatus; + + if (!dev->attached) + return IRQ_NONE; + /* lock to avoid race with comedi_poll */ + spin_lock_irqsave(&dev->spinlock, flags); + + /* save interrupt enable register state */ + irqstatus = readl(devpriv->mmio + P_IER); + + /* read interrupt type */ + irqtype = readl(devpriv->mmio + P_ISR); + + /* disable master interrupt */ + writel(0, devpriv->mmio + P_IER); + + /* clear interrupt */ + writel(irqtype, devpriv->mmio + P_ISR); + + switch (irqtype) { + case IRQ_RPS1: /* end_of_scan occurs */ + if (handle_eos_interrupt(dev)) + irqstatus = 0; + break; + case IRQ_GPIO3: /* check dio and conter interrupt */ + /* s626_dio_clear_irq(dev); */ + check_dio_interrupts(dev); + check_counter_interrupts(dev); + break; } /* enable interrupt */ - writel(irqstatus, devpriv->base_addr + P_IER); + writel(irqstatus, devpriv->mmio + P_IER); spin_unlock_irqrestore(&dev->spinlock, flags); return IRQ_HANDLED; @@ -988,14 +929,15 @@ static void ResetADC(struct comedi_device *dev, uint8_t *ppl) uint32_t LocalPPL; struct comedi_cmd *cmd = &(dev->subdevices->async->cmd); - /* Stop RPS program in case it is currently running. */ - MC_DISABLE(P_MC1, MC1_ERPS1); + /* Stop RPS program in case it is currently running */ + s626_mc_disable(dev, MC1_ERPS1, P_MC1); /* Set starting logical address to write RPS commands. */ pRPS = (uint32_t *) devpriv->RPSBuf.LogicalBase; - /* Initialize RPS instruction pointer. */ - WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase); + /* Initialize RPS instruction pointer */ + writel((uint32_t)devpriv->RPSBuf.PhysicalBase, + devpriv->mmio + P_RPSADDR1); /* Construct RPS program in RPSBuf DMA buffer */ @@ -1165,41 +1107,42 @@ static void ResetADC(struct comedi_device *dev, uint8_t *ppl) /* End of RPS program build */ } -/* TO COMPLETE, IF NECESSARY */ -static int s626_ai_insn_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +#ifdef unused_code +static int s626_ai_rinsn(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { + struct s626_private *devpriv = dev->private; + register uint8_t i; + register int32_t *readaddr; - return -EINVAL; -} - -/* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) */ -/* { */ -/* struct s626_private *devpriv = dev->private; */ -/* register uint8_t i; */ -/* register int32_t *readaddr; */ - -/* Trigger ADC scan loop start by setting RPS Signal 0. */ -/* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */ + /* Trigger ADC scan loop start */ + s626_mc_enable(dev, MC2_ADC_RPS, P_MC2); -/* Wait until ADC scan loop is finished (RPS Signal 0 reset). */ -/* while ( MC_TEST( P_MC2, MC2_ADC_RPS ) ); */ + /* Wait until ADC scan loop is finished (RPS Signal 0 reset) */ + while (s626_mc_test(dev, MC2_ADC_RPS, P_MC2)) + ; -/* Init ptr to DMA buffer that holds new ADC data. We skip the - * first uint16_t in the buffer because it contains junk data from - * the final ADC of the previous poll list scan. - */ -/* readaddr = (uint32_t *)devpriv->ANABuf.LogicalBase + 1; */ + /* + * Init ptr to DMA buffer that holds new ADC data. We skip the + * first uint16_t in the buffer because it contains junk data from + * the final ADC of the previous poll list scan. + */ + readaddr = (uint32_t *)devpriv->ANABuf.LogicalBase + 1; -/* Convert ADC data to 16-bit integer values and copy to application buffer. */ -/* for ( i = 0; i < devpriv->AdcItems; i++ ) { */ -/* *data = s626_ai_reg_to_uint( *readaddr++ ); */ -/* data++; */ -/* } */ + /* + * Convert ADC data to 16-bit integer values and + * copy to application buffer. + */ + for (i = 0; i < devpriv->AdcItems; i++) { + *data = s626_ai_reg_to_uint(*readaddr++); + data++; + } -/* return i; */ -/* } */ + return i; +} +#endif static int s626_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s, @@ -1210,14 +1153,9 @@ static int s626_ai_insn_read(struct comedi_device *dev, uint16_t range = CR_RANGE(insn->chanspec); uint16_t AdcSpec = 0; uint32_t GpioImage; + int tmp; int n; - /* interrupt call test */ -/* writel(IRQ_GPIO3,devpriv->base_addr+P_PSR); */ - /* Writing a logical 1 into any of the RPS_PSR bits causes the - * corresponding interrupt to be generated if enabled - */ - /* Convert application's ADC specification into form * appropriate for register programming. */ @@ -1237,27 +1175,29 @@ static int s626_ai_insn_read(struct comedi_device *dev, /* Delay 10 microseconds for analog input settling. */ udelay(10); - /* Start ADC by pulsing GPIO1 low. */ - GpioImage = RR7146(P_GPIO); - /* Assert ADC Start command */ - WR7146(P_GPIO, GpioImage & ~GPIO1_HI); - /* and stretch it out. */ - WR7146(P_GPIO, GpioImage & ~GPIO1_HI); - WR7146(P_GPIO, GpioImage & ~GPIO1_HI); - /* Negate ADC Start command. */ - WR7146(P_GPIO, GpioImage | GPIO1_HI); + /* Start ADC by pulsing GPIO1 low */ + GpioImage = readl(devpriv->mmio + P_GPIO); + /* Assert ADC Start command */ + writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO); + /* and stretch it out */ + writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO); + writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO); + /* Negate ADC Start command */ + writel(GpioImage | GPIO1_HI, devpriv->mmio + P_GPIO); /* Wait for ADC to complete (GPIO2 is asserted high when */ /* ADC not busy) and for data from previous conversion to */ /* shift into FB BUFFER 1 register. */ - /* Wait for ADC done. */ - while (!(RR7146(P_PSR) & PSR_GPIO2)) + /* Wait for ADC done */ + while (!(readl(devpriv->mmio + P_PSR) & PSR_GPIO2)) ; - /* Fetch ADC data. */ - if (n != 0) - data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1)); + /* Fetch ADC data */ + if (n != 0) { + tmp = readl(devpriv->mmio + P_FB_BUFFER1); + data[n - 1] = s626_ai_reg_to_uint(tmp); + } /* Allow the ADC to stabilize for 4 microseconds before * starting the next (final) conversion. This delay is @@ -1272,27 +1212,28 @@ static int s626_ai_insn_read(struct comedi_device *dev, /* Start a dummy conversion to cause the data from the * previous conversion to be shifted in. */ - GpioImage = RR7146(P_GPIO); - + GpioImage = readl(devpriv->mmio + P_GPIO); /* Assert ADC Start command */ - WR7146(P_GPIO, GpioImage & ~GPIO1_HI); - /* and stretch it out. */ - WR7146(P_GPIO, GpioImage & ~GPIO1_HI); - WR7146(P_GPIO, GpioImage & ~GPIO1_HI); - /* Negate ADC Start command. */ - WR7146(P_GPIO, GpioImage | GPIO1_HI); + writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO); + /* and stretch it out */ + writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO); + writel(GpioImage & ~GPIO1_HI, devpriv->mmio + P_GPIO); + /* Negate ADC Start command */ + writel(GpioImage | GPIO1_HI, devpriv->mmio + P_GPIO); /* Wait for the data to arrive in FB BUFFER 1 register. */ - /* Wait for ADC done. */ - while (!(RR7146(P_PSR) & PSR_GPIO2)) + /* Wait for ADC done */ + while (!(readl(devpriv->mmio + P_PSR) & PSR_GPIO2)) ; /* Fetch ADC data from audio interface's input shift register. */ - /* Fetch ADC data. */ - if (n != 0) - data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1)); + /* Fetch ADC data */ + if (n != 0) { + tmp = readl(devpriv->mmio + P_FB_BUFFER1); + data[n - 1] = s626_ai_reg_to_uint(tmp); + } return n; } @@ -1317,13 +1258,11 @@ static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd) static int s626_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int trignum) { - struct s626_private *devpriv = dev->private; - if (trignum != 0) return -EINVAL; - /* Start executing the RPS program. */ - MC_ENABLE(P_MC1, MC1_ERPS1); + /* Start executing the RPS program */ + s626_mc_enable(dev, MC1_ERPS1, P_MC1); s->async->inttrig = NULL; @@ -1407,10 +1346,10 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) return -EBUSY; } /* disable interrupt */ - writel(0, devpriv->base_addr + P_IER); + writel(0, devpriv->mmio + P_IER); /* clear interrupt request */ - writel(IRQ_RPS1 | IRQ_GPIO3, devpriv->base_addr + P_ISR); + writel(IRQ_RPS1 | IRQ_GPIO3, devpriv->mmio + P_ISR); /* clear any pending interrupt */ s626_dio_clear_irq(dev); @@ -1483,7 +1422,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) case TRIG_NONE: /* continous acquisition */ devpriv->ai_continous = 1; - devpriv->ai_sample_count = 0; + devpriv->ai_sample_count = 1; break; } @@ -1491,11 +1430,11 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) switch (cmd->start_src) { case TRIG_NOW: - /* Trigger ADC scan loop start by setting RPS Signal 0. */ - /* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */ + /* Trigger ADC scan loop start */ + /* s626_mc_enable(dev, MC2_ADC_RPS, P_MC2); */ - /* Start executing the RPS program. */ - MC_ENABLE(P_MC1, MC1_ERPS1); + /* Start executing the RPS program */ + s626_mc_enable(dev, MC1_ERPS1, P_MC1); s->async->inttrig = NULL; break; @@ -1511,7 +1450,7 @@ static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } /* enable interrupt */ - writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER); + writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->mmio + P_IER); return 0; } @@ -1628,11 +1567,11 @@ static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { struct s626_private *devpriv = dev->private; - /* Stop RPS program in case it is currently running. */ - MC_DISABLE(P_MC1, MC1_ERPS1); + /* Stop RPS program in case it is currently running */ + s626_mc_disable(dev, MC1_ERPS1, P_MC1); /* disable master interrupt */ - writel(0, devpriv->base_addr + P_IER); + writel(0, devpriv->mmio + P_IER); devpriv->ai_cmd_running = 0; @@ -1679,84 +1618,74 @@ static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, static void s626_dio_init(struct comedi_device *dev) { uint16_t group; - struct comedi_subdevice *s; /* Prepare to treat writes to WRCapSel as capture disables. */ DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP); /* For each group of sixteen channels ... */ for (group = 0; group < S626_DIO_BANKS; group++) { - s = dev->subdevices + 2 + group; - DEBIwrite(dev, diopriv->WRIntSel, 0); /* Disable all interrupts. */ - DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF); /* Disable all event */ - /* captures. */ - DEBIwrite(dev, diopriv->WREdgSel, 0); /* Init all DIOs to */ - /* default edge */ - /* polarity. */ - DEBIwrite(dev, diopriv->WRDOut, 0); /* Program all outputs */ - /* to inactive state. */ + /* Disable all interrupts */ + DEBIwrite(dev, LP_WRINTSEL(group), 0); + /* Disable all event captures */ + DEBIwrite(dev, LP_WRCAPSEL(group), 0xffff); + /* Init all DIOs to default edge polarity */ + DEBIwrite(dev, LP_WREDGSEL(group), 0); + /* Program all outputs to inactive state */ + DEBIwrite(dev, LP_WRDOUT(group), 0); } } -/* DIO devices are slightly special. Although it is possible to - * implement the insn_read/insn_write interface, it is much more - * useful to applications if you implement the insn_bits interface. - * This allows packed reading/writing of the DIO channels. The comedi - * core can convert between insn_bits and insn_read/write */ - static int s626_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { - /* - * The insn data consists of a mask in data[0] and the new data in - * data[1]. The mask defines which bits we are concerning about. - * The new data must be anded with the mask. Each channel - * corresponds to a bit. - */ - if (data[0]) { - /* Check if requested ports are configured for output */ - if ((s->io_bits & data[0]) != data[0]) - return -EIO; + unsigned long group = (unsigned long)s->private; + unsigned long mask = data[0]; + unsigned long bits = data[1]; - s->state &= ~data[0]; - s->state |= data[0] & data[1]; + if (mask) { + /* Check if requested channels are configured for output */ + if ((s->io_bits & mask) != mask) + return -EIO; - /* Write out the new digital output lines */ + s->state &= ~mask; + s->state |= (bits & mask); - DEBIwrite(dev, diopriv->WRDOut, s->state); + DEBIwrite(dev, LP_WRDOUT(group), s->state); } - data[1] = DEBIread(dev, diopriv->RDDIn); + data[1] = DEBIread(dev, LP_RDDIN(group)); return insn->n; } static int s626_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) + struct comedi_insn *insn, + unsigned int *data) { + unsigned long group = (unsigned long)s->private; + unsigned int chan = CR_CHAN(insn->chanspec); + unsigned int mask = 1 << chan; switch (data[0]) { case INSN_CONFIG_DIO_QUERY: - data[1] = - (s-> - io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT : - COMEDI_INPUT; + data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT; return insn->n; break; case COMEDI_INPUT: - s->io_bits &= ~(1 << CR_CHAN(insn->chanspec)); + s->io_bits &= ~mask; break; case COMEDI_OUTPUT: - s->io_bits |= 1 << CR_CHAN(insn->chanspec); + s->io_bits |= mask; break; default: return -EINVAL; break; } - DEBIwrite(dev, diopriv->WRDOut, s->io_bits); + DEBIwrite(dev, LP_WRDOUT(group), s->io_bits); - return 1; + return insn->n; } /* Now this function initializes the value of the counter (data[0]) @@ -1861,13 +1790,13 @@ static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k) { - DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL), + DEBIreplace(dev, k->MyCRB, ~CRBMSK_INTCTRL, CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A); } static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k) { - DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL), + DEBIreplace(dev, k->MyCRB, ~CRBMSK_INTCTRL, CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B); } @@ -2012,8 +1941,7 @@ static void SetMode_A(struct comedi_device *dev, struct enc_private *k, /* While retaining CounterB and LatchSrc configurations, program the */ /* new counter operating mode. */ DEBIreplace(dev, k->MyCRA, CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B, cra); - DEBIreplace(dev, k->MyCRB, - (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), crb); + DEBIreplace(dev, k->MyCRB, ~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A), crb); } static void SetMode_B(struct comedi_device *dev, struct enc_private *k, @@ -2074,8 +2002,7 @@ static void SetMode_B(struct comedi_device *dev, struct enc_private *k, /* While retaining CounterA and LatchSrc configurations, program the */ /* new counter operating mode. */ - DEBIreplace(dev, k->MyCRA, - (uint16_t) (~(CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B)), cra); + DEBIreplace(dev, k->MyCRA, ~(CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B), cra); DEBIreplace(dev, k->MyCRB, CRBMSK_CLKENAB_A | CRBMSK_LATCHSRC, crb); } @@ -2084,17 +2011,15 @@ static void SetMode_B(struct comedi_device *dev, struct enc_private *k, static void SetEnable_A(struct comedi_device *dev, struct enc_private *k, uint16_t enab) { - DEBIreplace(dev, k->MyCRB, - (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), - (uint16_t) (enab << CRBBIT_CLKENAB_A)); + DEBIreplace(dev, k->MyCRB, ~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A), + enab << CRBBIT_CLKENAB_A); } static void SetEnable_B(struct comedi_device *dev, struct enc_private *k, uint16_t enab) { - DEBIreplace(dev, k->MyCRB, - (uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B)), - (uint16_t) (enab << CRBBIT_CLKENAB_B)); + DEBIreplace(dev, k->MyCRB, ~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B), + enab << CRBBIT_CLKENAB_B); } static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k) @@ -2123,16 +2048,15 @@ static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k) static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k, uint16_t Trig) { - DEBIreplace(dev, k->MyCRA, (uint16_t) (~CRAMSK_LOADSRC_A), - (uint16_t) (Trig << CRABIT_LOADSRC_A)); + DEBIreplace(dev, k->MyCRA, ~CRAMSK_LOADSRC_A, + Trig << CRABIT_LOADSRC_A); } static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k, uint16_t Trig) { - DEBIreplace(dev, k->MyCRB, - (uint16_t) (~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL)), - (uint16_t) (Trig << CRBBIT_LOADSRC_B)); + DEBIreplace(dev, k->MyCRB, ~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL), + Trig << CRBBIT_LOADSRC_B); } static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k) @@ -2156,12 +2080,12 @@ static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k, struct s626_private *devpriv = dev->private; /* Reset any pending counter overflow or index captures. */ - DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL), + DEBIreplace(dev, k->MyCRB, ~CRBMSK_INTCTRL, CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A); /* Program counter interrupt source. */ DEBIreplace(dev, k->MyCRA, ~CRAMSK_INTSRC_A, - (uint16_t) (IntSource << CRABIT_INTSRC_A)); + IntSource << CRABIT_INTSRC_A); /* Update MISC2 interrupt enable mask. */ devpriv->CounterIntEnabs = @@ -2430,7 +2354,7 @@ static void s626_initialize(struct comedi_device *dev) int i; /* Enable DEBI and audio pins, enable I2C interface */ - MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C); + s626_mc_enable(dev, MC1_DEBI | MC1_AUDIO | MC1_I2C, P_MC1); /* * Configure DEBI operating mode @@ -2440,15 +2364,16 @@ static void s626_initialize(struct comedi_device *dev) * Set up byte lane steering * Intel-compatible local bus (DEBI never times out) */ - WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 | - (DEBI_TOUT << DEBI_CFG_TOUT_BIT) | - DEBI_SWAP | DEBI_CFG_INTEL); + writel(DEBI_CFG_SLAVE16 | + (DEBI_TOUT << DEBI_CFG_TOUT_BIT) | + DEBI_SWAP | DEBI_CFG_INTEL, + devpriv->mmio + P_DEBICFG); /* Disable MMU paging */ - WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE); + writel(DEBI_PAGE_DISABLE, devpriv->mmio + P_DEBIPAGE); /* Init GPIO so that ADC Start* is negated */ - WR7146(P_GPIO, GPIO_BASE | GPIO1_HI); + writel(GPIO_BASE | GPIO1_HI, devpriv->mmio + P_GPIO); /* I2C device address for onboard eeprom (revb) */ devpriv->I2CAdrs = 0xA0; @@ -2457,9 +2382,9 @@ static void s626_initialize(struct comedi_device *dev) * Issue an I2C ABORT command to halt any I2C * operation in progress and reset BUSY flag. */ - WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT); - MC_ENABLE(P_MC2, MC2_UPLD_IIC); - while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) + writel(I2C_CLKSEL | I2C_ABORT, devpriv->mmio + P_I2CSTAT); + s626_mc_enable(dev, MC2_UPLD_IIC, P_MC2); + while (!(readl(devpriv->mmio + P_MC2) & MC2_UPLD_IIC)) ; /* @@ -2467,9 +2392,9 @@ static void s626_initialize(struct comedi_device *dev) * reg twice to reset all I2C error flags. */ for (i = 0; i < 2; i++) { - WR7146(P_I2CSTAT, I2C_CLKSEL); - MC_ENABLE(P_MC2, MC2_UPLD_IIC); - while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) + writel(I2C_CLKSEL, devpriv->mmio + P_I2CSTAT); + s626_mc_enable(dev, MC2_UPLD_IIC, P_MC2); + while (!s626_mc_test(dev, MC2_UPLD_IIC, P_MC2)) ; } @@ -2479,7 +2404,7 @@ static void s626_initialize(struct comedi_device *dev) * DAC data setup times are satisfied, enable DAC serial * clock out. */ - WR7146(P_ACON2, ACON2_INIT); + writel(ACON2_INIT, devpriv->mmio + P_ACON2); /* * Set up TSL1 slot list, which is used to control the @@ -2487,22 +2412,23 @@ static void s626_initialize(struct comedi_device *dev) * SIB_A1 = store data uint8_t at next available location * in FB BUFFER1 register. */ - WR7146(P_TSL1, RSD1 | SIB_A1); - WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS); + writel(RSD1 | SIB_A1, devpriv->mmio + P_TSL1); + writel(RSD1 | SIB_A1 | EOS, devpriv->mmio + P_TSL1 + 4); /* Enable TSL1 slot list so that it executes all the time */ - WR7146(P_ACON1, ACON1_ADCSTART); + writel(ACON1_ADCSTART, devpriv->mmio + P_ACON1); /* * Initialize RPS registers used for ADC */ /* Physical start of RPS program */ - WR7146(P_RPSADDR1, (uint32_t)devpriv->RPSBuf.PhysicalBase); + writel((uint32_t)devpriv->RPSBuf.PhysicalBase, + devpriv->mmio + P_RPSADDR1); /* RPS program performs no explicit mem writes */ - WR7146(P_RPSPAGE1, 0); + writel(0, devpriv->mmio + P_RPSPAGE1); /* Disable RPS timeouts */ - WR7146(P_RPS1_TOUT, 0); + writel(0, devpriv->mmio + P_RPS1_TOUT); #if 0 /* @@ -2558,7 +2484,7 @@ static void s626_initialize(struct comedi_device *dev) * burst length = 1 DWORD * threshold = 1 DWORD. */ - WR7146(P_PCI_BT_A, 0); + writel(0, devpriv->mmio + P_PCI_BT_A); /* * Init Audio2's output DMA physical addresses. The protection @@ -2568,8 +2494,9 @@ static void s626_initialize(struct comedi_device *dev) */ pPhysBuf = devpriv->ANABuf.PhysicalBase + (DAC_WDMABUF_OS * sizeof(uint32_t)); - WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf); - WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); + writel((uint32_t)pPhysBuf, devpriv->mmio + P_BASEA2_OUT); + writel((uint32_t)(pPhysBuf + sizeof(uint32_t)), + devpriv->mmio + P_PROTA2_OUT); /* * Cache Audio2's output DMA buffer logical address. This is @@ -2584,7 +2511,7 @@ static void s626_initialize(struct comedi_device *dev) * DMAC will automatically halt and its PCI address pointer * will be reset when the protection address is reached. */ - WR7146(P_PAGEA2_OUT, 8); + writel(8, devpriv->mmio + P_PAGEA2_OUT); /* * Initialize time slot list 2 (TSL2), which is used to control @@ -2599,7 +2526,7 @@ static void s626_initialize(struct comedi_device *dev) */ /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2 */ - SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS); + writel(XSD2 | RSD3 | SIB_A2 | EOS, devpriv->mmio + VECTPORT(0)); /* * Initialize slot 1, which is constant. Slot 1 causes a @@ -2611,10 +2538,10 @@ static void s626_initialize(struct comedi_device *dev) */ /* Slot 1: Fetch DWORD from Audio2's output FIFO */ - SETVECT(1, LF_A2); + writel(LF_A2, devpriv->mmio + VECTPORT(1)); /* Start DAC's audio interface (TSL2) running */ - WR7146(P_ACON1, ACON1_DACSTART); + writel(ACON1_DACSTART, devpriv->mmio + P_ACON1); /* * Init Trim DACs to calibrated values. Do it twice because the @@ -2653,9 +2580,6 @@ static void s626_initialize(struct comedi_device *dev) /* Initialize the digital I/O subsystem */ s626_dio_init(dev); - - /* enable interrupt test */ - /* writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER); */ } static int s626_auto_attach(struct comedi_device *dev, @@ -2666,28 +2590,24 @@ static int s626_auto_attach(struct comedi_device *dev, struct comedi_subdevice *s; int ret; - dev->board_name = dev->driver->driver_name; - devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL); if (!devpriv) return -ENOMEM; dev->private = devpriv; - ret = comedi_pci_enable(pcidev, dev->board_name); + ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = 1; /* detach needs this */ - devpriv->base_addr = ioremap(pci_resource_start(pcidev, 0), - pci_resource_len(pcidev, 0)); - if (!devpriv->base_addr) + devpriv->mmio = pci_ioremap_bar(pcidev, 0); + if (!devpriv->mmio) return -ENOMEM; /* disable master interrupt */ - writel(0, devpriv->base_addr + P_IER); + writel(0, devpriv->mmio + P_IER); /* soft reset */ - writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1); + writel(MC1_SOFT_RESET, devpriv->mmio + P_MC1); /* DMA FIXME DMA// */ @@ -2707,79 +2627,79 @@ static int s626_auto_attach(struct comedi_device *dev, if (ret) return ret; - s = dev->subdevices + 0; + s = &dev->subdevices[0]; /* analog input subdevice */ - dev->read_subdev = s; - /* we support single-ended (ground) and differential */ - s->type = COMEDI_SUBD_AI; - s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_CMD_READ; - s->n_chan = S626_ADC_CHANNELS; - s->maxdata = (0xffff >> 2); - s->range_table = &s626_range_table; - s->len_chanlist = S626_ADC_CHANNELS; - s->insn_config = s626_ai_insn_config; - s->insn_read = s626_ai_insn_read; - s->do_cmd = s626_ai_cmd; - s->do_cmdtest = s626_ai_cmdtest; - s->cancel = s626_ai_cancel; - - s = dev->subdevices + 1; + s->type = COMEDI_SUBD_AI; + s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_CMD_READ; + s->n_chan = S626_ADC_CHANNELS; + s->maxdata = 0x3fff; + s->range_table = &s626_range_table; + s->len_chanlist = S626_ADC_CHANNELS; + s->insn_read = s626_ai_insn_read; + if (dev->irq) { + dev->read_subdev = s; + s->do_cmd = s626_ai_cmd; + s->do_cmdtest = s626_ai_cmdtest; + s->cancel = s626_ai_cancel; + } + + s = &dev->subdevices[1]; /* analog output subdevice */ - s->type = COMEDI_SUBD_AO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = S626_DAC_CHANNELS; - s->maxdata = (0x3fff); - s->range_table = &range_bipolar10; - s->insn_write = s626_ao_winsn; - s->insn_read = s626_ao_rinsn; - - s = dev->subdevices + 2; + s->type = COMEDI_SUBD_AO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = S626_DAC_CHANNELS; + s->maxdata = 0x3fff; + s->range_table = &range_bipolar10; + s->insn_write = s626_ao_winsn; + s->insn_read = s626_ao_rinsn; + + s = &dev->subdevices[2]; /* digital I/O subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 16; - s->maxdata = 1; - s->io_bits = 0xffff; - s->private = &dio_private_A; - s->range_table = &range_digital; - s->insn_config = s626_dio_insn_config; - s->insn_bits = s626_dio_insn_bits; - - s = dev->subdevices + 3; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 16; + s->maxdata = 1; + s->io_bits = 0xffff; + s->private = (void *)0; /* DIO group 0 */ + s->range_table = &range_digital; + s->insn_config = s626_dio_insn_config; + s->insn_bits = s626_dio_insn_bits; + + s = &dev->subdevices[3]; /* digital I/O subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 16; - s->maxdata = 1; - s->io_bits = 0xffff; - s->private = &dio_private_B; - s->range_table = &range_digital; - s->insn_config = s626_dio_insn_config; - s->insn_bits = s626_dio_insn_bits; - - s = dev->subdevices + 4; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 16; + s->maxdata = 1; + s->io_bits = 0xffff; + s->private = (void *)1; /* DIO group 1 */ + s->range_table = &range_digital; + s->insn_config = s626_dio_insn_config; + s->insn_bits = s626_dio_insn_bits; + + s = &dev->subdevices[4]; /* digital I/O subdevice */ - s->type = COMEDI_SUBD_DIO; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE; - s->n_chan = 16; - s->maxdata = 1; - s->io_bits = 0xffff; - s->private = &dio_private_C; - s->range_table = &range_digital; - s->insn_config = s626_dio_insn_config; - s->insn_bits = s626_dio_insn_bits; - - s = dev->subdevices + 5; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE; + s->n_chan = 16; + s->maxdata = 1; + s->io_bits = 0xffff; + s->private = (void *)2; /* DIO group 2 */ + s->range_table = &range_digital; + s->insn_config = s626_dio_insn_config; + s->insn_bits = s626_dio_insn_bits; + + s = &dev->subdevices[5]; /* encoder (counter) subdevice */ - s->type = COMEDI_SUBD_COUNTER; - s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL; - s->n_chan = S626_ENCODER_CHANNELS; - s->private = enc_private_data; - s->insn_config = s626_enc_insn_config; - s->insn_read = s626_enc_insn_read; - s->insn_write = s626_enc_insn_write; - s->maxdata = 0xffffff; - s->range_table = &range_unknown; + s->type = COMEDI_SUBD_COUNTER; + s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL; + s->n_chan = S626_ENCODER_CHANNELS; + s->maxdata = 0xffffff; + s->private = enc_private_data; + s->range_table = &range_unknown; + s->insn_config = s626_enc_insn_config; + s->insn_read = s626_enc_insn_read; + s->insn_write = s626_enc_insn_write; s626_initialize(dev); @@ -2790,24 +2710,26 @@ static int s626_auto_attach(struct comedi_device *dev, static void s626_detach(struct comedi_device *dev) { - struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct s626_private *devpriv = dev->private; if (devpriv) { /* stop ai_command */ devpriv->ai_cmd_running = 0; - if (devpriv->base_addr) { + if (devpriv->mmio) { /* interrupt mask */ - WR7146(P_IER, 0); /* Disable master interrupt. */ - WR7146(P_ISR, IRQ_GPIO3 | IRQ_RPS1); /* Clear board's IRQ status flag. */ + /* Disable master interrupt */ + writel(0, devpriv->mmio + P_IER); + /* Clear board's IRQ status flag */ + writel(IRQ_GPIO3 | IRQ_RPS1, + devpriv->mmio + P_ISR); /* Disable the watchdog timer and battery charger. */ WriteMISC2(dev, 0); - /* Close all interfaces on 7146 device. */ - WR7146(P_MC1, MC1_SHUTDOWN); - WR7146(P_ACON1, ACON1_BASE); + /* Close all interfaces on 7146 device */ + writel(MC1_SHUTDOWN, devpriv->mmio + P_MC1); + writel(ACON1_BASE, devpriv->mmio + P_ACON1); CloseDMAB(dev, &devpriv->RPSBuf, DMABUF_SIZE); CloseDMAB(dev, &devpriv->ANABuf, DMABUF_SIZE); @@ -2815,13 +2737,10 @@ static void s626_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); - if (devpriv->base_addr) - iounmap(devpriv->base_addr); - } - if (pcidev) { - if (dev->iobase) - comedi_pci_disable(pcidev); + if (devpriv->mmio) + iounmap(devpriv->mmio); } + comedi_pci_disable(dev); } static struct comedi_driver s626_driver = { @@ -2832,9 +2751,9 @@ static struct comedi_driver s626_driver = { }; static int s626_pci_probe(struct pci_dev *dev, - const struct pci_device_id *ent) + const struct pci_device_id *id) { - return comedi_pci_auto_config(dev, &s626_driver); + return comedi_pci_auto_config(dev, &s626_driver, id->driver_data); } /* |