Lines Matching +full:dac +full:- +full:mode +full:- +full:mask

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.
73 * @counter_int_enabs: counter interrupt enable mask for MISC2 register.
76 * @ana_buf: DMA buffer used to receive ADC data and hold DAC data.
77 * @dac_wbuf: pointer to logical adrs of DMA buffer used to hold DAC data.
78 * @dacpol: image of DAC polarity register.
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()
204 * Replace the specified bits in a gate array register. Imports: mask
209 unsigned int mask, unsigned int wdata) in s626_debi_replace() argument
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()
219 val &= mask; 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()
300 /* *********** DAC FUNCTIONS *********** */
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()
352 * Private helper function: Transmit serial data to DAC via Audio
358 struct s626_private *devpriv = dev->private; in s626_send_dac()
361 /* START THE SERIAL CLOCK RUNNING ------------- */ in s626_send_dac()
364 * Assert DAC polarity control and enable gating of DAC serial clock in s626_send_dac()
371 * causing the signals to be inactive during the DAC write. 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()
377 /* Copy DAC setpoint value to DAC's output DMA buffer. */ 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()
383 * the DAC's data value to A2's output FIFO. The DMA transfer will 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()
427 * finished transferring the DAC's data DWORD from the output FIFO in s626_send_dac()
433 dev_err(dev->class_dev, 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()
452 * exiting this function. We must do this so that the next DAC in s626_send_dac()
460 * 2. While slots 2-5 are executing due to a late slot 0 trap. In in s626_send_dac()
463 * execution before setting up the next DAC setpoint DMA transfer 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()
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()
498 * the next DAC write. This is detected when FB_BUFFER2 MSB changes in s626_send_dac()
504 dev_err(dev->class_dev, in s626_send_dac()
512 * Private helper function: Write setpoint to an application DAC channel.
517 struct s626_private *devpriv = dev->private; in s626_set_dac()
523 * Adjust DAC data polarity and set up Polarity Control Register image. 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()
533 /* Limit DAC setpoint value to valid range. */ in s626_set_dac()
538 * Set up TSL2 records (aka "vectors") for DAC update. Vectors V2 in s626_set_dac()
539 * and V3 transmit the setpoint to the target DAC. V4 and V5 send in s626_set_dac()
540 * data to a non-existent TrimDac channel just to keep the clock in s626_set_dac()
541 * running after sending data to the target DAC. This is necessary in s626_set_dac()
543 * end of the target DAC's serial data stream. When the sequence in s626_set_dac()
545 * disables gating for the DAC clock and all DAC chip selects. in s626_set_dac()
548 /* Choose DAC chip select to be asserted */ in s626_set_dac()
550 /* Slot 2: Transmit high data byte to target DAC */ in s626_set_dac()
552 dev->mmio + S626_VECTPORT(2)); in s626_set_dac()
553 /* Slot 3: Transmit low data byte to target DAC */ 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()
559 /* Slot 5: running after writing target DAC's low data byte */ in s626_set_dac()
561 dev->mmio + S626_VECTPORT(5)); in s626_set_dac()
564 * Construct and transmit target DAC's serial packet: in s626_set_dac()
566 * and D<12:0> is the DAC setpoint. Append a WORD value (that writes in s626_set_dac()
567 * to a non-existent TrimDac channel) that serves to keep the clock in s626_set_dac()
568 * running after the packet has been sent to the target DAC. in s626_set_dac()
570 val = 0x0F000000; /* Continue clock after target DAC data 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()
576 val |= ((u32)(chan & 1) << 15); /* Address the DAC channel in s626_set_dac()
579 val |= (u32)dacdata; /* Include DAC setpoint data. */ 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()
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()
618 * Construct and transmit target DAC's serial packet: in s626_write_trim_dac()
620 * DAC channel's address, and D<7:0> is the DAC setpoint. Append a in s626_write_trim_dac()
621 * WORD value (that writes a channel 0 NOP command to a non-existent in s626_write_trim_dac()
622 * main DAC channel) that serves to keep the clock running after the in s626_write_trim_dac()
623 * packet has been sent to the target DAC. in s626_write_trim_dac()
627 * Address the DAC channel within the trimdac device. in s626_write_trim_dac()
628 * Include DAC setpoint data. in s626_write_trim_dac()
700 * Set the operating mode for the specified counter. The setup
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()
732 case S626_ENCMODE_EXTENDER: /* Extender Mode: */ in s626_set_mode_a()
733 /* Force to Timer mode (Extender valid only for B counters). */ in s626_set_mode_a()
735 case S626_ENCMODE_TIMER: /* Timer Mode: */ in s626_set_mode_a()
740 /* ClkPolA behaves as always-on clock enable. */ in s626_set_mode_a()
745 default: /* Counter Mode: */ in s626_set_mode_a()
759 * Force positive index polarity if IndxSrc is software-driven only, in s626_set_mode_a()
767 * enable mask to indicate the counter interrupt is disabled. in s626_set_mode_a()
770 devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) | in s626_set_mode_a()
775 * new counter operating mode. 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()
810 case S626_ENCMODE_TIMER: /* Timer Mode: */ in s626_set_mode_b()
815 /* ClkPolB behaves as always-on clock enable. */ in s626_set_mode_b()
820 case S626_ENCMODE_EXTENDER: /* Extender Mode: */ in s626_set_mode_b()
825 /* ClkPolB controls IndexB -- always set to active. */ in s626_set_mode_b()
830 default: /* Counter Mode: */ in s626_set_mode_b()
844 * Force positive index polarity if IndxSrc is software-driven only, in s626_set_mode_b()
852 * enable mask to indicate the counter interrupt is disabled. in s626_set_mode_b()
855 devpriv->counter_int_enabs &= ~(S626_OVERMASK(chan) | in s626_set_mode_b()
860 * new counter operating mode. in s626_set_mode_b()
884 unsigned int mask = S626_CRBMSK_INTCTRL; in s626_set_enable() local
888 mask |= S626_CRBMSK_CLKENAB_A; in s626_set_enable()
891 mask |= S626_CRBMSK_CLKENAB_B; in s626_set_enable()
894 s626_debi_replace(dev, S626_LP_CRB(chan), ~mask, set); in s626_set_enable()
906 u16 mask; in s626_set_load_trig() local
911 mask = S626_CRAMSK_LOADSRC_A; in s626_set_load_trig()
915 mask = S626_CRBMSK_LOADSRC_B | S626_CRBMSK_INTCTRL; in s626_set_load_trig()
918 s626_debi_replace(dev, reg, ~mask, set); in s626_set_load_trig()
929 struct s626_private *devpriv = dev->private; in s626_set_int_src()
960 /* Update MISC2 interrupt enable mask. */ 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()
1016 unsigned int mask = 1 << (chan - (16 * group)); in s626_dio_set_irq() local
1021 s626_debi_write(dev, S626_LP_WREDGSEL(group), mask | status); in s626_dio_set_irq()
1025 s626_debi_write(dev, S626_LP_WRINTSEL(group), mask | status); in s626_dio_set_irq()
1032 s626_debi_write(dev, S626_LP_WRCAPSEL(group), mask | status); in s626_dio_set_irq()
1038 unsigned int mask) in s626_dio_reset_irq() argument
1044 s626_debi_write(dev, S626_LP_WRCAPSEL(group), mask); in s626_dio_reset_irq()
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()
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()
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()
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()
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()
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()
1657 /* Operating mode is Timer. */ 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()
1976 unsigned long group = (unsigned long)s->private; in s626_dio_insn_bits()
1979 s626_debi_write(dev, S626_LP_WRDOUT(group), s->state); 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()
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()
2022 /* Operating mode is Counter. */ 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()
2105 /* Operating mode is counter. */ 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()
2180 * Configure DEBI operating mode 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()
2225 * Init audio interface functional attributes: set DAC/ADC in s626_initialize()
2226 * serial clock rates, invert DAC serial clock so that in s626_initialize()
2227 * DAC data setup times are satisfied, enable DAC serial in s626_initialize()
2230 writel(S626_ACON2_INIT, dev->mmio + S626_P_ACON2); 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()
2303 * Initialize the DAC interface 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()
2327 * where DAC data is buffered for A2 output DMA transfers. 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()
2343 * to the DAC devices. Slot 0 is a NOP that is used to trap TSL in s626_initialize()
2347 * pull-up resistor) is shifted in and stored to the MSB of in s626_initialize()
2354 dev->mmio + S626_VECTPORT(0)); in s626_initialize()
2360 * and sent to the DAC during subsequent slots. All remaining in s626_initialize()
2362 * DAC device. in s626_initialize()
2366 writel(S626_LF_A2, dev->mmio + S626_VECTPORT(1)); in s626_initialize()
2368 /* Start DAC's audio interface (TSL2) running */ in s626_initialize()
2369 writel(S626_ACON1_DACSTART, dev->mmio + S626_P_ACON1); in s626_initialize()
2390 * Init all DAC outputs to 0V and init all DAC setpoint and in s626_initialize()
2404 * the watchdog timer, set DIO channels 0-5 to operate in the in s626_initialize()
2405 * standard DIO (vs. counter overflow) mode, disable the battery 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()
2550 /* interrupt mask */ 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()