Lines Matching +full:counter +full:- +full:1
1 // SPDX-License-Identifier: GPL-2.0+
11 * Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
19 * This module is not used directly by end-users. Rather, it
26 * DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
27 * DAQ 6601/6602 User Manual (NI 322137B-01)
28 * 340934b.pdf DAQ-STC reference manual
38 static void ni_tio_configure_dma(struct ni_gpct *counter, in ni_tio_configure_dma() argument
41 struct ni_gpct_device *counter_dev = counter->counter_dev; in ni_tio_configure_dma()
42 unsigned int cidx = counter->counter_index; in ni_tio_configure_dma()
55 ni_tio_set_bits(counter, NITIO_INPUT_SEL_REG(cidx), mask, bits); in ni_tio_configure_dma()
57 switch (counter_dev->variant) { in ni_tio_configure_dma()
69 ni_tio_set_bits(counter, NITIO_DMA_CFG_REG(cidx), mask, bits); in ni_tio_configure_dma()
78 struct ni_gpct *counter = s->private; in ni_tio_input_inttrig() local
79 struct comedi_cmd *cmd = &s->async->cmd; in ni_tio_input_inttrig()
83 if (trig_num != cmd->start_arg) in ni_tio_input_inttrig()
84 return -EINVAL; in ni_tio_input_inttrig()
86 spin_lock_irqsave(&counter->lock, flags); in ni_tio_input_inttrig()
87 if (counter->mite_chan) in ni_tio_input_inttrig()
88 mite_dma_arm(counter->mite_chan); in ni_tio_input_inttrig()
90 ret = -EIO; in ni_tio_input_inttrig()
91 spin_unlock_irqrestore(&counter->lock, flags); in ni_tio_input_inttrig()
94 ret = ni_tio_arm(counter, true, NI_GPCT_ARM_IMMEDIATE); in ni_tio_input_inttrig()
95 s->async->inttrig = NULL; in ni_tio_input_inttrig()
102 struct ni_gpct *counter = s->private; in ni_tio_input_cmd() local
103 struct ni_gpct_device *counter_dev = counter->counter_dev; in ni_tio_input_cmd()
105 counter_dev->routing_tables; in ni_tio_input_cmd()
106 unsigned int cidx = counter->counter_index; in ni_tio_input_cmd()
107 struct comedi_async *async = s->async; in ni_tio_input_cmd()
108 struct comedi_cmd *cmd = &async->cmd; in ni_tio_input_cmd()
112 comedi_buf_write_alloc(s, async->prealloc_bufsz); in ni_tio_input_cmd()
113 counter->mite_chan->dir = COMEDI_INPUT; in ni_tio_input_cmd()
114 switch (counter_dev->variant) { in ni_tio_input_cmd()
117 mite_prep_dma(counter->mite_chan, 32, 32); in ni_tio_input_cmd()
120 mite_prep_dma(counter->mite_chan, 16, 32); in ni_tio_input_cmd()
123 ni_tio_set_bits(counter, NITIO_CMD_REG(cidx), GI_SAVE_TRACE, 0); in ni_tio_input_cmd()
124 ni_tio_configure_dma(counter, true, true); in ni_tio_input_cmd()
126 if (cmd->start_src == TRIG_INT) { in ni_tio_input_cmd()
127 async->inttrig = &ni_tio_input_inttrig; in ni_tio_input_cmd()
129 async->inttrig = NULL; in ni_tio_input_cmd()
130 mite_dma_arm(counter->mite_chan); in ni_tio_input_cmd()
132 if (cmd->start_src == TRIG_NOW) in ni_tio_input_cmd()
133 ret = ni_tio_arm(counter, true, NI_GPCT_ARM_IMMEDIATE); in ni_tio_input_cmd()
134 else if (cmd->start_src == TRIG_EXT) { in ni_tio_input_cmd()
135 int reg = CR_CHAN(cmd->start_arg); in ni_tio_input_cmd()
138 /* using a device-global name. lookup reg */ in ni_tio_input_cmd()
145 ret = ni_tio_arm(counter, true, reg); in ni_tio_input_cmd()
153 struct ni_gpct *counter = s->private; in ni_tio_output_cmd() local
155 dev_err(counter->counter_dev->dev->class_dev, in ni_tio_output_cmd()
157 return -ENOTSUPP; in ni_tio_output_cmd()
162 struct comedi_cmd *cmd = &s->async->cmd; in ni_tio_cmd_setup()
163 struct ni_gpct *counter = s->private; in ni_tio_cmd_setup() local
164 unsigned int cidx = counter->counter_index; in ni_tio_cmd_setup()
166 counter->counter_dev->routing_tables; in ni_tio_cmd_setup()
171 if (cmd->scan_begin_src == TRIG_EXT) { in ni_tio_cmd_setup()
172 set_gate_source = 1; in ni_tio_cmd_setup()
173 gate_source = cmd->scan_begin_arg; in ni_tio_cmd_setup()
174 } else if (cmd->convert_src == TRIG_EXT) { in ni_tio_cmd_setup()
175 set_gate_source = 1; in ni_tio_cmd_setup()
176 gate_source = cmd->convert_arg; in ni_tio_cmd_setup()
185 return -EINVAL; in ni_tio_cmd_setup()
186 retval = ni_tio_set_gate_src_raw(counter, 0, reg); in ni_tio_cmd_setup()
193 retval = ni_tio_set_gate_src(counter, 0, gate_source); in ni_tio_cmd_setup()
196 if (cmd->flags & CMDF_WAKE_EOS) { in ni_tio_cmd_setup()
197 ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), in ni_tio_cmd_setup()
206 struct ni_gpct *counter = s->private; in ni_tio_cmd() local
207 struct comedi_async *async = s->async; in ni_tio_cmd()
208 struct comedi_cmd *cmd = &async->cmd; in ni_tio_cmd()
212 spin_lock_irqsave(&counter->lock, flags); in ni_tio_cmd()
213 if (!counter->mite_chan) { in ni_tio_cmd()
214 dev_err(counter->counter_dev->dev->class_dev, in ni_tio_cmd()
216 dev_err(counter->counter_dev->dev->class_dev, in ni_tio_cmd()
217 "Interrupt-driven commands not yet implemented.\n"); in ni_tio_cmd()
218 retval = -EIO; in ni_tio_cmd()
222 if (cmd->flags & CMDF_WRITE) in ni_tio_cmd()
228 spin_unlock_irqrestore(&counter->lock, flags); in ni_tio_cmd()
237 struct ni_gpct *counter = s->private; in ni_tio_cmdtest() local
238 unsigned int cidx = counter->counter_index; in ni_tio_cmdtest()
240 counter->counter_dev->routing_tables; in ni_tio_cmdtest()
244 /* Step 1 : check if triggers are trivially valid */ in ni_tio_cmdtest()
247 if (ni_tio_counting_mode_registers_present(counter->counter_dev)) in ni_tio_cmdtest()
249 err |= comedi_check_trigger_src(&cmd->start_src, sources); in ni_tio_cmdtest()
251 err |= comedi_check_trigger_src(&cmd->scan_begin_src, in ni_tio_cmdtest()
253 err |= comedi_check_trigger_src(&cmd->convert_src, in ni_tio_cmdtest()
255 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); in ni_tio_cmdtest()
256 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE); in ni_tio_cmdtest()
259 return 1; in ni_tio_cmdtest()
263 err |= comedi_check_trigger_is_unique(cmd->start_src); in ni_tio_cmdtest()
264 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); in ni_tio_cmdtest()
265 err |= comedi_check_trigger_is_unique(cmd->convert_src); in ni_tio_cmdtest()
269 if (cmd->convert_src != TRIG_NOW && cmd->scan_begin_src != TRIG_FOLLOW) in ni_tio_cmdtest()
270 err |= -EINVAL; in ni_tio_cmdtest()
277 switch (cmd->start_src) { in ni_tio_cmdtest()
281 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); in ni_tio_cmdtest()
293 * err |= ni_check_trigger_arg(CR_CHAN(cmd->start_arg), in ni_tio_cmdtest()
305 if (cmd->scan_begin_src != TRIG_EXT) in ni_tio_cmdtest()
306 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0); in ni_tio_cmdtest()
308 err |= ni_check_trigger_arg(CR_CHAN(cmd->scan_begin_arg), in ni_tio_cmdtest()
311 if (cmd->convert_src != TRIG_EXT) in ni_tio_cmdtest()
312 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0); in ni_tio_cmdtest()
314 err |= ni_check_trigger_arg(CR_CHAN(cmd->convert_arg), in ni_tio_cmdtest()
317 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, in ni_tio_cmdtest()
318 cmd->chanlist_len); in ni_tio_cmdtest()
319 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); in ni_tio_cmdtest()
332 int ni_tio_cancel(struct ni_gpct *counter) in ni_tio_cancel() argument
334 unsigned int cidx = counter->counter_index; in ni_tio_cancel()
337 ni_tio_arm(counter, false, 0); in ni_tio_cancel()
338 spin_lock_irqsave(&counter->lock, flags); in ni_tio_cancel()
339 if (counter->mite_chan) in ni_tio_cancel()
340 mite_dma_disarm(counter->mite_chan); in ni_tio_cancel()
341 spin_unlock_irqrestore(&counter->lock, flags); in ni_tio_cancel()
342 ni_tio_configure_dma(counter, false, false); in ni_tio_cancel()
344 ni_tio_set_bits(counter, NITIO_INT_ENA_REG(cidx), in ni_tio_cancel()
350 static int should_ack_gate(struct ni_gpct *counter) in should_ack_gate() argument
355 switch (counter->counter_dev->variant) { in should_ack_gate()
360 * (the bits are not listed in register-level manual) in should_ack_gate()
362 return 1; in should_ack_gate()
365 * During buffered input counter operation for e-series, in should_ack_gate()
370 spin_lock_irqsave(&counter->lock, flags); in should_ack_gate()
372 if (!counter->mite_chan || in should_ack_gate()
373 counter->mite_chan->dir != COMEDI_INPUT || in should_ack_gate()
374 (mite_done(counter->mite_chan))) { in should_ack_gate()
375 retval = 1; in should_ack_gate()
378 spin_unlock_irqrestore(&counter->lock, flags); in should_ack_gate()
384 static void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, in ni_tio_acknowledge_and_confirm() argument
389 unsigned int cidx = counter->counter_index; in ni_tio_acknowledge_and_confirm()
390 const unsigned short gxx_status = ni_tio_read(counter, in ni_tio_acknowledge_and_confirm()
392 const unsigned short gi_status = ni_tio_read(counter, in ni_tio_acknowledge_and_confirm()
411 if (counter->counter_dev->variant != in ni_tio_acknowledge_and_confirm()
413 *gate_error = 1; in ni_tio_acknowledge_and_confirm()
419 *tc_error = 1; in ni_tio_acknowledge_and_confirm()
424 if (should_ack_gate(counter)) in ni_tio_acknowledge_and_confirm()
428 ni_tio_write(counter, ack, NITIO_INT_ACK_REG(cidx)); in ni_tio_acknowledge_and_confirm()
429 if (ni_tio_get_soft_copy(counter, NITIO_MODE_REG(cidx)) & in ni_tio_acknowledge_and_confirm()
431 if (ni_tio_read(counter, NITIO_STATUS2_REG(cidx)) & in ni_tio_acknowledge_and_confirm()
433 dev_info(counter->counter_dev->dev->class_dev, in ni_tio_acknowledge_and_confirm()
437 *perm_stale_data = 1; in ni_tio_acknowledge_and_confirm()
442 void ni_tio_acknowledge(struct ni_gpct *counter) in ni_tio_acknowledge() argument
444 ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL); in ni_tio_acknowledge()
448 void ni_tio_handle_interrupt(struct ni_gpct *counter, in ni_tio_handle_interrupt() argument
451 unsigned int cidx = counter->counter_index; in ni_tio_handle_interrupt()
457 ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error, in ni_tio_handle_interrupt()
460 dev_notice(counter->counter_dev->dev->class_dev, in ni_tio_handle_interrupt()
462 s->async->events |= COMEDI_CB_OVERFLOW; in ni_tio_handle_interrupt()
465 s->async->events |= COMEDI_CB_ERROR; in ni_tio_handle_interrupt()
466 switch (counter->counter_dev->variant) { in ni_tio_handle_interrupt()
469 if (ni_tio_read(counter, NITIO_DMA_STATUS_REG(cidx)) & in ni_tio_handle_interrupt()
471 dev_notice(counter->counter_dev->dev->class_dev, in ni_tio_handle_interrupt()
473 s->async->events |= COMEDI_CB_OVERFLOW; in ni_tio_handle_interrupt()
479 spin_lock_irqsave(&counter->lock, flags); in ni_tio_handle_interrupt()
480 if (counter->mite_chan) in ni_tio_handle_interrupt()
481 mite_ack_linkc(counter->mite_chan, s, true); in ni_tio_handle_interrupt()
482 spin_unlock_irqrestore(&counter->lock, flags); in ni_tio_handle_interrupt()
486 void ni_tio_set_mite_channel(struct ni_gpct *counter, in ni_tio_set_mite_channel() argument
491 spin_lock_irqsave(&counter->lock, flags); in ni_tio_set_mite_channel()
492 counter->mite_chan = mite_chan; in ni_tio_set_mite_channel()
493 spin_unlock_irqrestore(&counter->lock, flags); in ni_tio_set_mite_channel()
509 MODULE_DESCRIPTION("Comedi command support for NI general-purpose counters");