Lines Matching +full:group +full:- +full:index +full:- +full:shift
1 // SPDX-License-Identifier: GPL-2.0+
6 * COMEDI - Linux Control and Measurement Device Interface
10 * Copyright (C) 2002-2004 Sensoray Co., Inc.
68 * struct s626_private - Working data for s626 driver.
69 * @ai_cmd_running: non-zero if ai_cmd is running.
97 /* Counter overflow/index event flag masks for RDMISC2. */
98 #define S626_INDXMASK(C) (1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 + 4)))
110 writel(val, dev->mmio + reg); in s626_mc_enable()
116 writel(cmd << 16, dev->mmio + reg); in s626_mc_disable()
124 val = readl(dev->mmio + reg); in s626_mc_test()
129 #define S626_BUGFIX_STREG(REGADRS) ((REGADRS) - 4)
162 dev_err(dev->class_dev, in s626_debi_transfer()
167 if (!(readl(dev->mmio + S626_P_PSR) & S626_PSR_DEBI_S)) in s626_debi_transfer()
172 dev_err(dev->class_dev, "DEBI transfer timeout\n"); in s626_debi_transfer()
181 writel(S626_DEBI_CMD_RDWORD | addr, dev->mmio + S626_P_DEBICMD); in s626_debi_read()
186 return readl(dev->mmio + S626_P_DEBIAD); in s626_debi_read()
196 writel(S626_DEBI_CMD_WRWORD | addr, dev->mmio + S626_P_DEBICMD); in s626_debi_write()
197 writel(wdata, dev->mmio + S626_P_DEBIAD); in s626_debi_write()
214 writel(S626_DEBI_CMD_RDWORD | addr, dev->mmio + S626_P_DEBICMD); in s626_debi_replace()
217 writel(S626_DEBI_CMD_WRWORD | addr, dev->mmio + S626_P_DEBICMD); in s626_debi_replace()
218 val = readl(dev->mmio + S626_P_DEBIAD); in s626_debi_replace()
221 writel(val & 0xffff, dev->mmio + S626_P_DEBIAD); in s626_debi_replace()
237 return -EBUSY; in s626_i2c_handshake_eoc()
246 writel(val, dev->mmio + S626_P_I2CCTRL); in s626_i2c_handshake()
259 ctrl = readl(dev->mmio + S626_P_I2CCTRL); in s626_i2c_handshake()
262 /* Return non-zero if I2C error occurred */ in s626_i2c_handshake()
269 struct s626_private *devpriv = dev->private; in s626_i2c_read()
278 devpriv->i2c_adrs) | in s626_i2c_read()
291 (devpriv->i2c_adrs | 1)) | in s626_i2c_read()
297 return (readl(dev->mmio + S626_P_I2CCTRL) >> 16) & 0xff; in s626_i2c_read()
302 /* TrimDac LogicalChan-to-PhysicalChan mapping table. */
305 /* TrimDac LogicalChan-to-EepromAdrs mapping table. */
326 status = readl(dev->mmio + S626_P_MC1); in s626_send_dac_eoc()
331 status = readl(dev->mmio + S626_P_SSR); in s626_send_dac_eoc()
336 status = readl(dev->mmio + S626_P_FB_BUFFER2); in s626_send_dac_eoc()
341 status = readl(dev->mmio + S626_P_FB_BUFFER2); in s626_send_dac_eoc()
346 return -EINVAL; in s626_send_dac_eoc()
348 return -EBUSY; in s626_send_dac_eoc()
358 struct s626_private *devpriv = dev->private; in s626_send_dac()
361 /* START THE SERIAL CLOCK RUNNING ------------- */ in s626_send_dac()
373 s626_debi_write(dev, S626_LP_DACPOL, devpriv->dacpol); in s626_send_dac()
375 /* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */ in s626_send_dac()
378 /* writel(val, dev->mmio + (uint32_t)devpriv->dac_wbuf); */ in s626_send_dac()
379 *devpriv->dac_wbuf = val; in s626_send_dac()
396 writel(S626_ISR_AFOU, dev->mmio + S626_P_ISR); in s626_send_dac()
408 dev_err(dev->class_dev, "DMA transfer timeout\n"); in s626_send_dac()
412 /* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */ in s626_send_dac()
417 * will be shifted in and stored in FB_BUFFER2 for end-of-slot-list in s626_send_dac()
421 dev->mmio + S626_VECTPORT(0)); in s626_send_dac()
433 dev_err(dev->class_dev, in s626_send_dac()
441 * simultaneously shift out and in the 0x00 that is ALWAYS the value in s626_send_dac()
446 dev->mmio + S626_VECTPORT(0)); in s626_send_dac()
448 /* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */ in s626_send_dac()
460 * 2. While slots 2-5 are executing due to a late slot 0 trap. In in s626_send_dac()
468 if (readl(dev->mmio + S626_P_FB_BUFFER2) & 0xff000000) { in s626_send_dac()
471 * in slots 2-5, so we now wait for slot 0 to execute and trap in s626_send_dac()
479 dev_err(dev->class_dev, in s626_send_dac()
490 * In order to do this, we reprogram slot 0 so that it will shift in in s626_send_dac()
491 * SD3, which is driven only by a pull-up resistor. in s626_send_dac()
494 dev->mmio + S626_VECTPORT(0)); in s626_send_dac()
504 dev_err(dev->class_dev, in s626_send_dac()
517 struct s626_private *devpriv = dev->private; in s626_set_dac()
527 dacdata = -dacdata; in s626_set_dac()
528 devpriv->dacpol |= signmask; in s626_set_dac()
530 devpriv->dacpol &= ~signmask; in s626_set_dac()
540 * data to a non-existent TrimDac channel just to keep the clock in s626_set_dac()
552 dev->mmio + S626_VECTPORT(2)); in s626_set_dac()
555 dev->mmio + S626_VECTPORT(3)); in s626_set_dac()
556 /* Slot 4: Transmit to non-existent TrimDac channel to keep clock */ in s626_set_dac()
558 dev->mmio + S626_VECTPORT(4)); in s626_set_dac()
561 dev->mmio + S626_VECTPORT(5)); in s626_set_dac()
567 * to a non-existent TrimDac channel) that serves to keep the clock in s626_set_dac()
571 * (write to non-existent trimdac). in s626_set_dac()
573 val |= 0x00004000; /* Address the two main dual-DAC devices in s626_set_dac()
586 struct s626_private *devpriv = dev->private; in s626_write_trim_dac()
593 devpriv->trim_setpoint[logical_chan] = dac_data; in s626_write_trim_dac()
599 * Set up TSL2 records for TrimDac write operation. All slots shift in s626_write_trim_dac()
600 * 0xFF in from pulled-up SD3 so that the end of the slot sequence in s626_write_trim_dac()
606 dev->mmio + S626_VECTPORT(2)); in s626_write_trim_dac()
609 dev->mmio + S626_VECTPORT(3)); in s626_write_trim_dac()
612 dev->mmio + S626_VECTPORT(4)); in s626_write_trim_dac()
615 dev->mmio + S626_VECTPORT(5)); in s626_write_trim_dac()
621 * WORD value (that writes a channel 0 NOP command to a non-existent in s626_write_trim_dac()
659 * access, 1: A index latches A, 2: B index latches B, 3: A overflow
683 * Reset a counter's index and overflow event capture flags.
709 struct s626_private *devpriv = dev->private; in s626_set_mode_a()
729 /* Populate all mode-dependent attributes of CRA & CRB images. */ in s626_set_mode_a()
740 /* ClkPolA behaves as always-on clock enable. */ in s626_set_mode_a()
759 * Force positive index polarity if IndxSrc is software-driven only, in s626_set_mode_a()
770 devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) | in s626_set_mode_a()
787 struct s626_private *devpriv = dev->private; in s626_set_mode_b()
807 /* Populate all mode-dependent attributes of CRA & CRB images. */ in s626_set_mode_b()
815 /* ClkPolB behaves as always-on clock enable. */ in s626_set_mode_b()
825 /* ClkPolB controls IndexB -- always set to active. */ in s626_set_mode_b()
844 * Force positive index polarity if IndxSrc is software-driven only, in s626_set_mode_b()
855 devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) | in s626_set_mode_b()
879 * Return/set a counter's enable. enab: 0=always enabled, 1=enabled by index.
923 * index/overflow events. int_source: 0=Disabled, 1=OverflowOnly,
929 struct s626_private *devpriv = dev->private; in s626_set_int_src()
934 /* Reset any pending counter overflow or index captures */ in s626_set_int_src()
949 /* Reset any pending counter overflow or index captures */ in s626_set_int_src()
961 devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) | in s626_set_int_src()
968 devpriv->counter_int_enabs |= S626_OVERMASK(chan); in s626_set_int_src()
971 devpriv->counter_int_enabs |= S626_INDXMASK(chan); in s626_set_int_src()
974 devpriv->counter_int_enabs |= (S626_OVERMASK(chan) | in s626_set_int_src()
981 * Generate an index pulse.
991 /* Pulse index */ in s626_pulse_index()
1001 /* Pulse index */ in s626_pulse_index()
1015 unsigned int group = chan / 16; in s626_dio_set_irq() local
1016 unsigned int mask = 1 << (chan - (16 * group)); in s626_dio_set_irq()
1020 status = s626_debi_read(dev, S626_LP_RDEDGSEL(group)); in s626_dio_set_irq()
1021 s626_debi_write(dev, S626_LP_WREDGSEL(group), mask | status); in s626_dio_set_irq()
1024 status = s626_debi_read(dev, S626_LP_RDINTSEL(group)); in s626_dio_set_irq()
1025 s626_debi_write(dev, S626_LP_WRINTSEL(group), mask | status); in s626_dio_set_irq()
1031 status = s626_debi_read(dev, S626_LP_RDCAPSEL(group)); in s626_dio_set_irq()
1032 s626_debi_write(dev, S626_LP_WRCAPSEL(group), mask | status); in s626_dio_set_irq()
1037 static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group, in s626_dio_reset_irq() argument
1044 s626_debi_write(dev, S626_LP_WRCAPSEL(group), mask); in s626_dio_reset_irq()
1051 unsigned int group; in s626_dio_clear_irq() local
1057 for (group = 0; group < S626_DIO_BANKS; group++) in s626_dio_clear_irq()
1058 s626_debi_write(dev, S626_LP_WRCAPSEL(group), 0xffff); in s626_dio_clear_irq()
1064 u16 irqbit, u8 group) in s626_handle_dio_interrupt() argument
1066 struct s626_private *devpriv = dev->private; in s626_handle_dio_interrupt()
1067 struct comedi_subdevice *s = dev->read_subdev; in s626_handle_dio_interrupt()
1068 struct comedi_cmd *cmd = &s->async->cmd; in s626_handle_dio_interrupt()
1070 s626_dio_reset_irq(dev, group, irqbit); in s626_handle_dio_interrupt()
1072 if (devpriv->ai_cmd_running) { in s626_handle_dio_interrupt()
1074 if ((irqbit >> (cmd->start_arg - (16 * group))) == 1 && in s626_handle_dio_interrupt()
1075 cmd->start_src == TRIG_EXT) { in s626_handle_dio_interrupt()
1079 if (cmd->scan_begin_src == TRIG_EXT) in s626_handle_dio_interrupt()
1080 s626_dio_set_irq(dev, cmd->scan_begin_arg); in s626_handle_dio_interrupt()
1082 if ((irqbit >> (cmd->scan_begin_arg - (16 * group))) == 1 && in s626_handle_dio_interrupt()
1083 cmd->scan_begin_src == TRIG_EXT) { in s626_handle_dio_interrupt()
1087 if (cmd->convert_src == TRIG_EXT) { in s626_handle_dio_interrupt()
1088 devpriv->ai_convert_count = cmd->chanlist_len; in s626_handle_dio_interrupt()
1090 s626_dio_set_irq(dev, cmd->convert_arg); in s626_handle_dio_interrupt()
1093 if (cmd->convert_src == TRIG_TIMER) { in s626_handle_dio_interrupt()
1094 devpriv->ai_convert_count = cmd->chanlist_len; in s626_handle_dio_interrupt()
1098 if ((irqbit >> (cmd->convert_arg - (16 * group))) == 1 && in s626_handle_dio_interrupt()
1099 cmd->convert_src == TRIG_EXT) { in s626_handle_dio_interrupt()
1103 devpriv->ai_convert_count--; in s626_handle_dio_interrupt()
1104 if (devpriv->ai_convert_count > 0) in s626_handle_dio_interrupt()
1105 s626_dio_set_irq(dev, cmd->convert_arg); in s626_handle_dio_interrupt()
1113 u8 group; in s626_check_dio_interrupts() local
1115 for (group = 0; group < S626_DIO_BANKS; group++) { in s626_check_dio_interrupts()
1117 irqbit = s626_debi_read(dev, S626_LP_RDCAPFLG(group)); in s626_check_dio_interrupts()
1121 s626_handle_dio_interrupt(dev, irqbit, group); in s626_check_dio_interrupts()
1129 struct s626_private *devpriv = dev->private; in s626_check_counter_interrupts()
1130 struct comedi_subdevice *s = dev->read_subdev; in s626_check_counter_interrupts()
1131 struct comedi_async *async = s->async; in s626_check_counter_interrupts()
1132 struct comedi_cmd *cmd = &async->cmd; in s626_check_counter_interrupts()
1159 if (devpriv->ai_convert_count > 0) { in s626_check_counter_interrupts()
1160 devpriv->ai_convert_count--; in s626_check_counter_interrupts()
1161 if (devpriv->ai_convert_count == 0) in s626_check_counter_interrupts()
1164 if (cmd->convert_src == TRIG_TIMER) { in s626_check_counter_interrupts()
1175 if (cmd->scan_begin_src == TRIG_TIMER) { in s626_check_counter_interrupts()
1180 if (cmd->convert_src == TRIG_TIMER) { in s626_check_counter_interrupts()
1181 devpriv->ai_convert_count = cmd->chanlist_len; in s626_check_counter_interrupts()
1189 struct s626_private *devpriv = dev->private; in s626_handle_eos_interrupt()
1190 struct comedi_subdevice *s = dev->read_subdev; in s626_handle_eos_interrupt()
1191 struct comedi_async *async = s->async; in s626_handle_eos_interrupt()
1192 struct comedi_cmd *cmd = &async->cmd; in s626_handle_eos_interrupt()
1198 u32 *readaddr = (u32 *)devpriv->ana_buf.logical_base + 1; in s626_handle_eos_interrupt()
1202 for (i = 0; i < cmd->chanlist_len; i++) { in s626_handle_eos_interrupt()
1206 * Convert ADC data to 16-bit integer values and copy in s626_handle_eos_interrupt()
1215 if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg) in s626_handle_eos_interrupt()
1216 async->events |= COMEDI_CB_EOA; in s626_handle_eos_interrupt()
1218 if (async->events & COMEDI_CB_CANCEL_MASK) in s626_handle_eos_interrupt()
1219 devpriv->ai_cmd_running = 0; in s626_handle_eos_interrupt()
1221 if (devpriv->ai_cmd_running && cmd->scan_begin_src == TRIG_EXT) in s626_handle_eos_interrupt()
1222 s626_dio_set_irq(dev, cmd->scan_begin_arg); in s626_handle_eos_interrupt()
1226 return !devpriv->ai_cmd_running; in s626_handle_eos_interrupt()
1235 if (!dev->attached) in s626_irq_handler()
1238 spin_lock_irqsave(&dev->spinlock, flags); in s626_irq_handler()
1241 irqstatus = readl(dev->mmio + S626_P_IER); in s626_irq_handler()
1244 irqtype = readl(dev->mmio + S626_P_ISR); in s626_irq_handler()
1247 writel(0, dev->mmio + S626_P_IER); in s626_irq_handler()
1250 writel(irqtype, dev->mmio + S626_P_ISR); in s626_irq_handler()
1265 writel(irqstatus, dev->mmio + S626_P_IER); in s626_irq_handler()
1267 spin_unlock_irqrestore(&dev->spinlock, flags); in s626_irq_handler()
1276 struct s626_private *devpriv = dev->private; in s626_reset_adc()
1277 struct comedi_subdevice *s = dev->read_subdev; in s626_reset_adc()
1278 struct comedi_cmd *cmd = &s->async->cmd; in s626_reset_adc()
1289 rps = (u32 *)devpriv->rps_buf.logical_base; in s626_reset_adc()
1292 writel((u32)devpriv->rps_buf.physical_base, in s626_reset_adc()
1293 dev->mmio + S626_P_RPSADDR1); in s626_reset_adc()
1296 if (cmd->scan_begin_src != TRIG_FOLLOW) { in s626_reset_adc()
1304 * because the first RPS DEBI Write following a non-RPS DEBI write in s626_reset_adc()
1328 for (devpriv->adc_items = 0; devpriv->adc_items < 16; in s626_reset_adc()
1329 devpriv->adc_items++) { in s626_reset_adc()
1334 * +-10V, 1 = +-5V, and EOPL = End of Poll List marker. in s626_reset_adc()
1374 (u32)devpriv->rps_buf.physical_base + in s626_reset_adc()
1375 (u32)((unsigned long)rps - in s626_reset_adc()
1376 (unsigned long)devpriv->rps_buf.logical_base); in s626_reset_adc()
1384 if (cmd->convert_src != TRIG_NOW) { in s626_reset_adc()
1400 * busy) and for data from previous conversion to shift into FB in s626_reset_adc()
1409 *rps++ = (u32)devpriv->ana_buf.physical_base + in s626_reset_adc()
1410 (devpriv->adc_items << 2); in s626_reset_adc()
1417 devpriv->adc_items++; /* Adjust poll list item count. */ in s626_reset_adc()
1453 *rps++ = (u32)devpriv->ana_buf.physical_base + in s626_reset_adc()
1454 (devpriv->adc_items << 2); in s626_reset_adc()
1461 if (devpriv->ai_cmd_running == 1) in s626_reset_adc()
1466 *rps++ = (u32)devpriv->rps_buf.physical_base; in s626_reset_adc()
1478 status = readl(dev->mmio + S626_P_PSR); in s626_ai_eoc()
1481 return -EBUSY; in s626_ai_eoc()
1489 u16 chan = CR_CHAN(insn->chanspec); in s626_ai_insn_read()
1490 u16 range = CR_RANGE(insn->chanspec); in s626_ai_insn_read()
1512 for (n = 0; n < insn->n; n++) { in s626_ai_insn_read()
1517 gpio_image = readl(dev->mmio + S626_P_GPIO); in s626_ai_insn_read()
1519 writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO); in s626_ai_insn_read()
1521 writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO); in s626_ai_insn_read()
1522 writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO); in s626_ai_insn_read()
1524 writel(gpio_image | S626_GPIO1_HI, dev->mmio + S626_P_GPIO); in s626_ai_insn_read()
1529 * shift into FB BUFFER 1 register. in s626_ai_insn_read()
1539 tmp = readl(dev->mmio + S626_P_FB_BUFFER1); in s626_ai_insn_read()
1540 data[n - 1] = s626_ai_reg_to_uint(tmp); in s626_ai_insn_read()
1559 gpio_image = readl(dev->mmio + S626_P_GPIO); in s626_ai_insn_read()
1561 writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO); in s626_ai_insn_read()
1563 writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO); in s626_ai_insn_read()
1564 writel(gpio_image & ~S626_GPIO1_HI, dev->mmio + S626_P_GPIO); in s626_ai_insn_read()
1566 writel(gpio_image | S626_GPIO1_HI, dev->mmio + S626_P_GPIO); in s626_ai_insn_read()
1575 /* Fetch ADC data from audio interface's input shift register. */ in s626_ai_insn_read()
1579 tmp = readl(dev->mmio + S626_P_FB_BUFFER1); in s626_ai_insn_read()
1580 data[n - 1] = s626_ai_reg_to_uint(tmp); in s626_ai_insn_read()
1590 for (n = 0; n < cmd->chanlist_len; n++) { in s626_ai_load_polllist()
1591 if (CR_RANGE(cmd->chanlist[n]) == 0) in s626_ai_load_polllist()
1592 ppl[n] = CR_CHAN(cmd->chanlist[n]) | S626_RANGE_5V; in s626_ai_load_polllist()
1594 ppl[n] = CR_CHAN(cmd->chanlist[n]) | S626_RANGE_10V; in s626_ai_load_polllist()
1597 ppl[n - 1] |= S626_EOPL; in s626_ai_load_polllist()
1606 struct comedi_cmd *cmd = &s->async->cmd; in s626_ai_inttrig()
1608 if (trig_num != cmd->start_arg) in s626_ai_inttrig()
1609 return -EINVAL; in s626_ai_inttrig()
1614 s->async->inttrig = NULL; in s626_ai_inttrig()
1646 return divider - 1; in s626_ns_to_timer()
1653 /* Preload upon index. */ in s626_timer_load()
1655 /* Disable hardware index. */ in s626_timer_load()
1663 /* Enabled by index */ in s626_timer_load()
1674 * Software index pulse forces the preload register to load in s626_timer_load()
1693 struct s626_private *devpriv = dev->private; in s626_ai_cmd()
1695 struct comedi_cmd *cmd = &s->async->cmd; in s626_ai_cmd()
1698 if (devpriv->ai_cmd_running) { in s626_ai_cmd()
1699 dev_err(dev->class_dev, in s626_ai_cmd()
1701 return -EBUSY; in s626_ai_cmd()
1704 writel(0, dev->mmio + S626_P_IER); in s626_ai_cmd()
1707 writel(S626_IRQ_RPS1 | S626_IRQ_GPIO3, dev->mmio + S626_P_ISR); in s626_ai_cmd()
1714 devpriv->ai_cmd_running = 0; in s626_ai_cmd()
1717 devpriv->ai_cmd_running = 1; in s626_ai_cmd()
1718 devpriv->ai_convert_count = 0; in s626_ai_cmd()
1720 switch (cmd->scan_begin_src) { in s626_ai_cmd()
1728 tick = s626_ns_to_timer(&cmd->scan_begin_arg, cmd->flags); in s626_ai_cmd()
1736 if (cmd->start_src != TRIG_EXT) in s626_ai_cmd()
1737 s626_dio_set_irq(dev, cmd->scan_begin_arg); in s626_ai_cmd()
1741 switch (cmd->convert_src) { in s626_ai_cmd()
1749 tick = s626_ns_to_timer(&cmd->convert_arg, cmd->flags); in s626_ai_cmd()
1757 if (cmd->scan_begin_src != TRIG_EXT && in s626_ai_cmd()
1758 cmd->start_src == TRIG_EXT) in s626_ai_cmd()
1759 s626_dio_set_irq(dev, cmd->convert_arg); in s626_ai_cmd()
1765 switch (cmd->start_src) { in s626_ai_cmd()
1772 s->async->inttrig = NULL; in s626_ai_cmd()
1776 s626_dio_set_irq(dev, cmd->start_arg); in s626_ai_cmd()
1777 s->async->inttrig = NULL; in s626_ai_cmd()
1780 s->async->inttrig = s626_ai_inttrig; in s626_ai_cmd()
1785 writel(S626_IRQ_GPIO3 | S626_IRQ_RPS1, dev->mmio + S626_P_IER); in s626_ai_cmd()
1798 err |= comedi_check_trigger_src(&cmd->start_src, in s626_ai_cmdtest()
1800 err |= comedi_check_trigger_src(&cmd->scan_begin_src, in s626_ai_cmdtest()
1802 err |= comedi_check_trigger_src(&cmd->convert_src, in s626_ai_cmdtest()
1804 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); in s626_ai_cmdtest()
1805 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); in s626_ai_cmdtest()
1812 err |= comedi_check_trigger_is_unique(cmd->start_src); in s626_ai_cmdtest()
1813 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); in s626_ai_cmdtest()
1814 err |= comedi_check_trigger_is_unique(cmd->convert_src); in s626_ai_cmdtest()
1815 err |= comedi_check_trigger_is_unique(cmd->stop_src); in s626_ai_cmdtest()
1824 switch (cmd->start_src) { in s626_ai_cmdtest()
1827 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); in s626_ai_cmdtest()
1830 err |= comedi_check_trigger_arg_max(&cmd->start_arg, 39); in s626_ai_cmdtest()
1834 if (cmd->scan_begin_src == TRIG_EXT) in s626_ai_cmdtest()
1835 err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 39); in s626_ai_cmdtest()
1836 if (cmd->convert_src == TRIG_EXT) in s626_ai_cmdtest()
1837 err |= comedi_check_trigger_arg_max(&cmd->convert_arg, 39); in s626_ai_cmdtest()
1842 if (cmd->scan_begin_src == TRIG_TIMER) { in s626_ai_cmdtest()
1843 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, in s626_ai_cmdtest()
1845 err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, in s626_ai_cmdtest()
1852 * err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 9); in s626_ai_cmdtest()
1855 if (cmd->convert_src == TRIG_TIMER) { in s626_ai_cmdtest()
1856 err |= comedi_check_trigger_arg_min(&cmd->convert_arg, in s626_ai_cmdtest()
1858 err |= comedi_check_trigger_arg_max(&cmd->convert_arg, in s626_ai_cmdtest()
1862 * external trigger - see above in s626_ai_cmdtest()
1863 * err |= comedi_check_trigger_arg_max(&cmd->scan_begin_arg, 9); in s626_ai_cmdtest()
1867 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, in s626_ai_cmdtest()
1868 cmd->chanlist_len); in s626_ai_cmdtest()
1870 if (cmd->stop_src == TRIG_COUNT) in s626_ai_cmdtest()
1871 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); in s626_ai_cmdtest()
1873 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); in s626_ai_cmdtest()
1880 if (cmd->scan_begin_src == TRIG_TIMER) { in s626_ai_cmdtest()
1881 arg = cmd->scan_begin_arg; in s626_ai_cmdtest()
1882 s626_ns_to_timer(&arg, cmd->flags); in s626_ai_cmdtest()
1883 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg); in s626_ai_cmdtest()
1886 if (cmd->convert_src == TRIG_TIMER) { in s626_ai_cmdtest()
1887 arg = cmd->convert_arg; in s626_ai_cmdtest()
1888 s626_ns_to_timer(&arg, cmd->flags); in s626_ai_cmdtest()
1889 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg); in s626_ai_cmdtest()
1891 if (cmd->scan_begin_src == TRIG_TIMER) { in s626_ai_cmdtest()
1892 arg = cmd->convert_arg * cmd->scan_end_arg; in s626_ai_cmdtest()
1894 &cmd->scan_begin_arg, arg); in s626_ai_cmdtest()
1906 struct s626_private *devpriv = dev->private; in s626_ai_cancel()
1912 writel(0, dev->mmio + S626_P_IER); in s626_ai_cancel()
1914 devpriv->ai_cmd_running = 0; in s626_ai_cancel()
1924 unsigned int chan = CR_CHAN(insn->chanspec); in s626_ao_insn_write()
1927 for (i = 0; i < insn->n; i++) { in s626_ao_insn_write()
1931 dacdata -= (0x1fff); in s626_ao_insn_write()
1937 s->readback[chan] = data[i]; in s626_ao_insn_write()
1940 return insn->n; in s626_ao_insn_write()
1946 * All DIO functions address a group of DIO channels by means of
1947 * "group" argument. group may be 0, 1 or 2, which correspond to DIO
1953 u16 group; in s626_dio_init() local
1958 /* For each group of sixteen channels ... */ in s626_dio_init()
1959 for (group = 0; group < S626_DIO_BANKS; group++) { in s626_dio_init()
1961 s626_debi_write(dev, S626_LP_WRINTSEL(group), 0); in s626_dio_init()
1963 s626_debi_write(dev, S626_LP_WRCAPSEL(group), 0xffff); in s626_dio_init()
1965 s626_debi_write(dev, S626_LP_WREDGSEL(group), 0); in s626_dio_init()
1967 s626_debi_write(dev, S626_LP_WRDOUT(group), 0); in s626_dio_init()
1976 unsigned long group = (unsigned long)s->private; in s626_dio_insn_bits() local
1979 s626_debi_write(dev, S626_LP_WRDOUT(group), s->state); in s626_dio_insn_bits()
1981 data[1] = s626_debi_read(dev, S626_LP_RDDIN(group)); in s626_dio_insn_bits()
1983 return insn->n; in s626_dio_insn_bits()
1991 unsigned long group = (unsigned long)s->private; in s626_dio_insn_config() local
1998 s626_debi_write(dev, S626_LP_WRDOUT(group), s->io_bits); in s626_dio_insn_config()
2000 return insn->n; in s626_dio_insn_config()
2016 unsigned int chan = CR_CHAN(insn->chanspec); in s626_enc_insn_config()
2018 /* Preload upon index. */ in s626_enc_insn_config()
2020 /* Disable hardware index. */ in s626_enc_insn_config()
2028 /* Enabled by index */ in s626_enc_insn_config()
2043 return insn->n; in s626_enc_insn_config()
2051 unsigned int chan = CR_CHAN(insn->chanspec); in s626_enc_insn_read()
2055 for (i = 0; i < insn->n; i++) { in s626_enc_insn_read()
2067 return insn->n; in s626_enc_insn_read()
2074 unsigned int chan = CR_CHAN(insn->chanspec); in s626_enc_insn_write()
2080 * Software index pulse forces the preload register to load in s626_enc_insn_write()
2101 /* Preload upon index. */ in s626_counters_init()
2103 /* Disable hardware index. */ in s626_counters_init()
2111 /* Enabled by index */ in s626_counters_init()
2128 struct s626_private *devpriv = dev->private; in s626_allocate_dma_buffers()
2132 addr = dma_alloc_coherent(&pcidev->dev, S626_DMABUF_SIZE, &appdma, in s626_allocate_dma_buffers()
2135 return -ENOMEM; in s626_allocate_dma_buffers()
2136 devpriv->ana_buf.logical_base = addr; in s626_allocate_dma_buffers()
2137 devpriv->ana_buf.physical_base = appdma; in s626_allocate_dma_buffers()
2139 addr = dma_alloc_coherent(&pcidev->dev, S626_DMABUF_SIZE, &appdma, in s626_allocate_dma_buffers()
2142 return -ENOMEM; in s626_allocate_dma_buffers()
2143 devpriv->rps_buf.logical_base = addr; in s626_allocate_dma_buffers()
2144 devpriv->rps_buf.physical_base = appdma; in s626_allocate_dma_buffers()
2152 struct s626_private *devpriv = dev->private; in s626_free_dma_buffers()
2157 if (devpriv->rps_buf.logical_base) in s626_free_dma_buffers()
2158 dma_free_coherent(&pcidev->dev, S626_DMABUF_SIZE, in s626_free_dma_buffers()
2159 devpriv->rps_buf.logical_base, in s626_free_dma_buffers()
2160 devpriv->rps_buf.physical_base); in s626_free_dma_buffers()
2161 if (devpriv->ana_buf.logical_base) in s626_free_dma_buffers()
2162 dma_free_coherent(&pcidev->dev, S626_DMABUF_SIZE, in s626_free_dma_buffers()
2163 devpriv->ana_buf.logical_base, in s626_free_dma_buffers()
2164 devpriv->ana_buf.physical_base); in s626_free_dma_buffers()
2169 struct s626_private *devpriv = dev->private; in s626_initialize()
2185 * Intel-compatible local bus (DEBI never times out) in s626_initialize()
2189 S626_DEBI_CFG_INTEL, dev->mmio + S626_P_DEBICFG); in s626_initialize()
2192 writel(S626_DEBI_PAGE_DISABLE, dev->mmio + S626_P_DEBIPAGE); in s626_initialize()
2195 writel(S626_GPIO_BASE | S626_GPIO1_HI, dev->mmio + S626_P_GPIO); in s626_initialize()
2198 devpriv->i2c_adrs = 0xA0; in s626_initialize()
2205 dev->mmio + S626_P_I2CSTAT); in s626_initialize()
2216 writel(S626_I2C_CLKSEL, dev->mmio + S626_P_I2CSTAT); in s626_initialize()
2230 writel(S626_ACON2_INIT, dev->mmio + S626_P_ACON2); in s626_initialize()
2234 * accumulation of ADC data: S626_RSD1 = shift data in on SD1. in s626_initialize()
2238 writel(S626_RSD1 | S626_SIB_A1, dev->mmio + S626_P_TSL1); in s626_initialize()
2240 dev->mmio + S626_P_TSL1 + 4); in s626_initialize()
2243 writel(S626_ACON1_ADCSTART, dev->mmio + S626_P_ACON1); in s626_initialize()
2250 writel((u32)devpriv->rps_buf.physical_base, in s626_initialize()
2251 dev->mmio + S626_P_RPSADDR1); in s626_initialize()
2253 writel(0, dev->mmio + S626_P_RPSPAGE1); in s626_initialize()
2255 writel(0, dev->mmio + S626_P_RPS1_TOUT); in s626_initialize()
2268 struct comedi_subdevice *s = dev->read_subdev; in s626_initialize()
2272 u16 index; in s626_initialize()
2293 for (index = 0; index < 500; index++) { in s626_initialize()
2311 writel(0, dev->mmio + S626_P_PCI_BT_A); in s626_initialize()
2319 phys_buf = devpriv->ana_buf.physical_base + in s626_initialize()
2321 writel((u32)phys_buf, dev->mmio + S626_P_BASEA2_OUT); in s626_initialize()
2323 dev->mmio + S626_P_PROTA2_OUT); in s626_initialize()
2329 devpriv->dac_wbuf = (u32 *)devpriv->ana_buf.logical_base + in s626_initialize()
2338 writel(8, dev->mmio + S626_P_PAGEA2_OUT); in s626_initialize()
2347 * pull-up resistor) is shifted in and stored to the MSB of in s626_initialize()
2352 /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2 */ in s626_initialize()
2354 dev->mmio + S626_VECTPORT(0)); in s626_initialize()
2366 writel(S626_LF_A2, dev->mmio + S626_VECTPORT(1)); in s626_initialize()
2369 writel(S626_ACON1_DACSTART, dev->mmio + S626_P_ACON1); in s626_initialize()
2404 * the watchdog timer, set DIO channels 0-5 to operate in the in s626_initialize()
2427 return -ENOMEM; in s626_auto_attach()
2433 dev->mmio = pci_ioremap_bar(pcidev, 0); in s626_auto_attach()
2434 if (!dev->mmio) in s626_auto_attach()
2435 return -ENOMEM; in s626_auto_attach()
2438 writel(0, dev->mmio + S626_P_IER); in s626_auto_attach()
2441 writel(S626_MC1_SOFT_RESET, dev->mmio + S626_P_MC1); in s626_auto_attach()
2449 if (pcidev->irq) { in s626_auto_attach()
2450 ret = request_irq(pcidev->irq, s626_irq_handler, IRQF_SHARED, in s626_auto_attach()
2451 dev->board_name, dev); in s626_auto_attach()
2454 dev->irq = pcidev->irq; in s626_auto_attach()
2461 s = &dev->subdevices[0]; in s626_auto_attach()
2463 s->type = COMEDI_SUBD_AI; in s626_auto_attach()
2464 s->subdev_flags = SDF_READABLE | SDF_DIFF; in s626_auto_attach()
2465 s->n_chan = S626_ADC_CHANNELS; in s626_auto_attach()
2466 s->maxdata = 0x3fff; in s626_auto_attach()
2467 s->range_table = &s626_range_table; in s626_auto_attach()
2468 s->len_chanlist = S626_ADC_CHANNELS; in s626_auto_attach()
2469 s->insn_read = s626_ai_insn_read; in s626_auto_attach()
2470 if (dev->irq) { in s626_auto_attach()
2471 dev->read_subdev = s; in s626_auto_attach()
2472 s->subdev_flags |= SDF_CMD_READ; in s626_auto_attach()
2473 s->do_cmd = s626_ai_cmd; in s626_auto_attach()
2474 s->do_cmdtest = s626_ai_cmdtest; in s626_auto_attach()
2475 s->cancel = s626_ai_cancel; in s626_auto_attach()
2478 s = &dev->subdevices[1]; in s626_auto_attach()
2480 s->type = COMEDI_SUBD_AO; in s626_auto_attach()
2481 s->subdev_flags = SDF_WRITABLE | SDF_READABLE; in s626_auto_attach()
2482 s->n_chan = S626_DAC_CHANNELS; in s626_auto_attach()
2483 s->maxdata = 0x3fff; in s626_auto_attach()
2484 s->range_table = &range_bipolar10; in s626_auto_attach()
2485 s->insn_write = s626_ao_insn_write; in s626_auto_attach()
2491 s = &dev->subdevices[2]; in s626_auto_attach()
2493 s->type = COMEDI_SUBD_DIO; in s626_auto_attach()
2494 s->subdev_flags = SDF_WRITABLE | SDF_READABLE; in s626_auto_attach()
2495 s->n_chan = 16; in s626_auto_attach()
2496 s->maxdata = 1; in s626_auto_attach()
2497 s->io_bits = 0xffff; in s626_auto_attach()
2498 s->private = (void *)0; /* DIO group 0 */ in s626_auto_attach()
2499 s->range_table = &range_digital; in s626_auto_attach()
2500 s->insn_config = s626_dio_insn_config; in s626_auto_attach()
2501 s->insn_bits = s626_dio_insn_bits; in s626_auto_attach()
2503 s = &dev->subdevices[3]; in s626_auto_attach()
2505 s->type = COMEDI_SUBD_DIO; in s626_auto_attach()
2506 s->subdev_flags = SDF_WRITABLE | SDF_READABLE; in s626_auto_attach()
2507 s->n_chan = 16; in s626_auto_attach()
2508 s->maxdata = 1; in s626_auto_attach()
2509 s->io_bits = 0xffff; in s626_auto_attach()
2510 s->private = (void *)1; /* DIO group 1 */ in s626_auto_attach()
2511 s->range_table = &range_digital; in s626_auto_attach()
2512 s->insn_config = s626_dio_insn_config; in s626_auto_attach()
2513 s->insn_bits = s626_dio_insn_bits; in s626_auto_attach()
2515 s = &dev->subdevices[4]; in s626_auto_attach()
2517 s->type = COMEDI_SUBD_DIO; in s626_auto_attach()
2518 s->subdev_flags = SDF_WRITABLE | SDF_READABLE; in s626_auto_attach()
2519 s->n_chan = 16; in s626_auto_attach()
2520 s->maxdata = 1; in s626_auto_attach()
2521 s->io_bits = 0xffff; in s626_auto_attach()
2522 s->private = (void *)2; /* DIO group 2 */ in s626_auto_attach()
2523 s->range_table = &range_digital; in s626_auto_attach()
2524 s->insn_config = s626_dio_insn_config; in s626_auto_attach()
2525 s->insn_bits = s626_dio_insn_bits; in s626_auto_attach()
2527 s = &dev->subdevices[5]; in s626_auto_attach()
2529 s->type = COMEDI_SUBD_COUNTER; in s626_auto_attach()
2530 s->subdev_flags = SDF_WRITABLE | SDF_READABLE | SDF_LSAMPL; in s626_auto_attach()
2531 s->n_chan = S626_ENCODER_CHANNELS; in s626_auto_attach()
2532 s->maxdata = 0xffffff; in s626_auto_attach()
2533 s->range_table = &range_unknown; in s626_auto_attach()
2534 s->insn_config = s626_enc_insn_config; in s626_auto_attach()
2535 s->insn_read = s626_enc_insn_read; in s626_auto_attach()
2536 s->insn_write = s626_enc_insn_write; in s626_auto_attach()
2543 struct s626_private *devpriv = dev->private; in s626_detach()
2547 devpriv->ai_cmd_running = 0; in s626_detach()
2549 if (dev->mmio) { in s626_detach()
2552 writel(0, dev->mmio + S626_P_IER); in s626_detach()
2555 dev->mmio + S626_P_ISR); in s626_detach()
2561 writel(S626_MC1_SHUTDOWN, dev->mmio + S626_P_MC1); in s626_detach()
2562 writel(S626_ACON1_BASE, dev->mmio + S626_P_ACON1); in s626_detach()
2579 return comedi_pci_auto_config(dev, &s626_driver, id->driver_data); in s626_pci_probe()